dotpcap / sharppcap

Official repository - Fully managed, cross platform (Windows, Mac, Linux) .NET library for capturing packets
1.31k stars 267 forks source link

UDP Payload in fragmented IP packet #13

Closed juyanith closed 7 years ago

juyanith commented 7 years ago

I've been using sharppcap in an application for some time with great success but I've recently hit an issue where retrieving PayloadData in a UdpPacket only returns the data in the first fragment.

My usage is pretty simple:

void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
    var ipPacket = (IpPacket)e.Packet.Extract(typeof(IpPacket));
    if (ipPacket != null)
    {
         var udpPacket = (UdpPacket)packet.Extract(typeof(UdpPacket));
         if (udpPacket != null)
         {
             var bytes = udpPacket.PayloadData;
             var text = Encoding.ASCII.GetString(bytes, 0, bytes.Length);

When I look at the packets in wireshark I see the reconstructed text, but my code only sees what is in the first fragment. Is there some setting to ensure the data has been reconstructed? I don't see any fragment flag in IpPacket.

EDIT 01/19/2017: I guess I should have posted this on the PacketDotNet site because these are PacketDotNet classes and as it turns out the fragmentation fields are in IPv4Packet (not IpPacket). I'll still have to reconstruct the fragmented packet but I have the data necessary to do so.

yhw720 commented 7 years ago

I'm also thinking about the same problem. In case of tcp, fragmented packets area also displayed. I want to know the solution.

juyanith commented 7 years ago

As I mentioned in the edit, you can find the fragment information by using IPv4Packet (or IPv6Packet I assume) instead of just IpPacket. Then you can test for fragmentation and rebuild everything. For example:

    // Is this packet framented?
    if (ipPacket.FragmentOffset > 0 || (ipPacket.FragmentFlags & 0x01) == 0x01)
    {
        // manage fragments 
    }

The issue with my original code is that the packets after the first one do not have a UDP header so the second call to Extract fails. What I ended up doing was writing a fragment manager class to keep track of them. When I added then last fragment it would return the complete set so I could reassemble the entire byte array and process the data.