It appears that there is still a bug in the checksum correction of ICMP packets which return through a NAT machine in response to an earlier sent out UDP packet from inside. The setup is a follows:
inside box NAT box internet ------------------------------------------------------------ 192.168.128.2 ---- 192.168.128.1|public_ip ---- 80.81.31.28 All machines run FreeBSD 4.10-STABLE (using the recently committed ipfilter-3.4.35). 192.168.128.2 does a "echo | nc -u 80.81.31.28 54321". Since nothing listens on port 54321, 80.81.31.28 sends back an ICMP packet type 3/3. Running ethereal on the inside wire we can capture this packet: Frame 2 (70 bytes on wire, 70 bytes captured) Ethernet II, Src: 00:02:b3:1f:25:dc, Dst: 00:e0:18:98:46:ef Internet Protocol, Src Addr: 80.81.31.28 (80.81.31.28), Dst Addr: 192.168.128.2 (192.168.128.2) Version: 4 Header length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00) Total Length: 56 Identification: 0xab72 Flags: 0x00 Fragment offset: 0 Time to live: 55 Protocol: ICMP (0x01) Header checksum: 0x283b (correct) Source: 80.81.31.28 (80.81.31.28) Destination: 192.168.128.2 (192.168.128.2) Internet Control Message Protocol Type: 3 (Destination unreachable) Code: 3 (Port unreachable) Checksum: 0x23b3 (incorrect, should be 0x9a4c) XXX ----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Internet Protocol, Src Addr: 192.168.128.2 (192.168.128.2), Dst Addr: 80.81.31.28 (80.81.31.28) Version: 4 Header length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00) Total Length: 7424 Identification: 0xab72 Flags: 0x00 Fragment offset: 0 Time to live: 54 Protocol: UDP (0x11) Header checksum: 0x2946 (incorrect, should be 0x0c63) Source: 192.168.128.2 (192.168.128.2) Destination: 80.81.31.28 (80.81.31.28) User Datagram Protocol, Src Port: 2723 (2723), Dst Port: 54321 (54321) Source port: 2723 (2723) Destination port: 54321 (54321) Length: 9 Checksum: 0x66ef The checksum in questions is marked with XXX. The problem happens only if the source port was changed by the NAT box due to the map tun0 192.168.128.0/24 -> 0/32 portmap tcp/udp 32768:65000 line. If we remove the "portmap ..." option, the ICMP packets won't have the checksum error and nc will quit immediately. I assmue that ip_nat.c doesn't take the changed port properly into account when recalculating the checksum of the "inner" ICMP packet. Everything worked before 3.4.35 was MFC'ed to FreeBSD 4.10-STABLE. The problems also mainfests when doing a traceroute from the inner box to the outer world as the resulting ICMP packets won't get back properly. Anybody seeing similar things? Thanks, -Andre