UNIX: разработка сетевых приложений
Часть 209 из 399 Информация о книге
12 if ((buf = net_rt_iflist(0, 0, &len)) == NULL)13 return(0);14 namelen = strlen(name);15 lim = buf + len;16 for (next = buf; next < lim; next += ifm->ifm_msglen) {17 ifm = (struct if_msghdr*)next;18 if (ifm->ifm_type == RTM_IFINFO) {19 sa = (struct sockaddr*)(ifm + 1);20 get_rtaddrs(ifm->ifm_addrs, sa, rti_info);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 == namelen25 && 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Мы обрабатываем сообщения в буфере (см. рис. 18.4) в поисках сообщений типа17-30. Найдя такое сообщение, мы вызываем нашу функциюRTM_IFINFO, чтобы установить указатели на структуры адреса сокета, а если присутствует структура имени интерфейса (элементget_rtaddrsмассиваRTAX_IFP), то имя интерфейса сравнивается с аргументом.rti_infoФункция if_indextoname
Следующая функция,
, показана в листинге 18.12.if_indextonameЛистинг 18.12. Возвращение имени интерфейса по его индексу
libroute/if_indextoname.c1 #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, содержащих все имена интерфейсов и индексы. Она показана в листинге 18.13.if_nameindexЛистинг 18.13. Возвращение всех имен и индексов интерфейсов
/
/libroute/if_nameindex.c1 #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;