How is ICMP NAT traversal supposed to work if the NAT device in question rewrites outbound ICMP packets?
Diagram
=========================================================================================
| CLIENT | <---> | NAT-C | <---> { internet } <---> | NAT-S | <---> | SERVER |
=========================================================================================
19.19.19.19 (external addresses) 72.72.72.72
192.168.0.2 192.168.0.1 (internal addresses) 172.16.0.1 172.16.0.2
Mechanics
A quick overview of ICMP holepunching as described in pwnat:
SERVER sends ICMP Echo Request packets (pings) to some other host (e.g. 3.3.3.3) to open up a hole in NAT-S. When CLIENT wants to connect, it sends an ICMP Time Exceeded packet to NAT-S, which is supposed to get routed to SERVER. For said routing to work, CLIENT constructs the ICMP Time Exceeded packet by embedding within it the same packet (ICMP Echo to 3.3.3.3) it expects SERVER to be sending in the first place.
Problem
If CLIENT needs to embed the same (ICMP Echo Request) packet as it left NAT-S in its ICMP Time Exceeded reply, it must know the packet's query ID. But how does it know this query ID?
According to RFC 3022 Section 2.2, when NAT-S encounters the outbound ICMP Echo Request, it rewrites the packet's query ID field to a unique external query ID so that it can route future ICMP Echo Replies with the same query ID to SERVER.
Given the problem above, it would seem that the premise behind pwnat and ICMP holepunching is invalid and it's never supposed to work. Am I missing something here?
Thanks in advance :)