Реализация фрагментации IP для пакета TCP / UDP в Pcap.Net - PullRequest
0 голосов
/ 26 декабря 2018

Я пытаюсь реализовать фрагментацию IP с помощью Pcap.Net.Это просто для пакетов, которые уже созданы, поскольку полезная нагрузка 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) создание нового пакета и отправка его через интерфейс Ethernet

К сожалению, если полезная нагрузка IPбольше, чем MTU, исключение происходит, поскольку пакет должен быть фрагментирован перед отправкой.

Поскольку я меняю IP-адрес, то для пакетов TCP / UDP контрольная сумма L4 должна быть пересчитана, и этот пересчет должензаголовок аккаунта L3.Поэтому необходимо построить часть полезной нагрузки L3 + L4 + (чтобы правильно рассчитать контрольную сумму L4), а затем разбить полезную нагрузку L4 + на части, чтобы соответствовать MTU L3.

Я пришел к решению, в котором я строюновый пакет (который больше, чем MTU), а затем протолкнуть его через вышеуказанную функцию, чтобы разорвать его на части, и затем я отправляю его, используя:

foreach (пакетный пакет в пакете) коммуникатор.SendPacket (новый пакет);

Это, однако, требует создания одного и того же пакета дважды, и я пытаюсь найти способ в Pcap.Net частично построить пакет (включая пересчет контрольной суммы L4) и одновременно разделитьэто во фрагменты, чтобы соответствовать MTU.

Я не знаю, как (и если это возможно в Pcap.Net) подготовить полезную нагрузку L3, которая будет состоять из полезной нагрузки tcpLayer / udpLayer + L4, так как контрольная сумма TCP вычисляется во времястроительство, а затем, наконец, собрать остальную часть пакета.Если бы это было возможно, мне нужно было бы просто собрать пакет, разделив его на части одновременно.

...