Как работает сокет AF_PACKET в Linux? - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь написать сниффер C для Linux и понять действия, происходящие в ядре во время сниффинга.

У меня проблемы с поиском ответа на следующий вопрос: если я инициализирую мой сокет следующим образом:

sock_raw = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));

Что происходит в ядре? Как я вижу все входящие и исходящие пакеты, но не «перехватываю» их? Потому что я понял, что когда ядро ​​получает пакет, оно отправляет его соответствующей функции обработчика протокола. Поэтому я не могу понять - клонирует ли ядро ​​пакет и отправляет его в дополнение к открытому сокету?

1 Ответ

0 голосов
/ 13 июля 2020

Что происходит в ядре?

Ядро просто дублирует пакеты , как только получает их с физического уровня (для входящих пакетов) или непосредственно перед отправкой на физический уровень (для исходящих пакетов). Одна копия каждого пакета отправляется в ваш сокет (если вы используете ETH_PH_ALL, вы слушаете все интерфейсы, но вы также можете bind(2) на конкретный). После того, как копия отправлена ​​в ваш сокет, другая копия продолжает обрабатываться, как обычно (например, идентификация и декодирование протокола, проверка правил брандмауэра и т. Д. c).

Как я видеть все входящие и исходящие пакеты, но не «перехватывать» их? сокет, вводящий новые пакеты (точно созданный в зависимости от протокола, который вы хотите захватить). Если вы только читаете входящих пакетов, вы просто обнюхиваете , ничего не перехватывая.

клонирует ли ядро ​​пакет и отправляет его в дополнение к сокет, который я открыл?

Да, в основном так и происходит. Это изображение может помочь вам визуализировать это.

man 7 packet также описывает это:

Пакетные сокеты используются для приема или отправки сырые пакеты на уровне драйвера устройства (OSI Layer 2). Они позволяют пользователю реализовывать модули протокола в пользовательском пространстве поверх физического уровня.

socket_type - это либо SOCK_RAW для необработанных пакетов, включая заголовок уровня канала, либо SOCK_DGRAM для подготовленных пакетов с заголовок на уровне ссылки удален. Информация заголовка на уровне ссылки доступна в общем формате в структуре sockaddr_ll. Протокол - это номер протокола IEEE 802.3 в сетевом порядке байтов. Список разрешенных протоколов см. В включаемом файле <linux/if_ether.h>. Если протокол установлен на htons(ETH_P_ALL), то принимаются все протоколы. Все входящие пакеты этого типа протокола будут переданы в сокет пакетов, прежде чем они будут переданы протоколам, реализованным в ядре.

...