KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Уильям Стивенс - UNIX: разработка сетевых приложений

Уильям Стивенс - UNIX: разработка сетевых приложений

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Уильям Стивенс, "UNIX: разработка сетевых приложений" бесплатно, без регистрации.
Перейти на страницу:

■ AF_INET. Получение или установка переменных, влияющих на протоколы Интернета. Следующий уровень с помощью одной из констант IPROTO_xxx задает протокол. BSD/OS 3.0 предоставляет на этом уровне около 30 переменных, управляющих такими свойствами, как генерация ядром переадресации ICMP, использование параметров TCP из RFC 1323, отправка контрольных сумм UDP и т.д. Пример подобного применения функции sysctl мы покажем в конце этого раздела.

■ AF_LINK. Получение или установка информации канального уровня, такой как число интерфейсов PPP.

■ AF_ROUTE. Возвращение информации либо о таблице маршрутизации, либо о списке интерфейсов. Мы вскоре опишем эту информацию.

■ AF_UNSPEC. Получение или установка некоторых переменных уровня сокета, таких как максимальный размер буфера отправки или приема сокета.

Когда вторым элементом массива name является AF_ROUTE, третий элемент (номер протокола) всегда нулевой (поскольку протоколы внутри семейства AF_ROUTE отличаются от протоколов, например, в семействе AF_INET), четвертый элемент — это семейство адресов, а пятый и шестой элементы задают выполняемые действия. Вся эта информация обобщается в табл. 18.3.


Таблица 18.3. Информация функции sysctl, возвращаемая для маршрутизирующего домена

name[] Возвращает таблицу Возвращает кэш APR маршрутизации Возвращает список интерфейсов 0 CTL_NET CTL_NET CTL_NET 1 AF_ROUTE AF_ROUTE AF_ROUTE 2 0 0 0 3 AF_INET AF_INET AF_INET 4 NET_RT_DUMP NET_RT_FLAGS NET_RT_IFLIST 5 0 RTF_LLINFO 0

Поддерживаются три операции, задаваемые элементом name[4]. (Константы NET_RT_xxx определяются в заголовочном файле <sys/socket.h>.) Информация возвращается через указатель oldp при вызове функции sysctl. Этот буфер содержит переменное число сообщений RTM_xxx (см. табл. 18.1).

1. Операция NET_RT_DUMP возвращает таблицу маршрутизации для семейства адресов, заданного элементом name[3]. Если задано нулевое семейство адресов, возвращаются таблицы маршрутизации для всех семейств адресов.

Рис. 18.4. Информация возвращаемая функцией sysctl для команд CTL_NET и NET_RT_IFLIST

Таблица маршрутизации возвращается как переменное число сообщений RTM_GET, причем за каждым сообщением следует до четырех структур адреса сокета: получатель, шлюз, маска сети и маска клонирования записи в таблице маршрутизации. Пример такого сообщения мы показали в правой части рис. 18.1, а в нашем коде в листинге 18.4 проводится анализ одного из сообщений. В результате применения этой операции функции sysctl ядром возвращается одно или несколько таких сообщений.

2. Операция NET_RT_FLAGS возвращает таблицу маршрутизации для семейства адресов, заданного элементом name[3], но учитываются только те записи таблицы маршрутизации, для которых значение флага RTF_xxx равно указанному в элементе name[5]. У всех записей кэша ARP в таблице маршрутизации установлен бит флага RTF_LLINFO.

Информация возвращается в том же формате, что и в предыдущем пункте.

3. Операция NET_RT_IFLIST возвращает информацию обо всех сконфигурированных интерфейсах. Если элемент name[5] ненулевой, это номер индекса интерфейса и возвращается информация только об этом интерфейсе. (Более подробно об индексах интерфейсов мы поговорим в разделе 18.6.) Все адреса, присвоенные каждому интерфейсу, также возвращаются, и если элемент name[3] ненулевой, возвращаются только адреса для семейства адресов, указанного в этом элементе.

Для каждого интерфейса возвращается по одному сообщению RTM_IFINFO, за которым следует одно сообщение RTM_NEWADDR для каждого адреса, заданного для интерфейса. За сообщением RTM_IFINFO следует по одной структуре адреса сокета канального уровня, а за каждым сообщением RTM_NEWADDR — до трех структур адреса сокета: адрес интерфейса, маска сети и широковещательный адрес. Эти два сообщения представлены на рис. 18.4.

Пример: определяем, включены ли контрольные суммы UDP

Теперь мы приведем простой пример использования функции sysctl с протоколами Интернета для проверки, включены ли контрольные суммы UDP. Некоторые приложения UDP (например, BIND) проверяют при запуске, включены ли контрольные суммы UDP, и если нет, пытаются включить их. Для того чтобы включить подобное свойство, требуются права привилегированного пользователя, но мы сейчас просто проверим, включено это свойство или нет. В листинге 18.7 представлена наша программа.

Листинг 18.7. Проверка включения контрольных сумм

//route/checkudpsum.c

 1 #include "unproute.h"

 2 #include <netinet/udp.h>

 3 #include <netinet/ip_var.h>

 4 #include <netinet/udp_var.h> /* для констант UDPCTL_xxx */


 5 int

 6 main(int argc, char **argv)

 7 {

 8  int mib[4], val;

 9  size_t len;


10  mib[0] = CTL_NET;

11  mib[1] = AF_INET;

12  mib[2] = IPPROTO_UDP;

13  mib[3] = UDPCTL_CHECKSUM;


14  len = sizeof(val);

15  Sysctl(mib, 4, &val, &len, NULL, 0);

16  printf("udp checksum flag: %dn", val);


17  exit(0);

18 }

Включение системных заголовков

2-4 Следует включить заголовочный файл <netinet/udp_var.h>, чтобы получить определение констант UDP функции sysctl. Для него требуются два других заголовка.

Вызов функции sysctl

10-16 Мы размещаем в памяти массив целых чисел с четырьмя элементами и храним константы, соответствующие иерархии, показанной на рис. 18.3. Поскольку мы только получаем переменную и не присваиваем ей значение, аргумент newp функции sysctl мы задаем как пустой указатель, и поэтому аргумент newp этой функции имеет нулевое значение, oldp указывает на нашу целочисленную переменную, в которую сохраняется результат, a oldenp указывает на переменную типа «значение- результат», хранящую размер этого целого числа. Мы выводим либо 0 (отключено), либо 1 (включено).

18.5. Функция get_ifi_info (повтор)

Вернемся к примеру из раздела 17.6 — возвращение всех активных интерфейсов в виде связного списка структур ifi_info (см. листинг 17.2). Программа prifinfo остается без изменений (см. листинг 17.3), но теперь мы покажем версию функции get_ifi_info, использующую функцию sysctl вместо вызова SIOCGIFCONF функции ioctl в листинге 17.4.

Сначала в листинге 18.8 мы представим функцию net_rt_iflist. Эта функция вызывает функцию sysctl с командой NET_RT_IFLIST, чтобы возвратить список интерфейсов для заданного семейства адресов.

Листинг 18.8. Вызов функции sysctl для возвращения списка интерфейсов

//libroute/net_rt_iflist.c

 1 #include "unproute.h"


 2 char*

 3 net_rt_iflist(int family, int flags, size_t *lenp)

 4 {

 5  int mib[6];

 6  char *buf;


 7  mib[0] = CTL_NET;

 8  mib[1] = AF_ROUTE;

 9  mib[2] = 0;

10  mib[3] = family; /* только адреса этого семейства */

11  mib[4] = NET_RT_IFLIST;

12  mib[5] = flags; /* индекс интерфейса или 0.*/

13  if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0)

14   return (NULL);


15  if ((buf = malloc(*lenp)) == NULL)

16   return (NULL);

17  if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) {

18   free(buf);

19   return (NULL);

20  }

21  return (buf);

22 }

7-14 Инициализируется массив mib, как показано в табл. 18.3, для возвращения списка интерфейсов и всех сконфигурированных адресов заданного семейства. Затем функция sysctl вызывается дважды. В первом вызове функции третий аргумент нулевой, в результате чего в переменной, на которую указывает lenp, возвращается размер буфера, требуемый для хранения всей информации об интерфейсе.

15-21 Затем в памяти выделяется место для буфера, и функция sysctl вызывается снова, на этот раз с ненулевым третьим аргументом. При этом переменная, на которую указывает lenp, содержит при завершении функции число, равное количеству информации, хранимой в буфере, и эта переменная размещается в памяти вызывающим процессом. Указатель на буфер также возвращается вызывающему процессу.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*