udpread.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include "udpcksum.h"
  2. struct udpiphdr *udp_check(char *, int);
  3. /*
  4. * Read from the network until a UDP datagram is read that matches
  5. * the arguments.
  6. */
  7. /* include udp_read */
  8. struct udpiphdr *
  9. udp_read(void)
  10. {
  11. int len;
  12. char *ptr;
  13. struct ether_header *eptr;
  14. for ( ; ; ) {
  15. ptr = next_pcap(&len);
  16. switch (datalink) {
  17. case DLT_NULL: /* loopback header = 4 bytes */
  18. return(udp_check(ptr+4, len-4));
  19. case DLT_EN10MB:
  20. eptr = (struct ether_header *) ptr;
  21. if (ntohs(eptr->ether_type) != ETHERTYPE_IP)
  22. err_quit("Ethernet type %x not IP", ntohs(eptr->ether_type));
  23. return(udp_check(ptr+14, len-14));
  24. case DLT_SLIP: /* SLIP header = 24 bytes */
  25. return(udp_check(ptr+24, len-24));
  26. case DLT_PPP: /* PPP header = 24 bytes */
  27. return(udp_check(ptr+24, len-24));
  28. default:
  29. err_quit("unsupported datalink (%d)", datalink);
  30. }
  31. }
  32. }
  33. /* end udp_read */
  34. /*
  35. * Check the received packet.
  36. * If UDP and OK, return pointer to packet.
  37. * If ICMP error, return NULL.
  38. * We assume the filter picks out desired UDP datagrams.
  39. */
  40. /* include udp_check */
  41. struct udpiphdr *
  42. udp_check(char *ptr, int len)
  43. {
  44. int hlen;
  45. struct ip *ip;
  46. struct udpiphdr *ui;
  47. /* *INDENT-OFF* */
  48. if (len < sizeof(struct ip) + sizeof(struct udphdr))
  49. err_quit("len = %d", len);
  50. /* *INDENT-ON* */
  51. /* 4minimal verification of IP header */
  52. ip = (struct ip *) ptr;
  53. if (ip->ip_v != IPVERSION)
  54. err_quit("ip_v = %d", ip->ip_v);
  55. hlen = ip->ip_hl << 2;
  56. /* *INDENT-OFF* */
  57. if (hlen < sizeof(struct ip))
  58. err_quit("ip_hl = %d", ip->ip_hl);
  59. if (len < hlen + sizeof(struct udphdr))
  60. err_quit("len = %d, hlen = %d", len, hlen);
  61. /* *INDENT-ON* */
  62. if ( (ip->ip_sum = in_cksum((uint16_t *) ip, hlen)) != 0)
  63. err_quit("ip checksum error");
  64. if (ip->ip_p == IPPROTO_UDP) {
  65. ui = (struct udpiphdr *) ip;
  66. return(ui);
  67. } else
  68. err_quit("not a UDP packet");
  69. }
  70. /* end udp_check */