Wireshark-dev: [Wireshark-dev] Wrong dissection of UDP encapsulated IKEv2 packets

From: Goran Macut <goran.macut@xxxxxxxxxxxx>
Date: Fri, 21 Feb 2014 13:50:00 +0000
Hello,


I'm working at Ericsson's R&D in Croatia. During the work on one of
our projects we've noticed that IPsec IKEv2 packets, encapsulated in
UDP for NAT traversal, sometimes aren't properly dissected.


I have analysed the problem:

To enable NAT traversal, IPsec ESP and IKE traffic can
be encapsulated into UDP, on port 4500. Even though the UDP
encapsulated packets should be sent with source and destination
ports set to 4500, the NAT box can change the source port in
this situation:

*------------*  *-----*                        *------------*
| Endpoint 1 |--| NAT |-----public network-----| Endpoint 2 |
*------------*  *-----*                        *------------*

Endpoint 1 sends packets with source and destination ports 4500.
NAT then changes the source port of the message to P1. Endpoint
2 receives the message and responds to the port P1, with source
port set to 4500. NAT changes the destination port P1 of the
response to port 4500, and Endpoint 1 receives packets on 4500.

If we dump packets on Endpoint 1, they will have source and
destination ports 4500, and Wireshark will be able to dissect
these messages well. However, Endpoint 2 will see ports P1 and
4500, and Wireshark will have problems with correct dissection.
Currently, if the port P1 is lower than 4500, and Wireshark
recognizes it, the message won't be recognized as UDP
encapsulated.

RFC5996 states:
"2.23. NAT Traversal
   It is a common practice of NATs to translate TCP and UDP
   port numbers as well as addresses and use the port numbers
   of inbound packets to decide which internal node should get
   a given packet. For this reason, even though IKE packets
   MUST be sent to and from UDP port 500 or 4500, they MUST be
   accepted coming from any port and responses MUST be sent to
   the port from whence they came.  This is because the ports
   may be modified as the packets pass through NATs."



I have inspected your code and tried to devise a solution. It seems
to me that the least destructive way to try to solve this problem in
a clean way is to add a heuristic dissector for UDP which will
detect packets that have at least one of the UDP ports set to 4500.
Of course, I don't know your architecture well, there might be a
better way.

I have implemented that change, tested it with my examples and it
works, but only after enabling UDP heuristic dissectors in preferences.
I have a commit prepared, would you be willing to accept it on
your Gerrit to check it out?


Best regards,
Goran Macut