UNIX: разработка сетевых приложений
Шрифт:
21 if ((sa = rti_infо[RTAX_IFP]) != NULL) {
22 if (sa->sa_family == AF_LINK) {
23 sdl = (struct sockaddr_dl*)sa;
24 if (sdl->sdl_nlen == namelen
25 && strncmp(&sdl->sdl_data[0], name,
26 sdl->sdl_nlen) == 0) {
27 idx = sdl->sdl_index; /* сохранение перед
вызовом free */
28 free(buf);
29 return(idx);
30 }
31 }
32 }
33 }
34 }
35 free(buf);
36 return(0); /*
индекс для имени не найден */
37 }
Получение списка интерфейсов
12-13
Наша функция net_rt_iflist
возвращает список интерфейсов. Обработка только сообщений RTM_IFINFO
17-30
Мы обрабатываем сообщения в буфере (см. рис. 18.4) в поисках сообщений типа RTM_IFINFO
. Найдя такое сообщение, мы вызываем нашу функцию get_rtaddrs
, чтобы установить указатели на структуры адреса сокета, а если присутствует структура имени интерфейса (элемент RTAX_IFP
массива rti_info
), то имя интерфейса сравнивается с аргументом. Функция if_indextoname
Следующая функция,
if_indextoname
, показана в листинге 18.12. Листинг 18.12. Возвращение имени интерфейса по его индексу
libroute/if_indextoname.c
1 #include "unpifi.h"
2 #include "unproute.h"
3 char*
4 if_indextoname(unsigned int index, char *name)
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 if ((buf = net_rt_iflist(0, index, &len)) == NULL)
12 return (NULL);
13 lim = buf + len;
14 for (next = buf; next < lim; next += ifm->ifm_msglen) {
15 ifm = (struct if_msghdr*)next;
16 if (ifm->ifm_type == RTM_IFINFO) {
17 sa = (struct sockaddr*)(ifm + 1);
18 get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
19 if ((sa = rti_info[RTAX_IFP]) != NULL) {
20 if (sa->sa_family == AF_LINK) {
21 sdl = (struct sockaddr_dl*)sa;
22 if (sdl->sdl_index == index) {
23 int slen = min(IFNAMSIZ - 1, sdl->sdl_nlen);
24 strncpy(name, sdl->sdl_data, slen);
25 name[slen] = 0; /*
завершающий нуль */
26 free(buf);
27 return (name);
28 }
29 }
30 }
31 }
32 }
33 free(buf);
34 return (NULL); /* нет соответствия индексу */
35 }
Эта функция практически идентична предыдущей, но вместо поиска имени интерфейса мы сравниваем индекс интерфейса с аргументом вызывающего процесса. Кроме того, второй аргумент нашей функции
net_rt_iflist
— это заданный индекс, поэтому результат должен содержать информацию только для определенного интерфейса. Когда обнаруживается совпадение, возвращается имя интерфейса, к которому добавляется завершающий нуль. Функция 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)
Поделиться с друзьями: