Книга: UNIX: разработка сетевых приложений

Фильтрация по типу сообщений ICMPv6

Фильтрация по типу сообщений ICMPv6

Символьный сокет ICMPv4 получает большинство сообщений ICMPv4, полученных ядром. Но ICMPv6 является расширением ICMPv4, включающим функциональные возможности ARP и IGMP (см. раздел 2.2). Следовательно, символьный сокет ICMPv6 потенциально может принимать гораздо больше пакетов по сравнению с символьным сокетом ICMPv4. Но большинство приложений, использующих символьные сокеты, заинтересованы только в небольшом подмножестве всех ICMP-сообщений.

Для уменьшения количества пакетов, передаваемых от ядра к приложению через символьный ICMPv6-сокет, предусмотрен фильтр, связанный с приложением. Фильтр объявляется с типом данных struct icmp6_filter, который определяется в заголовочном файле <netinet/icmp6.h>. Для установки и получения текущего ICMPv6-фильтра для символьного сокета ICMPv6 используются функции setsockopt и getsockopt с аргументом level, равным IPPROTO_ICMPV6, и аргументом optname, равным ICMP6_FILTER.

Со структурой icmp6_filter работают шесть макросов.

#include <netinet/icmp6.h>
void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *filt);
void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *filt);
void ICMP6_FILTER_SETPASS(int msgtype, struct icmp6_filter *filt);
void ICMP6_FILTER_SETBLOCK(int msgtype, struct icmp6_filter *filt);
int ICMP6_FILTER_WILLPASS(int msgtype, const struct icmp6_filter *filt);
int ICMP6_FILTER_WILLBLOCK(int msgtype, const struct icmp6_filter *filt);
Все возвращают: 1, если фильтр пропускает (блокирует) сообщение данного типа, 0 в противном случае

Аргумент filt всех макрокоманд является указателем на переменную icmp6_filter, изменяемую первыми четырьмя макрокомандами и проверяемую последними двумя. Аргумент msgtype является значением в интервале от 0 до 255, определяющим тип ICMP-сообщения.

Макрокоманда SETPASSALL указывает, что все типы сообщений должны пересылаться приложению, а макрокоманда SETBLOCKALL — что никакие сообщения не должны посылаться приложениям. По умолчанию при создании символьного сокета ICMPv6 подразумевается, что все типы ICMP-сообщений пересылаются приложению.

Макрокоманда SETPASS определяет конкретный тип сообщений, который должен пересылаться приложению, а макрокоманда SETBLOCK блокирует один конкретный тип сообщений. Макрокоманда WILLPASS возвращает значение 1, если определенный тип пропускается фильтром. Макрокоманда WILLBLOCK возвращает значение 1, если определенный тип блокирован фильтром, и нуль в противном случае.

В качестве примера рассмотрим приложение, которое будет получать только ICMPv6-извещения маршрутизатора:

struct icmp6_filter myfilt;
fd = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
ICMP6_FILTER_SETBLOCKALL(&myfilt);
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &myfilt);
Setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt));

Сначала мы блокируем все типы сообщений (поскольку по умолчанию все типы сообщений пересылаются), а затем разрешаем пересылать только извещения маршрутизатора. Несмотря на то, что мы используем фильтр, приложение должно быть готово к получению всех типов пакетов ICMPv6, потому что любые пакеты ICMPv6, полученные между вызовами socket и setsockopt, будут добавлены в очередь на сокете. Параметр ICMP6_FILTER — лишь средство оптимизации условий функционирования приложения.

Оглавление книги

Оглавление статьи/книги

Генерация: 1.084. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз