Welcome to Энциклопедия сетевых протоколов
Поиск

Модули
· Титульная страница
· Мир протоколов
· Основные темы
· Архив публикаций
· Поиск
· Каталог ссылок
· Участники
· Документы и программы

Выбор языка
Язык интерфейса:


Статистика
20490446
запросов с 22 сентября 2005

Внешняя статистика
Rambler's Top100

  
Пакетный сокет в Linux
Опубликовано 05 окт. 2005 (Ср.) в 22:30:46
Тема: Реализации протоколов

Сокет packet (тип PF_PACKET) используется для приема и передачи необработанных (raw) пакетов на канальном уровне (OSI Layer 2). Интерфейс сокета позволяет реализовать в пользовательском пространстве модули протоколов, использующих только сервис канального уровня.

В качестве типа сокета может указываться значение SOCK_RAW (необработанные пакеты, включающие заголовок канального уровня) или SOCK_DGRAM (обработанные пакеты с удаленным заголовком канального уровня). Заголовки канального уровня представляются в виде структуры sockaddr_ll, описанной ниже.



Поле sll_protocol содержит номер протокола IEEE 802.31 (значение ETH_P_ALL соответствует всем протоколам Ethernet). Все входящие пакеты заданного в адресной структуре протокола, будут передаваться пакетному сокету до их передачи протокольным модулям ядра.

Для того, чтобы открыть пакетный сокет приложение должно иметь флаг возможности CAP_NET_RAW или исполняться от имени пользователя с эффективным идентификатором UID=0.

Пакеты SOCK_RAW передаются и принимаются от драйвера устройства без каких-либо изменений в данных. При получении пакета адресная информация разбирается и передается в структуру sockaddr_ll. При передаче пакета полученный от пользователя буфер должен содержать заголовок канального уровня. Такой пакет передается без изменений сетевому драйверу интерфейса, указанного в поле адреса получателя.

Обработка пакетов SOCK_DGRAM происходит на более высоком уровне. Заголовок канального уровня удаляется из пакета до передачи этого пакета пользователю. Передаваемые через пакетный сокет пакеты SOCK_DGRAM получают подходящий заголовок канального уровня в структуре sockaddr_ll до их размещения в очереди.

По умолчанию все пакеты заданного типа протокола передаются пакетному сокету. Для того, чтобы получать только пакеты от интересующего интерфейса, следует использовать функцию bind, передав ей в качестве параметра структуру sockaddr_ll для соответствующего интерфейса, чтобы связать сокет с этим интерфейсом. В этом случае из адресной структуры используются лишь поля sll_protocol и sll_ifindex.

Операции подключения (connect) не поддерживаются для пакетного сокета.

Если при вызове функций recvmsg, recv, recvfrom был установлен флаг MSG_TRUNC, функции всегда будут возвращать реальный размер кадра в среде, даже если он отличается от размера кадра в буфере (заполнение для выравнивания).

Для переносимых программ разумно использовать сокеты PF_PACKET через библиотеку pcap, хотя эта библиотека не перекрывает всех возможностей пакетных сокетов.

Пакетные сокеты SOCK_DGRAM не пытаются создавать или разбирать заголовки IEEE 802.2 LLC для кадров IEEE 802.3. При выборе для передачи в качестве протокола ETH_P_802_3 ядро создает кадр 802.3 и заполняет поле размера. Пользовательская программа должна предоставить заголовок LLC для создания законченного пакета. Входящие пакеты 802.3 не демультиплексируются по полям протокола DSAP/SSAP – они просто передаются пользовательскому приложению как пакеты протокола ETH_P_802_2 с готовым заголовком LLC. Таким образом, привязка к протоколу ETH_P_802_3 невозможна и приложению следует использовать привязку к протоколу ETH_P_802_2 и самостоятельно выполнять демультиплексирование. По умолчанию для передаваемых пакетов используется инкапсуляция Ethernet DIX.

Пакетные сокеты никак не связаны с цепочками правил межсетевых экранов.

Типы адресов

Для адресации пакетный сокет использует независимую от адресов физического уровня структуру sockaddr_ll.

struct sockaddr_ll {

unsigned short sll_family; /* AF_PACKET */

unsigned short sll_protocol; /* протокол канального уровня */

int sll_ifindex; /* номер интерфейса */

unsigned short sll_hatype; /* тип заголовка */

unsigned char sll_pkttype; /* тип пакета */

unsigned char sll_halen; /* размер адреса */

unsigned char sll_addr[8]; /* аппаратный адрес */

};

Поле sll_protocol содержит идентификатор стандартного типа протокола Ethernet (см. файл linux/if_ether.h). Поле sll_ifindex содержит индекс интерфейса2; sll_hatype задает тип ARP3. Поле sll_pkttype указывает тип адресации пакета; допустимыми типами являются PACKET_HOST (пакеты, адресованные локальному хосту), PACKET_BROADCAST (широковещательные пакеты канального уровня), PACKET_MULTICAST (групповая адресация на канальном уровне), PACKET_OTHERHOST (пакет для другого хоста, который может быть захвачен интерфейсом, работающим в режиме promiscuous), и PACKET_OUTGOING (для пакетов от локального хоста, возвращенных пакетному сокету). Перечисленные типы адресации имеют смысл только для принимаемых пакетов. Поля sll_addr и sll_halen содержат аппаратный адрес (например, IEEE 802.3) и его размер. Интерпретация этих полей зависит от конкретного устройства.

При передаче пакетов достаточно задать значения sll_family=AF_PACKET, sll_addr, sll_halen и sll_ifindex. Остальные поля должны иметь значение 0. Поля sll_hatype и sll_pkttype устанавливаются в принимаемых пакетах только для информации. Для связывания сокетов используются только поля sll_protocol и sll_ifindex.

Опции сокета

Пакетные сокеты могут использоваться для групповой рассылки на канальном уровне и работы интерфейсов в режиме захвата. Опции сокета задаются с помощью функции setsockopt для SOL_PACKET. Опция PACKET_ADD_MEMBERSHIP добавляет привязку, а опция PACKET_DROP_MEMBERSHIP удаляет ее. В обоих случаях в качестве аргумента передается структура:

struct packet_mreq

{

int mr_ifindex; /* индекс интерфейса */

unsigned short mr_type; /* действие */

unsigned short mr_alen; /* размер адреса */

unsigned char mr_address[8]; /* аппаратный адрес */

};

Поле mr_ifindex содержит индекс интерфейса, для которого нужно изменить состояние, mr_type задает выполняемое действие (PACKET_MR_PROMISC разрешает прием из среды всех пакетов – режим захвата, PACKET_MR_MULTICAST привязывает сокет к multicast-группе канального уровня, а PACKET_MR_ALLMULTI разрешает сокету принимать все пакеты с групповыми адресами, поступающие в данный интерфейс).

Для решения этих задач можно использовать также стандартные операции IOCTL SIOCSIFFLAGS, SIOCADDMULTI, SIOCDELMULTI.

Операции IOCTL

Для получения временной метки последнего доставленного пакета может использоваться SIOCGSTAMP со структурой timeval в качестве аргумента.

Кроме того для пакетных сокетов поддерживаются все операции IOCTL, определенные для netdevice и socket.

Обработка ошибок

Пакетные сокеты не выполняют обработки каких-либо ошибок за исключением тех, которые происходят при передаче пакетов драйверу устройства.

Коды ошибок

Таблица 1 Коды ошибок для пакетных сокетов

Код

Описание

ENETDOWN

Интерфейс неактивен.

ENOTCONN

Функции не передан адрес интерфейса.

ENODEV

Задано неизвестное имя устройства или индекс интерфейса.

EMSGSIZE

Размер пакета превышает значение MTU для интерфейса.

ENOBUFS

Недостаточно памяти для размещения пакета.

EFAULT

Пользователь передал некорректный адрес памяти.

EINVAL

Некорректный аргумент

ENXIO

В адресе содержится некорректный индекс интерфейса.

EPERM

Пользователь не имеет прав на выполнение операции.

EADDRNOTAVAIL

Передан неизвестный адрес multicast-группы.

ENOENT

Пакет не был получен

Драйверы устройств могут генерировать дополнительные коды ошибок.

Известные проблемы

  1. Обработка IEEE 802.2/803.3 LLC может трактоваться как ошибка.

  2. Отсутствует документация для фильтров сокета.

  3. Расширение MSG_TRUNC для функции recvmsg является слишком опасным – вместо него следует использовать управляющее сообщение.

  4. Отсутствует способ определения исходного адреса получателя пакетов SOCK_DGRAM.

1Поддерживаемые номера протоколов перечислены в файле <linux/if_ether.h>

2Значению 0 соответствуют все интерфейсы системы – это значение можно использовать только для привязки сокетов

3Допустимые идентификаторы типов перечислены в файле <linux/if_arp.h>


 
Вход
Регистрационное имя

Пароль

[Восстановить пароль]

Если у Вас еще нет учетной записи, Вы можете зарегистрироваться.


Связанные ссылки
· Поиск в разделе Реализации протоколов
· Статьи пользователя Николай Малых


Самая популярная статья раздела Реализации протоколов:
RAW-сокеты в Linux


Оценка статьи
Средняя оценка: 3.33
голос.: 3


Оцените эту публикацию:

Отлично
Очень хорошо
Хорошо
Приемлемо
Плохо


Параметры

 Вариант для печати Вариант для печати


Связанные темы

Настройка сетевых параметров хостов

"Вход" | Вход/регистрация | 0 коммент.
Комментарии выражают мнение их авторов. Администрация сайта не несет никакой ответственности за достоверность представленных в комментариях посетителей сведений, а также за содержание таких комментариев.

Для публикации своих комментариев Вам нужно зарегистрироваться..
Copyright © Nikolai Malykh
Все права на опубликованные на сайте материалы принадлежат Nikolai Malykh, если в опубликованном на сайте документе явно не указано иное.
Не разрешается воспроизведение опубликованных на сайте документов без согласия правообладателя.

Hosted By Web Hosting by iPage

Copyright © 2005 by Nikolai Malykh
Based on PHP-Nuke by Francisco Burzi. This is free software, and you may redistribute it under the GPL. Author comes with absolutely no warranty.
Время генерации страницы: 0.09 сек.