【问题标题】:Split packet into 2 packets with pcapdotnet使用 pcapdotnet 将数据包分成 2 个数据包
【发布时间】:2012-10-27 16:14:49
【问题描述】:

如何使用 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);
    }

【问题讨论】:

  • 不确定你想如何分割它,但你的方法的签名返回一个Packet,所以我猜你只是创建一个。您可能想返回一个数据包列表,可能吗?还是IEnumerable&lt;Packet&gt;?
  • 是的,这是错误的,但我的问题是其余的是否还可以?
  • 嗯,您正在构建一个数据包,并返回一个数据包。我不知道您所说的“拆分数据包”是什么意思。怎么拆分?
  • 我更新了我的代码,但我不知道如何构建和返回 IEnumerable,我使用 IpV4Fragmentation 属性拆分数据包
  • 但是IpV4Fragmentation.Equals 是做什么的?如果两个数据包相等,这不是只返回true吗?无论如何,你想对这些数据包做什么,立即发送它们?

标签: c# pcap.net


【解决方案1】:

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

在 Pcap.Net 中,IpV4Fragmentation 类包含两个定义它的属性:

  • IpV4Fragmentation.Options:
    • 对于除最后一个以外的所有片段,应设置为IpV4FragmentationOptions.MoreFragments
    • 对于最后一个片段,应该设置为IpV4FragmentationOptions.None
  • IpV4Fragmentation.Offset:
    • 包含片段的偏移量(必须能被 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;
    }
}

[根据@brickner 的建议更新]

【讨论】:

  • 确实看起来是一个好的开始。您可能应该将 MoreFragments 放在所有段最后一个。此外,由于舍入问题,这似乎不会涵盖整个原始数据包,但可以轻松调试和修复。
  • @brickner:谢谢,我认为该代码中会有错误。我刚刚更新了代码来解决这两个问题。我相信这个方法更合适的输入应该是片段长度而不是片段的数量,所以 OP 可能想要进一步调整它。
猜你喜欢
  • 2012-11-16
  • 2016-10-26
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 2012-10-10
  • 1970-01-01
  • 2010-10-20
相关资源
最近更新 更多