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

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

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

10  char *buf, *ptr;


11  buf = Malloc(sizeof(struct udpiphdr) + 100);

12  ptr = buf + sizeof(struct udpiphdr); /* мСсто для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² IP ΠΈ UDP */


13  *((uint16_t*)ptr) = htons(1234); /* ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ */

14  ptr += 2;

15  *((uint16_t*)ptr) = htons(0x0100); /* Ρ„Π»Π°Π³ΠΈ */

16  ptr += 2;

17  *((uint16_t*)ptr) = htons(1); /* количСство запросов */

18  ptr += 2;

19  *((uint16_t*)ptr) = 0; /* количСство записСй Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅ */

20  ptr += 2;

21  *((uint16_t*)ptr) = 0; /* количСство Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Ρ‹Ρ… записСй */

22  ptr += 2;

23  *((uint16_t*)ptr) = 0; /* количСство Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… записСй */

24  ptr += 2;


25  memcpy(ptr, "\001a\014root-servers\003net\000", 20);

26  ptr += 20;

27  *((uint16_t*)ptr) = htons(1); /* Ρ‚ΠΈΠΏ запроса = А */

28  ptr += 2;

29  *((uint16_t*)ptr) = htons(1); /* класс запроса = 1 (IP-адрСс) */

30  ptr += 2;


31  nbytes = (ptr - buf) - sizeof(struct udpiphdr);

32  udp_write(buf, mbytes),

33  if (verbose)

35  printf("sent: %d bytes of data\n", nbytes);

36 }

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ указатСля Π½Π° Π±ΡƒΡ„Π΅Ρ€

11-12 Π’ Π±ΡƒΡ„Π΅Ρ€Π΅ buf имССтся мСсто для 20-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP, 8-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° UDP ΠΈ Π΅Ρ‰Π΅ 100 Π±Π°ΠΉΡ‚ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…. Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ptr установлСн Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π±Π°ΠΉΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ….

Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ запроса DNS

13-24 Π”ля понимания Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ устройства Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP трСбуСтся ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° сообщСния DNS. Π­Ρ‚Ρƒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 14.3 [111]. ΠœΡ‹ присваиваСм полю ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 1234, сбрасываСм Ρ„Π»Π°Π³ΠΈ, Π·Π°Π΄Π°Π΅ΠΌ количСство запросов β€” 1, Π° Π·Π°Ρ‚Π΅ΠΌ обнуляСм количСство записСй рСсурсов (RR, resource records), ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΡ‹Ρ… Π² ΠΎΡ‚Π²Π΅Ρ‚, количСство RR, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΡ… полномочия, ΠΈ количСство Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… RR.

25-30 Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ простой запрос, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ располагаСтся послС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°: запрос Ρ‚ΠΈΠΏΠ° А IP-адрСса ΡƒΠ·Π»Π° a.root-servers.net. Π­Ρ‚ΠΎ Π΄ΠΎΠΌΠ΅Π½Π½ΠΎΠ΅ имя Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ 20 Π±Π°ΠΉΡ‚ ΠΈ состоит ΠΈΠ· 4 Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠ²: однобайтовая Ρ‡Π°ΡΡ‚ΡŒ a, 12-байтовая Ρ‡Π°ΡΡ‚ΡŒ root-servers, 3-байтовая Ρ‡Π°ΡΡ‚ΡŒ net ΠΈ корнСвая Ρ‡Π°ΡΡ‚ΡŒ, Π΄Π»ΠΈΠ½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ 0 Π±Π°ΠΉΡ‚. Π’ΠΈΠΏ запроса 1 (Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ запрос Ρ‚ΠΈΠΏΠ° А), ΠΈ класс запроса Ρ‚Π°ΠΊΠΆΠ΅ 1.

Π—Π°ΠΏΠΈΡΡŒ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP

31-32 Π­Ρ‚ΠΎ сообщСниС состоит ΠΈΠ· 36 Π±Π°ΠΉΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… (восСмь 2-Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ ΠΈ 20-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ΅ Π΄ΠΎΠΌΠ΅Π½Π½ΠΎΠ΅ имя). ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Π½Π°ΡˆΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ udp_write для формирования Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² UDP ΠΈ IP ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ записи Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP Π² наш ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт.

Π’ листингС 29.9 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция open_output, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π°Ρ с ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌΠΈ сокСтами.

Листинг 29.9. Ѐункция open_output: ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° символьного сокСта

 2 int rawfd; /* ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт */


 3 void

 4 open_output(void)

 5 {

 6  int on=1;

 7  /*

 8   * Для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ IP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ Π½ΡƒΠΆΠ΅Π½ ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт

 9   * Для Π΅Π³ΠΎ создания Π½ΡƒΠΆΠ½Ρ‹ ΠΏΡ€Π°Π²Π° ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

10   * ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ сокСта IP_HDRINCL.

11   */

12  rawfd = Socket(dest->sa_family, SOCK_RAW, 0);


13  Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on., sizeof(on));

14 }

ОбъявлСниС дСскриптора символьного сокСта

2 ΠœΡ‹ объявляСм Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ дСскриптор символьного сокСта.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сокСта ΠΈ установка IP_HDRINCL

7-13 ΠœΡ‹ создаСм ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ сокСта IP_HDRINCL. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ IP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ IP.

Π’ листингС 29.10 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° наша функция udp_write, которая Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ IP ΠΈ UDP, Π° Π·Π°Ρ‚Π΅ΠΌ записываСт Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡƒ Π² ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт.

Листинг 29.10. Ѐункция udp_write: Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² UDP ΠΈ IP ΠΈ запись Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ IP Π² ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт

//udpcksum/udpwrite.c

19 void

20 udp_write(char *buf, int userlen)

21 {

22  struct udpiphdr *ui;

23  struct ip *ip;


24  /* Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΈ вычислСниС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы */

25  ip = (struct ip*)buf;

26  ui = (struct udpiphdr*)buf;

27  bzero(ui, sizeof(*ui));

28  /* добавляСм 8 ΠΊ Π΄Π»ΠΈΠ½Π΅ псСвдозаголовка */

29  ui->ui_len = htons((uint16_t)(sizeof(struct udphdr) + userlen));

30  /* Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ 28 ΠΊ Π΄Π»ΠΈΠ½Π΅ IP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ */

31  userlen += sizeof(struct udpiphdr);


32  ui->ui_pr = IPPROTO_UDP;

33  ui->ui_src.s_addr = ((struct sockaddr_in*)local)->sin_addr.s_addr;

34  ui->ui_dst.s_addr = ((struct sockaddr_in*)dest)->sin_addr.s_addr;

35  ui->ui_sport = ((struct sockaddr_in*)local)->sin_port;

36  ui->ui_dport = ((struct sockaddr_in*)dest)->sin_port;

37  ui->ui_ulen = ui->ui_len;

38  if (zerosum == 0) {

39 #if 1 /* Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π° if 0 для Solaris 2.x. x < 6 */

40   if ((ui->ui_sum = m_cksum((u_int16_t*)in, userlen)) == 0)

41   ui->ui_sum = 0xffff;

42 #else

43   ui->ui_sum = ui->ui_len;

44 #endif

45  }


46  /* Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΡΡ‚Π°Π²ΡˆΠ΅ΠΉΡΡ части IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° */

47  /* функция p_output() вычисляСт ΠΈ сохраняСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΡƒΡŽ сумму IP */

48  ip->ip_v = IPVERSION;

49  ip->ip_hl = sizeof(struct ip) >> 2;

50  ip->ip_tos = 0;

51 #if defined(linux) || defined(__OpenBSD__)

52  ip->ip_len = htons(userlen); /* сСтСвой порядок Π±Π°ΠΉΡ‚ΠΎΠ² */

53 #else

54  ip->ip_len = userlen; /* порядок Π±Π°ΠΉΡ‚ΠΎΠ² ΡƒΠ·Π»Π° */

55 #endif

56  ip->ip_id = 0; /* это ΠΏΡƒΡΡ‚ΡŒ устанавливаСт ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ IP */

57  ip->ip_off = 0; /* смСщСниС Ρ„Π»Π°Π³ΠΎΠ², Ρ„Π»Π°Π³ΠΈ MF ΠΈ DF */

58  ip->ip_ttl = TTL_OUT;

59  Sendto(rawfd, buf, userlen, 0, dest, destlen);

60 }

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²

24-26 Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ip ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π½Π°Ρ‡Π°Π»ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP (структуру ip), Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ui ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Ρ‚ΠΎ ΠΆΠ΅ мСсто, Π½ΠΎ структура udpiphdr являСтся объСдинСниСм Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² IP ΠΈ UDP.

ΠžΠ±Π½ΡƒΠ»Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°

27 ΠœΡ‹ явным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ записываСм Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π½ΡƒΠ»ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΡƒΡ‡Π΅Ρ‚ случайного мусора, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠ³ ΠΎΡΡ‚Π°Ρ‚ΡŒΡΡ Π² Π±ΡƒΡ„Π΅Ρ€Π΅, ΠΏΡ€ΠΈ вычислСнии ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы.

ОбновлСниС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π΄Π»ΠΈΠ½Ρ‹

28-31 ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ ui_len β€” это Π΄Π»ΠΈΠ½Π° Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP: количСство Π±Π°ΠΉΡ‚ΠΎΠ² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… плюс Ρ€Π°Π·ΠΌΠ΅Ρ€ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° UDP (8 Π±Π°ΠΉΡ‚). ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ userlen (количСство Π±Π°ΠΉΡ‚ΠΎΠ² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ Π·Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ UDP) увСличиваСтся Π½Π° 28 (20 Π±Π°ΠΉΡ‚ Π½Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ IP ΠΈ 8 Π±Π°ΠΉΡ‚ Π½Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ UDP), для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ настоящСму Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ IP.

Π—Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° UDP ΠΈ вычислСниС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы UDP

32-45 ΠŸΡ€ΠΈ вычислСнии ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы UDP учитываСтся Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ Π΄Π°Π½Π½Ρ‹Π΅ UDP, Π½ΠΎ ΠΈ поля Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP. Π­Ρ‚ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP ΠΎΠ±Ρ€Π°Π·ΡƒΡŽΡ‚ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ называСтся псСвдозаголовком (pseudoheader). Π’ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ псСвдозаголовка обСспСчиваСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ссли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы Π²Π΅Ρ€Π½ΠΎ, Ρ‚ΠΎ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ° Π±Ρ‹Π»Π° доставлСна Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΡƒΠ·Π΅Π» ΠΈ с ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°. Π’ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… строках Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ»Π΅ΠΉ Π² IP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… псСвдозаголовок. Π”Π°Π½Π½Ρ‹ΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° нСсколько Π·Π°ΠΏΡƒΡ‚Π°Π½, Π½ΠΎ Π΅Π³ΠΎ объяснСниС приводится Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 23.6 [128]. ΠšΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ являСтся запись ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы UDP Π² ΠΏΠΎΠ»Π΅ ui_sum, Ссли Π½Π΅ установлСн Ρ„Π»Π°Π³ zerosum (Ρ‡Ρ‚ΠΎ соотвСтствуСт Π½Π°Π»ΠΈΡ‡ΠΈΡŽ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки -0).

Если ΠΏΡ€ΠΈ вычислСнии ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы получаСтся 0, вмСсто Π½Π΅Π³ΠΎ записываСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0xffff. Π’ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ эти числа ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚, Π½ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» UDP устанавливаСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΡƒΡŽ сумму Π² Π½ΡƒΠ»ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° вовсС Π½Π΅ Π±Ρ‹Π»Π° вычислСна. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² листингС 28.10 ΠΌΡ‹ Π½Π΅ провСряСм, Ρ€Π°Π²Π½ΠΎ Π»ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы Π½ΡƒΠ»ΡŽ: Π΄Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π² случаС ICMPv4 Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Π΅Π΅ отсутствия.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² Solaris 2.x, Π³Π΄Π΅ x<6, Π² случаях, ΠΊΠΎΠ³Π΄Π° Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP ΠΈΠ»ΠΈ сСгмСнты TCP ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ΡΡ с символьного сокСта ΠΏΡ€ΠΈ установлСнном ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ IP_HDRINCL, Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ошибка. ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΡƒΡŽ сумму вычисляСт ядро, Π° ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π΅ ui_sum Ρ€Π°Π²Π½Ρ‹ΠΌ Π΄Π»ΠΈΠ½Π΅ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP.

Π—Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP

36-49 ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ установили ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ сокСта IP_HDRINCL, Π½Π°ΠΌ слСдуСт Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ΠΏΠΎΠ»Π΅ΠΉ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ IP. (Π’ Ρ€Π°Π·Π΄Π΅Π»Π΅ 28.3 обсуТдаСтся запись Π² ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ΠΏΡ€ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΠΎΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ IP_HDRINCL.) ΠœΡ‹ присваиваСм полю ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½ΡƒΠ»ΡŒ (ip_id), Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ IP Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ задания значСния этого поля. IP Ρ‚Π°ΠΊΠΆΠ΅ вычисляСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΡƒΡŽ сумму IP, Π° функция sendto записываСт Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡƒ IP.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»Π΅ ip_len ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ сСтСвой порядок Π±Π°ΠΉΡ‚ΠΎΠ², Π»ΠΈΠ±ΠΎ порядок Π±Π°ΠΉΡ‚ΠΎΠ² ΡƒΠ·Π»Π°. Π­Ρ‚ΠΎ типичная ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π°Ρ ΠΏΡ€ΠΈ использовании ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сокСтов.