Таблица 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.2. Структура rti_info, заполненная с помощью нашей функции get_rtaddrs
Затем наша программа проходит массив rti_info
, делая все, что ей нужно, с непустыми указателями массива.
37-44
Каждый из присутствующих четырех возможных адресов выводится. Мы вызываем нашу функцию sock_ntop_host
для вывода адреса получателя и адреса шлюза, но для вывода двух масок подсети вызываем нашу функцию sock_masktop
. Эту новую функцию мы покажем далее.
В листинге 18.5 показана наша функция get_rtaddrs
, которую мы вызывали в листинге 18.4.
Листинг 18.5. Создание массива указателей на структуры адреса сокета в маршрутизирующем сообщении
//libroute/get_rtaddrs.c
1 #include "unproute.h"
2 /*
3 * Округляем 'а' до следующего значения, кратного 'size'
4 */
5 #define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
6 /* Переходим к следующей структуре адреса сокета.
7 * Если sa_len равно 0, это значит, что
8 * размер выражен числом типа u_long).
9 */
10 #define NEXT_SA(ap) ар = (SA*) \
11 ((caddr_t)ар + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof(u_long)) : \
12 sizeof(u_long)))
13 void
14 get_rtaddrs(int addrs, SA *sa, SA **rti_info)
15 {
16 int i;
17 for (i = 0; i
18 if (addrs & (1 sa_data[2];
7 if (sa->sa_len == 0)
8 return ("0.0.0.0");
9 else if (sa->sa_len == 5)
10 snprintf(str, sizeof(str), '"%d.0.0.0", *ptr);
11 else if (sa->sa_len == 6)
12 snprintf(str, sizeof(str), "%d.%d.0.0", *ptr, *(ptr + 1));
13 else if (sa->sa_len == 7)
14 snprintf(str, sizeof(str), "%d.%d.%d.0", *ptr, *(ptr + 1), *(ptr + 2));
15 else if (sa->sa_len == 8)
16 snprintf(str, sizeof(str), "%d.%d.%d.%d",
17 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3));
18 else
19 snprintf(str, sizeof(str), "(unknown mask, len = %d, family = %d)",
20 sa->sa_len, sa->sa_family);
21 return (str);
22 }
7-21
Если длина равна нулю, то подразумевается маска 0.0.0.0. Если длина равна 5, хранится только первый байт 32-разрядной маски, а для оставшихся трех байтов подразумевается нулевое значение. Когда длина равна 8, хранятся все 4 байта маски.
Читать дальше
Конец ознакомительного отрывка
Купить книгу