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

14  icmp = (struct icmp*)(ptr + hlen1); /* начало ICMP-заголовка */

15  if ((icmplen = len - hlen1) < 8)

16   return; /* плохой пакет */

17  if (icmp->icmp_type == ICMP_ECHOREPLY) {

18   if (icmp->icmp_id != pid)

19    return; /* это не ответ на наш ECHO_REQUEST */

20   if (icmplen < 16)

21    return; /* недостаточно данных */

22  tvsend = (struct timeval*)icmp->icmp_data;

23  tv_sub(tvrecv, tvsend);

24  rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;

25  printf("%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f ms\n",

26   icmplen, Sock_ntop_host(pr->sarecv, pr->salen),

27   icmp->icmp_seq, ip->ip_ttl, rtt);

28  } else if (verbose) {

29   printf(" %d bytes from %s: type = %d, code = %d\n",

30   icmplen, Sock_ntop_host(pr->sarecv, pr->salen),

31   icmp->icmp_type, icmp->icmp_code);

32  }

33 }

Извлечение указателя на ICMP-заголовок

10-16 Значение поля длины заголовка IPv4, умноженное на 4, дает размер заголовка IPv4 в байтах. (Следует помнить, что IPv4-заголовок может содержать параметры.) Это позволяет нам установить указатель icmp так, чтобы он указывал на начало ICMP-заголовка. Мы проверяем, относится ли данный пакет к протоколу ICMP и имеется ли в нем достаточно данных для проверки временной отметки, включенной нами в эхо-запрос. На рис. 28.3 приведены различные заголовки, указатели и длины, используемые в коде.

Рис. 28.3. Заголовки, указатели и длина при обработке ответов ICMPv4

Проверка эхо-ответа ICMP

17-21 Если сообщение является эхо-ответом ICMP, то необходимо проверить поле идентификатора, чтобы выяснить, относится ли этот ответ к посланному данным процессом запросу. Если программа ping запущена на одном узле несколько раз, каждый процесс получает копии всех полученных ICMP-сообщений.

22-27 Путем вычитания времени отправки сообщения (содержащегося в части ICMP-ответа, отведенной под дополнительные данные) из текущего времени (на которое указывает аргумент функции tvrecv) вычисляется значение RTT. Время RTT преобразуется из микросекунд в миллисекунды и выводится на экран вместе с полем порядкового номера и полученным значением TTL. Поле порядкового номера позволяет пользователю проследить, не были ли пакеты пропущены, переупорядочены или дублированы, а значение TTL показывает количество транзитных узлов между двумя узлами.

Вывод всех полученных ICMP-сообщений при включении параметра verbose

28-32 Если пользователем указан параметр командной строки -v, также выводятся поля типа и кода из всех других полученных ICMP-сообщений.

Обработка сообщений ICMPv6 управляется функцией proc_v6, приведенной в листинге 28.8. Она аналогична функции proc_v4, представленной в листинге 28.6. Однако поскольку символьные сокеты IPv6 не передают процессу заголовок IPv6, ограничение на количество транзитных узлов приходится получать в виде вспомогательных данных. Для этого нам приходится подготавливать сокет функцией init_v6, представленной в листинге 28.7.

Листинг 28.7. Функция init_v6: подготовка сокета

 1 void

 2 init_v6()

 3 {

 4 #ifdef IPV6

 5  int on = 1;

 6  if (verbose == 0) {

 7   /* установка фильтра, пропускающего только пакеты ICMP6_ECHO_REPLY. если

        не включен параметр verbose (вывод всех ICMP-сообщений) */

 8   struct icmp6_filter myfilt;

 9   ICMP6_FILTER_SETBLOCKALL(&myfilt);

10   ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &myfilt);

11   setsockopt(sockfd, IPPROTO_IPV6, ICMP6_FILTER, &myfilt,

12    sizeof(myfilt));

13   /* игнорируем ошибку, потому что фильтр - необязательная оптимизация */

14  }

15  /* следующую ошибку тоже игнорируем; придется обойтись без вывода

       ограничения на количество транзитных узлов */

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

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

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