C# 使用pcapdotnet将数据包拆分为2个数据包

C# 使用pcapdotnet将数据包拆分为2个数据包,c#,pcap.net,C#,Pcap.net,如何使用pcapdotnet将数据包拆分为两个数据包?这是我尝试过的,但我不知道是否正确: public IEnumerable<Packet> splitPacket(Packet packet) { EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer(); IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethern

如何使用pcapdotnet将数据包拆分为两个数据包?这是我尝试过的,但我不知道是否正确:

    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);
    }
public IEnumerable可拆分数据包(数据包)
{
EthernetLayer ethernet=(EthernetLayer)packet.ethernet.ExtractLayer();
IpV4Layer IpV4Layer=(IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
DateTime packetTimestamp=packet.Timestamp;
ILayer payload=packet.Ethernet.IpV4.payload.ExtractLayer();
IPV4.Equals(数据包,数据包);
返回PacketBuilder.Build(packetTimestamp、以太网、ipv4层、有效负载);
}

我从未使用过Pcap.Net,因此我不确定这是否可行,但总体思路是将数据(有效负载层)分成几个块,然后发送。为了确保片段可以重新组装,您还需要添加一些关于每个片段位置(偏移量)的信息

在Pcap.Net中,
IpV4Fragmentation
类包含两个属性,它们定义了这一点:

  • ipv4碎片。选项
    • 对于除最后一个片段以外的所有片段,应将其设置为
      IpV4FragmentationOptions.MoreFragments
    • 对于最后一个片段,应将其设置为
      IpV4FragmentationOptions.None
  • ipv4碎片。偏移量
    • 包含片段的偏移量(必须可被8整除)。第一个片段的偏移量为零
考虑到这一点,我会这样写:

(免责声明:这是用记事本写的,我不知道它是否能编译,更不用说它能正常工作了):

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;
    }
}
public IEnumerable拆分(数据包,int numberOfFragments)
{
//获取原始图层
var ethernet=(EthernetLayer)packet.ethernet.ExtractLayer();
var ipV4=(IpV4Layer)packet.Ethernet.ipV4.ExtractLayer();
var time=数据包。时间戳;
//提取数据
var payload=(PayloadLayer)packet.Ethernet.IpV4.payload.ExtractLayer();
var totalLength=有效载荷长度;
//将数据分割成更小的段
var partialLength=总长度/碎片数;
//确保它可以被8整除
//(见http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly)
部分长度=(部分长度/8)*8;
//逐一发送
var偏移=0;
而(偏移量<总长度)
{
//获取此片段的长度
var fragmentLength=部分长度;
var options=IpV4FragmentationOptions.MoreFragments;
//这是最后一个碎片吗?如果需要修剪长度
如果(偏移+碎片长度>=总长度)
{
选项=IPV4碎片选项。无;
碎片长度=总长度-偏移量;
}
//将实际数据复制到新缓冲区中
var newBuffer=payload.ReadBytes(偏移量、碎片长度);
var newPayload=newpayloadlayer(){Data=newBuffer};
//更改IP层碎片选项
ipV4.Fragmentation=新的ipV4碎片(选项,偏移量);
//还它
返回PacketBuilder.Build(时间、以太网、ipV4、新负载);
//下一偏移量
偏移量+=碎片长度;
}
}

[更新为@brickner的建议]

不确定要如何拆分它,但方法的签名返回单个
数据包,因此我猜您只创建了一个。您可能想返回一个数据包列表,可能吧?或者
IEnumerable
?是的,这是一个错误,但我的问题是其余的是否可以?好的,您正在构建一个数据包,并返回一个数据包。我不知道你说的“分包”是什么意思。如何拆分?我更新了代码,但不知道如何构建和返回IEnumerable,我使用IpV4Fragmentation属性拆分数据包,但IpV4Fragmentation.Equals的作用是什么?这不是只有在两个数据包相等时才返回true吗?不管怎样,你想用这些数据包做什么,立即发送它们?看起来确实是一个好的开始。除了最后一个片段外,您可能应该在所有片段上放置更多片段。此外,由于舍入问题,这似乎不能覆盖整个原始数据包,但这可以很容易地调试和修复。@brickner:谢谢,我猜想代码中会有bug。我刚刚更新了代码来解决这两个问题。我相信这个方法更合适的输入应该是片段长度,而不是片段的数量,所以OP可能想进一步调整它。