Тип PcapDotNet и Datalink
Я пытаюсь манипулировать некоторыми сетевыми захватами (формат pcap) с помощью Pcap.net. Я открываю файл pcap и создаю дампер с помощью:
OfflinePacketDevice selectedDevice = new OfflinePacketDevice(pcapInFile);
using (PacketCommunicator PcapReader = selectedDevice.Open(655360, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
PacketDumpFile PcapWriter = PcapReader.OpenDump(pcapOutFile);
PcapReader.ReceivePackets(count, PacketDispatcher);
}
И PacketDispatcher будет что-то вроде:
private void PacketDispatcher(Packet packet)
{
// Manipulate the packet
PcapWriter.Dump(packet);
}
Все в порядке, поскольку pcapInFile Datalink имеет тип Ethernet. Но у меня есть несколько захватов без уровня Ethernet (rawip), и мне нужно построить новый уровень Ethernet. В этом типе заглавных букв тип связи данных такой же, как pcapInFile (raw ip), и я хочу изменить его на ethernet...
Если я сохраню все манипулируемые пакеты в ienumerable и дам их с помощью:
PacketDumpFile.Dump(pcapOutFile, new PcapDataLink(1), Packets.Count(), Packets);
Работает нормально... Но это не очень полезно, если вы имеете дело с файлами нескольких гигабайт...
Любая идея? Спасибо!
2 ответа
Что ж, несмотря на то, что это не ответ, а обходной путь, и, поскольку никто не написал лучшего решения, вот как это исправить:
Используйте SharPcap вместо PcapDotNet, тогда вы можете объявить читателя и писателя следующим образом:
public CaptureFileReaderDevice PcapReader;
public CaptureFileWriterDevice PcapWriter;
PcapReader = new CaptureFileReaderDevice(fileIn);
PcapReader.OnPacketArrival += packetDispatcher;
PcapReader.Capture();
В функции packetDispatcher:
RawCapture raw = new RawCapture(LinkLayers.Ethernet, e.Packet.Timeval,RebuildNullLinkLayer(e, offset));
CaptureHandler.PcapWriter.Write(raw);
А в функции RebuildNullLinkLayer вы можете добавить уровень Ethernet, изменить все, что вы хотите, и т.д...
Обратите внимание, что когда вы вызываете конструктор RawCapture, вы можете выбрать канальный уровень (моя первоначальная проблема с Pcap.Net...), поэтому, если вы анализируете захват RawIp, вы можете конвертировать пакеты в Ethernet.
Предполагая, что проблема заключается в наличии всех пакетов в ОЗУ, вы можете создать IEnumerable, который не содержит всего в ОЗУ, используя yield.
Таким образом, когда Dumper сбрасывает пакеты, он вызывает ваш метод для заполнения следующего элемента с помощью yield.