10

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!

misteryes
  • 2,167
  • 4
  • 32
  • 58
  • 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 Jun 03 '13 at 14:08
  • 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 Jun 03 '13 at 15:16
  • 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 Jun 03 '13 at 15:34
  • 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 Jun 03 '13 at 15:58
  • you mean IP fragmentation also adds UDP header to the second IP fragment? why my tcpdump can't capture the second fragment? – misteryes Jun 03 '13 at 16:00
  • I'm not so familiar with the underpinnings of tcp/ip that I can say how UDP fragmentation actually works at the packet level. I always assumed that datagrams didn't fragment. Were you able to collect captures that show fragmentation of your UDP packets in wireshark? – Iron Savior Jun 03 '13 at 16:26
  • Check this out looks like a java demonstration about [reconstructing fragments](http://jnetpcap.com/book/export/html/91) – Iron Savior Jun 03 '13 at 16:35
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31137/discussion-between-iron-savior-and-misteryes) – Iron Savior Jun 03 '13 at 17:49
  • @IronSavior The IP stack re-assembles the fragments based on information in the IP header. Once re-assembled, you're left with one packet with an UDP header, which will identify the local application/socket. libpcap receives frames before they are re-assembled. It is therefore not possible to capture anything but the 1. fragment when using a filter that includes stuff in the UDP header. – nos Nov 07 '13 at 12:35

1 Answers1

11

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