Чтение онлайн

ЖАНРЫ

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

u_char ifm_type; /* тип сообщения */

int ifm_addrs; /* как rtm_addrs */

int ifm_flags; /* значение if_flags */

u_short ifm_index; /* индекс интерфейса, с которым связан адрес */

struct if_data ifm_data; /* статистические и другие сведения */

};

struct ifa_msghdr { /* из <net/if.h> */

u_short ifam_msglen; /* для пропуска некорректных сообщений */

u_char ifam_version; /*
для обеспечения двоичной совместимости в будущем */

u_char ifam_type; /* тип сообщения */

int ifam_addrs; /* как rtm_addrs */

int ifam_flags; /* значение ifa_flags */

u_short ifam_index; /* индекс интерфейса, с которым связан адрес */

int ifam_metric; /* значение ifa_metric */

};

struct ifma_msghdr { /* из <net/if.h> */

u_short ifmam_msglen; /* для пропуска некорректных сообщений */

u_char ifmam_version; /* для обеспечения двоичной совместимости в будущем */

u_char ifmam_type; /* тип сообщения */

int ifmam_addrs; /* аналог rtm_addrs */

int ifmam_flags; /* значение ifa_flags */

u_short ifmam_index; /* индекс связанного ifp */

};

struct if_announcemsghdr { /* из <net/if.h> */

u_short ifan_msglen; /* для пропуска некорректных сообщений */

u_char ifan_version; /* для обеспечения двоичной совместимости в будущем */

u_char ifan_type; /* тип сообщения */

u_short ifan_index; /* индекс связанного ifp */

char ifan_name[IFNAMSIZ]; /* название интерфейса, напр. "en0" */

u_short ifan_what; /* тип объявления */

};

Первые три элемента каждой структуры одни и те же: длина, версия и тип сообщения. Тип — это одна из констант из первого столбца табл. 18.1. Элемент длины

xxx_msglen
позволяет приложению пропускать типы сообщений, которые оно не распознает.

Элементы

rtm_addrs
,
ifm_addrs
и
ifam_addrs
являются битовыми масками, указывающими, какая из возможных восьми структур адреса сокета следует за сообщением. В табл. 18.2 показаны константы и значения для битовой маски, определяемые в заголовочном файле
<net/route.h>
.

Таблица 18.2. Константы, используемые для ссылки на структуры адреса сокета в маршрутизирующих сообщениях

Битовая маска, константа Битовая маска, значение Индекс массива, константа Индекс массива, значение Структура адреса сокета содержит
RTA_DST 0x01 RTAX_DST 0 Адрес получателя
RTA_GATEWAY 0x02 RTAX_GATEWAY 1 Адрес шлюза
RTA_NETMASK 0x04 RTAX_NETMASK 2 Маска сети
RTA_GENMASK 0x08 RTAX_GENMASK 3 Маска
клонирования
RTA_IFP 0x10 RTAX_IFP 4 Имя интерфейса
RTA_IFA 0x20 RTAX_IFA 5 Адрес интерфейса
RTA_AUTHOR 0x40 RTAX_AUTHOR 6 Отправитель запроса на перенаправление
RTA_BRD 0x80 RTAX_BRD 7 Адрес получателя типа «точка-точка» или широковещательный
RTAX_MAX 8 Максимальное количество элементов

В том случае, когда имеется множество структур адреса сокета, они всегда располагаются в порядке, показанном в таблице.

Пример: получение и вывод записи из таблицы маршрутизации

Теперь мы покажем пример использования маршрутизирующих сокетов. Наша программа получает аргумент командной строки, состоящий из адреса IPv4 в точечно-десятичной записи, и отправляет ядру сообщение

RTM_GET
для получения этого адреса. Ядро ищет адрес в своей таблице маршрутизации IPv4 и возвращает сообщение
RTM_GET
с информацией о соответствующей записи из таблицы маршрутизации. Например, если мы выполним на нашем узле
freebsd
такой код

freebsd # getrt 206.168.112.219

dest: 0.0.0.0

gateway: 12.106.32.1

netmask: 0.0.0.0

мы увидим, что этот адрес получателя использует маршрут по умолчанию (который хранится в таблице маршрутизации с IP-адресом получателя 0.0.0.0 и маской 0.0.0.0). Маршрутизатор следующей ретрансляции — это интернет-шлюз нашей системы. Если мы выполним

freebsd # getrt 192.168.42.0

dest: 192.168.42.0

gateway: AF_LINK, index=2

netmask: 255.255.255.0

задав в качестве получателя главную сеть Ethernet, получателем будет сама сеть. Теперь шлюзом является исходящий интерфейс, возвращаемый в качестве структуры

sockaddr_dl
с индексом интерфейса 2.

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

Рис. 18.1. Обмен данными с ядром на маршрутизирующем сокете для команды RTM_GET

Мы создаем буфер, содержащий структуру

rt_msghdr
, за которой следует структура адреса сокета, содержащая адрес получателя, информацию о котором должно найти ядро. Тип сообщения (
rtm_type
) —
RTM_GET
, а битовая маска (
rtm_addrs
) —
RTA_DST
(вспомните табл. 18.2). Эти значения указывают, что структура адреса сокета, следующая за структурой
rt_msghdr
, — это структура, содержащая адрес получателя. Эта команда может использоваться с любым семейством протоколов (предоставляющим таблицу маршрутизации), поскольку семейство адресов, в которое входит искомый адрес, указано в структуре адреса сокета.

Поделиться с друзьями: