UNIX: разработка сетевых приложений
Часть 197 из 399 Информация о книге
131 memcpy(ifi->ifi_dstaddr, sin6ptr,132 sizeof(struct sockaddr_in6));133 }134 #endif135 break;136 default:137 break;138 }139 }140 free(buf);141 return(ifihead); /* указатель на первую структуру в связной списке */142 }Мы копируем IP-адрес, возвращенный из нашего начального вызова102-104функцииSIOCGIFCONF, в структуру, которую мы создаем.ioctlЕсли интерфейс поддерживает широковещательную передачу, мы получаем широковещательный адрес с помощью вызова106-119функцииSIOCGIFBRDADDR. Мы выделяем память для структуры адреса сокета, содержащей этот адрес, и добавляем ее к структуреioctl, которую мы создаем. Аналогично, если интерфейс является интерфейсом типа «точка-точка», вызовifi_infoвозвращает IP-адрес другого конца связи.SIOCGIFBRDADDRОбработка случая IPv6 — полная аналогия IPv4 за тем исключением, что вызов123-133не делается, потому что IPv6 не поддерживает широковещательную передачу.SIOCGIFBRDADDRВ листинге 17.8 показана функция
, которой передается указатель, возвращенный функциейfree_ifi_info. Эта функция освобождает всю динамически выделенную память.get_ifi_infoЛистинг 17.8. Функция free_ifi_info: освобождение памяти, которая была динамически выделена функцией get_ifi_info
//iосtl/get_ifi_info.c143 void144 free_ifi_info(struct ifi_info *ifihead)145 {146 struct ifi_info *ifi, *ifinext;147 for (ifi = ifihead; ifi != NULL; ifi = ifinext) {148 if (ifi->ifi_addr != NULL)149 free(ifi->ifi_addr);150 if (ifi->ifi_brdaddr != NULL)151 free(ifi->ifi_brdaddr);152 if (ifi->ifi_dstaddr != NULL)153 free(ifi->ifi_dstaddr);154 ifinext = ifi->ifi_next; /* невозможно получить ifi_nextпосле вызова freed */155 free(ifi);156 }157 }17.7. Операции с интерфейсами
Как мы показали в предыдущем разделе, запрос
возвращает имя и структуру адреса сокета для каждого сконфигурированного интерфейса. Существует множество других вызовов, позволяющих установить или получить все остальные характеристики интерфейса. ВерсияSIOCGIFCONFэтих вызовов (get) часто запускается программойSIOCGxxx, а версияnetstat(set) — программойSIOCSxxx. Любой пользователь может получить информацию об интерфейсе, в то время как установка этой информации требует прав привилегированного пользователя.ifconfigЭти вызовы получают или возвращают структуру
, адрес которой задается в качестве третьего аргумента функцииifreq. Интерфейс всегда идентифицируется по имени:ioctl,le0,lo0, — то есть по имени, заданному в элементеppp0структурыifr_name.ifreqМногие из этих запросов используют структуру адреса сокета, для того чтобы задать или возвратить IP-адрес или маску адреса. Для IPv4 адрес или маска содержится в элементе
из структуры адреса сокета Интернета. Для IPv6 они помещаются в элементsin_addrструктуры адреса сокета IPv6.sin6_addr■
. Возвращает адрес направленной передачи в элементеSIOCGIFADDR.ifr_addr■
. Устанавливает адрес интерфейса из элементаSIOCSIFADDR. Также вызывается функция инициализации для интерфейса.ifr_addr■
. Возвращает флаги интерфейса в элементеSIOCGIFFLAGS. Имена различных флагов определяются в видеifr_flagsв заголовочном файлеIFF_xxx. Флаги указывают, например, включен ли интерфейс (<net/if.h>), является ли он интерфейсом типа «точка-точка» (IFF_UP), поддерживает ли широковещательную передачу (IFF_POINTOPOINT) и т.д.IFF_BROADCAST■
. Устанавливает флаги из элементаSIOCSIFFLAGS.ifr_flags■
. Возвращает адрес типа «точка-точка» в элементеSIOCGIFDSTADDR.ifr_dstaddr■
. Устанавливает адрес типа «точка-точка» из элементаSIOCSIFDSTADDR.ifr_dstaddr■
. Возвращает широковещательный адрес в элементеSIOCGIFBRDADDR. Приложение сначала должно получить флаги интерфейса, а затем сделать корректный вызов:ifr_broadaddrдля широковещательного интерфейса илиSIOCGIFBRDADDR— для интерфейса типа «точка-точка».SIOCGIFDSTADDR■
. Устанавливает широковещательный адрес из элементаSIOCSIFBRDADDR.ifr_broadaddr■
. Возвращает маску подсети в элементеSIOCGIFNETMASK.ifr_addr■
. Устанавливает маску подсети из элементаSIOCSIFNETMASK.ifr_addr