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

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

Шрифт:

2 void

3 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

4 {

5 int n;

6 char mesg[MAXLINE];

7 int on;

8 char control[MAXLINE];

9 struct msghdr msg;

10 struct cmsghdr *cmsg;

11 struct iovec iov[1];

12 on = 1;

13 Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));

14 bzero(&msg, sizeof(msg));

15 iov[0].iov_base = mesg;

16 msg.msg_name = pcliaddr;

17 msg.msg_iov = iov;

18 msg.msg_iovlen = 1;

19 msg.msg_control = control;

20 for (;;) {

21 msg.msg_namelen = clilen;

22 msg.msg_controllen = sizeof(control);

23 iov[0].iov_len = MAXLINE;

24 n = Recvmsg(sockfd, &msg, 0);

25 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;

26 cmsg = CMSG_NXTHDR(&msg, cmsg)) {

27 if (cmsg->cmsg_level == IPPROTO_IPV6 &&

28 cmsg->cmsg_type == IPV6_RTHDR) {

29 inet6_srcrt_print(CMSG_DATA(cmsg));

30 Inet6_rth_reverse(CMSG_DATA(cmsg), CMSG_DATA(cmsg));

31 }

32 }

33 iov[0].iov_len = n;

34 Sendmsg(sockfd, &msg, 0);

35 }

36 }

Включение параметра IPV6_RECVRTHDR и подготовка структуры msghdr

12-13
Чтобы получить информацию о маршруте, мы должны установить параметр сокета
IPV6_RECVRTHDR
. Кроме того, мы должны использовать функцию
recvmsg
, поэтому мы настраиваем поля структуры
msghdr
, которые не требуют изменения.

Настройка изменяемых полей и вызов recvmsg

21-24
Мы устанавливаем размер полей длины и вызываем
recvmsg
.

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

25-32
Мы перебираем вспомогательные данные, используя
CMSG_FIRSTHDR
и
CMSG_NXTHDR
. Несмотря на то, что мы ожидаем получить только один объект вспомогательных данных, выполнить такой перебор всегда полезно. Если мы обнаруживаем заголовок маршрутизации, он распечатывается функцией
inet6_srcrt_print
(листинг 27.7). Затем маршрут обращается функцией
inet6_rth_reverse
для последующего использования при возвращении пакета клиенту. В данном случае обращение производится без копирования в новый буфер, так что можно использовать старый объект вспомогательных данных для отправки пакета клиенту.

Отправка эхо-пакета

33-34
Мы устанавливаем длину пакета и передаем его клиенту вызовом
sendmsg
.

Благодаря наличию вспомогательных библиотечных функций IPv6 наша функция

inet6_srcrt_print
становится почти тривиальной.

Листинг 27.7. Функция inet6_srcrt_print: вывод маршрута

1 #include "unp.h"

2 void

3 inet6_srcrt_print(void *ptr)

4 {

5 int i, segments;

6 char str[INET6_ADDRSTRLEN];

7 segments = Inet6_rth_segments(ptr);

8 printf("received source route: ");

9 for (i = 0; i < segments; i++)

10 printf("%s ", Inet_ntop(AF_INET6, Inet6_rth_getaddr(ptr, i),

11 str, sizeof(str)));

  • Читать дальше
  • 1
  • ...
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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