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