Tuesday, September 11, 2007

BPF - Non RFC Compliant?

It's been a while I haven't written anything about network traffics analysis and it's fun to do it again. If you don't know what is BPF, you can check it out here -

- FreeBSD BPF Man Page

- Good Old BPF paper

Here's the description of the Berkeley Packet Filter, it provides a raw interface to data link layers in a protocol independent fashion. All packets on the network, even those destined for other hosts, are accessible through this mechanism.

I came across this when I was trying to filter multicast network traffics from the packet capture file. From my understanding and the RFC references, IPv4 multicast addressing is in the class D of which the first octet of IP address is in the range of 224-239. I tried to confirm what I have learned from the resources below -

- IANA Address Assignment

- RFC3171

- RFC2365

- RFC3330

- IETF Draft

Then I use this BPF filter(ip multicast) to accomplish my need -

shell>tcpdump -ttttnnr multicast-mix.pcap 'ip multicast'

As expected, the tcpdump output shows all the multicast traffics. But wait, it shows other unexpected traffics where I spotted there are some traffics with the destination IP of which I don't think it belongs to multicast addressing. To understand the BPF filter , I dump the compiled packet-matching code in a human readable by running -

shell>tcpdump -d ip multicast
tcpdump: WARNING: eth0: no IPv4 address assigned
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 5
(002) ldb [30]
(003) jge #0xe0 jt 4 jf 5
(004) ret #96
(005) ret #0

From the instruction 000 and 001, we know it is IPv4 traffic. 002 will look at the 30th byte offset in the Ethernet frame where it is actually the location for first octet of destination IP address and 003 performs jge #0xe0 which it will jump into that byte offset and check if it is equal or greater than 0xe0(in decimal it is 224).

If the condition is true(jt 4), it will jump to 4th instruction and returns 96 bytes which is the default snap length of what tcpdump has captured in single ethernet frame, else(jf 5) it will just return nothing.

To be clear, as long as the first octet of destination IP greater than 224, the BPF filter "ip multicast" will catch it.

ip multicast = 224.x.x.x - 255.x.x.x

This is not RFC compliant, isn't it? Therefore to do what I really want with BPF filter, I have to use this -

ip[16]>=224 and ip[16]<=239

I don't mean everything must be RFC Compliant as we know some evil vendors tend to break it. Anyway I just share my finding.

Enjoy (;])

No comments: