17.5. Конфигурация интерфейса

17.5. Конфигурация интерфейса

Один из шагов, выполняемых многими программами, работающими с сетевыми интерфейсами системы, — это получение от ядра списка всех интерфейсов, сконфигурированных в системе. Это делается с помощью вызова SIOCGIFCONF, использующего структуру ifconf, которая, в свою очередь, использует структуру ifreq. Обе эти структуры показаны в листинге 17.1[1].

Листинг 17.1. Структуры ifconf и ifreq, используемые в различных вызовах функции ioctl, относящихся к интерфейсам

//<net/if.h> struct ifconf {

 int ifc_len; /* размер буфера, "значение-результат" */

 union {

  caddr_t      ifcu_buf;  /* ввод от пользователя к ядру */

  struct ifreq *ifcu_req; /* ядро возвращает пользователю */

 } ifc_ifcu;

};

#define ifc_buf ifc_ifcu.ifcu_buf /* адрес буфера */

#define ifc_req ifc_ifcu.ifcu_req /* массив возвращенных структур */

#define IFNAMSIZ 16

struct ifreq {

 char ifr_name[IFNAMSIZ]; /* имя интерфейса, например "le0" */

 union {

  struct sockaddr ifru_addr;

  struct sockaddr ifru_dstaddr;

  struct sockaddr ifru_broadaddr;

  short           ifru_flags;

  int             ifru_metric;

  caddr_t         ifru_data;

 } ifr_ifru;

};

#define ifr_addr ifr_ifru.ifru_addr       /* адрес */

#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* другой конец линии передачи, называемой

                                             "точка-точка" */

#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* широковещательный адрес */

#define ifr_flags ifr_ifru.ifru_flags     /* флаги */

#define ifr_metric ifr_ifru.ifru_metric   /* метрика */

#define ifr_data ifr_ifru.ifru_data       /* с использованием интерфейсом */

Прежде чем вызвать функцию ioctl, мы выделяем в памяти место для буфера и для структуры ifconf, а затем инициализируем эту структуру. Мы показываем это на рис. 17.1, предполагая, что наш буфер имеет размер 1024 байта. Третий аргумент функции ioctl — это указатель на нашу структуру ifconf.

Рис. 17.1. Инициализация структуры ifconf перед вызовом SIOCGIFCONF

Если мы предположим, что ядро возвращает две структуры ifreq, то при завершении функции ioctl мы можем получить ситуацию, представленную на рис. 17.2. Затененные области были изменены функцией ioctl. Буфер заполняется двумя структурами, и элемент ifc_len структуры ifconf обновляется, с тем чтобы соответствовать количеству информации, хранимой в буфере. Предполагается, что на этом рисунке каждая структура ifreq занимает 32 байта.

Рис. 17.2. Значения, возвращаемые в результате вызова SIOCGIFCONF

Указатель на структуру ifreq также используется в качестве аргумента оставшихся функций ioctl интерфейса, показанных в табл. 17.1, которые мы описываем в разделе 17.7. Отметим, что каждая структура ifreq содержит объединение (union), а директивы компилятора #define позволяют непосредственно обращаться к полям объединения по их именам. Помните о том, что в некоторых системах в объединение ifr_ifru добавлено много зависящих от реализации элементов.

Данный текст является ознакомительным фрагментом.