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
rti_info
Обработка имени интерфейса
25-42
ifi_info
AF_LINK
nlen
ifi_info
sdl_alen
ifi_info
ifi_hlen
В листинге 18.10 показана вторая часть нашей функции
get_ifi_info
Листинг 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);