### Example Multi-Layer Setup Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Illustrates configuring WinDivert to intercept events across different layers. This allows for granular control over packet capture, connection tracking, and socket monitoring. ```c // Capture all packets at network layer HANDLE network = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 0, 0); // Monitor TCP connections at flow layer HANDLE flows = WinDivertOpen("tcp", WINDIVERT_LAYER_FLOW, 0, 0); // Block suspicious sockets at socket layer HANDLE socket = WinDivertOpen("tcp && localPort == 4444", WINDIVERT_LAYER_SOCKET, 1000, 0); ``` -------------------------------- ### Layer-Independent Fields: Basic Examples Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md Examples demonstrating the use of layer-independent fields like 'outbound', 'loopback', and 'length'. ```WinDivert Filter Language outbound // All outbound traffic ``` ```WinDivert Filter Language !loopback && outbound // Non-loopback outbound traffic ``` ```WinDivert Filter Language length > 1500 // Packets larger than 1500 bytes ``` ```WinDivert Filter Language random32 < 100000 // 1 in ~43000 chance (for sampling) ``` -------------------------------- ### Batch Send Example with WinDivertSendEx Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-core.md Demonstrates how to use WinDivertSendEx to send a batch of multiple packets. Ensure packet data and addresses are correctly populated before calling. ```c // Batch send multiple packets UINT8 packet_batch[10 * 1500]; // 10 packets of ~1500 bytes each WINDIVERT_ADDRESS addr_batch[10]; // ... fill in packet data and addresses ... if (!WinDivertSendEx(handle, packet_batch, 15000, NULL, 0, addr_batch, sizeof(addr_batch), NULL)) { printf("SendEx failed: %d\n", GetLastError()); } ``` -------------------------------- ### Example Priority Chain Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Demonstrates setting up multiple WinDivert handles with different priorities to create a processing chain. Higher priority handles are invoked first. ```c // First pass: collect statistics (highest priority) HANDLE stats = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 30000, WINDIVERT_FLAG_SNIFF); // Second pass: block specific traffic (medium priority) HANDLE firewall = WinDivertOpen("tcp.DstPort == 1234", WINDIVERT_LAYER_NETWORK, 0, 0); // Third pass: NAT/modify (low priority) HANDLE nat = WinDivertOpen("tcp", WINDIVERT_LAYER_NETWORK, -1000, 0); ``` -------------------------------- ### Validate Filter Syntax Without Installation Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Use WINDIVERT_FLAG_NO_INSTALL to open a handle and validate filter syntax without installing the filter in the kernel. This is useful for testing filter compilation. ```c // Validate filter syntax without installing it HANDLE handle = WinDivertOpen(user_filter, WINDIVERT_LAYER_NETWORK, 0, WINDIVERT_FLAG_NO_INSTALL); if (handle == INVALID_HANDLE_VALUE) { printf("Filter syntax error\n"); } else { printf("Filter is valid\n"); WinDivertClose(handle); } ``` -------------------------------- ### Receiving a Packet with WinDivertRecv Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-core.md This example demonstrates how to use WinDivertRecv to capture a network packet. It checks for errors and prints the received packet length and address information. ```c UINT8 packet[WINDIVERT_MTU_MAX]; UINT packet_len; WINDIVERT_ADDRESS addr; if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr)) { printf("Recv failed: %d\n", GetLastError()); } else { printf("Received packet: %u bytes\n", packet_len); printf("Layer: %d, Outbound: %d\n", addr.Layer, addr.Outbound); } ``` -------------------------------- ### Filter Syntax: Grouping Example Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md Use parentheses to explicitly group conditions for complex filter logic. ```WinDivert Filter Language (outbound && tcp.DstPort == 80) || (inbound && tcp.SrcPort == 443) ``` -------------------------------- ### Batch Packet Reception Example Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-core.md This C code snippet demonstrates how to receive a batch of up to 255 packets using WinDivertRecvEx. It includes receiving packet data and addresses, and notes the requirement for manual packet boundary detection. ```c // Batch receive up to 255 packets UINT8 packet_batch[WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX]; WINDIVERT_ADDRESS addr_batch[WINDIVERT_BATCH_MAX]; UINT recv_len, addr_len = sizeof(addr_batch); if (!WinDivertRecvEx(handle, packet_batch, sizeof(packet_batch), &recv_len, 0, addr_batch, &addr_len, NULL)) { printf("RecvEx failed: %d\n", GetLastError()); return; } // Parse individual packets from batch // (requires manual packet boundary detection) ``` -------------------------------- ### Basic Packet Capture and Re-injection Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md Captures network packets matching a filter and re-injects them. Ensure WinDivert is properly installed and handles are managed. ```c #include "windivert.h" #include int main() { HANDLE handle = WinDivertOpen("tcp", WINDIVERT_LAYER_NETWORK, 0, 0); if (handle == INVALID_HANDLE_VALUE) { printf("Failed to open WinDivert\n"); return 1; } UINT8 packet[WINDIVERT_MTU_MAX]; UINT packet_len; WINDIVERT_ADDRESS addr; while (WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr)) { printf("Captured %u-byte packet\n", packet_len); // Process packet... // Re-inject WinDivertSend(handle, packet, packet_len, NULL, &addr); } WinDivertClose(handle); return 0; } ``` -------------------------------- ### Filter HTTP GET and DNS Queries Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md Use payload access to filter for specific application-level data. The first example checks for an HTTP GET request on port 80, and the second checks for a DNS query flag. ```plaintext tcp.DstPort == 80 && tcp.Payload[0] == 'G' // HTTP GET udp.DstPort == 53 && packet16[22] == 0x0100 // DNS query flag ``` -------------------------------- ### Filter Syntax: Negation Examples Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md Prefix conditions with '!' to negate them, useful for excluding specific traffic types. ```WinDivert Filter Language !loopback // Non-loopback traffic ``` ```WinDivert Filter Language !tcp // Non-TCP traffic ``` ```WinDivert Filter Language !(outbound && tcp) // Not (outbound AND TCP) ``` -------------------------------- ### Reflection Layer Filter Examples Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md These filters apply to the Reflection layer, allowing you to match events related to handle openings and closures by specific processes or with certain flags. ```C event == 8 // Handle opened ``` ```C processId == 1234 // Process 1234 opened/closed handle ``` ```C layer == 0 && flags == 0x0001 // SNIFF mode on NETWORK layer ``` -------------------------------- ### Socket Layer Filter Examples Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md Use these filters to match network events on the Socket layer. They can be used to identify specific connection attempts, binds, or socket closures. ```C event == 4 && remotePort == 443 // Connect to HTTPS ``` ```C event == 3 && localPort == 4444 // Bind to port 4444 ``` ```C processId == 1234 && event == 7 // Process 1234 closes socket ``` ```C protocol == 17 && remoteAddr == 8.8.8.8 // DNS queries to Google ``` -------------------------------- ### WinDivertHelperParsePacket Batch Processing Loop Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html Example of how to iterate through a batch of packets using WinDivertHelperParsePacket. The function updates the packet pointer and length for the next iteration. ```c while (WinDivertHelperParsePacket(pPacket, packetLen, ..., &pPacket, &packetLen)) { ... } ``` -------------------------------- ### Re-inject a received packet using WinDivertSend Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-core.md Example of re-injecting a packet that was previously received. Ensure the WinDivert handle was opened with appropriate flags and the address structure is correctly populated. ```c // Re-inject a received packet WINDIVERT_ADDRESS addr; // ... receive packet data into buffer ... if (!WinDivertSend(handle, packet, packet_len, NULL, &addr)) { printf("Send failed: %d\n", GetLastError()); } ``` -------------------------------- ### WinDivertGetParam Function Signature Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html Gets a WinDivert parameter. Use this to retrieve current queue settings or driver version. ```c BOOL WinDivertGetParam( __in HANDLE handle, __in WINDIVERT_PARAM param, __out UINT64 *pValue ); ``` -------------------------------- ### Build WinDivert User-Mode Library Source: https://github.com/basil00/windivert/wiki/WinDivert-Documentation Builds the WinDivert user-mode library and sample programs using MinGW cross-compilers on Linux. Ensure WinDivert drivers are built first. ```bash sh mingw-build.sh ``` -------------------------------- ### Build WinDivert Drivers Source: https://github.com/basil00/windivert/wiki/WinDivert-Documentation Builds the WinDivert drivers from source. Requires Windows Driver Kit 7.1.0. Run in the appropriate build environment console. ```bash wddk-build.bat ``` -------------------------------- ### Get WinDivert Driver Major Version Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Retrieves the major version number of the WinDivert driver. This is a read-only parameter. ```c UINT64 major; if (WinDivertGetParam(handle, WINDIVERT_PARAM_VERSION_MAJOR, &major)) { printf("Driver major version: %llu\n", major); } ``` -------------------------------- ### Configuration Options Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md Details on configuring WinDivert handles, including parameters, flags, priority settings, and batch processing capabilities. ```APIDOC ## Configuration Options ### Description Configuration parameters, flags, and tuning options for WinDivert handles. ### Handle Parameters - `WINDIVERT_PARAM_QUEUE_LENGTH`: Sets the number of buffered packets (range: 32–16384, default: 4096). - `WINDIVERT_PARAM_QUEUE_TIME`: Sets the queue flush timeout in milliseconds (range: 100–16000, default: 2000). - `WINDIVERT_PARAM_QUEUE_SIZE`: Sets the maximum queue memory usage (range: 64 KB–32 MB, default: 4 MB). - `WINDIVERT_PARAM_VERSION_MAJOR`, `WINDIVERT_PARAM_VERSION_MINOR`: Read-only parameters for driver version. ### Handle Flags - `WINDIVERT_FLAG_SNIFF` (0x0001): Enables sniff mode for observation without packet diversion. - `WINDIVERT_FLAG_DROP` (0x0002): Configures the kernel to drop packets directly, bypassing user-mode delivery. - `WINDIVERT_FLAG_RECV_ONLY` (0x0004): Restricts the handle to only receiving packets. - `WINDIVERT_FLAG_SEND_ONLY` (0x0008): Restricts the handle to only sending packets. - `WINDIVERT_FLAG_NO_INSTALL` (0x0010): Validates a filter without installing it. - `WINDIVERT_FLAG_FRAGMENTS` (0x0020): Enables delivery of individual IP fragments. ### Priority Handles can be ordered using a priority value ranging from -30000 (lowest) to 30000 (highest). ### Batch Processing Supports processing up to 255 packets per call. Throughput can be tuned via `WINDIVERT_PARAM_QUEUE_LENGTH`. ``` -------------------------------- ### Configure and Receive Batch Packets Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md This C code snippet demonstrates how to configure and receive a batch of packets using WinDivertRecvEx. Ensure the packet and address buffers are adequately sized for the desired batch size. ```c #define BATCH_SIZE 64 UINT8 packet_buf[BATCH_SIZE * WINDIVERT_MTU_MAX]; WINDIVERT_ADDRESS addr_buf[BATCH_SIZE]; UINT recv_len, addr_len = sizeof(addr_buf); // Receive batch if (WinDivertRecvEx(handle, packet_buf, sizeof(packet_buf), &recv_len, 0, addr_buf, &addr_len, NULL)) { printf("Received %u bytes\n", recv_len); } ``` -------------------------------- ### Convert 64-bit Network to Host Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperNtohll to convert a 64-bit value from network byte order to host byte order. This function ensures correct interpretation of 64-bit network values. ```c UINT64 WinDivertHelperNtohll(UINT64 x); ``` -------------------------------- ### Get WinDivert Parameter Source: https://github.com/basil00/windivert/wiki/WinDivert-Documentation Retrieves the current value of a WinDivert parameter. Supports configuration and read-only parameters like driver version. ```c BOOL WinDivertGetParam( __in HANDLE handle, __in WINDIVERT_PARAM param, __out UINT64 *pValue); ``` -------------------------------- ### Filter Language Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md Reference for the WinDivert filter language, including operators, field selectors for various network layers, and example filter expressions. ```APIDOC ## Filter Language ### Description Syntax and elements of the WinDivert packet filter language. ### Operators - Boolean: `&&` (AND), `||` (OR), `!` (NOT). - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=`. ### Fields - Layer-independent: `outbound`, `inbound`, `loopback`, `impostor`, `length`, `random8/16/32`, `timestamp`, `fragment`. - Network layer (IP/IPv6): `ip`, `ipv6`, `ip.TTL`, `ip.Protocol`, `ip.SrcAddr`, `ip.DstAddr`, etc. - Transport layer (TCP/UDP): `tcp.Syn`, `tcp.Ack`, `tcp.Fin`, `tcp.Rst`, `tcp.Payload[N]`, `udp.SrcPort`, `udp.DstPort`, etc. - ICMP: `icmp.Type`, `icmp.Code`. - Flow layer: `event`, `processId`, `localAddr`, `remoteAddr`, `protocol`. - Socket layer: `event`, `processId`, `protocol`. - Reflection layer: `event`, `processId`, `layer`, `priority`, `flags`. ### Examples Filters can be constructed for port matching, protocol identification, address filtering, application protocol detection, and process-based filtering. ``` -------------------------------- ### Convert 32-bit Host to Network Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperHtonl to convert a 32-bit value from host byte order to network byte order. Prepare 32-bit data for network transmission using this function. ```c UINT32 WinDivertHelperHtonl(UINT32 x); ``` -------------------------------- ### Get WinDivert Driver Version Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Retrieves both the major and minor version numbers of the WinDivert driver. This is useful for checking compatibility or logging purposes. ```c UINT64 major, minor; WinDivertGetParam(handle, WINDIVERT_PARAM_VERSION_MAJOR, &major); WinDivertGetParam(handle, WINDIVERT_PARAM_VERSION_MINOR, &minor); printf("Driver version: %llu.%llu\n", major, minor); ``` -------------------------------- ### Convert 32-bit Network to Host Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperNtohl to convert a 32-bit value from network byte order to host byte order. This function is vital for processing 32-bit network data correctly. ```c UINT32 WinDivertHelperNtohl(UINT32 x); ``` -------------------------------- ### Convert 64-bit Host to Network Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperHtonll to convert a 64-bit value from host byte order to network byte order. This function is used to format 64-bit data for network transmission. ```c UINT64 WinDivertHelperHtonll(UINT64 x); ``` -------------------------------- ### Packet Modification Example Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md Modifies the destination port of TCP packets and recalculates checksums before re-injection. This snippet assumes a packet has already been captured and parsed. ```c PWINDIVERT_IPHDR ip_hdr; PWINDIVERT_TCPHDR tcp_hdr; if (WinDivertHelperParsePacket(packet, packet_len, &ip_hdr, NULL, NULL, NULL, NULL, &tcp_hdr, NULL, NULL, NULL, NULL, NULL)) { if (tcp_hdr != NULL) { // Modify TCP destination port tcp_hdr->DstPort = htons(8080); // Recalculate checksums WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0); // Re-inject WinDivertSend(handle, packet, packet_len, NULL, &addr); } } ``` -------------------------------- ### Example HTTP Filter Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html This filter selects outbound TCP packets destined for port 80, which typically represent HTTP traffic. It ensures the packet has a payload. ```C HANDLE handle = WinDivertOpen( "outbound and " "tcp.PayloadLength > 0 and " "tcp.DstPort == 80", 0, 0, 0); ``` -------------------------------- ### Open WinDivert to Capture All Traffic Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html Opens a WinDivert handle to capture all network traffic. Requires WinDivertOpen to be called. ```c HANDLE handle = WinDivertOpen("true", 0, 0, 0); ``` -------------------------------- ### Configure WinDivert for Low Latency Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Sets the kernel queue time to 100 milliseconds. Use smaller values for low-latency scenarios like real-time filtering or firewalling to ensure buffered packets reach user-mode quickly, at the cost of increased system overhead. ```c if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_TIME, 100)) { printf("Failed to set queue time\n"); } ``` -------------------------------- ### Convert 16-bit Network to Host Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperNtohs to convert a 16-bit value from network byte order to host byte order. This is essential for correctly interpreting 16-bit network data on the local machine. ```c UINT16 WinDivertHelperNtohs(UINT16 x); ``` -------------------------------- ### Convert 16-bit Host to Network Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperHtons to convert a 16-bit value from host byte order to network byte order. This is necessary when sending 16-bit data over a network. ```c UINT16 WinDivertHelperHtons(UINT16 x); ``` -------------------------------- ### Implement Simple Firewall Rule Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md Drop inbound TCP connections with the SYN flag that are destined for internal IP address ranges. ```c // Drop inbound connections to internal addresses WinDivertOpen( "inbound && tcp.Syn && (ip.DstAddr >= 167772160 && ip.DstAddr <= 167772415)", WINDIVERT_LAYER_NETWORK, 0, WINDIVERT_FLAG_DROP); ``` -------------------------------- ### Filter Validation Example Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md Validates a WinDivert filter string to ensure it is syntactically correct before use. This helps prevent runtime errors due to invalid filter expressions. ```c const char *filter = "tcp.DstPort == 443"; const char *error_str = NULL; UINT error_pos = 0; char compiled[256]; if (!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_NETWORK, compiled, sizeof(compiled), &error_str, &error_pos)) { printf("Filter error at position %u: %s\n", error_pos, error_str); } else { printf("Filter is valid\n"); } ``` -------------------------------- ### Accessing Packet Information with WINDIVERT_ADDRESS Source: https://github.com/basil00/windivert/blob/master/_autodocs/types.md Demonstrates how to check packet direction (outbound/inbound), IP version (IPv4/IPv6), and layer-specific information using the WINDIVERT_ADDRESS structure. ```c WINDIVERT_ADDRESS addr; // ... receive packet ... if (addr.Outbound) { printf("Outbound packet\n"); } else { printf("Inbound packet\n"); } if (addr.IPv6) { printf("IPv6 packet\n"); } if (addr.Layer == WINDIVERT_LAYER_NETWORK) { printf("Interface: %u\n", addr.Network.IfIdx); } ``` -------------------------------- ### Uninstall WinDivert using windivertctl Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html Use the windivertctl sample program to uninstall the WinDivert driver. This is an alternative to manual service management. ```bash windivertctl uninstall ``` -------------------------------- ### Open WinDivert Handle for Outbound TCP Traffic Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-core.md Opens a WinDivert handle to intercept all outbound TCP traffic. Requires administrator privileges. Ensure the WinDivert driver is installed. ```c #include "windivert.h" #include int main() { // Divert all outbound TCP traffic HANDLE handle = WinDivertOpen( "outbound && tcp", WINDIVERT_LAYER_NETWORK, 0, 0 ); if (handle == INVALID_HANDLE_VALUE) { printf("Failed to open WinDivert: %d\n", GetLastError()); return 1; } // Use handle... WinDivertClose(handle); return 0; } ``` -------------------------------- ### Get Windows Error Message String Source: https://github.com/basil00/windivert/blob/master/_autodocs/errors.md Retrieves a human-readable error message string for a given Windows error code using FormatMessageA. Ensure to free the allocated buffer with LocalFree. ```c #include #include void PrintErrorMessage(DWORD err) { LPSTR message = NULL; FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, (LPSTR)&message, 0, NULL); if (message) { printf("Error %u: %s\n", err, message); LocalFree(message); } } ``` -------------------------------- ### Basic WinDivert Application Template Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html This template outlines the fundamental structure for a WinDivert application using the WINDIVERT_LAYER_NETWORK layer. It includes opening a handle and entering a capture-modify-reinject loop. ```C HANDLE handle; // WinDivert handle WINDIVERT_ADDRESS addr; // Packet address char packet[MAXBUF]; // Packet buffer UINT packetLen; // Open some filter handle = WinDivertOpen("...", WINDIVERT_LAYER_NETWORK, 0, 0); if (handle == INVALID_HANDLE_VALUE) { // Handle error exit(1) } ``` -------------------------------- ### Configure Fragment Handling Handle Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Use WINDIVERT_FLAG_FRAGMENTS to divert IP fragments individually instead of reassembling them. This is relevant for low-level fragment manipulation. ```c // Handle IP fragments individually HANDLE handle = WinDivertOpen("ip && ip.MF || ip.FragOff", WINDIVERT_LAYER_NETWORK, 0, WINDIVERT_FLAG_FRAGMENTS); ``` -------------------------------- ### Get WinDivert Queue Length Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-core.md Use WinDivertGetParam to retrieve the current queue length of a WinDivert handle. The retrieved value is stored in the provided UINT64 pointer. Check the return value for success. ```c BOOL WinDivertGetParam( HANDLE handle, WINDIVERT_PARAM param, UINT64 *pValue); UINT64 queue_len; if (!WinDivertGetParam(handle, WINDIVERT_PARAM_QUEUE_LENGTH, &queue_len)) { printf("GetParam failed: %d\n", GetLastError()); } else { printf("Queue length: %llu\n", queue_len); } ``` -------------------------------- ### Filter Flow Layer Events Source: https://github.com/basil00/windivert/blob/master/_autodocs/filter-language.md Filter network traffic based on flow layer events. Examples include identifying established connections, filtering for outbound HTTPS traffic, and isolating traffic from a specific process. ```plaintext event == 1 // Connection established protocol == 6 && remotePort == 443 // Outbound HTTPS processId == 1234 // Traffic from process 1234 ``` -------------------------------- ### Safe WinDivertOpen with Detailed Error Reporting Source: https://github.com/basil00/windivert/blob/master/_autodocs/errors.md Opens a WinDivert handle with comprehensive error checking. It attempts to provide more specific error messages for invalid parameters by compiling the filter, and reports issues like missing administrator privileges or the driver not being installed. ```c #include "windivert.h" #include #include HANDLE OpenWinDivertHandle(const char *filter, WINDIVERT_LAYER layer) { HANDLE handle = WinDivertOpen(filter, layer, 0, 0); if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_INVALID_PARAMETER) { // Try to compile filter for better error info char object[256]; const char *error_str = NULL; UINT error_pos = 0; if (!WinDivertHelperCompileFilter(filter, layer, object, sizeof(object), &error_str, &error_pos)) { printf("Filter syntax error at position %u: %s\n", error_pos, error_str); } } else if (err == ERROR_ACCESS_DENIED) { printf("Error: Administrator privileges required\n"); } else if (err == ERROR_FILE_NOT_FOUND) { printf("Error: WinDivert driver not installed\n"); } else { printf("Error: Failed to open WinDivert handle (%u)\n", err); } return INVALID_HANDLE_VALUE; } return handle; } ``` -------------------------------- ### Core API Functions Source: https://github.com/basil00/windivert/blob/master/_autodocs/README.md This section details the core functions for interacting with WinDivert, including opening and closing handles, receiving and sending packets, and managing handle parameters. ```APIDOC ## Core API Functions ### Description Core functions for packet I/O operations with WinDivert. ### API Functions - `WinDivertOpen()`: Opens a WinDivert handle for packet capture and manipulation. - `WinDivertRecv()` / `WinDivertRecvEx()`: Receives network packets from the WinDivert handle. - `WinDivertSend()` / `WinDivertSendEx()`: Sends or injects network packets using the WinDivert handle. - `WinDivertClose()`: Closes an existing WinDivert handle, releasing resources. - `WinDivertSetParam()`: Sets a parameter for the WinDivert handle. - `WinDivertGetParam()`: Retrieves the value of a parameter for the WinDivert handle. ``` -------------------------------- ### Configure Sniff and Receive-Only Handle Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Combine WINDIVERT_FLAG_SNIFF and WINDIVERT_FLAG_RECV_ONLY to create a handle that observes traffic without the capability to modify it. ```c // Observe traffic without capability to modify HANDLE handle = WinDivertOpen("tcp", WINDIVERT_LAYER_NETWORK, 0, WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY); ``` -------------------------------- ### WinDivertOpen Source: https://github.com/basil00/windivert/wiki/WinDivert-Documentation Opens a WinDivert handle to capture and/or modify network packets. This is the entry point for using the WinDivert API. ```APIDOC ## WinDivertOpen ### Description Opens a WinDivert handle to capture and/or modify network packets. This is the entry point for using the WinDivert API. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Open WinDivert for Inbound TCP SYNs Source: https://github.com/basil00/windivert/blob/master/doc/windivert.html Opens a WinDivert handle to capture inbound TCP SYN packets. Requires WinDivertOpen to be called. ```c HANDLE handle = WinDivertOpen( "inbound and " "tcp.Syn", 0, 0, 0 ); ``` -------------------------------- ### Configure WinDivert for Memory Constraints Source: https://github.com/basil00/windivert/blob/master/_autodocs/configuration.md Sets the kernel queue size to 1 MB. This is useful for memory-constrained systems to limit the total memory consumed by buffered packets. ```c if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_SIZE, 1048576)) { printf("Failed to set queue size (1 MB limit)\n"); } ``` -------------------------------- ### Convert IPv6 Address Network to Host Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperNtohIPv6Address for in-place conversion of an IPv6 address from network byte order to host byte order. This is useful for displaying IPv6 addresses correctly. ```c void WinDivertHelperNtohIPv6Address( const UINT *inAddr, UINT *outAddr); ``` -------------------------------- ### Core Packet I/O Functions Source: https://github.com/basil00/windivert/blob/master/_autodocs/INDEX.md Reference for core functions used for opening, reading, writing, and closing WinDivert handles, as well as managing parameters. ```APIDOC ## Core Functions ### WinDivertOpen #### Description Opens a WinDivert handle for packet capture or injection. #### Method N/A (Function Call) #### Parameters - **filter** (const WCHAR*) - Required - The filter string to apply. - **layer** (WINDIVERT_LAYER) - Required - The layer to capture/inject packets from/to. - **priority** (UINT16) - Required - The priority of the handle. - **flags** (UINT64) - Required - Flags to configure handle behavior. #### Return Value Returns a handle to WinDivert or NULL on failure. ### WinDivertRecv #### Description Receives a captured packet from a WinDivert handle. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **packet** (PVOID) - Required - Buffer to store the packet. - **packetLen** (UINT32) - Required - Maximum size of the packet buffer. - **recvLen** (UINT32*) - Optional - Actual length of the received packet. - **addr** (WINDIVERT_ADDRESS*) - Optional - Address information for the packet. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertRecvEx #### Description Receives a captured packet from a WinDivert handle with extended options. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **packet** (PVOID) - Required - Buffer to store the packet. - **packetLen** (UINT32) - Required - Maximum size of the packet buffer. - **recvLen** (UINT32*) - Optional - Actual length of the received packet. - **flags** (UINT32) - Required - Extended receive flags. - **addr** (WINDIVERT_ADDRESS*) - Optional - Address information for the packet. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertSend #### Description Sends a packet through a WinDivert handle for injection. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **packet** (PVOID) - Required - Buffer containing the packet to send. - **packetLen** (UINT32) - Required - Length of the packet to send. - **addr** (WINDIVERT_ADDRESS*) - Optional - Address information for the packet. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertSendEx #### Description Sends a packet through a WinDivert handle for injection with extended options. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **packet** (PVOID) - Required - Buffer containing the packet to send. - **packetLen** (UINT32) - Required - Length of the packet to send. - **flags** (UINT32) - Required - Extended send flags. - **addr** (WINDIVERT_ADDRESS*) - Optional - Address information for the packet. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertShutdown #### Description Shuts down a WinDivert handle. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **shutdown** (WINDIVERT_SHUTDOWN) - Required - Shutdown mode. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertClose #### Description Closes a WinDivert handle. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertSetParam #### Description Sets a parameter for a WinDivert handle. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **param** (WINDIVERT_PARAM) - Required - The parameter to set. - **value** (PVOID) - Required - The value to set the parameter to. - **valueLen** (UINT32) - Required - The length of the value. #### Return Value Returns TRUE on success, FALSE on failure. ### WinDivertGetParam #### Description Gets a parameter for a WinDivert handle. #### Method N/A (Function Call) #### Parameters - **handle** (HANDLE) - Required - The WinDivert handle. - **param** (WINDIVERT_PARAM) - Required - The parameter to get. - **value** (PVOID) - Required - Buffer to store the parameter value. - **valueLen** (UINT32*) - Required - The length of the value buffer. #### Return Value Returns TRUE on success, FALSE on failure. ``` -------------------------------- ### Format IPv6 Address to String Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Formats a binary IPv6 address (stored as an array of UINT32) into its string representation. The output buffer must be at least 46 bytes to accommodate a full IPv6 address. ```c char addr_str[46]; UINT32 addr[4] = { ... }; // IPv6 address bytes if (WinDivertHelperFormatIPv6Address(addr, addr_str, sizeof(addr_str))) { printf("Address: %s\n", addr_str); } ``` -------------------------------- ### Format IPv4 Address to String Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Formats a binary IPv4 address (network byte order) into a dotted-decimal string. Ensure the provided buffer is large enough (minimum 16 bytes) to hold the formatted address. ```c char addr_str[16]; UINT32 addr = 0xC0A80101; // 192.168.1.1 in network byte order if (WinDivertHelperFormatIPv4Address(addr, addr_str, sizeof(addr_str))) { printf("Address: %s\n", addr_str); } ``` -------------------------------- ### Convert IPv6 Address Host to Network Byte Order (C) Source: https://github.com/basil00/windivert/blob/master/_autodocs/api-reference/windivert-helpers.md Use WinDivertHelperHtonIPv6Address to convert an IPv6 address from host byte order to network byte order. This function prepares IPv6 addresses for network transmission. ```c void WinDivertHelperHtonIPv6Address( const UINT *inAddr, UINT *outAddr); ``` -------------------------------- ### Host to Network Byte Order Conversion Functions Source: https://github.com/basil00/windivert/wiki/WinDivert-Documentation These functions convert values from host byte order to network byte order. They are essential for preparing data to be sent over a network. ```c UINT16 WinDivertHelperHtons( __in UINT16 x ); UINT32 WinDivertHelperHtonl( __in UINT32 x ); UINT64 WinDivertHelperHtonll( __in UINT64 x ); void WinDivertHelperHtonIpv6Address( __in const UINT *inAddr, __out UINT *outAddr ); ```