Open gvanem opened 7 months ago
I think Windows is a bit different from most if not all UN*Xes, i that it loops back traffic (probably both explicitly to 127.0.0.1 and traffic sent to an IP address assigned to one of the machine's own interfaces) without sending it through a "loopback adapter".
At least on macOS:
$ ifconfig lo0
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=201<PERFORMNUD,DAD>
so the loopback interface has both
#define IFCAP_RXCSUM 0x00001 /* can offload checksum on RX */
#define IFCAP_TXCSUM 0x00002 /* can offload checksum on TX */
supported - which doesn't really mean that the checksum is offloaded, as there's no NIC to which to offload it, it just means "if memory and the networking stack can't be trusted not to corrupt the packet, we have bigger problems, so don't bother with checksumming loopback traffic".
And, if I run tcpdump -v -i lo0
and ping 127.0.0.1
in parallel, I do, in fact, get
10:56:36.704203 IP (tos 0x0, ttl 64, id 45714, offset 0, flags [none], proto ICMP (1), length 84, bad cksum 0 (->ca14)!)
localhost > localhost: ICMP echo request, id 25009, seq 8, length 64
10:56:36.704252 IP (tos 0x0, ttl 64, id 18475, offset 0, flags [none], proto ICMP (1), length 84, bad cksum 0 (->347c)!)
localhost > localhost: ICMP echo reply, id 25009, seq 8, length 64
10:56:37.704843 IP (tos 0x0, ttl 64, id 28446, offset 0, flags [none], proto ICMP (1), length 84, bad cksum 0 (->d89)!)
localhost > localhost: ICMP echo request, id 25009, seq 9, length 64
10:56:37.704869 IP (tos 0x0, ttl 64, id 7596, offset 0, flags [none], proto ICMP (1), length 84, bad cksum 0 (->5efb)!)
localhost > localhost: ICMP echo reply, id 25009, seq 9, length 64
10:56:38.708813 IP (tos 0x0, ttl 64, id 20941, offset 0, flags [none], proto ICMP (1), length 84, bad cksum 0 (->2ada)!)
localhost > localhost: ICMP echo request, id 25009, seq 10, length 64
10:56:38.708858 IP (tos 0x0, ttl 64, id 39189, offset 0, flags [none], proto ICMP (1), length 84, bad cksum 0 (->e391)!)
localhost > localhost: ICMP echo reply, id 25009, seq 10, length 64
so the same thing is happening there. I suspect the same would happen on Linux/*BSD/Solaris/AIX/etc.
Windows, not having a loopback device in its networking stack, may not have a way to indicate through "query network adapter" calls, but I suspect the same thing is happening here.
Npcap's loopback adapter, as I understand it, is a special hack to allow that traffic to be captured, so you can't query its checksum-offloading using ipconfig
. However, if libpcap were to be enhanced to provide a way to get checksum offloading feature information, Npcap could either try to find out what Windows is doing for loopback traffic, if there's a way to do that, or could just say "yup, loopback traffic gets IP checksums offloaded". (I don't know why it doesn't offload TCP/UDP checksums; perhaps neither TCP nor UDP knows that the packets will go over the loopback code path.)
If loopback were enhanced in that fashion, tcpdump could avoid checking the checksums if they're marked as offloaded and, if libpcap is also enhanced to read and write pcapng files, and pcapng were to provide checksum offloading indications either in IDBs or EPBs, tcpdump (and Wireshark/TShark) could also avoid checking it in pcapng capture files.
If loopback were enhanced in that fashion, tcpdump could avoid checking the checksums if they're marked as offloaded ...
That would be nice to avoid all this noise. Check for something like:
if ((pcap_dev->flags & PCAP_IF_LOOPBACK) &&
!(pcap_dev->flag & PCAP_IF_LOOPBACK_NO_CHECKSUM))
// do not print 'cksum 0'
...
But where could libpcap get this info from? IpHlpAPI is of no real help here.
!(pcap_dev->flag & PCAP_IF_LOOPBACK_NO_CHECKSUM))
That should be done for all adapters, at least for transmitted packets, not just the loopback adapter.
But where could libpcap get this info from? IpHlpAPI is of no real help here.
If we go wandering in the Land of OID, we find OID_TCP_OFFLOAD_CURRENT_CONFIG
, which seems to provide a whole bunch of "what sort of offloading is being done" information; the Npcap driver provides an ioctlDeviceIoControl()
to get and set OIDs, with its Packet32 library providing PacketRequest()
to do that, and libpcap on Windows providing oid_get_request()
/oid_set_request()
, so libpcap could use that.
I'm not sure whether the NDIS OID get/set calls would work on the loopback device, but, if not, at one of those three layers - driver, Packet32 or libpcap - the loopback device could be handled specially.
Many years ago I made a change for windump -Dvv
to be extra verbose:
7. \Device\NPF_{6568F487-0016-453C-8C29-5C28DEDF27A0} [Up, Running, Connected]
Description: Realtek PCIe GbE Family Controller
Unicast Addr: fe80::a087:37e9:a635:f23c, 10.0.0.10
Anycast Addr: <None>
Multicast Addr: ff01::1, ff02::1, ff02::c, ff02::fb, ff02::1:3, ff02::1:ff00:4f34, ff02::1:ff06:7ac, ff02::1:ff35:f23c, ff02::1:ff37:1585, ff02::1:ff41:5ffc
DNS Servers: 193.213.112.4, 8.8.8.8
IfType: Ethernet (6)
OperStatus: Up (1)
MAC address: D8:BB:C1:06:16:48 (AMD-PC, Micro-Star INTL CO., LTD.)
MTU: 1480
Tx speed: 1 GB/s
Rx speed: 1 GB/s
WINS servers: <None>
Gateways: <None>
IPv4 metric: 25
IPv6 metric: 25
Adapter Flags: NDIS
Phys media: Unspecified
Link state: <failed>
NDIS ver: 6.40
Drvr version: 10.54.1111.2021
Drvr date: 11-11-2021
Drvr installed: 10-06-2023, 09:42:19
Dev. instance: PCI\VEN_10EC&DEV_8168&SUBSYS_7C911462&REV_15\6&10d9d0ba&0&0038020A
PnPCapabilities: 0x0100
ServiceName: rt640x64
Available OIDs for this adapter:
0x00010101 OID_GEN_SUPPORTED_LIST
...
160 OIDs (2 unknown, 40 duplicates).
8. \Device\NPF_Loopback [Up, Running, Loopback]
Description: Adapter for loopback traffic capture
Adapter Flags: <N/A>
Phys media: <N/A>
Link state: <N/A>
NDIS ver: <N/A>
Available OIDs for this adapter:
<None>
My code is simply calling:
struct {
PACKET_OID_DATA oidData;
DWORD values [1000];
} oid;
BOOL rc;
memset (&oid, 0, sizeof(oid));
oid.oidData.Oid = OID_GEN_SUPPORTED_LIST;
oid.oidData.Length = sizeof(oid);
if (air_hnd)
rc = (DeviceIoControl(air_hnd, oid.oidData.Oid, NULL, 0, NULL, 0, &oid.oidData.Length, NULL) == TRUE);
else rc = (PacketRequest(adapter, FALSE, &oid.oidData) == TRUE);
if (rc) {
// dump all OIDs
}
Now with NPcap and a PacketRequest(adapter,..);
for the Loopback, rc == FALSE
. Yikes!
So I guess a Loopback Adapter does not try to resemble a physical adapter at all. But I've never tested my code with such a strange beast (since I installed NPcap 1.79 only last week).
But other pseudo-adapters like WAN Miniport, do indeed look like a physical adapter:
3. \Device\NPF_{7D3F744A-F0AD-44BD-82C8-B27C74755C6A} [Up, Running, Connected]
Description: WAN Miniport (IP)
Unicast Addr: <None>
Anycast Addr: <None>
Multicast Addr: <None>
DNS Servers: <None>
IfType: Ethernet (6)
OperStatus: Up (1)
MAC address: <None>
MTU: 1500
Tx speed: 0
Rx speed: 0
WINS servers: <None>
Gateways: <None>
Adapter Flags: NDIS
Phys media: Unspecified
Link state: <failed>
NDIS ver: 6.30
Drvr version: 10.0.19041.1
Drvr date: 6-21-2006
Drvr installed: 15-07-2022, 21:35:00
Dev. instance: SWD\MSRRAS\MS_NDISWANIP
PnPCapabilities: <Unknown>
ServiceName: NdisWan
Available OIDs for this adapter:
0x00010101 OID_GEN_SUPPORTED_LIST
...
104 OIDs
I installed NPcap 1.79 some days ago. And it works fine. Thanks! Except that I noted in
tcpdump.exe
(orwindump.exe
) all the received IP (?) packets are printed with acksum 0
:I'm not sure if this is a feature or short-coming of NPcap or not. Or windump? I cannot imagine. I have not enabled checksum offload of my physical networks adapters (if that would make a difference. I think not).
I also see these
cksum 0
for loopback traffic inside the Thunderbird email client (when I press About | Check for updates etc.).To Reproduce
In a Windows-shell (like
CMD
, yuk!):and notice all the
cksum 0
texts. Seems only the IP-checksums are0
and the TCP/UDP check-sums are OK.Expected behavior
I want checksum to appear as they are sent by
ping.exe
, Thunderbird or whatever.Screenshots
A
start windump.exe --color -vvtni \Device\NPF_Loopback
followed by aping -n 3 -4 127.0.0.1
look like: