Split packet into 2 packets with pcapdotnet

前端 未结 1 1389
时光说笑
时光说笑 2021-01-26 16:42

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         


        
1条回答
  •  梦毁少年i
    2021-01-26 17:30

    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
    • 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 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]

    0 讨论(0)
提交回复
热议问题