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

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

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

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ функция β€” это udp_read, показанная Π² листингС 29.11. Она вызываСтся ΠΈΠ· ΠΊΠΎΠ΄Π°, прСдставлСнного Π² листингС 29.6.

Листинг 29.11. Ѐункция udp_read: Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈΠ· устройства Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²

//udpcksum/udpread.c

 7 struct udpiphdr*

 8 udp_read(void)

 9 {

10  int len;

11  char *ptr;

12  struct ether_header *eptr;


13  for (;;) {

14   ptr = next_pcap(&len);


15   switch (datalink) {

16   case DLT_NULL: /* Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ ΠΏΠ΅Ρ‚Π»ΠΈ = 4 Π±Π°ΠΉΡ‚Π° */

17    return (udp_check(ptr + 4, len β€” 4));


18   case DLT_EN10MB:

19    eptr = (struct ether_header*)ptr;

20    if (ntohs(eptr->ether_type) != ETHERTYPE_IP)

21     err_quit("Ethernet type not IP", ntohs(eptr->ether_type));

22    return (udp_check(ptr + 14, len β€” 14));


23   case DLT_SLIP: /* Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ SLIP = 24 Π±Π°ΠΉΡ‚Π° */

24    return (udp_check(ptr + 24, len β€” 24));


25   case DLT_PPP: /* Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ PPP = 24 Π±Π°ΠΉΡ‚Π° */

26    return (udp_check(ptr + 24, len β€” 24));


27   default:

28    err_quit("unsupported datalink (%d)", datalink);

29   }

30  }

31 }

14-29 ΠΠ°ΡˆΠ° функция next_pcap (см. листинг 29.12) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈΠ· устройства Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ². ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ канального уровня Ρ€Π°Π·Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ Π² зависимости ΠΎΡ‚ фактичСского Ρ‚ΠΈΠΏΠ° устройства, ΠΌΡ‹ примСняСм Π²Π΅Ρ‚Π²Π»Π΅Π½ΠΈΠ΅ Π² зависимости ΠΎΡ‚ значСния, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ pcap_datalink.

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

Π‘Π΄Π²ΠΈΠ³ΠΈ Π½Π° 4, 14 ΠΈ 24 Π±Π°ΠΉΡ‚Π° ΠΎΠ±ΡŠΡΡΠ½ΡΡŽΡ‚ΡΡ Π½Π° рис. 31.9 [128]. Π‘Π΄Π²ΠΈΠ³, Ρ€Π°Π²Π½Ρ‹ΠΉ 24 Π±Π°ΠΉΡ‚Π°ΠΌ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² SLIP ΠΈ PPP, примСняСтся Π² BSD/OS 2.1.

НСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² Π½Π°Π·Π²Π°Π½ΠΈΠΈ DLT_EN10MB Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Β«10ΠœΠ’Β», этот Ρ‚ΠΈΠΏ канального уровня ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для сСтСй Ethernet, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Ρ€Π°Π²Π½Π° 100 ΠœΠ±ΠΈΡ‚/с.

Наша функция udp_check (см. листинг 29.13) исслСдуСт ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈ провСряСт поля Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… IP ΠΈ UDP.

Π’ листингС 29.12 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция next_pcap, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈΠ· устройства Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ².

Листинг 29.12. Ѐункция next_pcap: Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚

//udpcksum/pcap.c

38 char*

39 next_pcap(int *len)

40 {

41  char *ptr;

42  struct pcap_pkthdr hdr;


43  /* ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ, ΠΏΠΎΠΊΠ° ΠΏΠ°ΠΊΠ΅Ρ‚ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ² */

44  while ((ptr = (char*)pcap_next(pd, &hdr)) == NULL);


45  *len = hdr.caplen; /* Π΄Π»ΠΈΠ½Π° Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π° */

46  return (ptr);

47 }

43-44 ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pcap_next, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΡƒΡŽ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚. Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ являСтся Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Π΄Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° структуру pcap_pkthdr, которая Ρ‚ΠΎΠΆΠ΅ возвращаСтся Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΠΎΠΉ:

struct pcap_pkthdr {

 struct timeval ts;     /* врСмСнная ΠΌΠ΅Ρ‚ΠΊΠ° */

 bpf_u_int32    caplen; /* Π΄Π»ΠΈΠ½Π° Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° */

 bpf_u_int32    len;    /* полная Π΄Π»ΠΈΠ½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°, находящСгося Π² ΠΊΠ°Π½Π°Π»Π΅ */

};

ВрСмСнная ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° относится ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ, ΠΊΠΎΠ³Π΄Π° ΠΏΠ°ΠΊΠ΅Ρ‚ Π±Ρ‹Π» считан устройством Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ фактичСской ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° процСссу, которая ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ caplen содСрТит Π΄Π»ΠΈΠ½Ρƒ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… (вспомним, Ρ‡Ρ‚ΠΎ Π² листингС 29.2 нашСй ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ shaplen Π±Ρ‹Π»ΠΎ присвоСно Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 200 ΠΈ ΠΎΠ½Π° являлась Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pcap_open_live Π² листингС 29.5). НазначСниС устройства Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² состоит Π² Π·Π°Ρ…Π²Π°Ρ‚Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ², Π° Π½Π΅ всСго содСрТимого ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π°. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ len β€” это полная Π΄Π»ΠΈΠ½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°, находящСгося Π² ΠΊΠ°Π½Π°Π»Π΅. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ caplen Π±ΡƒΠ΄Π΅Ρ‚ всСгда мСньшС ΠΈΠ»ΠΈ Ρ€Π°Π²Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ len.

45-46 ΠŸΠ΅Ρ€Π΅Ρ…вачСнная Ρ‡Π°ΡΡ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚Π° возвращаСтся Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ (Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ), ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ являСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚. Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ фактичСски Π½Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ канального уровня, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ прСдставляСт собой 14-Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Ethernet Π² случаС ΠΊΠ°Π΄Ρ€Π° Ethernet ΠΈΠ»ΠΈ 4-Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΉ ΠΏΡΠ΅Π²Π΄ΠΎΠΊΠ°Π½Π°Π»ΡŒΠ½Ρ‹ΠΉ (pseudo-link) Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π² случаС Π·Π°ΠΊΠΎΠ»ΡŒΡ†ΠΎΠ²ΠΊΠΈ Π½Π° сСбя.

Если ΠΌΡ‹ посмотрим Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pcap_next, ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ функциями сущСствуСт Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Β«Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚Ρ€ΡƒΠ΄Π°Β», схСматичСски ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π½ΠΎΠ΅ Π½Π° рис. 29.5. НашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pcap_, срСди ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΅ΡΡ‚ΡŒ ΠΊΠ°ΠΊ зависящиС, Ρ‚Π°ΠΊ ΠΈ Π½Π΅ зависящиС ΠΎΡ‚ устройства Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ². НапримСр, ΠΌΡ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ рСализация BPF Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ read, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ рСализация DLPI Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ getmsg, Π° рСализация Linux Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ recvfrom.

Рис. 29.5. ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для чтСния ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²

Наша функция udp_check провСряСт Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ поля Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… IP ΠΈ UDP. Она ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 29.13. Π­Ρ‚Ρƒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΎΡ‚ устройства Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ IP Π½Π΅ Π·Π°ΠΌΠ΅Ρ‡Π°Π΅Ρ‚ этого ΠΏΠ°ΠΊΠ΅Ρ‚Π°. Для символьного сокСта это Π½Π΅ Ρ‚Π°ΠΊ.

44-61 Π”Π»ΠΈΠ½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π° Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ хотя Π±Ρ‹ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ IP ΠΈ UDP. ВСрсия IP провСряСтся вмСстС с Π΄Π»ΠΈΠ½ΠΎΠΉ ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммой Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP. Если ΠΏΠΎΠ»Π΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡƒ UDP, функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½Π΅Π½Π½Ρ‹ΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ IP/UDP. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pcap_setfilter Π² листингС 29.5, Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

Листинг 29.13. Ѐункция udp_check: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎΠ»Π΅ΠΉ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… IP ΠΈ UDP

//udpcksum/udpread.c

38 struct udpiphdr*

39 udp_check(char *ptr, int len)

40 {

41  int hlen;

42  struct ip *ip;

43  struct udpiphdr *ui;


44  if (len < sizeof(struct ip) + sizeof(struct udphdr))

45   err_quit("len = %d", len);


46  /* минимальная ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° IP */

47  ip = (struct ip*)ptr;

48  if (ip->ip_v != IPVERSION)

49   err_quit("ip_v = %d", ip->ip_v);

50  hlen = ip->ip_hl << 2;

51  if (hlen < sizeof(struct ip))

52   err_quit("ip_hl = %d", ip->ip_hl);

53  if (len < hlen + sizeof(struct udphdr))

54   err_quit("len = %d, hlen = %d", len, hlen);


55  if ((ip->ip_sum = in_cksum((u_short )ip, hlen)) != 0)

56   err_quit("ip checksum error");


57  if (ip->ip_p == IPPROTO_UDP) {

58   ui = (struct udpiphdr*)ip;

59   return (ui);

60  } else

61  err_quit("not a UDP packet");

62 }

Ѐункция cleanup, показанная Π² листингС 29.14, вызываСтся ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main нСпосрСдствСнно ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, Π° Ρ‚Π°ΠΊΠΆΠ΅ вызываСтся Π² качСствС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала Π² случаС, Ссли ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (см. листинг 29.4).

Листинг 29.14. Ѐункция cleanup

//udpcksum/cleanup.c

 2 void

 3 cleanup(int signo)

 4 {

 5  struct pcap_stat stat;


 6  fflush(stdout);

 7  putc('\n', stdout);


 8  if (verbose) {

 9   if (pcap_stats(pd, &stat) < 0)

10    err_quit("pcap_stats: %s\n", pcap_geterr(pd));

11   printf("%d packets received by filter\n", stat.ps_recv);

12   printf("%d packets dropped by kernel\n", stat.ps_drop);

13  }

14  exit(0);

15 }

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ статистики ΠΏΠΎ Π·Π°Ρ…Π²Π°Ρ‚Ρƒ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²

8-13 Π€ΡƒΠ½ΠΊΡ†ΠΈΡ pcap_stats ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ статистику Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²: ΠΎΠ±Ρ‰Π΅Π΅ количСство ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² ΠΈ количСство ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ядру.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€

Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ запустим Π½Π°ΡˆΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки -0 ΠΈ убСдимся, Ρ‡Ρ‚ΠΎ сСрвСр ΠΈΠΌΠ΅Π½ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π½Π° приходящиС Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹, Π½Π΅ содСрТащиС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммы. ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π°Π΅ΠΌ Ρ„Π»Π°Π³ -v.

macosx # udpcksum -i en1 -0 -v bridget.rudoff.com domain

device = en1

local net = 172.24.37.64. netmask = 255.255.255.224

cmd = udp and src host 206.168.112.96 and src port 53

datalink = 1

sent: 36 bytes of data

UDP checksums on

received UDP checksum = 9d15


3 packets received by filter

0 packets dropped by kernel

Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ запускаСм Π½Π°ΡˆΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΎΠ±Ρ€Π°Ρ‰Π°ΡΡΡŒ ΠΊ Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ сСрвСру ΠΈΠΌΠ΅Π½, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ подсчСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сумм. Π§Π΅ΠΌ дальшС, Ρ‚Π΅ΠΌ слоТнСС становится Π½Π°ΠΉΡ‚ΠΈ сСрвСр ΠΈΠΌΠ΅Π½ с ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΌ подсчСтом ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сумм.

macosx # udpcksum -i en1 -v freebsd4.unpbook.com domain

device = en1

localnet = 172.24.37.64, netmask = 255.255.255.224

cmd = udp and src host 172.24.37.94 and src port 53

datalink = 1

sent: 36 bytes of data

UDP checksums off

received UDP checksum = 0


3 packets received by filter

0 packets dropped by kernel

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ libnet

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ приводятся Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ open_output ΠΈ send_dns_query, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… вмСсто ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сокСтов ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ libnet. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° libnet Π±Π΅Ρ€Π΅Ρ‚ Π½Π° сСбя Π·Π°Π±ΠΎΡ‚Ρƒ ΠΎ мноТСствС Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ, Π² частности, устраняСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌΠΎΡΡ‚ΡŒΡŽ, связанныС с вычислСниСм ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сумм ΠΈ порядком Π±Π°ΠΉΡ‚ΠΎΠ² Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ Π²Ρ‹ΡˆΠ΅. Ѐункция open output прСдставлСна Π² листингС 29.15.