3 #include netinet/ip.h
4 static u_char *optr; /* указатель на формируемые параметры */
5 static u_char *lenptr; /* указатель на длину параметра SRR */
6 static int ocnt; /* количество адресов */
7 u_char*
8 inet_srcrt_init(int type)
9 {
10 optr = Malloc(44); /* NOP, код параметра. len, указатель + до 10
адресов */
11 bzero(optr, 44); /* гарантирует наличие EOL на конце */
12 ocnt = 0;
13 *optr++ = IPOPT_NOP; /* выравнивающие NOP */
14 *optr++ = type ? IPOPT_SSRR : IPOPT_LSRR;
15 lenptr = optr++; /* поле длины заполняется позже */
16 *optr++ = 4; /* сдвиг на первый адрес */
17 return(optr - 4); /* указатель для setsockopt */
18 }
10-17
len
. Это значение мы будем записывать при поочередном добавлении адресов к списку. Указатель на параметр возвращается вызывающему процессу, а затем передается как четвертый аргумент функции
setsockopt
.Следующая функция,
inet_srcrt_add
, добавляет один IPv4-адрес к создаваемому маршруту от отправителя.Листинг 27.2
. Функция inet_srcrt_add: добавление одного IPv4-адреса к маршруту от отправителя//ipopts/sourceroute.с
19 int
20 inet_srcrt_add(char *hostptr)
21 {
22 int len;
23 struct addrinfo *ai;
24 struct sockaddr_in *sin;
25 if (ocnt 9)
26 err_quit("too many source routes with: %s", hostptr);
27 ai = Host_serv(hostptr, NULL, AF_INET, 0);
28 sin = (struct sockaddr_in*)ai-ai_addr;
29 memcpy(optr, sin-sin_addr, sizeof(struct in_addr));
30 freeaddrinfo(ai);
31 optr += sizeof(struct in_addr);
32 ocnt++;
33 len = 3 + (ocnt * sizeof(struct in_addr));
34 *lenptr = len;
35 return(len + 1); /* размер для setsockopt */
36 }
19-20
25-26
29-37
host_serv
обрабатывает имя узла или его IP-адрес, а возвращаемый ей адрес в двоичной форме мы помещаем в список. Мы обновляем поле
len
и возвращаем полный размер буфера (с учетом параметров NOP), который вызывающий процесс затем передаст функции
setsockopt
.Когда полученный маршрут от отправителя возвращается приложению функцией
getsockopt
, формат этого параметра отличается от того, что было показано на рис. 27.1. Формат полученного параметра маршрута от отправителя показан на рис. 27.2.Рис. 27.2
. Формат параметра маршрута от отправителя, возвращаемого функцией getsockoptВ первую очередь, мы можем отметить, что порядок следования адресов изменен ядром на противоположный относительно полученного маршрута от отправителя. Имеется в виду следующее: если в полученном маршруте содержались адреса А, В, С и D в указанном порядке, то под противоположным порядком подразумевается следующий: D, С, В, А. Первые 4 байта содержат первый IP-адрес из списка, затем следует однобайтовый параметр NOP (для выравнивания), затем — 3-байтовый заголовок параметра маршрута от отправителя, и далее остальные IP-адреса. После 3-байтового заголовка может следовать до 9 IP-адресов, и максимальное значение поля
len
в возвращенном заголовке равно 39. Поскольку параметр NOP всегда присутствует, длина буфера, возвращаемая функцией
getsockopt
, всегда будет равна значению, кратному 4 байтам.