Перевод справки, поставляемой вместе с дистрибутивом SharpPcap
Вступление
Перехват пакетов (или перехвата пакетов) — это процесс сбора, всех пакетов проходящих через определенный сетевой интерфейс. Захват сетевых пакетов в наших приложениях позволяет реализовывать такие приложения как: мониторинг сети, сетевые анализаторы и средства безопасности. Цель библиотеки WinPcap для Windows предоставить API для низкоуровневого мониторинга сети. Среди приложений, использующих WinPcap являются знаменитые tcpdump и Wireshark.
О SharpPcap
Цель SharpPcap-обеспечить основу для захвата, инъекции и анализа сетевых пакетов для .NET приложений.
SharpPcap активно развивается с открытым исходным код размещенным на SourceForge. Патчи исходного кода, для улучшения или исправления ошибок приветствуются через sharppcap список рассылки разработчиков. Сообщения об ошибках, пожеланиях и другие вопросы активно обсуждаются на форумах поддержки, так что если у вас есть проблемы с библиотекой, пожалуйста, не стесняйтесь спрашивать.
SharpPcap-это полностью управляемая кросс-платформенная библиотека. Та же сборка работает под Microsoft .NET также как Моно на 32 и 64-битных платформах.
Следующий список иллюстрирует возможности, которые в настоящее время поддерживаются в SharpPcap:
- Одна сборка для Microsoft .NET и Моно платформ на Windows (32 или 64-разрядные), Linux (32 или 64 бит) и Mac.
- Высокая производительность — SharpPcap позволяет захватывать данные до >3MB/s скорости передачи
- WinPcap частично поддерживает:
- Удаленный захват пакетов
- Настройка размер буфера ядра (??)
- Инъекции пакетов, используя отправку очередей.
- Сбор сетевой статистики по определенному сетевому интерфейсу
- Поддержка AirPcap
- Перечисление и отображение подробных сведений о физических сетевых интерфейсов на Windows-машине.
- Захват низкоуровневых сетевых пакетов, проходящих через определенный интерфейс.
- Использование Packet.Net для разбора пакетов
- Чтение и запись в pcap файлы
Packet.Net поддерживает для анализа и разбора следующие протоколы:
- Ethernet
- SLL (Linux Cooked-Mode Capture)
- ARP (Address Resolution Protocol)
- IP (Internet Protocol):
- TCP (Transmission Control Protocol)
- UDP (User Datagram Protocol)
- ICMP (Internet Control Message Protocol):
- IGMPv2
- PPPoE
- PTP
- LLDP
- Wake-on-LAN(WOL)
Архитектура SharpPcap
SharpPcap имеет многоуровневую архитектуру, на верхнем уровне классы, которые работают с всеми устройствами:
- CaptureDeviceList — Возвращает список всех устройств в системе
- ICaptureDevice — Все устройства захвата имеют интерфейс ICaptureDevice
Иерархия пространства имен:
- LibPcap
- LibPcapLiveDevice — ICaptureDevice
- LibPcapLiveDeviceList – запрашивает список LibPcapLiveDevice устройств (он включает pcap/winpcap и airpcap устройства)
- CaptureFileReaderDevice – Устройство, которое считывает из pcap файла
- CaptureFileWriterDevice – Устройство, которое создает и записывает в pcap файл
- WinPcap
- WinPcapDeviceList – Запрашивает список WinPcapDevices (он включает winpcap и airpcap устройства)
- WinPcapDevice — LibPcapLiveDevice с дополнительными WinPcap функциями и интерфейсами
- AirPcap
- AirPcapDeviceList – Запрашивает список AirPcapDevices
- AirPcapDevice — WinPcapDevice с дополнительными AirPcap функциями и интерфейсами
CaptureDeviceList возвращает список всех устройств. Каждый из ICaptureDevice будет либо LibPcapLiveDevice, WinPcapDevice или AirPcapDevice. Это позволяет получить всех устройств и дифференцировать их по типам. Если вы хотите получить конкретный тип устройства, можно использовать один из особых *DeviceList классов.
// Получаем все устройства var devices = CaptureDeviceList; // дифференцируем по типу устройства foreach(ICaptureDevice dev in devices) { if(dev is AirPcapDevice) { // обрабатываем если это AirPcapDevice } else if(dev is WinPcapDevice) { // обрабатываем если это WinPcapDevice } else if(dev is LibPcapLiveDevice) { // обрабатываем если это LibPcapLiveDevice } }
// Получить только WinPcap (и AirPcap устройство) var devices = AirPcapDeviceList; foreach(AirPcapDevice dev in devices) { // Обработать AirPcap устройство }
Packet.Net architecture and usage
Packet.Net перешли от модели наследования к модели вложенности пакетов. Все пакеты содержат свойство Packet PayloadPacket и Byte[] PayloadData свойство.. Tcp-пакет, захваченный по Ethernet можно получить как EthernetPacket -> IPv4-Пакет -> Tcp-Пакет. В Packet.Net Tcp пакет может быть доступен как capturedPacket.PayloadPacket.PayloadPacket, так и с помощью статического метода GetEncapsulsted(), который был добавлен, так что теперь можно делать и так тоже TcpPacket tcpPacket = TcpPacket.GetEncapsulated(capturedPacket);.
GetEncapsulated() — интеллектуальный метод и предназначен для работы в различных случаях. UdpPacket.GetEncapsulated() вернет Udp пакет, который состоит из EthernetPacket -> IP-пакета -> UdpPacket. Мы рекомендуем использовать метод GetEncapsulated() для разбора пакетов.
С Packet.Net построение пакетов выглядит так:
using PacketDotNet; ushort tcpSourcePort = 123; ushort tcpDestinationPort = 321; var tcpPacket = new TcpPacket(tcpSourcePort, tcpDestinationPort); var ipSourceAddress = System.Net.IPAddress.Parse("192.168.1.1"); var ipDestinationAddress = System.Net.IPAddress.Parse("192.168.1.2"); var ipPacket = new IPv4Packet(ipSourceAddress, ipDestinationAddress); var sourceHwAddress = "90-90-90-90-90-90"; var ethernetSourceHwAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(sourceHwAddress); var destinationHwAddress = "80-80-80-80-80-80"; var ethernetDestinationHwAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(destinationHwAddress); / / Примечание: Используем EthernetPacketType.None, чтобы проиллюстрировать, // что тип Ethernet протокола обновляется на основе данных полученного пакета Ethernetvar ethernetPacket = new EthernetPacket(ethernetSourceHwAddress, ethernetDestinationHwAddress, EthernetPacketType.None); // Теперь "сшиваем" все пакеты вместе ipPacket.PayloadPacket = tcpPacket; ethernetPacket.PayloadPacket = ipPacket; // И распечатываем, чтобы удостоверится что всё так как мы хотели Console.WriteLine(ethernetPacket.ToString()); //для получения байт, которые представляют этот вновь созданный EthernetPacket используем свойство Bytes byte[] packetBytes = ethernetPacket.Bytes;