在Pcap.Net中为TCP / UDP数据包实现IP分段

时间:2018-12-26 17:34:34

标签: c# pcap.net

我正在尝试使用Pcap.Net实现IP分段。 对于已构建的数据包而言,这很简单,因为L3有效负载仅被分成几部分。 我有一个做到这一点的代码。它返回数据包片段列表,以将其发送到线路中。

    private static List<Packet> FragmentPacket(Packet packet)
    {
        EthernetLayer ethernetLayer = (EthernetLayer)packet.Ethernet.ExtractLayer();
        IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
        PayloadLayer payload = (PayloadLayer)packet.Ethernet.IpV4.Payload.ExtractLayer();

        // implement IP fragmentation
        int totalLength = payload.Length;
        int fragmentLength = 1480;
        int fragmentOffset = 0;
        IpV4FragmentationOptions FragOptions;

        List<Packet> fragmentsList = new List<Packet>();

        while (fragmentOffset < totalLength)
        {
            if (fragmentOffset + fragmentLength >= totalLength)
            {
                //last fragment
                FragOptions = IpV4FragmentationOptions.None;
                fragmentLength = totalLength - fragmentOffset;
            }
            else
            {
                //more fragments to go
                FragOptions = IpV4FragmentationOptions.MoreFragments;
            }

            IpV4Layer newipV4Layer =
                new IpV4Layer
                {
                    Source = ipV4Layer.Source,
                    CurrentDestination = ipV4Layer.CurrentDestination,
                    Fragmentation = new IpV4Fragmentation(FragOptions, (ushort)fragmentOffset),
                    HeaderChecksum = null, // Will be filled automatically.
                    Identification = 123,
                    Options = IpV4Options.None,
                    Protocol = ipV4Layer.Protocol, 
                    Ttl = ipV4Layer.Ttl, // 128,
                    TypeOfService = ipV4Layer.TypeOfService,
                };

            byte[] newBuffer = payload.Data.ToArray();
            PayloadLayer fragmentedPayload = new PayloadLayer { Data = new Datagram(newBuffer, fragmentOffset, fragmentLength) };

            PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, fragmentedPayload);
            fragmentsList.Add(builder.Build(DateTime.Now));

            fragmentOffset = fragmentOffset + fragmentedPayload.Length;
        }

        return fragmentsList;
    }

但是我实际上正在做的是:

1)通过Loopback接口接收大数据包(通常大于物理接口的MTU)

2)拆卸它,修改IP地址

3)建立一个新数据包并通过以太网接口发送它

不幸的是,如果IP有效负载大于MTU,则会发生异常,因为在发送之前需要对数据包进行分段。

因为我要更改IP地址,所以对于TCP / UDP数据包,必须重新计算L4校验和,并且此重新计算必须考虑到L3标头。因此,需要先构建L3 + L4 +有效载荷零件(以正确计算L4校验和),然后将L4 +有效载荷分成适合L3 MTU的零件。

我遇到了一个解决方案,其中我要构建一个新的数据包(比MTU大),然后通过上述功能将其推入以将其分成几部分,然后使用以下命令进行发送:

foreach(packetList中的数据包newpacket)     communicator.SendPacket(newpacket);

但是,这需要两次构建相同的数据包,我试图在Pcap.Net中找到一种方法来部分构建一个数据包(包括重新计算L4校验和),同时将其分成多个片段以适合MTU。

我不知道如何(如果在Pcap.Net中可能的话)准备由tcpLayer / udpLayer + L4有效负载组成的L3有效负载,因为在构建过程中会计算TCP校验和,然后最终构建其余的数据包。 如果可以的话,我只需要在一次将数据包分成几部分后就构建它。

0 个答案:

没有答案