Репликация UDP-порта - SharpPCap BSOD - PullRequest
1 голос
/ 17 июня 2020

Я написал простую программу с использованием sharppcap для репликации входящих пакетов udp на другой порт. Допустим, у меня есть входящие пакеты на порт 25000, я получу их с помощью sharppcap, создам новый пакет Ethe rnet, идентичный предыдущему, и только изменим порт назначения на 27000, а затем отправлю пакет.

Программа работает именно так, как я хотел, я получаю один и тот же пакет UDP на порт 25000 и порт 27000.

Но через некоторое время, иногда 1 час, иногда 2 часа, иногда 12 часов, я получаю BSOD. Я понятия не имею, что именно вызывает BSOD (в минидампе я просто знаю его ядро ​​и hal.dll), а в дереве адресов - первый, если "ipnat.sys".

Вот мой код:

device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
            // Open the device for capturing
            device.Open();
            device.Filter = $"udp dst port {_portIncomming} and ip src not {_ipSource}";
            // Start capture 'INFINTE' number of packets
            device.Capture();
            // Close the pcap device
            // (Note: this line will never be called since
            //  we're capturing infinite number of packets
            device.Close();

И получите:

private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            var device = e.Device;
            var packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
            if (packet is EthernetPacket)
            {
                var eth = packet.Extract<EthernetPacket>();
                var ip = eth.Extract<IPPacket>();
                if (ip != null)
                {
                    var udp = packet.Extract<UdpPacket>();
                    device.SendPacket(CreateDuplicate(eth.SourceHardwareAddress, eth.DestinationHardwareAddress, udp.PayloadData, ip.SourceAddress, ip.DestinationAddress));                                        
                }                                
            }
        }

И CreateDuplicate:

private static EthernetPacket CreateDuplicate(PhysicalAddress source, PhysicalAddress dest, byte[] data, IPAddress ipSource, IPAddress ipDest)
        {
            ushort udpSourcePort = _portIncomming;
            ushort udpDestinationPort = _newDestPort;
            var udpPacket = new UdpPacket(udpSourcePort, udpDestinationPort);

            var ipSourceAddress = ipSource;
            var ipDestinationAddress = ipDest;
            var ipPacket = new IPv4Packet(ipSourceAddress, ipDestinationAddress);                       

            var ethernetSourceHwAddress = source;
            var ethernetDestinationHwAddress = dest;

            // NOTE: using EthernetPacketType.None to illustrate that the Ethernet
            //       protocol type is updated based on the packet payload that is
            //       assigned to that particular Ethernet packet
            var ethernetPacket = new EthernetPacket(ethernetSourceHwAddress,
                ethernetDestinationHwAddress,
                EthernetType.None);

            // Now stitch all of the packets together
            udpPacket.PayloadData = data;
            udpPacket.ParentPacket = ipPacket;
            ipPacket.PayloadPacket = udpPacket;
            ethernetPacket.PayloadPacket = ipPacket;

            ipPacket.UpdateIPChecksum();
            udpPacket.Checksum = udpPacket.CalculateUdpChecksum();
            ethernetPacket.UpdateCalculatedValues();

            //byte[] packetBytes = ethernetPacket.Bytes;
            return ethernetPacket;
        }

У вас есть идея, подсказка или уже написанная программа, которая решает мою проблему. Работающая ОС: Windows Server 2012 R2

...