Чтение онлайн

ЖАНРЫ

UNIX: разработка сетевых приложений
Шрифт:

Таблица 19.3. Типы расширений PF_KEY

Тип заголовка расширения Описание Структура
SADB_EXT_ADDRESS_DST Адрес получателя SA sadb_address
SADB_EXT_ADDRESS_PROXY Адрес прокси-сервера SA sadb_address
SADB_EXT_ADDRESS_SRC Адрес отправителя SA sadb_address
SADB_EXT_IDENTITY_DST Личность получателя sadb_ident
SADB_EXT_IDENTITY_SRC Личность
отправителя
sadb_ident
SADB_EXT_KEY_AUTH Ключ аутентификации sadb_key
SADB_EXT_KEY_ENCRYPT Ключ шифрования sadb_key
SADB_EXT_LIFETIME_CURRENT Текущее время жизни SA sadb_lifetime
SADB_EXT_LIFETIME_HARD Жесткое ограничение на время жизни SA sadb_lifetime
SADB_EXT_LIFETIME_SOFT Гибкое ограничение на время жизни SA sadb_lifetime
SADB_EXT_PROPOSAL Предлагаемая ситуация sadb_prop
SADB_EXT_SA Соглашение о безопасности sadb_sa
SADB_EXT_SENSITIVITY Важность SA sadb_sens
SADB_EXT_SPIRANGE Диапазон допустимых значений SPI sadb_spirange
SADB_EXT_SUPPORTED_AUTH Поддерживаемые алгоритмы аутентификации sadb_supported
SADB_EXT_SUPPORTED_ENCRYPT Поддерживаемые алгоритмы шифрования sadb_supported

Рассмотрим несколько примеров сообщений и расширений, используемых в типичных операциях с сокетами управления ключами.

19.3. Дамп базы соглашений о безопасности

Для дампа текущей базы соглашений о безопасности используется сообщение

SADB_DUMP
. Это самое простое из сообщений, поскольку оно не требует никаких расширений, а состоит только из 16-байтового заголовка
sadb_msg
. Когда процесс отправляет сообщение
SADB_DUMP
ядру через сокет управления ключами, ядро отвечает последовательностью сообщений
SADB_DUMP
по тому же сокету. В каждом сообщении содержится одна запись базы SADB. Конец последовательности обозначается сообщением со значением 0 в поле
sadb_msg_seq
.

Поле

sadb_msg_satype
позволяет запросить только записи определенного типа. Значения этого поля следует брать из табл. 19.2. При указании значения
SADB_SATYPE_UNSPEC
возвращаются все записи базы. Не все типы соглашений о безопасности поддерживаются всеми реализациями. Реализация KAME поддерживает только соглашения, относящиеся к IPSec (
SADB_SATYPE_AH
и
SADB_SATYPE_ESP
), поэтому при попытке получить дамп записей
SADB_SATYPE_RIPV2
будет возвращена ошибка
EINVAL
. Если же записей, относящихся к запрошенному типу, в таблице нет (но они поддерживаются), функция возвращает ошибку
ENOENT
.

Программа, получающая записи из базы данных безопасности, приведена в листинге 19.2.

Листинг 19.2. Дамп базы соглашений о безопасности

//key/dump.c

1 void

2 sadb_dump(int type)

3 {

4 int s;

5 char buf[4096];

6 struct sadb_msg msg;

7 int goteof;

8 s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);

9 /*
формирование и отправка запроса SADB_DUMP */

10 bzero(&msg, sizeof(msg));

11 msg.sadb_msg_version = PF_KEY_V2;

12 msg.sadb_msg_type = SADB_DUMP;

13 msg.sadb_msg_satype = type;

14 msg.sadb_msg_len = sizeof(msg) / 8;

15 msg.sadb_msg_pid = getpid;

16 printf("Sending dump message:\n");

17 print_sadb_msg(&msg, sizeof(msg));

18 Write(s, &msg, sizeof(msg));

19 printf("\nMessages returned:\n");

20 /* считывание и вывод всех ответов SADB_DUMP */

21 goteof = 0;

22 while (goteof == 0) {

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 говорится, что если первый символ третьего аргумента функции — двоеточие, то это тоже должно отключать вывод сообщений в стандартный поток сообщений об ошибках, однако не все реализации в настоящий момент выполняют данное требование.

Поделиться с друзьями: