UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
19-20
ioctl
EINVAL
lastlen
22-23
ioctl
lastlen
break
26-27
ifreq
29-31
ifi_info
ifihead
ifipnext
Следующая часть нашей функции
get_ifi_info
Листинг 17.5. Конфигурация интерфейса процесса
//lib/get_ifi_info.c
34 for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
35 ifr = (struct ifreq*)ptr;
36 #ifdef HAVE_SOCKADDR_SA_LEN
37 len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
38 #else
39 switch (ifr->ifr_addr.sa_family) {
40 #ifdef IPV6
41 case AF_INET6:
42 len = sizeof(struct sockaddr_in6);
43 break;
44 #endif
45 case AF_INET:
46 default:
47 len = sizeof(struct sockaddr);
48 break;
49 }
50 #endif /* HAVE_SOCKADDR_SA_LEN */
51 ptr += sizeof(ifr->ifr_name) + len; /* для следующей строки */
52 #ifdef HAVE_SOCKADDR_DL_STRUCT
53 /* предполагается, что AF_LINK идет перед AF_INET и AF_INET6 */
54 if (ifr->ifr_addr.sa_family == AF_LINK) {
55 struct sockaddr_dl *sdl = (struct sockaddr_dl*)&ifr->ifr_addr;
56 sdlname = ifr->ifr_name;
57 idx = sdl->sdl_index;
58 haddr = sdl->sdl_data + sdl->sdl_nlen;
59 hlen = sdl->sdl_alen;
60 }
61 #endif
62 if (ifr->ifr_addr.sa_family != family)
63 continue; /* игнорируется, если семейство адреса не то */
64 myflags = 0;
65 if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)
66 *cptr = 0; /* замена двоеточия нулем */
67 if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
68 if (doaliases == 0)
69 continue; /* этот интерфейс уже обработан */
70 myflags = IFI_ALIAS;
71 }
72 memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
73 ifrcopy = *ifr;
74 Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
75 flags = ifrcopy.ifr_flags;
76 if ((flags & IFF_UP) == 0)
77 continue; /* игнорируется, если интерфейс не используется */
35-51
freq ifr
ptr
ifreq
В системах, поддерживающих IPv6, не оговаривается, возвращается ли адрес IPv6 вызовом SIOCGIFCONF. Для более новых систем мы вводим оператор case, в котором предусмотрена возможность возвращения адресов IPv6. Проблема состоит в том, что объединение в структуре ifreq определяет возвращаемые адреса как общие 16-байтовые структуры sockaddr, подходящие для 16-байтовых структур sockaddr_in IPv4, но для 24-байтовых структур sockaddr_in6 IPv6 они слишком малы. В случае возвращения адресов IPv6 возможно некорректное поведение существующего кода, созданного в предположении, что в каждой структуре ifreq содержится структура sockaddr фиксированного размера. В системах, где структура sockaddr имеет поле sa_len, никаких проблем не возникает, потому что такие системы легко могут указывать размер структур sockaddr.
52-60
sockaddr
AF_LINK
SIOCGIFCONF
62-63
get_ini_info