I've discovered that fragmented UDP packets get corrupted by Packet.NET;
specifically, the UDP Length header field (which only exists in the first
fragment) is falsified (to represent the length of just that fragment), and
the two bytes in subsequent fragments have the two bytes corrupted in the
position where the UDP length would be.
Note that fragmentation happens at IP level; the UDP header is not repeated.
I've crudely fixed the problem for my application by removing the "set" code
in UdpPacket.cs for Length. I'm only trying to parse captured packets; I'm not
What would a proper fix be?
The proper fix would be to have something at the IP level perform packet
reassembly. Current code has no inter-packet state but we can introduce new
objects that can handle packets and keep state.
It could be fixed without changing existing code if there was an IpReassembly
class that took in raw packet data. It could then parse the data into packets
(which would be IP Packets), and then reassemble the data into a full lower
level packet and pass that to the appropriate protocol parser, like Udp. Would
require some manipulation of data but probably wouldn't be too difficult to
take the data contents of the IP datagrams, munge them into two and build a
new unfragmented packet, then pass that back into Packet.Parse() to get the
full udp or tcp packet.
Wireshark talks a little about it here:
If this is a business related task I'd be available to contract to implement
this functionality. email@example.com.
Well, proper fixes can be done at two levels. One, as you say, is to do the
packet reassembly within Packet.Net. The other is at least to stop Packet.Net
from corrupting the packets. Surely, corrupting packets has to be considered
as a bug?
I'm happy to reassemble packets in our application - in fact I've done it
already - but I've had to modify Packet.Net in order to get uncorrupted data.
I'm conscious that the "fix" I've applied works for our use case, but cannot
be considered as general, so there's no point in my submitting the change.
What I have not been able to do is to amass anything like a good enough
overview of Packet.Net so that I can see a proper solution at this lower
Packet.net performs a lot of lazy evaluation of fields. In this case, what do
you mean that the length bytes are corrupted? How are they corrupted? Of
course this would be fixed if there was a bug, I'm just wondering if the
length is correct for that particular fragment.
The example I'm using is a UDP message (captured from the real world) that is
roughly 1900 bytes long, and the UDP payload is split into two IP packets.
What happens is:
the first fragment is of course the only one that carries a UDP length field, and this refers to the total length of the UDP message, but Packet.Net amends the UDP length field as if the first fragment were the complete message;
the second fragment of course does not carry a UDP header, but Packet.Net corrupts the two payload bytes where the UDP length would be if a UDP header were present, putting in values that would represent the UDP length if that fragment were a complete UDP message.
I hope that's a clear enough explanation. I feel I've used too many words :-(
Can you email me the two Ethernet packets in a .pcap file that represent the
fragmented udp packet? I presume wireshark gets this right? I'll look here to
see why the values might be being corrupted as its usually policy that no
values be altered by parsing.
I have the same problem. Is it solved or did you need a pcap file with the 2 UDP frames?
Thanks for your help
I’ve never heard anything more since. I assume the bug is still there.
I haven't looked at the issue yet. It may be a good approach to use a wrapper around the ip stream that will put the packets back together. The packet dissectors today handle a single packet so reassembly seems like it should be a higher level operation. For instance no state is kept in packet.net so how would the packet decoding code know to wait for the fragment in the next packet? What if that packet never arrived or arrived after other packets etc.
I'm happy with the idea of reassembly happening at a higher level - but a first requirement for that to happen is that packet.net must not corrupt the data in the lower level packets.
Ahh I see. I'm surprised the lengths are being adjusted like that. The lazy parsing done by Packet.net for performance reasons usually avoids that kind of thing.
I found your original email with the fragmented packet example. I'll see if I can't find some time to look at it this week so at least the content of the packets are accessible for the higher level code to put things back together.
I would be happy if FragmentOffset field is correct. So I can reassemble my frame by myself...
I can test if necessary
Any News? Is a workaround available? I need to continue my application ;-)
I do this "manually" with a class that reassemble fragments. FragmentOffset is 1/8 of the real size...
I opened this as a bug on SharpPcap before realizing it belonged in Packet.Net, and that this discussion existed.
I have not used SourceForge a lot in a long time, but if I can manage to get my changes uploaded, I can send you a fix that I believe is the correct one for this issue.
Basically, if an IP packet has a non-zero FragmentationOffset (meaning it is not the first fragment in this sequence of packets), it passes the packet through as payload data, it doesn't try to parse it into any specific form, which is where the corruption happens.
Dave Higton's explanation is spot on from my perspective, exactly the same thing is happening to my program.