Литмир - Электронная Библиотека
Содержание  
A
A

23   int msglen;

24   struct sadb_msg *msgp;

25   msglen = Read(s, &buf, sizeof(buf));

26   msgp = (struct sadb_msg*)&buf;

27   print_sadb_msg(msgp, msglen);

28   if (msgp->sadb_msg_seq == 0)

29    goteof = 1;

30  }

31  close(s);

32 }

33 int

34 main(int argc, char **argv)

35 {

36  int satype = SADB_SATYPE_UNSPEC;

37  int c;

38  opterr = 0; /* отключение записи в stderr для getopt() */

39  while ((c = getopt(argc, argv, "t:")) != -1) {

40   switch (c) {

41   case 't':

42    if ((satype = getsatypebyname(optarg)) == -1)

43     err_quit("invalid -t option %s", optarg);

44    break;

45   default:

46    err_quit("unrecognized option: %c", c);

47   }

48  }

49  sadb_dump(satype);

50 }

В этом листинге мы впервые встречаемся с функцией

getopt
, определяемой стандартом POSIX. Третий аргумент представляет собой строку символов, которые могут быть приняты в качестве аргументов командной строки: в нашем случае только
t
. За символом следует двоеточие, означающее, что за ключом должно быть указано численное значение. В программах, которые могут принимать несколько аргументов, эти аргументы должны объединяться. Например, в листинге 29.3 соответствующая строка имеет вид
0i:l:v
. Это означает, что ключи
i
и
l
сопровождаются дополнительными аргументами, а
0
и
v
— не сопровождаются.

Эта функция работает с четырьмя глобальными переменными, определенными в заголовочном файле

<unistd.h>
.

extern char *optarg;

extern int optind, opterr, optopt;

Перед вызовом

getopt
мы устанавливаем
opterr
в нуль, чтобы функция не направляла сообщений об ошибках в стандартный поток вывода этих сообщений, потому что мы хотим обрабатывать их самостоятельно. В стандарте POSIX говорится, что если первый символ третьего аргумента функции — двоеточие, то это тоже должно отключать вывод сообщений в стандартный поток сообщений об ошибках, однако не все реализации в настоящий момент выполняют данное требование.

Открытие сокета PF_KEY

1-8
 Сначала мы открываем сокет
PF_KEY
. Для этого требуются определенные привилегии, поскольку сокет дает доступ к управлению ключами.

Формирование запроса SADB_DUMP

9-15
 Мы начинаем с обнуления структуры
sadb_msg
, что позволяет нам не инициализировать поля, которые должны остаться нулевыми. Затем мы заполняем все интересующие нас поля по отдельности.

Если при открытии сокета в качестве третьего аргумента использовалась константа

PF_KEY_V2
, все сообщения, направляемые в такой сокет, должны иметь версию
PF_KEY_V2
. Нужный нам тип сообщения —
SADB_DUMP
. Длина сообщения устанавливается равной длине заголовка без расширений, поскольку для запроса дампа расширения не нужны. Наконец, идентификатор процесса устанавливается равным идентификатору нашего процесса. Это обязательное условие для всех сообщений.

Отображение и отправка сообщения SADB_DUMP

16-18
 Мы отображаем сообщение при помощи функции
print_sadb_msg
. Мы не приводим листинг этой функции, потому что он достаточно длинный и не представляет особого интереса, однако он включен в набор свободно распространяемых программ, доступный для скачивания с сайта этой книги. Функция принимает сообщение, подготовленное к отправке или полученное от ядра, и выводит всю содержащуюся в этом сообщении информацию в удобной для чтения форме.

После вызова функции подготовленное сообщение записывается в сокет.

Чтение ответов

19-30
 Программа считывает сообщения и выводит их в цикле при помощи функции
print_sadb_msg
. Последнее сообщение последовательности имеет порядковый номер 0, что мы трактуем как «конец файла».

Закрытие сокета PF_KEY

31
Мы закрываем открытый в начале работы сокет управления ключами.

Обработка аргументов командной строки

38-48
 На долю функции
main
остается не так уж много работы. Программа принимает единственный аргумент — тип соглашений о безопасности, которые должны быть запрошены из базы. По умолчанию тип равен
SADB_SATYPE_UNSPEC
. Указав другой тип в аргументе командной строки, пользователь может выбрать интересующие его записи. Наша программа вызывает нашу же функцию
getsatypebyname
, возвращающую значение типа (константу) по его названию.

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

49
 Наконец, мы вызываем функцию
sadb_dump
, которая уже была описана.

Пробный запуск

Ниже приведен пример выполнения программы дампа базы данных безопасности в системе с двумя статическими соглашениями о безопасности.

macosx % <b>dump Sending dump message:</b>

SADB Message Dump, errno 0, satype Unspecified, seq 0, pid 20623

Messages returned:

SADB Message Dump, errno 0. satype IPsec AH, seq 1, pid 20623

SA: SPI=258 Replay Window=0 State=Mature

Authentication Algorithm: HMAC-MD5

Encryption Algorithm: None

213
{"b":"225366","o":1}