.NET написание файлов PCAP

Все,

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

У меня есть клиент, который попросил меня предоставить службу, которая читает файлы pcap и записывает пакеты в свою базу данных по своему выбору. Затем клиент может запросить базу данных (диапазон дат / времени), и в результате должен быть файл pcap, содержащий пакеты, которые соответствуют критериям этого диапазона.

До сих пор я обнаружил, что с библиотеками "дамп", то есть запись pcap, кажется доступным, только когда он связан с конкретным устройством захвата. Это не так для моего сценария.

Я использую PCAP.NET для чтения оригинальных файлов pcap и извлечения пакетов. Я сохраняю пакеты в базе данных, а затем могу прочитать данные из базы данных и воссоздать пакеты, но я не нахожу способ записать результаты запроса в файл pcap.

В простейшем случае рассмотрим структуру данных List типа Packet (настолько плохо знакомую с фактической записью в переполнение стека, что я не знаю, как написать List T с угловыми скобками, которые не фильтруются) - выполните любую из доступных библиотек Поддержка записи этой структуры в PCAP?

Учитывая, что это не является распространенным сценарием, я задаюсь вопросом о достоверности всего сценария. Я должен также отметить, что у меня есть в общей сложности два дня работы с данными PCAP, это должно было быть доказательством концептуального применения, и поэтому вполне возможно, что я упускаю часть знаний, которая делает это тривиальным.

Заранее благодарим вас за ваше драгоценное время, внимание и извинения, если мои попытки с Google и даже больше времени с поиском переполнения стека упустили очевидное.

Крис

2 ответа

Решение

Я считаю, что статический метод Pcap.Net PacketDumpFile.Dump() дает вам именно то, что вам нужно.

Вот простой инструмент на C#, который я написал для преобразования ETL в файлы PCAP, пример того, как вы можете написать файл PCAP. Это записывает файл с типом заголовка Link-Layer Ethernet. Обратитесь к http://www.tcpdump.org/linktypes.html для других типов.

Решение Visual Studio здесь https://github.com/chentiangemalc/EtlToCap

using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace chentiangemalc
{
    public static class NetworkRoutines
    {

        public static long ConvertEtlToPcap(string source, string destination, UInt32 maxPacketSize)
        {
            int result = 0;
            using (BinaryWriter writer = new BinaryWriter(File.Open(destination, FileMode.Create)))
            {

                UInt32 magic_number = 0xa1b2c3d4;
                UInt16 version_major = 2;
                UInt16 version_minor = 4;
                Int32 thiszone = 0;
                UInt32 sigfigs = 0;
                UInt32 snaplen = maxPacketSize;
                UInt32 network = 1; // LINKTYPE_ETHERNET

                writer.Write(magic_number);
                writer.Write(version_major);
                writer.Write(version_minor);
                writer.Write(thiszone);
                writer.Write(sigfigs);
                writer.Write(snaplen);
                writer.Write(network);

                long c = 0;
                long t = 0;
                using (var reader = new EventLogReader(source, PathType.FilePath))
                {
                    EventRecord record;
                    while ((record = reader.ReadEvent()) != null)
                    {
                        c++;
                        t++;
                        if (c == 100000)
                        {
                            Console.WriteLine(String.Format("Processed {0} events",t));
                            c = 0;
                        }
                        using (record)
                        {
                            if (record.Id == 1001 && record.ProviderName == "Microsoft-Windows-NDIS-PacketCapture")
                            {
                                result++;
                                DateTime timeCreated = (DateTime)record.TimeCreated;
                                UInt32 ts_sec = (UInt32)((timeCreated.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
                                UInt32 ts_usec = (UInt32)(((timeCreated.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds) - ((UInt32)((timeCreated.Subtract(new DateTime(1970, 1, 1))).TotalSeconds * 1000))) * 1000;
                                UInt32 incl_len = (UInt32)record.Properties[2].Value;
                                if (incl_len > maxPacketSize)
                                {
                                   Console.WriteLine(String.Format("Packet size of {0} exceeded max packet size {1}, packet ignored",incl_len,maxPacketSize));
                                }
                                UInt32 orig_len = incl_len;

                                writer.Write(ts_sec);
                                writer.Write(ts_usec);
                                writer.Write(incl_len);
                                writer.Write(orig_len);
                                writer.Write((byte[])record.Properties[3].Value);

                            }
                        }
                    }
                }
            }
            return result;
        }
    }
}
Другие вопросы по тегам