Шрифт:
63 ifi->ifi_addr = Calloc(1, sa->sa_len);
64 memcpy(ifi->ifi_addr, sa, sa->sa_len);
65 }
66 if ((flags & IFF_BROADCAST) && (sa = rti_infо[RTAX_BRD]) |= NULL) {
67 ifi->ifi_brdaddr = Calloc(1, sa->sa_len);
68 memcpy(ifi->ifi_brdaddr, sa, sa->sa_len);
69 }
70 if ((flags & IFF_POINTOPOINT) &&
71 (sa = rti_infо[RTAX_BRD]) != NULL) {
72 ifi->ifi_dstaddr = Calloc(1, sa->sa_len);
73 memcpy(ifi->ifi_dstaddr, sa, sa->sa_len);
74 }
75 } else
76 err_quit("unexpected message type %d", ifm->ifm_type);
77 }
78 /* "ifihead" указывает на первую структуру в связном списке */
79 return (ifihead); /* указатель на первую структуру в связном списке */
80 }
Возвращение IP-адресов
44-65
Сообщение RTM_NEWADDR
возвращается функцией sysctl
для каждого адреса, связанного с интерфейсом: для первичного адреса и для всех альтернативных имен (псевдонимов). Если мы уже заполнили IP-адрес для этого интерфейса, то мы имеем дело с альтернативным именем. Поэтому если вызывающему процессу нужен адрес псевдонима, мы должны выделить память для другой структуры ifi_info
, скопировать заполненные поля и затем заполнить возвращенный адрес. Возвращение широковещательного адреса и адреса получателя
66-75
Если интерфейс поддерживает широковещательную передачу, возвращается широковещательный адрес, а если интерфейс является интерфейсом типа «точка-точка», возвращается адрес получателя. 18.6. Функции имени и индекса интерфейса
Документ RFC 3493 [36] определяет четыре функции, обрабатывающие имена и индексы интерфейсов. Эти четыре функции используются во многих случаях, когда необходимо описать интерфейс. Они были предложены в процессе разработки API IPv6 (главы 21 и 27), однако индексы интерфейсов имеются и в API IPv4 (например, в вызове
IP_RECVIF
или AF_LINK
для маршрутизирующего сокета). Основной принцип, объявляемый в этом документе, состоит в том, что каждый интерфейс имеет уникальное имя и уникальный положительный индекс (нуль в качестве индекса никогда не используется).
#include <net/if.h>
unsigned int if_nametoindex(const char * ifname);
Возвращает: положительный индекс интерфейса в случае успешного выполнения, 0 в случае ошибки
char *if_indextoname(unsigned int ifindex, char * ifname);
Возвращает: указатель на имя интерфейса в случае успешного выполнения, NULL в случае ошибки
struct if_nameindex *if_nameindex(void);
Возвращает: непустой указатель в случае успешного выполнения, NULL в случае ошибки
void if_freenameindex(struct if_nameindex * Iptr);
Функция
if_nametoindex
возвращает индекс интерфейса, имеющего имя ifname
. Функция if_indextoname
возвращает указатель на имя интерфейса, если задан его индекс ifindex
. Аргумент ifname
указывает на буфер размера IFNAMSIZ
(определяемый в заголовочном файле <net/if.h> из листинга 17.1), который вызывающий процесс должен выделить для хранения результата, и этот указатель возвращается в случае успешного выполнения функции if_indextoname
. Функция
if_nameindex
возвращает указатель на массив структур if_nameindex
:
struct if_nameindex {
unsigned int if_index; /* 1, 2. ... */
char *if_name; /* имя, завершаемое нулем: "le0", ... */
};
Последняя запись в этом массиве содержит структуру с нулевым индексом
if_index
и с пустым указателем ifname
. Память для этого массива, а также для имен, на которые указывают элементы массива, выделяется динамически и освобождается при вызове функции if_freenameindex
. Теперь мы представим реализацию этих четырех функций с использованием маршрутизирующих сокетов.
Функция if_nametoindex
В листинге 18.11 показана функция
if_nametoindex
. Листинг 18.11. Возвращение индекса интерфейса по его имени
//libroute/if_nametoindex.c
1 #include "unpifi.h"
2 #include "unproute.h"
3 unsigned int