3. Если для символьного сокета был определен внешний адрес с помощью функции connect
, IP-адрес отправителя в полученной дейтаграмме должен совпадать с этим адресом, иначе дейтаграмма не посылается данному сокету.
Следует отметить, что если символьный сокет создан с нулевым значением аргумента protocol
и не вызывается ни функция bind
, ни функция connect
, то сокет получает копии всех дейтаграмм, которые ядро направляет символьным сокетам.
Дейтаграммы IPv4 всегда передаются через символьные сокеты целиком, вместе с заголовками. В версии IPv6 символьному сокету передается все, кроме дополнительных заголовков (см., например, рис. 28.4 и 28.6).
В заголовке IPv4, передаваемом приложению, для ip_len, ip_off и ip_id установлен порядок байтов узла, а все остальные ноля имеют порядок байтов сети. В системе Linux все поля остаются в сетевом порядке байтов.
Как уже говорилось, интерфейс символьных сокетов определяется таким образом, чтобы работа со всеми протоколами, в том числе и не обрабатываемыми ядром, осуществлялась одинаково. Поэтому содержимое полей зависит от ядра операционной системы.
В предыдущем разделе мы отметили, что все ноля символьного сокета IPv6 остаются в сетевом порядке байтов.
Фильтрация по типу сообщений ICMPv6
Символьный сокет ICMPv4 получает большинство сообщений ICMPv4, полученных ядром. Но ICMPv6 является расширением ICMPv4, включающим функциональные возможности ARP и IGMP (см. раздел 2.2). Следовательно, символьный сокет ICMPv6 потенциально может принимать гораздо больше пакетов по сравнению с символьным сокетом ICMPv4. Но большинство приложений, использующих символьные сокеты, заинтересованы только в небольшом подмножестве всех ICMP-сообщений.
Для уменьшения количества пакетов, передаваемых от ядра к приложению через символьный ICMPv6-сокет, предусмотрен фильтр, связанный с приложением. Фильтр объявляется с типом данных struct icmp6_filter
, который определяется в заголовочном файле
. Для установки и получения текущего ICMPv6-фильтра для символьного сокета ICMPv6 используются функции setsockopt
и getsockopt
с аргументом level
, равным IPPROTO_ICMPV6
, и аргументом optname
, равным ICMP6_FILTER
.
Со структурой icmp6_filter
работают шесть макросов.
#include
void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *
void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *
void ICMP6_FILTER_SETPASS(int
void ICMP6_FILTER_SETBLOCK(int
int ICMP6_FILTER_WILLPASS(int
int ICMP6_FILTER_WILLBLOCK(int
Аргумент filt
всех макрокоманд является указателем на переменную icmp6_filter
, изменяемую первыми четырьмя макрокомандами и проверяемую последними двумя. Аргумент msgtype
является значением в интервале от 0 до 255, определяющим тип ICMP-сообщения.
Макрокоманда SETPASSALL
указывает, что все типы сообщений должны пересылаться приложению, а макрокоманда SETBLOCKALL
— что никакие сообщения не должны посылаться приложениям. По умолчанию при создании символьного сокета ICMPv6 подразумевается, что все типы ICMP-сообщений пересылаются приложению.
Макрокоманда SETPASS
определяет конкретный тип сообщений, который должен пересылаться приложению, а макрокоманда SETBLOCK
блокирует один конкретный тип сообщений. Макрокоманда WILLPASS
возвращает значение 1, если определенный тип пропускается фильтром. Макрокоманда WILLBLOCK
возвращает значение 1, если определенный тип блокирован фильтром, и нуль в противном случае.
В качестве примера рассмотрим приложение, которое будет получать только ICMPv6-извещения маршрутизатора: