Наше меню (нажмите)

UNIX: разработка сетевых приложений

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 394
Читать онлайн

UNIX: разработка сетевых приложений читать книгу онлайн

UNIX: разработка сетевых приложений - читать бесплатно онлайн , автор Стивенс Уильям Ричард

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту pbn.book@yandex.ru для удаления материала

Перейти на страницу:

 4 get_ifi_info(int family, int doaliases)

 5 {

 6  int flags;

 7  char *buf, *next, *lim;

 8  size_t len;

 9  struct if_msghdr *ifm;

10  struct ifa_msghdr *ifam;

11  struct sockaddr *sa, *rti_info[RTAX_MAX];

12  struct sockaddr_dl *sdl;

13  struct ifi_info *ifi, *ifisave, *ifihead, **ifipnext;

14  buf = Net_rt_iflist(family, 0, &len);

15  ifihead = NULL;

16  ifipnext = &ifihead;

17  lim = buf + len;

18  for (next = buf; next < lim; next += ifm->ifm_msglen) {

19   ifm = (struct if_msghdr*)next;

20   if (ifm->ifm_type = RTM_IFINFO) {

21    if (((flags = ifm->ifm_flags) & IFF_UP) == 0)

22     continue; /* игнорируем, если интерфейс не активен */

23    sa = (struct sockaddr*)(ifm + 1);

24    get_rtaddrs(ifm->ifm_addrs, sa, rti_info);

25    if ((sa = rti_info[RTAX_IFP]) != NULL) {

26     ifi = Calloc(1, sizeof(struct ifi_info));

27     *ifipnext = ifi; /* предыдущий указатель указывал на эту

                           структуру */

28     ifipnext = &ifi->ifi_next; /* указатель на следующую структуру */

29     ifi->ifi_flags = flags;

30     if (sa->sa_family == AF_LINK) {

31      sdl = (struct sockaddr_dl*)sa;

32      ifi->ifi_index = sdl->sdl_index;

33      if (sdl->sdl_nlen > 0)

34       snprintf(ifi->ifi_name, IFI_NAME, "%*s",

35        sdl->sdl_nlen, &sdl->sdl_data[0]);

36      else

37       snprintf(ifi->ifi_name, IFI_NAME, "index %d",

38        sdl->sdl_index);

39      if ((ifi->ifi_hlen = sdl->sdl_alen) > 0)

40       memcpy(ifi->ifi_haddr, LLADDR(sdl),

41      min(IFI_HADDR, sdl->sdl_alen));

42     }

43    }

6-14
 Мы объявляем локальные переменные и затем вызываем нашу функцию
net_rt_iflist
.

17-19
 Цикл
for
— это цикл по всем сообщениям маршрутизации, попадающим в буфер в результате выполнения функции
sysctl
. Мы предполагаем, что сообщение — это структура
if_msghdr
, и рассматриваем поле
ifm_type
(вспомните, что первые три элемента трех структур идентичны, поэтому все равно, какую из трех структур мы используем для просмотра типа элемента).

Проверка, включен ли интерфейс

20-22
 Для каждого интерфейса возвращается структура
RTM_IFINFO
. Если интерфейс не активен, он игнорируется.

Определение, какие структуры адреса сокета присутствуют

23-24
 
sa
указывает на первую структуру адреса сокета, следующую за структурой
if_msghdr
. Наша функция get_rtaddrs инициализирует массив
rti_info
в зависимости от того, какие структуры адреса сокета присутствуют.

Обработка имени интерфейса

25-42
 Если присутствует структура адреса сокета с именем интерфейса, в памяти размещается структура
ifi_info
и хранятся флаги интерфейса. Предполагаемым семейством этой структуры адреса сокета является
AF_LINK
, что означает структуру адреса сокета канального уровня. Если элемент sdl_
nlen
ненулевой, имя интерфейса копируется в структуру
ifi_info
. В противном случае в качестве имени хранится строка, содержащая индекс интерфейса. Если элемент
sdl_alen
ненулевой, аппаратный адрес (например, адрес Ethernet) копируется в структуру
ifi_info
, а его длина также возвращается как
ifi_hlen
.

В листинге 18.10 показана вторая часть нашей функции

get_ifi_info
, которая возвращает IP-адреса для интерфейса.

Листинг 18.10. Функция get_ifi_info, вторая часть

//route/get_ifi_info.c

44   } else if (ifm->ifm_type == RTM_NEWADDR) {

45    if (ifi->ifi_addr) { /* уже имеется IP-адрес для интерфейса */

46     if (doaliases == 0)

47      continue;

48     /* у нас имеется новый IP-адрес для существующего интерфейса */

49     ifisave = ifi;

50     ifi = Calloc(1, sizeof(struct ifi_info));

51     *ifipnext = ifi; /* предыдущий указатель указывал на эту

                           структуру */

52     ifipnext = &ifi->ifi_next; /* указатель на следующую структуру */

53     ifi->ifi_flags = ifi_save->ifi_flags;

54     ifi->ifi_index = ifisave->ifi_index;

55     ifi->ifi_hlen = ifisave->ifi_hlen;

56     memcpy(ifi->ifi_name, ifisave->ifi_name, IFI_NAME);

57     memcpy(ifi->ifi_haddr, ifisave->ifi_haddr, IFI_HADDR);

Перейти на страницу:
Комментариев (0)

0