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

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

Шрифт:

Листинг 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 }

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

1-27
Первый цикл
while
вычисляет сумму всех 16-битовых значений. Если длина нечетная, то к сумме добавляется конечный байт. Алгоритм, приведенный в листинге 28.11, является простым алгоритмом, подходящим для программы
ping
, но неудовлетворительным для больших объемов вычислений контрольных сумм, производимых ядром.

ПРИМЕЧАНИЕ

Эта функция взята из общедоступной версии программы ping, написанной Майком Мюссом (Mike Muuss).

Последней функцией нашей программы

ping
является функция
send_v6
, приведенная в листинге 28.12, которая формирует и посылает эхо-запросы ICMPv6.

Функция

send_v6
аналогична функции
send_v4
, но обратите внимание, что она не вычисляет контрольную сумму. Как отмечалось ранее, поскольку для вычисления контрольной суммы ICMPv6 используется адрес отправителя из IPv6-заголовка, данная контрольная сумма вычисляется для нас ядром, после того как ядро выяснит адрес отправителя.

Листинг 28.12. Функция send_v6: построение и отправка ICMPv6-сообщения эхо-запроса

//ping/send_v6.c

1 #include "ping.h"

2 void

3 send_v6

4 {

5 #ifdef IPV6

6 int len;

7 struct icmp6_hdr *icmp6;

8 icmp6 = (struct icmp6_hdr*)sendbuf,

9 icmp6->icmp6_type = ICMP6_ECHO_REQUEST;

10 icmp6->icmp6_code = 0;

11 icmp6->icmp6_id = pid;

12 icmp6->icmp6_seq = nsent++;

13 memset((icmp6 + 1), 0xa5, datalen); /* заполнение по шаблону */

14 Gettimeofday((struct timeval*)(icmp6 + 1), NULL);

15 len = 8 + datalen; /* 8-байтовый заголовок ICMPv6 */

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

17 /* ядро вычисляет и сохраняет контрольную сумму само */

18 #endif /* IPV6 */

19 }

28.6. Программа traceroute

В этом разделе мы приведем собственную версию программы

traceroute
. Как и в случае с программой
ping
, приведенной в предыдущем разделе, мы представляем нашу собственную, а не общедоступную версию. Это делается для того, чтобы во-первых, получить версию, поддерживающую как IPv4, так и IPv6, а во-вторых, не отвлекаться на множество параметров, не относящихся к обсуждению сетевого программирования.

  • Читать дальше
  • 1
  • ...
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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