Книга: UNIX: разработка сетевых приложений
Функция if_nameindex
Разделы на этой странице:
Функция if_nameindex
Следующая функция, if_nameindex
, возвращает массив структур if_nameindex
, содержащих все имена интерфейсов и индексы. Она показана в листинге 18.13.
Листинг 18.13. Возвращение всех имен и индексов интерфейсов
//libroute/if_nameindex.c
1 #include "unpifi.h"
2 #include "unproute.h"
3 struct if_nameindex*
4 if_nameindex(void)
5 {
6 char *buf, *next, *lim;
7 size_t len;
8 struct if_msghdr *ifm;
9 struct sockaddr *sa, *rti_info[RTAX_MAX];
10 struct sockaddr_dl *sdl;
11 struct if_nameindex *result, *ifptr;
12 char *namptr;
13 if ((buf = net_it_iflist(0, 0, &len)) == NULL)
14 return (NULL);
15 if ((result = malloc(len)) == NULL) /* завышенная оценка */
16 return (NULL);
17 ifptr = result;
18 namptr = (char*)result + len; /* имена начинаются с конца буфера */
19 lim = buf + len;
20 for (next = buf; next < lim; next += ifm->ifm_msglen) {
21 ifm = (struct if_msghdr*)next;
22 if (ifm->ifm_type == RTM_IFINFO) {
23 sa = (struct sockaddr*)(ifm + 1);
24 get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
25 if ((sa = rti_infо[RTAX_IFP]) != NULL) {
26 if (sa->sa_family == AF_LINK) {
27 sdl = (struct sockaddr_in*)sa;
28 namptr -= sdl->sdl_nlen + 1;
29 strncpy(namptr, &sdl->sdl_data[0], sdl->sdl_nlen);
30 namptr[sdl->sdl_nlen] = 0; /* завершающий нуль */
31 ifptr->if_name = namptr;
32 ifptr->if_index = sdl->sdl_index;
33 ifptr++;
34 }
35 }
36 }
37 }
38 ifptr->if_name = NULL; /* отмечаем конец массива структур */
39 ifptr->if_index = 0;
40 free(buf);
41 return (result); /* вызывающий процесс должен освободить память
с помощью free(), когда все сделано */
43 }
Получение списка интерфейсов, выделение места для результата
13-18
Мы вызываем нашу функцию net_rt_iflist
для возвращения списка интерфейсов. Мы также используем возвращаемый размер в качестве размера буфера, который мы размещаем в памяти для записи массива возвращаемых структур if_nameindex
. Оценка необходимого размера буфера несколько завышена, но это проще, чем проходить список интерфейсов дважды: один раз для подсчета числа интерфейсов и общего размера имен, а второй — для записи этой информации. Мы создаем массив if_nameindex
в начале этого буфера и записываем имена интерфейсов, начиная с конца буфера.
Обработка только сообщений RTM_IFINFO
22-36
Мы обрабатываем все сообщения, ища сообщения RTM_IFINFO
и следующие за ними структуры адреса сокета. Имя и индекс интерфейса записываются в создаваемый нами массив.
Завершение массива
38-39
Последняя запись в массиве имеет пустой указатель if_name
и нулевой индекс.
- Функция if_freenameindex
- 2.1.3. Функция getopt_long()
- Группировка по встроенным функциям и UDF
- 19.1.1. Функция jQuery()
- Функция strcmp( )
- Управление функциями узла
- Функция программного обеспечения
- 3.2. Ключи типа key_t и функция ftok
- 9.10. Функция sctp_recvmsg
- Функция document
- Функция generate-id
- Функция console.log