■ FIOASYNC
. Флаг, управляющий получением сигналов асинхронного ввода-вывода ( SIGIO
), устанавливается или сбрасывается для сокета в зависимости от того, является ли третий аргумент функции ioctl
пустым указателем. Этот флаг имеет то же действие, что и флаг статуса файла O_ASYNC
, который можно установить и сбросить с помощью команды F_SETFL
функции ioctl
.
■ FIONREAD
. Возвращает число байтов, в настоящий момент находящихся в приемном буфере сокета, как целое число, на которое указывает третий аргумент функции ioctl
. Это свойство работает также для файлов, каналов и терминалов. Более подробно об этом вызове мы рассказывали в разделе 14.7.
■ FIOSETOWN
. Эквивалент SIOCSPGRP
для сокета.
■ FIOGETOWN
. Эквивалент SIOCGPGRP
для сокета.
17.5. Конфигурация интерфейса
Один из шагов, выполняемых многими программами, работающими с сетевыми интерфейсами системы, — это получение от ядра списка всех интерфейсов, сконфигурированных в системе. Это делается с помощью вызова SIOCGIFCONF
, использующего структуру ifconf
, которая, в свою очередь, использует структуру ifreq
. Обе эти структуры показаны в листинге 17.1 [1] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
.
Листинг 17.1. Структуры ifconf и ifreq, используемые в различных вызовах функции ioctl, относящихся к интерфейсам
// 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.2. Значения, возвращаемые в результате вызова SIOCGIFCONF
Указатель на структуру ifreq
также используется в качестве аргумента оставшихся функций ioctl
интерфейса, показанных в табл. 17.1, которые мы описываем в разделе 17.7. Отметим, что каждая структура ifreq
содержит объединение ( union
), а директивы компилятора #define
позволяют непосредственно обращаться к полям объединения по их именам. Помните о том, что в некоторых системах в объединение ifr_ifru
добавлено много зависящих от реализации элементов.
17.6. Функция get_ifi_info
Поскольку многим программам нужно знать обо всех интерфейсах системы, мы разработаем нашу собственную функцию get_ifi_info
, возвращающую связный список структур — по одной для каждого активного в настоящий момент интерфейса. В этом разделе мы покажем, как эта функция реализуется с помощью вызова SIOCGIFCONF
функции ioctl
, а в главе 18 мы создадим ее другую версию, использующую маршрутизирующие сокеты.
ПРИМЕЧАНИЕ
BSD/OS предоставляет функцию getifaddrs, имеющую аналогичную функциональность.
Поиск по всему дереву исходного кода BSD/OS 2.1 показывает, что 12 программ выполняют вызов SIOCGIFCONF функции ioctl для определения присутствующих интерфейсов.
Сначала мы определяем структуру ifi_info
в новом заголовочном файле, который называется unpifi.h
, показанном в листинге 17.2.
Листинг 17.2. Заголовочный файл unpifi.h
//ioctl/unpifi.h
1 /* Наш собственный заголовочный файл для программ, которым требуется
2 информация о конфигурации интерфейса. Включаем его вместо "unp.h". */
Читать дальше
Конец ознакомительного отрывка
Купить книгу