sysctl()

Получить или установить информацию о диспетчере сокетов

Прототип:

#include <sys/param.h>
#include <sys/sysctl.h>
int sysctl( int *name,
u_int namelen,
void *oldp,
size_t *oldlenp,
void *newp,
size_t newlen );

Аргументы:

name
Массив целых чисел, определяющий имя стиля Management Information Base (MIB) для элемента, который требуется установить или получить. Минимальное количество записей в этом массиве - 2; максимум - CTL_MAXNAME.
namelen
Длина name.
oldp
NULL, или указатель на буфер, в котором функция может хранить старое значение.
oldlenp
NULL, или указатель на область памяти, которая изначально определяет размер буфера oldp. Функция изменяет значение в этой области на размер старой информации, хранящейся в буфере oldp.
newp
NULL, или указатель на буфер, содержащий новое значение.
newlen
Размер нового значения.

Библиотека:

libsocket

Описание:

Функция sysctl() извлекает информацию о менеджере сокетов и позволяет процессам с соответствующими привилегиями устанавливать эту информацию. Данные, доступные из sysctl(), состоят из целых чисел и таблиц. Также можно получить или установить данные с помощью утилиты sysctl, используя командную строку.

Состояние описывается с помощью имени стиля Management Information Base (MIB), указанного в name, который представляет собой массив из namelen целых чисел.


Note: Описание наиболее часто используемых переменных см. в sysctl в Справочнике по Утилитам

Функция sysctl() копирует информацию для указанной переменной в буфер, указанный oldp. Размер буфера задается oldlenp перед вызовом, что дает информацию о количестве данных, скопированных после успешного вызова. Если объем доступных данных превышает размер предоставленного буфера, вызов доставляет столько данных, сколько умещается в предоставленном буфере, и возвращается с кодом ошибки ENOMEM. Если старое значение не нужно, то можно установить для oldp и oldlenp значение NULL.

Можно определить размер доступных данных, вызвав sysctl() с параметром NULL для oldp. Функция сохраняет размер доступных данных в месте, указанном oldlenp. Для некоторых операций объем места может часто меняться. Для этих операций система пытается округлить возвращаемый размер в большую сторону, чтобы он был достаточно большим для вызова и чтобы вернуть данные вскоре после этого.

Чтобы указать новое значение, следует установить newp так, чтобы он указывал на буфер длины newlen, из которого должно быть взято запрошенное значение. Если не требуется устанавливать новое значение, то необходимо установить для newp значение NULL, а для newlen значение 0.

Имена верхнего уровня определяются с помощью префикса CTL_ в <sys/sysctl.h>. Все последующие уровни находятся в следующих заголовочных файлах:

Заголовочный файл Содержание
<sys/sysctl.h> Идентификаторы верхнего уровня
<sys/socket.h> Сетевые идентификаторы второго уровня
<netinet/in.h> Интернет-идентификаторы третьего уровня и IP-идентификаторы четвертого уровня
<netinet/icmp_var.h> Идентификаторы ICMP четвертого уровня
<netinet/tcp_var.h> Идентификаторы TCP четвертого уровня
<netinet/udp_var.h> Идентификаторы UDP четвертого уровня

Файл <sys/sysctl.h> определяет идентификаторы верхнего уровня следующим образом:

#define CTL_UNSPEC 0 /* unused */
#define CTL_KERN 1 /* "high kernel": proc, limits */
#define CTL_VM 2 /* virtual memory */
#define CTL_VFS 3 /* file system, mount type is next */
#define CTL_NET 4 /* network, see socket.h */
#define CTL_DEBUG 5 /* debugging parameters */
#define CTL_HW 6 /* generic cpu/io */
#define CTL_MACHDEP 7 /* machine dependent */
#define CTL_USER 8 /* user-level */
#define CTL_DDB 9 /* in-kernel debugger */
#define CTL_PROC 10 /* per-proc attr */
#define CTL_VENDOR 11 /* vendor-specific data */
#define CTL_EMUL 12 /* emulation-specific data */
#define CTL_MAXID 13 /* number of valid top-level ids */
#define CTL_NAMES { \
{ 0, 0 }, \
{ "kern", CTLTYPE_NODE }, \
{ "vm", CTLTYPE_NODE }, \
{ "vfs", CTLTYPE_NODE }, \
{ "net", CTLTYPE_NODE }, \
{ "debug", CTLTYPE_NODE }, \
{ "hw", CTLTYPE_NODE }, \
{ "machdep", CTLTYPE_NODE }, \
{ "user", CTLTYPE_NODE }, \
{ "ddb", CTLTYPE_NODE }, \
{ "proc", CTLTYPE_NODE }, \
{ "vendor", CTLTYPE_NODE }, \
{ "emul", CTLTYPE_NODE }, \
}

Обратите внимание, что определения CTL_* соответствуют строкам, определенным ниже. Пример построения массива целых чисел из нескольких строк:

kern.clockrate
Имя верхнего уровня (kern) соответствует CTL_KERN, как показано выше. Имя второго уровня (тактовая частота) также определяется в <sys/sysctl.h>. Записи в массиве name, которые будут переданы в sysctl(), будут следующими:
Запись Значение См.:
0 CTL_KERN <sys/sysctl.h>
1 KERN_CLOCKRATE <sys/sysctl.h>
kern.mbuf.mblowat
И снова имя верхнего уровня соответствует CTL_KERN. Имя второго уровня определяется в <sys/sysctl.h>, но необходимо искать в <sys/mbuf.h> имя третьего уровня. Записи в массиве name будут следующими:
Запись Значение См.:
0 CTL_KERN <sys/sysctl.h>
1 KERN_MBUF <sys/sysctl.h>
2 MBUF_MBLOWAT <sys/mbuf.h>
net.inet.tcp.mssdflt
Имя первого уровня (net) соответствует CTL_NET, как показано выше. Имя второго уровня (inet) предназначено для информации об Интернет-протоколах и определяется как одно из семейств адресов в <sys/socket>. Имя третьего уровня (tcp) определяется как один из протоколов в <netinet/in.h>, а имя четвертого уровня (mssdflt) определяется в <netinet/in_offload.h>. Записи в массиве name будут следующими:
Запись Значение См.:
0 CTL_NET <sys/sysctl.h>
1 AF_INET <sys/socket.h>
2 IPPROTO_TCP <netinet/in.h>
3 TCPCTL_MSSDFLT <netinet/in_offload.h>

Возвращаемое значение:

0
Успешное завершение.
-1
Возникла ошибка. Код ошибки записан в errno.

Коды ошибок:

EFAULT
Один из буферов name, oldp, newp, или параметр длины oldlenp содержит некорректный адрес.
EINVAL
Длина массива имен меньше двух или больше, чем записей в нем больше, чем CTL_MAXNAME, либо был задан ненулевой newp, и его длина, указанная в newlen, слишком велика или слишком мала.
ENOMEM
Длина, на которую указывает oldlenp, слишком мала для запрошенного значения.
ENOTDIR
В массиве имен указывается промежуточное имя, а не оконечное.
EOPNOTSUPP
В массиве имен указано неизвестное значение.
EPERM
Произведена попытка установить значение только для чтения, или процесс без соответствующей привилегии попытался установить или изменить значение, защищенное текущим уровнем безопасности системы.

Примеры:

Следующий фрагмент кода проверяет, включена ли контрольная сумма UDP-пакетов:

int mib[5], val;
size_t len;
mib[0] = CTL_NET;
mib[1] = AF_INET;
mib[2] = IPPROTO_UDP;
mib[3] = UDPCTL_CHECKSUM;
len = sizeof( val );
sysctl( mib, 4, &val, &len, NULL, 0 );

Классификация:

Unix

Безопасность использования
Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Нет
В потоке
Да

Тематические ссылки:

ICMP6, ICMP, INET6, IP6, IP, IPsec, ROUTE, TCP, UDP, UNIX протоколы

sysctl в Справочнике по Утилитам




Предыдущий раздел: Описание API сетевой библиотеки