Обнаружение пакетов с помощью C # и pcapdotnet: как избежать потери пакетов - PullRequest
0 голосов
/ 12 октября 2019

Я пишу программное обеспечение на C # и PcapDotNet, которое должно захватывать все сегменты tcp на определенном порту, расшифровывать их (TLS) и затем анализировать полезную нагрузку. К сожалению, у меня проблема с потерей пакетов. Когда я сравниваю вывод моей программы и Wireshark, некоторые пакеты отсутствуют. Контекст является критическим, и я не могу принять потерю пакетов.

Для захвата пакетов я использую библиотеку Pcap.net. Я определил BPF (пакетный фильтр Беркли) для захвата только пакетов с определенных портов и IP-адресов (так же, как тот, который я использую в Wireshark). Затем я определил свою функцию обратного вызова, которая вызывается при получении пакета.

В Program.Main ():

communicator = networkInterface.Open(65536, PacketDeviceOpenAttributes.Promiscuous | PacketDeviceOpenAttributes.MaximumResponsiveness, 100);

if (communicator.DataLink.Kind != DataLinkKind.Ethernet)
{
   throw new Exception("This program works only on Ethernet networks.");
}

BerkeleyPacketFilter filter = communicator.CreateFilter("...");

communicator.SetFilter(filter);

communicator.ReceivePackets(0, PacketHandler);

И моя функция Main.PacketHandler ():

public static void PacketHandler(Packet packet)
{
   IPAddress sourceIP = IPAddress.Parse(packet.Ethernet.IpV4.Source.ToString());
   IPAddress destinationIP = IPAddress.Parse(packet.Ethernet.IpV4.Destination.ToString());
   ushort sourcePort = packet.Ethernet.IpV4.Tcp.SourcePort;
   ushort destinationPort = packet.Ethernet.IpV4.Tcp.DestinationPort;

   TcpSession tcpSession;
   tcpSession = GetTcpSession(sourceIP, sourcePort, destinationIP, destinationPort);

   bool isServerPacket = false;

   if (tcpSession.server._ip.Equals(sourceIP) && tcpSession.server._port == sourcePort)
      sServerPacket = true;

   uint sequenceNumber = packet.Ethernet.IpV4.Tcp.SequenceNumber;

   if (_lastTcpSequenceNb != default(uint) && sequenceNumber == _lastTcpSequenceNb)
      return;

   _lastTcpSequenceNb = sequenceNumber;


   byte[] tcpPayload = packet.Ethernet.IpV4.Tcp.Payload.ToArray();

   // ... Packets analysis... etc
}

Я думаю, что в функции обратного вызова слишком много операций (я скрыл много строк), которые создают (может быть?) Своего рода «задержку», объясняющую, почему некоторые пакеты игнорируются. Вот некоторые решения, о которых я подумал ...: - Разделить приложение на две программы: программу-сниффер, которая регистрирует все пакеты без какой-либо обработки, и вторую программу, которая периодически читает и обрабатывает их. - Использовать многопоточность?

У вас есть лучшее решение?

...