9
votes

I want to capture UDP packets which are destined to a local port, the filtering expression is like udp port 20000. I notice if there are IP fragmentation on a UDP packet, libpcap can only capture the first IP fragment. I guess the reason is the second IP fragment are not with UDP header(I think it is the same for TCP), so libpcap can't capture them using the filter express udp port 20000.

are there any workaround for this? or any other libraries which can capture packets destined to a specific local port?

thanks!

1
If a UDP packet is fragmented and the fragments do not identify their source/destination, then how in the name of Zeus's butthole do they get routed to the proper host and application?Iron Savior
The second fragment is with IP header but no UDP header. The IP/TCP stack will assembly the first and second IP fragment before it delivers the whole UDP packet to the application. But it seems to me that libpcap can't recognize the second IP fragment.misteryes
How would a tcp/ip stack know that the second fragment belongs to the same socket as the first one without the UDP header? Maybe you will have to do the reassembly yourself--which really shouldn't be that difficult.Iron Savior
I guess the second IP fragment has an Identification and fragment offset which is constent with the first IP fragment. And they have the same source ip and destination ip. So IP/TCP stack can recognize them? Anyway, my udp server can get the whole UDP packets, but tcpdump can only get the first IP fragment, what is the reason behind this?misteryes
you mean IP fragmentation also adds UDP header to the second IP fragment? why my tcpdump can't capture the second fragment?misteryes

1 Answers

10
votes

I guess the reason is the second IP fragment are not with UDP header(I think it is the same for TCP), so libpcap can't capture them using the filter express udp port 20000.

Yes, that is correct.

You might try udp port 20000 or (ip[6:2] & 0x1fff) != 0, which will capture packets to or from port 20000 and IP fragments other than the first fragment; that's not ideal, but it's all you can do with libpcap filters, given that the filter mechanism it uses (which is part of the OS kernel) does not maintain any history between packets, and therefore has no way of knowing that a packet with a given IP ID happens to be part of the same fragment as another packet with the same IP ID, a fragment offset of 0, and a UDP header with port 20000.

(Note also that at least some versions of Linux would transmit fragments of an IP datagram in reverse order - in order to allow the recipient to see the last fragment first, and thus to be able to more often correctly estimate the size of the reassembled packet. That would make it even more difficult to capture all the fragments of IP packets with a filter that checks fields in the TCP or UDP header.)