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

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

Шрифт:
ПРИМЕЧАНИЕ

Формат, приведенный на рис. 27.2, определен в заголовочном файле <netinet/ip_var.h> в виде следующей структуры:

#define MAX_IPOPTLEN 40

struct ipoption {

struct in_addr ipopt_dst; /* адрес первого получателя */

char ipopt_list[MAX_IPOPTLEN]; /* соответствующие параметры */

};

В листинге 27.3 мы анализируем эти данные, не используя указанную структуру.

Возвращаемый формат отличается от того, который был передан функции

setsockopt
. Если нам было бы нужно преобразовать формат, показанный на рис. 27.2, к формату, показанному на рис. 27.1, нам следовало бы поменять местами первые и вторые 4 байта и изменить значение поля
len
, добавив к имеющемуся значению 4. К счастью, нам не нужно этого делать, так как Беркли-реализации автоматически используют обращенный маршрут от получателя для сокета TCP. Иными словами, данные, возвращаемые функцией
getsockopt
(представленные на рис. 27.2), носят чисто информативный характер. Нам не нужно вызывать функцию
setsockopt
, чтобы указать ядру на необходимость использования данного маршрута для дейтаграмм IP, отсылаемых по соединению TCP, — ядро сделает это само. Подобный пример с нашим сервером TCP мы вскоре увидим.

Следующей из рассматриваемых нами функций, связанных с параметром маршрутизации, полученный маршрут от отправителя передается в формате, показанном на рис. 27.2. Затем она выводит соответствующую информацию. Эту функцию

inet_srtcrt_print
мы показываем в листинге 27.3.

Листинг 27.3. Функция inet_srtcrt_print: вывод полученного маршрута от отправителя

//ipopts/sourceroute.c

37 void

38 inet_srcrt_print(u_char *ptr, int len)

39 {

40 u_char c;

41 char str[INET_ADDRSTRLEN];

42 struct in_addr hop1;

43 memcpy(&hop1, ptr, sizeof(struct in_addr));

44 ptr += sizeof(struct in_addr);

45 while ((c = *ptr++) == IPOPT_NOP); /* пропуск параметров NOP */

46 if (с == IPOPT_LSRR)

47 printf("received LSRR: ");

48 else if (c == IPOPT_SSRR)

49 printf("received SSRR: ");

50 else {

51 printf("received option type %d\n", c);

52 return;

53 }

54 printf("%s ", Inet_ntop(AF_INET, &hop1, str, sizeof(str)));

55 len = *ptr++ - sizeof(struct in_addr); /* вычитаем адрес получателя */

56 ptr++; /* пропуск указателя */

57 while (len > 0) {

58 printf("%s ", Inet_ntop(AF_INET, ptr, str, sizeof(str)));

59 ptr += sizeof(struct in_addr);

60 len -= sizeof(struct in_addr);

61 }

62 printf("\n");

63 }

Сохраняем первый адрес IP, пропускаем все параметры NOP

43-45
Первый IP-адрес в буфере сохраняется, а все следующие за ним параметры NOP мы пропускаем.

Проверяем параметр маршрута от отправителя

46-62
Мы выводим информацию о маршруте и проверяем значение поля
code
, содержащегося в 3-байтовом заголовке, получаем значение поля
len
и пропускаем указатель
ptr
. Затем мы выводим все IP-адреса, следующие за 3-байтовым заголовком, кроме IP-адреса получателя.

Пример

Теперь мы модифицируем наш эхо-сервер TCP таким образом, чтобы выводить полученный маршрут от отправителя, а эхо-клиент TCP — так, чтобы маршрут от отправителя можно было задавать. В листинге 27.4 показан код эхо-клиента TCP.

Листинг 27.4. Эхо-клиент TCP, задающий маршрут от отправителя

//ipopts/tcpcli01.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

  • Читать дальше
  • 1
  • ...
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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