How can I split a packet into two packets using pcapdotnet? This is what I tried, but I don\'t know whether it\'s correct:
public IEnumerable s
I have never used Pcap.Net, so I am not sure if this will work, but the general idea is to split the data (the "payload layer") into several chunks and then send it. To make sure the fragments can be reassembled, you also need to add some info about the position (offset) of each fragment.
In Pcap.Net, the IpV4Fragmentation
class contains two properties which define this:
IpV4Fragmentation.Options
:
IpV4FragmentationOptions.MoreFragments
,IpV4FragmentationOptions.None
IpV4Fragmentation.Offset
:
With this in mind, I would write something like this:
(Disclaimer: this was written in Notepad, I have no clue if it even compiles, let alone works as it should):
public IEnumerable Split(Packet packet, int numberOfFragments)
{
// get original layers
var ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
var ipV4 = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
var time = packet.Timestamp;
// extract the data
var payload = (PayloadLayer)packet.Ethernet.IpV4.Payload.ExtractLayer();
var totalLength = payload.Length;
// split data into smaller segments
var partialLength = totalLength / numberOfFragments;
// make sure it's divisible with 8
// (see http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly)
partialLength = (partialLength / 8) * 8;
// send one by one
var offset = 0;
while (offset < totalLength)
{
// get length for this fragment
var fragmentLength = partialLength;
var options = IpV4FragmentationOptions.MoreFragments;
// is this the last fragment? trim length if needed
if (offset + fragmentLength >= totalLength)
{
options = IpV4FragmentationOptions.None;
fragmentLength = totalLength - offset;
}
// copy the actual data into a new buffer
var newBuffer = payload.ReadBytes(offset, fragmentLength);
var newPayload = new PayloadLayer() { Data = newBuffer };
// change IP layer fragmentation options
ipV4.Fragmentation = new IpV4Fragmentation(options, offset);
// return it
yield return PacketBuilder.Build(time, ethernet, ipV4, newPayload);
// next offset
offset += fragmentLength;
}
}
[Updated with @brickner's suggestions]