WinDivert 1.2 Upgrade Guide =========================== This is a quick guide for developers who wish to upgrade their applications from WinDivert1.1.X to WinDivert1.2.Y. 1 Checksums ----------- WinDivert1.1.X will automatically calculate checksums by default unless explicitly disabled by the `WINDIVERT_FLAG_NO_CHECKSUM` flag. This was inefficient for many applications that did not bother to set the flag. WinDivert1.2.Y changes the behavior by effectively making the "no checksum" mode the default. Under the new behavior, checksum fields returned by `WinDivertRecv()` or `WinDivertRecvEx()` will either be valid (if already present) or be set to zero (if absent). If your application already used the `WINDIVERT_FLAG_NO_CHECKSUM` flag, you can simply remove that flag, e.g.: HANDLE handle = WinDivertOpen(filter, layer, priority, flags | WINDIVERT_FLAG_NO_CHECKSUM); becomes: HANDLE handle = WinDivertOpen(filter, layer, priority, flags); For applications that desire the old behavior, the checksums can be recovered via an explicit call to `WinDivertHelperCalcChecksums()` as follows: BOOL res = WinDivertRecv(handle, packet, &packet_len, &addr, &read_len); if (!res) { // Handle errors } WinDivertHelperCalcChecksums(packet, packet_len, WINDIVERT_HELPER_NO_REPLACE); The `WINDIVERT_HELPER_NO_REPLACE` flag ensures `WinDivertHelperCalcChecksums()` does not replace non-zero checksum fields that are already valid. 2 New Filter Syntax ------------------- WinDivert1.2.Y extends the existing WinDivert filtering language with C-style conditional expressions, i.e.: (Condition? TrueFilter: FalseFilter) where `Condition`, `TrueFilter` and `FalseFilte`r are themselves filter language expressions. For example, the following filter captures all TCP/UDP traffic with destination port 1000. (tcp? tcp.DstPort == 1000: udp and udp.DstPort == 1000) Conditional expressions can also be used for negation: (Filter? false: true) Conditional expressions allow for higher-level rule-based style filters that are generally easier to define. 3 New Filter Functions ---------------------- Passing an invalid filter string to `WinDivertOpen()` will cause failure with `GetLastError()` returning `ERROR_INVALID_PARAMETER`. Under WinDivert1.1.X there was no way to determine the exact cause of the error. WinDivert1.2.Y introduces a new function, `WinDivertHelperCheckFilter()`, that can be used to determine the cause of filter string errors more accurately. This can be used for better error messages, e.g.: BOOL res = WinDivertOpen(filter, layer, ...); if (!res) { // Handle errors: const char *errStr; UINT errPos; res = WinDivertHelperCheckFilter(filter, layer, &errStr, &errPos); if (!res) { fprintf(stderr, "bad filter string: %s (pos=%u)\n", errStr, errPos); exit(EXIT_FAILURE); } ... } For example, if filter=`ip and tcp.Port == 80` then the error will be: bad filter string: Filter expression contains a bad token (pos=7) The error is that "tcp.Port" is an invalid token (should be `tcp.DstPort` or `tcp.SrcPort`) WinDivert1.2.Y also introduces a `WinDivertHelperEvalFilter()` that can be used to evaluate a filter on a given packet outside of the driver. This function is mainly intended for debugging purposes.