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

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

Шрифт:

9 #endif

10 int

11 readable_v6(void)

12 {

13 #ifdef IPV6

14 int i, hlen2, icmp6len, sport;

15 char buf[MAXLINE];

16 char srcstr[INET6_ADDRSTRLEN], dststr[INET6_ADDRSTRLEN];

17 ssize_t n;

18 socklen_t len;

19 struct ip6_hdr *ip6, *hip6;

20 struct icmp6_hdr *icmp6;

21 struct udphdr *udp;

22 struct sockaddr_in6 from, dest;

23 struct icmpd_err icmpd_err;

24 len = sizeof(from);

25 n = Recvfrom(fd6, buf, MAXLINE, 0, (SA*)&from, &len);

26 printf("%d bytes ICMPv6 from %s:", n, Sock_ntop_host((SA*)&from, len));

27 icmp6 = (struct icmp6_hdr*)buf; /* начало заголовка ICMPv6 */

28 if ((icmp6len = n) < 8)

29 err_quit("icmp6len (%d) < 8", icmp6len);

30 printf(" type = %d, code = %d\n", icmp6->icmp6_type, icmp6->icmp6_code);

Вторая часть функции

readable_v6
приведена в листинге 28.32. Код аналогичен приведенному в листинге 28.30: мы проверяем тип ICMP-ошибки, убеждаемся, что дейтаграмма, вызвавшая ошибку, является UDP-дейтаграммой, а затем строим структуру
icmpd_err
, которую отсылаем клиенту.

Листинг 28.32. Обработка полученной дейтаграммы ICMPv6, вторая часть

//icmpd/readable_v6.c

31 if (icmp6->icmp6_type == ICMP6_DST_UNREACH ||

32 icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG ||

33 icmp6->icmp6_type == ICMP6_TIME_EXCEEDED) {

34 if (icmp6len < 8+8)

35 err_quit("icmp6len (%d) < 8 + 8", icmp6len);

36 hip6 = (struct ip6_hdr*)(buf + 8);

37 hlen2 = sizeof(struct ip6_hdr);

38 printf("\tsrcip = %s, dstip = %s, next hdr = %d\n",

39 Inet_ntop(AF_INET6, &hip6->ip6_src, srcstr, sizeof(srcstr)),

40 Inet_ntop(AF_INET6, &hip6->ip6_dst, dststr, sizeof(dststr)),

41 hip6->ip6_nxt);

42 if (hip6->ip6_nxt == IPPROTO_UDP) {

43 udp = (struct udphdr*)(buf + 8 + hlen2);

44 sport = udp->uh_sport;

45 /* поиск доменного сокета клиента, отправка заголовков */

46 for (i = 0; i <= maxi; i++) {

47 if (client[i].connfd >= 0 &&

48 client[i].family == AF_INET6 &&

49 client[i].lport == sport) {

50 bzero(&dest, sizeof(dest));

51 dest.sin6_family = AF_INET6;

52 #ifdef HAVE_SOCKADDR_SA_LEN

53 dest.sin6_len = sizeof(dest);

54 #endif

55 memcpy(&dest.sin6_addr, &hip6->ip6_dst,

56 sizeof(struct in6_addr));

57 dest.sin6_port = udp->uh_dport;

58 icmpd_err.icmpd_type = icmp6->icmp6_type;

59 icmpd_err.icmpd_code = icmp6->icmp6_code;

  • Читать дальше
  • 1
  • ...
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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