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

 3 sig_alrm(int signo)

 4 {

 5  (*pr-fsend);

 6  alarm(1);

 7  return;

 8 }

Функция send_v4, приведенная в листинге 28.10, строит ICMPv4 сообщение эхо-запроса и записывает его в символьный сокет.

Листинг 28.10. Функция send_v4: построение эхо-запроса ICMPv4 и его отправка

//ping/send_v4.c

 1 #include "ping.h"

 2 void

 3 send_v4(void)

 4 {

 5  int len;

 6  struct icmp *icmp;

 7  icmp = (struct icmp*)sendbuf;

 8  icmp-icmp_type = ICMP_ECHO;

 9  icmp-icmp_code = 0;

10  icmp-icmp_id = pid;

11  icmp-icmp_seq = nsent++;

12  memset(icmp-icmp_data, 0xa5, datalen); /* заполнение по шаблону */

13  Gettimeofday((struct timeval*)icmp-icmp_data, NULL);

14  len = 8 + datalen; /* контрольная сумма по заголовку и данным */

15  icmp-icmp_cksum = 0;

16  icmp-icmp_cksum = in_cksum((u_short*)icmp, len);

17  Sendto(sockfd, sendbuf, len, 0, pr-sasend, pr-salen);

18 }

Формирование ICMP-сообщения

7-13 ICMPv4 сообщение сформировано. В поле идентификатора установлен идентификатор нашего процесса, а порядковый номер установлен как глобальная переменная nset, которая затем увеличивается на 1 для следующего пакета. Текущее время сохраняется в части данных ICMP-сообщения.

Вычисление контрольной суммы ICMP

14-16 Для вычисления контрольной суммы ICMP значение поля контрольной суммы устанавливается равным 0, затем вызывается функция in_cksum, а результат сохраняется в поле контрольной суммы. Контрольная сумма ICMPv4 вычисляется по ICMPv4-заголовку и всем следующим за ним данным.

Отправка дейтаграммы

17 ICMP-сообщение отправлено на символьный сокет. Поскольку параметр сокета IP_HDRINCLне установлен, ядро составляет заголовок IPv4 и добавляет его в начало нашего буфера.

Контрольная сумма Интернета является суммой обратных кодов 16-разрядных значений. Если длина данных является нечетным числом, то для вычисления контрольной суммы к данным дописывается один нулевой байт. Перед вычислением контрольной суммы поле контрольной суммы должно быть установлено в 0. Такой алгоритм применяется для вычисления контрольных сумм IPv4, ICMPv4, IGMPv4, ICMPv6, UDP и TCP. В RFC 1071 [12] содержится дополнительная информация и несколько числовых примеров. В разделе 8.7 книги [128] более подробно рассказывается об этом алгоритме, а также приводится более эффективная его реализация. В нашем случае контрольную сумму вычисляет функция in_cksum, приведенная в листинге 28.11.

Листинг 28.11. Функция in_cksum: вычисление контрольной суммы Интернета

//libfree/in_cksum.c

 1 uint16_t

 2 in_cksum(uint16_t *addr, int len)

 3 {

 4  int nleft = len;

 5  uint32_t sum = 0;

 6  uint16_t *w = addr;

 7  uint16_t answer = 0;

 8  /*

 9   * Наш алгоритм прост: к 32-разрядному аккумулятору sum мы добавляем

10   * 16-разрядные слова, а затем записываем все биты переноса из старших

11   * 16 разрядов в младшие 16 разрядов.

12   */

13  while (nleft 1) {

14   sum += *w++;

15   nleft -= 2;

16  }

17  /* при необходимости добавляем четный байт */

18  if (nleft == 1) {

19   *(unsigned char*)(answer) = *(unsigned char*)w;

20   sum += answer;

21  }

22  /* перемещение битов переноса из старших 16 разрядов в младшие */

23  sum = (sum 16) + (sum 0xffff); /* добавление старших 16 к младшим */

24  sum += (sum 16); /* добавление переноса */

25  answer = ~sum; /* обрезаем по 16 разрядам */

26  return(answer);

27 }

Алгоритм вычисления контрольной суммы Интернета
Перейти на страницу:

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

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

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

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

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

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

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

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