问题
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<Packet> splitPacket(Packet packet)
{
EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
DateTime packetTimestamp = packet.Timestamp;
ILayer payload = packet.Ethernet.IpV4.Payload.ExtractLayer();
IpV4Fragmentation.Equals(packet, packet);
yield return PacketBuilder.Build(packetTimestamp, ethernet, ipV4Layer, payload);
}
回答1:
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
:- for all fragments except tha last one, it should be set to
IpV4FragmentationOptions.MoreFragments
, - for the last fragment, it should be set to
IpV4FragmentationOptions.None
- for all fragments except tha last one, it should be set to
IpV4Fragmentation.Offset
:- contains the offset of the fragment (which must be divisible by 8). This offset is zero for the first fragment.
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<Packet> 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]
来源:https://stackoverflow.com/questions/13272565/split-packet-into-2-packets-with-pcapdotnet