Указывая протокол ETH_P_ххх
, мы тем самым сообщаем канальному уровню, какой тип из получаемых канальным уровнем кадров передавать сокету. Если канальный уровень поддерживает смешанный режим (например, Ehternet), то устройство тоже должно работать в смешанном режиме. Это осуществляется при помощи параметра сокета PACKET_ADD_MEMBERSHIP
с использованием структуры packet_mreq
. При этом необходимо указать конкретный интерфейс и задать тип действия PACKET_MR_PROMISC
. В старых системах для этого нужно вызвать функцию ioctl
с запросом SIOCGIFFLAGS
для получения флагов, установить флаг IFF_PROMISC
и далее сохранить флаги с помощью SIOCSIFFLAGS
. К сожалению, при использовании этого метода программы, работающие в смешанном режиме, могут мешать друг другу, а если в одной из них содержатся ошибки, то она может и не отключить смешанный режим по завершении.
Сравнивая это средство Linux с BPF и DLPI, мы можем отметить некоторые различия.
1. В Linux не обеспечивается буферизация. Фильтрация на уровне ядра доступна только в новых системах (при помощи параметра SO_ATTACH_FILTER
). Существует обычный буфер приема сокета, но отсутствует возможность буферизации и отправки приложению нескольких кадров с помощью одной операции считывания. Это увеличивает накладные расходы, связанные с копированием потенциально возможных больших объемов данных из ядра в приложение.
2. В Linux не предусмотрена фильтрация на уровне устройства. Сокеты PF_PACKET
могут быть связаны с устройством функцией bind
. Если в вызове функции socket
указан аргумент ETH_P_IP
, то все пакеты IPv4 со всех устройств (например, Ethernet, каналы PPP, каналы SLIP и закольцовка) будут переданы на сокет. Функция recvfrom
возвращает общую структуру адреса сокета, а элемент sa_data
содержит имя устройства (например, eth0
). Тогда приложение само должно игнорировать данные с тех устройств, которые не представляют для него интереса. Здесь мы сталкиваемся фактически с той же проблемой: возможно, что приложение будет получать слишком много данных, особенно в случае наблюдения за высокоскоростной сетью.
29.5. Libcap: библиотека для захвата пакетов
Библиотека захвата пакетов libcap
обеспечивает не зависящий от реализации доступ к средствам операционной системы, с помощью которых осуществляется этот захват. В настоящее время поддерживается только чтение пакетов (хотя добавление нескольких строк кода в библиотеку позволяет также записывать пакеты в некоторых системах). В следующем разделе приводится описание альтернативной библиотеки, которая не только дает возможность записывать пакеты на канальный уровень, но и позволяет конструировать пакеты произвольного типа.
Сейчас осуществляется поддержка BPF для Беркли-ядер, DLPI для Solaris 2.x, NIT для SunOS 4.1.x, пакетных сокетов ( SOCK_PACKET
, PF_PACKET
) в Linux и нескольких других операционных системах. Библиотека libcap
используется программой tcpdump
. Всего в библиотеке насчитывается порядка 25 функций, но вместо того чтобы просто описывать их, мы продемонстрируем их фактическое использование на примере, рассматриваемом в следующем разделе. Названия всех функций начинаются с pcap_
. Они описаны более подробно на странице руководства, которая называется pcap
.
ПРИМЕЧАНИЕ
Библиотека libcap находится в свободном доступе по адресу http://www.tcpdump.org/.
29.6. Libnet: библиотека создания и отправки пакетов
Библиотека libnet
предоставляет интерфейс для создания и отправки в сеть пакетов произвольного содержимого. Она обеспечивает доступ на уровне символьных сокетов и доступ к канальному уровню в формате, не зависящем от реализации.
Библиотека скрывает большую часть деталей формирования заголовков IP, UDP и TCP и обеспечивает приложению простой и переносимый интерфейс для отправки пакетов канального уровня и IP-пакетов через символьные сокеты. Как и libcap
, библиотека libnet
содержит достаточно много функций. Мы приведем пример использования небольшой их части, предназначенной для работы с символьными сокетами, но в следующем разделе. Для сравнения там же будет приведен код, непосредственно работающий с символьными сокетами. Все функции библиотеки начинаются с префикса libnet_
. За более подробным их описанием вы можете обратиться к странице руководства libnet
или к доступной в Сети документации.
ПРИМЕЧАНИЕ
Библиотека libnet свободно доступна по адресу http://www.packetfactory.net/libnet/. Руководство находится по адресу http://www.packetfactory.net/libnet/manual. На момент написания этой книги в Сети имелось руководство только по устаревшей версии 1.0. Актуальная версия 1.1 имеет значительно отличающийся интерфейс. В нашем примере используется API версии 1.1.
Читать дальше
Конец ознакомительного отрывка
Купить книгу