Для получения значений используется аргумент
oldp
. Он указывает на буфер, в котором ядро сохраняет значение. Аргумент
oldenp
имеет тип «значение-результат»: когда функция вызывается, значение, на которое указывает
oldenp
, задает размер этого буфера, а по завершении функции значением этого аргумента становится количество данных, сохраненных ядром в буфере. Если размера буфера недостаточно, возвращается ошибка
ENOMEM
. В специальном случае
oldp
может быть пустым указателем, a
oldenp
— непустым указателем, и тогда ядро определяет, сколько данных возвратилось бы при вызове, сообщая это значение через
oldenp
.
Чтобы установить новое значение, используется аргумент
newp
, указывающий на буфер размера
newlen
. Если новое значение не задается,
newp
должен быть пустым указателем, a
newlen
должен быть равен нулю.
В руководстве (man) по применению функции
sysctl
подробно описывается различная системная информация, которую можно получить с помощью этой функции: информация о файловых системах, виртуальной памяти, ограничениях ядра, аппаратных характеристиках и т.д. Нас интересует сетевая подсистема, на которую указывает первый элемент массива name, равный
CTL_NET
(константы
CTL_<i>xxx</i>
определяются в заголовочном файле
<sys/sysctl.h>
). Тогда второй элемент может быть одним из перечисленных ниже.
■
AF_INET
. Получение или установка переменных, влияющих на протоколы Интернета. Следующий уровень с помощью одной из констант
IPROTO_<i>xxx</i>
задает протокол. 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_<i>xxx</i>
определяются в заголовочном файле
<sys/socket.h>
.) Информация возвращается через указатель
oldp
при вызове функции
sysctl
. Этот буфер содержит переменное число сообщений
RTM_<i>xxx</i>
(см. табл. 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_<i>xxx</i>
равно указанному в элементе
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.