Уровень IPv4 генерирует заголовок IP при посылке пакета, если только сокету не задана опция IP_HDRINCL. Если она задана, то пакет должен содержать заголовок IP. Принимаемые пакеты всегда содержат заголовок IP.
Открывать raw-сокеты могут только процессы с идентификатором эффективного пользователя, равным нулю, или имеющие возможность CAP_NET_RAW.
Все пакеты или ошибки, совпадающие с номером протокола protocol, указанным raw-сокету, передаются этому сокету. Список возможных протоколов и назначенных им номеров указан в RFC1700 и в getprotobyname(3).
Протокол IPPROTO_RAW подразумевает разрешенный IP_HDRINCL и принимает все протоколы IP. Передача протоколов в этом случае не разрешена.
Поля заголовка IP, изменяемые IP_HDRINCL при передаче | |
IP Checksum | Всегда заполняется. |
Source Address | Заполняется, если значение равно нулю. |
Packet Id | Заполняется, если значение равно нулю. |
Total Length | Всегда заполняется. |
Если указано IP_HDRINCL и заголовок IP имеет ненулевой адрес назначения, то для маршрутизации пакета используется адрес назначения сокета. Если указано значение MSG_DONTROUTE, то адрес назначения должен ссылаться на локальный интерфейс, иначе в любом случае будет производится поиск в таблице маршрутизации, хотя маршруты через шлюзы будут игнорироваться. Если значение IP_HDRINCL не установлено, то опции заголовка IP в raw-сокетах могут быть установлены с помощью setsockopt(2); более подробная информация приведена в ip(7).
В Linux 2.2 все поля заголовка IP и опции могут быть заданы с помощью опций сокета IP. Это означает, что raw-сокеты, как правило, необходимы лишь для новых протоколов или протоколов без интерфейса пользователя (таких, как ICMP).
Принятый пакет передается всем подключенным (bound) к этому протоколу сокетам до того, как он будет передан другим обработчикам протокола (например, протокольным модулям ядра).
Кроме того, поддерживаются все датаграммные опции сокетов SOL_IP ip(7).
Raw-сокет может быть подключен к определенному локальному адресу с помощью вызова bind(2). Если он не подключен, принимаются все пакеты указанного протокола IP. Кроме того, RAW-сокет может быть подключен к определенному сетевому устройству с помощью SO_BINDTODEVICE; см. socket(7).
Сокет IPPROTO_RAW предназначен только для передачи (посылки) пакетов. Если Вы хотите получать все пакеты IP, используйте пакетный сокет ( packet(7)) с протоколом ETH_P_IP. Обратите внимание, что пакетные сокеты в отличие от raw-сокетов не собирают фрагменты IP.
Если Вы хотите получать все пакеты ICMP для датаграммного сокета, то лучше использовать IP_RECVERR ; см. ip(7).
Raw-сокеты могут "перехватывать" в Linux все протоколы, даже имеющие протокольный модуль в ядре (такие, как ICMP или TCP). В этом случае пакеты передаются как модулю ядра, так и raw-сокету(-ам). Это не должно быть отражено в переносимых программах, так как многие другие реализации BSD-сокетов имеют определенные ограничения.
Linux никогда не изменяет заголовки, полученные от пользователя (за исключением заполнения некоторых обнуленных полей, как описано в случае с IP_HDRINCL). Такое поведение отличается от поведения многих других реализаций raw-сокетов.
RAW-сокеты, в общем случае, не являются переносимыми, поэтому следует избегать их использования в переносимых программах.
Передача через raw-сокет должна освуществляться с помощью протокола IP из sin_port; эта возможность исчезла в Linux 2.2. Избежать этого можно, используя IP_HDRINCL.
Коды raw-сокетов в версии Linux 2.0 при установленном флаге SO_BSDCOMPAT были специально сделаны "совместимыми" с BSD по существующим ошибкам. Из Linux 2.2 это было удалено.
Если установлена опция IP_HDRINCL, датаграммы не будут фрагментированы и их размер будет ограничен MTU интерфейсом. Это ограничение Linux 2.2.
В Linux 2.2 отсутствует настройка протокола IP для отправки его в sin_port, и всегда используется тот протокол, к которому был подключен сокет или который был упомянут при первом вызове socket(2).
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |