Эффективное программирование TCP-IP

       

Как работает tcpdump


Посмотрим, как работает программа t cpdump и на каком уровне протоколов она перехватывает пакеты. Как и большинство сетевых анализаторов, tcpdump состоит из двух компонент: первая работает в ядре и занимается перехватом и, возможно фильтрацией пакетов, а вторая действует в адресном пространстве пользователя и определяет интерфейс пользователя, а также выполняет форматирование и фильтрацию пакетов, если последнее не делается ядром.

Пользовательская компонента tcpdump взаимодействует с компонентой в ядре при помощи библиотеки libpcap (библиотека для перехвата пакетов), которая абстрагирует системно-зависимые детали общения с канальным уровнем стека протоколов. Например, в системах на основе BSD libpcap взаимодействует с пакетным фильтром BSD (BSD packet filter - BPF) [McCanne and Jacobson 1993]. BPF исследует каждый пакет, проходящий через канальный уровень, и сопоставляет его с фильтром, заданным пользователем. Если пакет удовлетворяет критерию фильтрации, то его копия помещается в выделенный ядром буфер, который ассоциируется с данным фильтром. Когда буфер заполняется или истекает заданный пользователем тайм-аут, содержимое буфера передается приложению с помощью libpcap.

Этот процесс изображен на рис. 4.4. Показано, как tcpdump и любая другая программа считывают необработанные пакеты с помощью BPF, а также изображено еще одно приложение, читающее данные из стека TCP/IP, как обычно.

Примечание: Хотя на этом рисунке и tcpdump, и программа используют библиотеку libpcap, можно напрямую общаться с ВРF или иным интерфейсом, о чем будет сказано ниже. Достоинство libpcap в том, что она предоставляет системно-независимые средства доступа к необработанным пакетам. В настоящее время эта библиотека поддерживает BPF; интерфейс канального провайдера (data link provider interface – DLPI); систему SunOS NIT; потоковую NIT; сокеты типа SOCK_PACKET, применяемые в системе Linux; интерфейс snoop (IRIX) и разработанный в Стэнфордском университете интерфейс enet. В дистрибутив WinDump входит также версия libpcap для Windows.


Обратите внимание, что BPF перехватывает сетевые пакеты на уровне драйвера устройства, то есть сразу после того, как они считаны с носителя. Это не то же самое что чтение из простого сокета. В ситуации с простым сокетом вы получаете IР-датаграммы, уже обработанные уровнем IP и переданные непосредственно приложению минуя транспортный уровень (TCP или UDP). Об этом рассказывается в совете 40.

Начиная с версии 2.0, архитектура WinDump очень напоминает используемую в системах BSD. Эта программа пользуется специальным NDIS-драйвером (NDIS- Network Driver Interface Specification - спецификация стандартного интерфейса сетевых адаптеров), предоставляющим совместимый с BPF фильтр и интерфейс. В архитектуре WinDump NDIS-драйвер фактически представляет собой часть стека протоколов, но функционирует он так же, как показано на рис. 4.4, только надо заменить BPF на пакетный драйвер NDIS.

Как работает tcpdump


Рис. 4.4. Перехват пакетов с помощью BPF

Другие операционные системы используют несколько иные механизмы. В системах, производных от SVR4, для доступа к простым сокетам применяется интерфейс DLPI [Unix International 1991]. DLPI - это не зависящий от протокола, основанный на системе STREAMS [Ritchie 1984] интерфейс к канальному уровню, С помощью DLPI можно напрямую получить доступ к канальному уровню, но по соображениям эффективности обычно вставляют в поток STREAMS-модули pfmod и bufmod. Модуль bufmod предоставляет услуги по буферизации сообщений и увеличивает эффективность за счет ограничения числа контекстных переключений, требуемых для доставки данных.

Примечание: Это аналогично чтению полного буфера из сокета вместо побайтного чтения.

Модуль pfmod - это фильтр, аналогичный BPF. Поскольку он несовместим с фильтром BPF, tcpdump вставляет этот модуль в поток, а фильтрацию выполняет в пространстве пользователя. Это не столь эффективно, как при использовании BPF, так как в пространство пользователя приходится передавать каждый пакет, даже если он не нужен программе tcpdump.

На рис. 4.5 показаны tcpdump без модуля pf mod и приложение, которое получает необработанные пакеты с использованием находящегося в ядре фильтра.



На рис. 4. 5 также представлены приложения, пользующиеся библиотекой libpcap, но, как и в случае BPF, это необязательно. Для отправки сообщений непосредственно в поток и получения их обратно можно было бы воспользоваться вызовами getmsg и putmsg. Книга [Rago 1993] - отличный источник информации о программировании системы STREAMS, DLPI и системных вызовах getmsg и putmsq. Более краткое обсуждение вопроса можно найти в главе 33 книги [Stevens 1998].

Как работает tcpdump


Рис. 4.5. Перехват пакетов с помощью DLPI

Наконец, есть еще и архитектура Linux. В этой системе доступ к необработанным сетевым пакетам производится через интерфейс сокетов типа SOCK_PACKET. Для использования этого простого механизма надо открыть подобный сокет, привязать к нему требуемый сетевой интерфейс, включить режим пропускания всех пакетов (promiscuous mode) и читать из сокета.

Примечание: Начиная с версии 2.2 ядра Linux, рекомендуется несколько другой интерфейс, но последняя версия libpcap по-прежнему поддерживает описанный выше.

Например, строка

s = socket( AF_INET, SOCK_PACKET, htons( ETH_P_ALL ) );

открывает сокет, предоставляющий доступ ко всем Ethernet-пакетам. В качестве третьего параметра можно также указать ЕТН_Р_IР (пакеты IP), ETH_P_IPV6 (пакеты IPv6) или ETH_P_ARP (пакеты ARP). Будем считать, что этот интерфейс аналогичен простым сокетам (SOCK_RAW), только доступ производится к канальному, а не сетевому (IP) уровню.

К сожалению, несмотря на простоту и удобство этого интерфейса, он не очень эффективен. В отличие от обычных сокетов, ядро в этом случае не осуществляет никакой буферизации, так что каждый пакет доставляется приложением сразу после поступления. Отсутствует также фильтрация на уровне ядра (если не считать параметра ЕТН_Р_* ). Поэтому фильтровать приходится на прикладном уровне, а это означает, что приложение должно получать все пакеты без исключения.


Содержание раздела