summaryrefslogtreecommitdiff
path: root/common/packet.c
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>1999-04-12 21:37:03 +0000
committerTed Lemon <source@isc.org>1999-04-12 21:37:03 +0000
commitbd5ef11d6c57c0a6eac4a01e3e624c20856adaa7 (patch)
treec6a3726baf1b0d8dcfb815836d74dc1cf4ba13dc /common/packet.c
parent0536c3efe7956bf790cc2d316f055755b402cbe2 (diff)
downloadisc-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.c64
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;
}