Wireshark mailing list archives

Re: Filtering on fields in tunnel headers


From: Sake Blok <sake () euronet nl>
Date: Wed, 12 Sep 2012 10:42:55 +0200

On 12 sep 2012, at 09:01, Jaap Keuter wrote:
On 09/11/2012 11:30 PM, Martin Isaksson wrote:
If I have a packet with protocols like eth:vlan:ip:udp:gtp:ip:tcp, is there a
way to filter in one of the IP headers only?
I know I can do frame[22:2] == D4:DD (here IP ID of first IP header), but it's
not very dynamic, so if for some reason the bytes are in different places, this
would fail.

Well, for the IPid in the first IP header, you can just use ip.id ;-)
But yes, for the inner IP layer, it gets complicated...

Currently there's no way to filter on ip{inner}/ip{outer} in a packet. If it's ip it's ip it's ip; s/ip/<your 
proto>/g. That can be a strength (like catching ICMP) and a weakness (like in tunnels). This would require some 
fundamental dissection and display filter work.

Another work-around I've tried is to list one of the IP IDs with tshark and grep.

Capture filters can come to the rescue, while they are not very good for higher layer protocols and protocols that 
involve reassembly, they can do an amazing job at looking at offsets and calculating offsets into the packet.

Here is an example of finding SIP packets (tcp or udp) on port 5060 inside an IP-IP tunnel:

ip proto 4 and (ip[((ip[0]&0x0f)<<2)+9]=17 or ip[((ip[0]&0x0f)<<2)+9]=6) and 
(ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+0:2]=5060 or 
ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+2:2]=5060)

OK, it's not as complicated as it looks, here we go:

We only look at IP-IP tunneled packets, so:

ip proto 4

To get to the start of the inner IP layer, we need to calculate the ip header length of the outer IP layer. This can be 
done with:

(ip[0]&0x0f)<<2

So, the IP protocol field at offset 9 of the inner IP header is at offset ((ip[0]&0x0f)<<2)+9 in the outer IP header. 
So to check on UDP or TCP, we need:

ip[((ip[0]&0x0f)<<2)+9]=17 or ip[((ip[0]&0x0f)<<2)+9]=6

Then we need to check the ports, which are at offset 0 (src) and 2 (dst) in the UDP/TCP header, so we need to skip both 
IP headers and incorporate flexible IP header lengths. For the inner Ip layer, the length is:

ip[((ip[0]&0x0f)<<2)]&0x0f)<<2

Adding the offset of the inner IP layer into the outer IP layer:

(ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2

So the src port can be found at:

ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+0:2]

So, checking for port 5060 becomes:

ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+0:2]=5060 or 
ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+2:2]=5060



Putting it all together:

ip proto 4 and (ip[((ip[0]&0x0f)<<2)+9]=17 or ip[((ip[0]&0x0f)<<2)+9]=6) and 
(ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+0:2]=5060 or 
ip[((ip[0]&0x0f)<<2)+((ip[((ip[0]&0x0f)<<2)]&0x0f)<<2)+2:2]=5060)

You can follow the same process for your packets and use tcpdump to extract your traffic into a new capture file.

If you need any help, just post a tracefile with a couple of packets and I see if I can assist you...

Cheers,
Sake

___________________________________________________________________________
Sent via:    Wireshark-users mailing list <wireshark-users () wireshark org>
Archives:    http://www.wireshark.org/lists/wireshark-users
Unsubscribe: https://wireshark.org/mailman/options/wireshark-users
             mailto:wireshark-users-request () wireshark org?subject=unsubscribe


Current thread: