SharpPcap библиотека для перехвата пакетов. Введение.

SharpPcap
Перевод справки, поставляемой вместе с дистрибутивом SharpPcap

Вступление

Перехват пакетов (или перехвата пакетов) — это процесс сбора, всех пакетов проходящих через определенный сетевой интерфейс. Захват сетевых пакетов в наших приложениях позволяет реализовывать такие приложения как: мониторинг сети, сетевые анализаторы и средства безопасности. Цель библиотеки WinPcap для Windows предоставить API для низкоуровневого мониторинга сети. Среди приложений, использующих WinPcap являются знаменитые tcpdump и Wireshark.

О SharpPcap

Цель SharpPcap-обеспечить основу для захвата, инъекции и анализа сетевых пакетов для .NET приложений.

SharpPcap активно развивается с открытым исходным код размещенным на SourceForge. Патчи исходного кода, для улучшения или исправления ошибок приветствуются через sharppcap список рассылки разработчиков. Сообщения об ошибках, пожеланиях и другие вопросы активно обсуждаются на форумах поддержки, так что если у вас есть проблемы с библиотекой, пожалуйста, не стесняйтесь спрашивать.

SharpPcap-это полностью управляемая кросс-платформенная библиотека. Та же сборка работает под Microsoft .NET также как Моно на 32 и 64-битных платформах.

Следующий список иллюстрирует возможности, которые в настоящее время поддерживаются в SharpPcap:

  1. Одна сборка для Microsoft .NET и Моно платформ на Windows (32 или 64-разрядные), Linux (32 или 64 бит) и Mac.
  2. Высокая производительность — SharpPcap позволяет захватывать данные до >3MB/s скорости передачи
  3. WinPcap частично поддерживает:
    • Удаленный захват пакетов
    • Настройка размер буфера ядра (??)
    • Инъекции пакетов, используя отправку очередей.
  4. Сбор сетевой статистики по определенному сетевому интерфейсу
  5. Поддержка AirPcap
  6. Перечисление и отображение подробных сведений о физических сетевых интерфейсов на Windows-машине.
  7. Захват низкоуровневых сетевых пакетов, проходящих через определенный интерфейс.
  8. Использование Packet.Net для разбора пакетов
  9. Чтение и запись в pcap файлы

Packet.Net поддерживает для анализа и разбора следующие протоколы:

Архитектура 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;

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *