Чтение онлайн

ЖАНРЫ

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)

Поделиться с друзьями: