diff options
author | Ted Lemon <source@isc.org> | 1999-04-12 21:37:03 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 1999-04-12 21:37:03 +0000 |
commit | bd5ef11d6c57c0a6eac4a01e3e624c20856adaa7 (patch) | |
tree | c6a3726baf1b0d8dcfb815836d74dc1cf4ba13dc /common/packet.c | |
parent | 0536c3efe7956bf790cc2d316f055755b402cbe2 (diff) | |
download | isc-dhcp-bd5ef11d6c57c0a6eac4a01e3e624c20856adaa7.tar.gz |
Fix up error message printing. Base UDP checksum on UDP header length.
Diffstat (limited to 'common/packet.c')
-rw-r--r-- | common/packet.c | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/common/packet.c b/common/packet.c index 66a13712..f354100e 100644 --- a/common/packet.c +++ b/common/packet.c @@ -22,7 +22,7 @@ #ifndef lint static char copyright[] = -"$Id: packet.c,v 1.23 1999/03/26 19:19:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n"; +"$Id: packet.c,v 1.24 1999/04/12 21:37:03 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -217,18 +217,25 @@ ssize_t decode_hw_header (interface, buf, bufix, from) /* UDP header and IP header decoded together for convenience. */ -ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len) +ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, buflen) struct interface_info *interface; unsigned char *buf; int bufix; struct sockaddr_in *from; unsigned char *data; - int len; + int buflen; { struct ip *ip; struct udphdr *udp; u_int32_t ip_len = (buf [bufix] & 0xf) << 2; u_int32_t sum, usum; + static int ip_packets_seen; + static int ip_packets_bad_checksum; + static int udp_packets_seen; + static int udp_packets_bad_checksum; + static int udp_packets_length_checked; + static int udp_packets_length_overflow; + int len; ip = (struct ip *)(buf + bufix); udp = (struct udphdr *)(buf + bufix + ip_len); @@ -243,18 +250,24 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len) return -1; #endif /* USERLAND_FILTER */ + ++ip_packets_seen; /* Check the IP header checksum - it should be zero. */ if (wrapsum (checksum (buf + bufix, ip_len, 0))) { - static int packets_seen; - static int packets_bad_checksum; - - if (packets_seen && - (++packets_seen / ++packets_bad_checksum) < 2) - log_info ("Bad IP checksum: %x", - wrapsum (checksum (buf + bufix, sizeof *ip, 0))); + ++ip_packets_bad_checksum; + if (ip_packets_seen > 4 && + (++ip_packets_seen / ++ip_packets_bad_checksum) < 2) { + log_info ("%d bad IP checksums seen in %d packets", + ip_packets_bad_checksum, ip_packets_seen); + ip_packets_seen = ip_packets_bad_checksum = 0; + } return -1; } + /* Check the IP packet length. */ + if (ntohs (ip -> ip_len) != buflen) + log_debug ("ip length %d disagrees with bytes received %d.", + ntohs (ip -> ip_len), buflen); + /* Copy out the IP source address... */ memcpy (&from -> sin_addr, &ip -> ip_src, 4); @@ -264,7 +277,23 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len) if (!data) { data = buf + bufix + ip_len + sizeof *udp; - len -= ip_len + sizeof *udp; + len = ntohs (udp -> uh_ulen) - sizeof *udp; + ++udp_packets_length_checked; + if (len + data > buf + buflen) { + ++udp_packets_length_overflow; + if (udp_packets_length_checked > 4 && + (udp_packets_length_checked / + udp_packets_length_overflow) < 2) { + log_info ("%d udp packets in %d too long - dropped", + udp_packets_length_overflow, + udp_packets_length_checked); + udp_packets_length_overflow + = udp_packets_length_checked = 0; + } + return -1; + } + if (len + data != buf + buflen) + log_debug ("accepting packet with data after udp payload."); } usum = udp -> uh_sum; @@ -279,12 +308,15 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len) (u_int32_t) ntohs (udp -> uh_ulen))))); + ++udp_packets_seen; if (usum && usum != sum) { - static int packets_seen; - static int packets_bad_checksum; - if (packets_seen && - (++packets_seen / ++packets_bad_checksum) < 2) - log_info ("Bad udp checksum: %x %x", usum, sum); + ++udp_packets_bad_checksum; + if (udp_packets_seen > 4 && + (udp_packets_seen / udp_packets_bad_checksum) < 2) { + log_info ("%d bad udp checksums seen in %d packets", + udp_packets_bad_checksum, udp_packets_seen); + udp_packets_seen = udp_packets_bad_checksum = 0; + } return -1; } |