Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

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

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

  • Читать дальше
  • 1
  • ...
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: