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 :)