0

pcapdotnet を使用してパケットを 2 つのパケットに分割するにはどうすればよいですか? これは私が試したものですが、正しいかどうかはわかりません:

    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);
    }
4

1 に答える 1

1

私はPcap.Netを使用したことがないので、これが機能するかどうかはわかりませんが、一般的な考え方は、データ(「ペイロードレイヤー」)をいくつかのチャンクに分割してから送信することです。フラグメントを確実に再アセンブルできるようにするには、各フラグメントの位置(オフセット)に関する情報も追加する必要があります。

Pcap.Netでは、IpV4Fragmentationクラスにはこれを定義する2つのプロパティが含まれています。

  • 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の提案で更新]

于 2012-11-08T12:09:17.397 に答える