UNIX: разработка сетевых приложений
Пример: определяем, включены ли контрольные суммы UDP
Теперь мы приведем простой пример использования функции
с протоколами Интернета для проверки, включены ли контрольные суммы UDP. Некоторые приложения UDP (например, BIND) проверяют при запуске, включены ли контрольные суммы UDP, и если нет, пытаются включить их. Для того чтобы включить подобное свойство, требуются права привилегированного пользователя, но мы сейчас просто проверим, включено это свойство или нет. В листинге 18.7 представлена наша программа.sysctlЛистинг 18.7. Проверка включения контрольных сумм
//route/checkudpsum.c1 #include "unproute.h"2 #include <netinet/udp.h>3 #include <netinet/ip_var.h>4 #include <netinet/udp_var.h> /* для констант UDPCTL_xxx */5 int6 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: %d\n", val);17 exit(0);18 }Включение системных заголовковСледует включить заголовочный файл2-4, чтобы получить определение констант UDP функции<netinet/udp_var.h>. Для него требуются два других заголовка.sysctlВызов функции sysctlМы размещаем в памяти массив целых чисел с четырьмя элементами и храним константы, соответствующие иерархии, показанной на рис. 18.3. Поскольку мы только получаем переменную и не присваиваем ей значение, аргумент10-16функцииnewpмы задаем как пустой указатель, и поэтому аргументsysctlэтой функции имеет нулевое значение,newpуказывает на нашу целочисленную переменную, в которую сохраняется результат, aoldpуказывает на переменную типа «значение- результат», хранящую размер этого целого числа. Мы выводим либо 0 (отключено), либо 1 (включено).oldenp18.5. Функция get_ifi_info (повтор)
Вернемся к примеру из раздела 17.6 — возвращение всех активных интерфейсов в виде связного списка структур
(см. листинг 17.2). Программаifi_infoостается без изменений (см. листинг 17.3), но теперь мы покажем версию функцииprifinfo, использующую функциюget_ifi_infoвместо вызоваsysctlфункцииSIOCGIFCONFв листинге 17.4.ioctlСначала в листинге 18.8 мы представим функцию
. Эта функция вызывает функциюnet_rt_iflistс командойsysctl, чтобы возвратить список интерфейсов для заданного семейства адресов.NET_RT_IFLISTЛистинг 18.8. Вызов функции sysctl для возвращения списка интерфейсов
//libroute/net_rt_iflist.c1 #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, как показано в табл. 18.3, для возвращения списка интерфейсов и всех сконфигурированных адресов заданного семейства. Затем функцияmibвызывается дважды. В первом вызове функции третий аргумент нулевой, в результате чего в переменной, на которую указываетsysctl, возвращается размер буфера, требуемый для хранения всей информации об интерфейсе.lenpЗатем в памяти выделяется место для буфера, и функция15-21вызывается снова, на этот раз с ненулевым третьим аргументом. При этом переменная, на которую указываетsysctl, содержит при завершении функции число, равное количеству информации, хранимой в буфере, и эта переменная размещается в памяти вызывающим процессом. Указатель на буфер также возвращается вызывающему процессу.lenpПРИМЕЧАНИЕПоскольку размер таблицы маршрутизации или число интерфейсов может изменяться между двумя вызовами функции sysctl, значение, возвращаемое при первом вызове, содержит поправочный множитель 10% [128, с. 639-640].
В листинге 18.9 показана первая половина функции
.get_ifi_infoЛистинг 18.9. Функция get_ifi_info, первая половина
//route/get_ifi_info.c3 struct ifi_info *