Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сСтСвых ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 218

Автор Уильям БтивСнс

21-25 Π’ызываСтся функция getsockname, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π΄Π΅ΠΌΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π°, связанного с сокСтом. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ нСизвСстно, ΠΊΠ°ΠΊΠΎΠ² Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π°, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ для размСщСния структуры адрСса сокСта, ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ структуру sockaddr_storage, которая достаточно Π²Π΅Π»ΠΈΠΊΠ° для структуры адрСса сокСта любого ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ систСмой Ρ‚ΠΈΠΏΠ° ΠΈ обСспСчиваСт Π½ΡƒΠΆΠ½ΠΎΠ΅ Π²Ρ‹Ρ€Π°Π²Π½ΠΈΠ²Π°Π½ΠΈΠ΅.

26-33 Π‘СмСйство адрСсов сокСта вмСстС с Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ ΠΏΠΎΡ€Ρ‚Π° сохраняСтся Π² структурС client. Если Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π° Ρ€Π°Π²Π΅Π½ Π½ΡƒΠ»ΡŽ, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sock_bind_wild для связывания ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ адрСса ΠΈ динамичСски Π½Π°Π·Π½Π°Ρ‡Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΡ€Ρ‚Π° с сокСтом, Π½ΠΎ, ΠΊΠ°ΠΊ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅, Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² рСализациях SVR4.

Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΎΠ± успСхС

34 ΠžΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚, содСрТащий символ "1", отправляСтся ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.

Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ UDP-сокСта ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

35 Π—Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Ρƒ с UDP-сокСтом ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Π΅Π³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ close. ДСскриптор Π±Ρ‹Π» пСрСслан Π½Π°ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, являСтся ΠΊΠΎΠΏΠΈΠ΅ΠΉ; ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, UDP-сокСт всС Π΅Ρ‰Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

37-45 Π•сли происходит ошибка, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ Π±Π°ΠΉΡ‚. Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, наша Ρ‡Π°ΡΡ‚ΡŒ Π΄ΠΎΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ сокСта Unix закрываСтся, ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ дСскриптор удаляСтся ΠΈΠ· Π½Π°Π±ΠΎΡ€Π° дСскрипторов для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select. Полю connfd структуры client присваиваСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ -1, Ρ‡Ρ‚ΠΎ являСтся ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Π½Π° Π΅Π΅ освобоТдСниС.

Ѐункция readable_v4 вызываСтся, ΠΊΠΎΠ³Π΄Π° ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ICMPv4 ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ для чтСния. ΠŸΠ΅Ρ€Π²Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 28.29. Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π΅Π½ ΠΊΠΎΠ΄Ρƒ для ICMPv4, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌΡƒ Ρ€Π°Π½Π΅Π΅ Π² листингах 28.6 ΠΈ 28.15.

Листинг 28.29. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ ICMPv4, пСрвая Ρ‡Π°ΡΡ‚ΡŒ

//icmpd/readable_v4.c

 1 #include "icmpd.h"

 2 #include <netinet/in_systm.h>

 3 #include <netinet/ip.h>

 4 #include <netinet/ip_icmp.h>

 5 #include <netinet/udp.h>


 6 int

 7 readable_v4(void)

 8 {

 9  int i, hlen1, hlen2, icmplen, sport;

10  char buf[MAXLINE];

11  char srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN];

12  ssize_t n;

13  socklen_t len;

14  struct ip *ip, *hip;

15  struct icmp *icmp;

16  struct udphdr *udp;

17  struct sockaddr_in from, dest;

18  struct icmpd_err icmpd_err;


19  len = sizeof(from);

20  n = Recvfrom(fd4, buf, MAXLINE, 0, (SA*)&from, &len);


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


22  ip = (struct ip*)buf; /* Π½Π°Ρ‡Π°Π»ΠΎ IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° */

23  hlen1 = ip->ip_hl << 2; /* Π΄Π»ΠΈΠ½Π° IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° */


24  icmp = (struct icmp*)(buf + hlen1); /* Π½Π°Ρ‡Π°Π»ΠΎ ICMP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° */

25  if ((icmplen = n - hlen1) < 8)

26   err_quit("icmplen (%d) < 8", icmplen);


27  printf(" type = %d, code = %d\n", icmp->icmp_type, icmp->icmp_code);

Ѐункция Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠΌ сообщСнии ICMP. Π­Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ сдСлано для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Π΄Π΅ΠΌΠΎΠ½Π°, ΠΈ Π²Ρ‹Π²ΠΎΠ΄ управляСтся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки.

Π’ листингС 28.30 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° вторая Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ readable_v4.

Листинг 28.30. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ ICMPv4, вторая Ρ‡Π°ΡΡ‚ΡŒ

//icmpd/readable_v4.c

28  if (icmp->icmp_type == ICMP_UNREACH ||

29   icmp->icmp_type ==ICMP_TIMXCEED ||

30   icmp->icmp_type == ICMP_SOURCEQUENCH) {

31   if (icmplen < 8 + 20 + 8)

32    err_quit("icmplen (%d) < 8 + 20 + 8, icmplen);


33   hip = (struct ip*)(buf + hlen1 + 8);

34   hlen2 = hip->ip_hl << 2;

35   printf("\tsrcip = %s, dstip = %s, proto = %d\n",

36    Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)),

37    Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)),

38    hip->ip_p);

39   if (hip->ip_p == IPPROTO_UDP) {

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

41    sport = udp->uh_sport;


42    /* поиск Π΄ΠΎΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ сокСта ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° */

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

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

45      client[i].family == AF_INET &&

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


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

48      dest.sin_family = AF_INET;

49 #ifdef HAVE_SOCKADDR_SA_LEN

50      dest.sin_len = sizeof(dest);

51 #endif

52      memcpy(&dest.sin_addr, &hip->ip_dst,

53       sizeof(struct in_addr));

54      dest.sin_port = udp->uh_dport;


55      icmpd_err.icmpd_type = icmp->icmp_type;

56      icmpd_err.icmpd_code = icmp->icmp_code;

57      icmpd_err.icmpd_len = sizeof(struct sockaddr_in);

58      memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));


59      /* ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° ΠΈ Ρ‚ΠΈΠΏΠ° ICMP Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ errno */

60      icmpd_err.icmpd_errno = EHOSTUNREACH; /* ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ */

61      if (icmp->icmp_type == ICMP_UNREACH) {

62       if (icmp->icmp_code == ICMP_UNREACH_PORT)

63        icmpd_err.icmpd_errno = ECONNREFUSED;

64       else if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG)

65        icmpd_err.icmpd_errno = EMSGSIZE;

66      }

67      Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));

68     }

69    }

70   }

71  }

72  return(--nready);

73 }

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚ΠΈΠΏΠ° сообщСния, ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ прилоТСния

29-31 ICMP-сообщСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΡΡ‹Π»Π°ΡŽΡ‚ΡΡ прилоТСниям, β€” это сообщСния ΠΎ нСдоступности ΠΏΠΎΡ€Ρ‚Π°, ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° (см. Ρ‚Π°Π±Π». 28.1).

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ошибки UDP, поиск ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

34-42 Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ hip ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ возвращаСтся сразу послС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ICMP. Π­Ρ‚ΠΎ IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹, Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅ΠΉ ICMP-ΠΎΡˆΠΈΠ±ΠΊΡƒ. ΠœΡ‹ убСТдаСмся, Ρ‡Ρ‚ΠΎ эта IP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ° являСтся UDP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠΎΠΉ, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ Π½ΠΎΠΌΠ΅Ρ€ UDP-ΠΏΠΎΡ€Ρ‚Π° ΠΈΠ· UDP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ Π·Π° IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ.

43-55 ΠŸΠΎ всСм структурам client осущСствляСтся поиск подходящСго сСмСйства адрСсов ΠΈ ΠΏΠΎΡ€Ρ‚Π°. Если соотвСтствиС Π½Π°ΠΉΠ΄Π΅Π½ΠΎ, строится структура адрСса сокСта IPv4, которая содСрТит IP-адрСс получатСля ΠΈ ΠΏΠΎΡ€Ρ‚ ΠΈΠ· UDP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹, Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅ΠΉ ΠΎΡˆΠΈΠ±ΠΊΡƒ.

ΠŸΠΎΡΡ‚Ρ€ΠΎΠ΅Π½ΠΈΠ΅ структуры icmpd_err

56-70 Π‘троится структура icmpd_err, посылаСмая ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Ρ‡Π΅Ρ€Π΅Π· Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix. Π’ΠΈΠΏ ΠΈ ΠΊΠΎΠ΄ сообщСния ICMP сначала ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ errno, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² Ρ‚Π°Π±Π». 28.1.

Ошибки ICMPv6 ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ readable_v6, пСрвая Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 28.31. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок ICMPv6 Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° ΠΊΠΎΠ΄Ρƒ, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌΡƒ Π² листингах 28.7 ΠΈ 28.16.

Листинг 28.31. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ ICMPv6, пСрвая Ρ‡Π°ΡΡ‚ΡŒ

//icmpd/readable_v6.c

 1 #include "icmpd.h"

 2 #include <netinet/in_systm.h>

 3 #include <netinet/ip.h>

 4 #include <netinet/ip_icmp.h>

 5 #include <netinet/udp.h>


 6 #ifdef IPV6

 7 #include <netinet/ip6.h>

 8 #include <netinet/icmp6.h>

 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 &&