Читаем UNIX: разработка сетевых приложений полностью

28  pid = getpid 0xffff; /* поле идентификатора ICMP имеет размер 16 бит */

29  Signal(SIGALRM, sig_alrm);

30  ai = Host_serv(host, NULL, 0, 0);

31  h = Sock_ntop_host(ai-ai_addr, ai-ai_addrlen);

32  printf("PING %s (%s): %d data bytes\n",

33  ai-ai_canonname ? ai-ai_canonname : h, h, datalen);

34  /* инициализация в соответствии с протоколом */

35  if (ai-ai_family == AF_INET) {

36   pr = proto_v4;

37 #ifdef IPV6

38  } else if (ai-ai_family == AF_INET6) {

39   pr = proto_v6;

40   if (IN6_IS_ADDR_V4MAPPED((((struct sockaddr_in6*)

41    ai-ai_addr)-sin6_addr)))

42    err_quit("cannot ping IPv4-mapped IPv6 address");

43 #endif

44  } else

45   err_quit("unknown address family %d", ai-ai_family);

46  pr-sasend = ai-ai_addr;

47  pr-sarecv = Calloc(1, ai-ai_addrlen);

48  pr-salen = ai-ai_addrlen;

49  readloop;

50  exit(0);

51 }

Определение структуры proto для IPv4 и IPv6

2-7 Определяется структура protoдля IPv4 и IPv6. Указатели структуры адреса сокета инициализируются как нулевые, поскольку еще не известно, какая из версий будет использоваться — IPv4 или IPv6.

Длина дополнительных данных

8 Устанавливается количество дополнительных данных (56 байт), которые будут посылаться с эхо-запросом ICMP. При этом полная IPv4-дейтаграмма будет иметь размер 84 байта (20 байт на IPv4-заголовок и 8 байт на ICMP-заголовок), а IPv6-дейтаграмма будет иметь длину 104 байта. Все данные, посылаемые с эхо- запросом, должны быть возвращены в эхо-ответе. Время отправки эхо-запроса будет сохраняться в первых 8 байтах области данных, а затем, при получении эхо- ответа, будет использоваться для вычисления и вывода времени RTT.

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

15-24 Единственный параметр командной строки, поддерживаемый в нашей версии, это параметр -v, в результате использования которого большинство ICMP-сообщений будут выводиться на консоль. (Мы не выводим эхо-ответы, принадлежащие другой запущенной копии программы ping.) Для сигнала SIGALRMустанавливается обработчик, и мы увидим, что этот сигнал генерируется один раз в секунду и вызывает отправку эхо-запросов ICMP.

Обработка аргумента, содержащего имя узла

31-48 Строка, содержащая имя узла или IP-адрес, является обязательным аргументом и обрабатывается функцией host_serv. Возвращаемая структура addrinfoсодержит семейство протоколов — либо AF_INET, либо AF_INET6. Глобальный указатель pr устанавливается на требуемую в конкретной ситуации структуру proto. Также с помощью вызова функции IN6_IS_ADDR_V4MAPPEDмы убеждаемся, что адрес IPv6 на самом деле не является адресом IPv4, преобразованным к виду IPv6, поскольку даже если возвращаемый адрес является адресом IPv6, узлу будет отправлен пакет IPv4. (Если такая ситуация возникнет, можно переключиться и использовать IPv4.) Структура адреса сокета, уже размещенная в памяти с помощью функции getaddrinfo, используется для отправки, а другая структура адреса сокета того же размера размещается в памяти для получения.

Обработка ответов осуществляется функцией readlоор, представленной в листинге 28.4.

Листинг 28.4. Функция readloop

//ping/readlоор.c

 1 #include "ping.h"

 2 void

 3 readloop(void)

 4 {

 5  int size;

 6  char recvbuf[BUFSIZE];

 7  char controlbuf[BUFSIZE];

 8  struct msghdr msg;

 9  struct iovec iov;

10  ssize_t n;

11  struct timeval tval;

12  sockfd = Socket(pr-sasend-sa_family, SOCK_RAW, pr-icmpproto);

13  setuid(getuid); /* права привилегированного пользователя

                         больше не нужны */

14  if (pr-finit)

15   (*pr-finit);

16  size = 60 * 1024; /* setsockopt может завершиться с ошибкой */

17  setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, size, sizeof(size));

Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT