]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Fix up error message printing. Base UDP checksum on UDP header length.
authorTed Lemon <source@isc.org>
Mon, 12 Apr 1999 21:37:03 +0000 (21:37 +0000)
committerTed Lemon <source@isc.org>
Mon, 12 Apr 1999 21:37:03 +0000 (21:37 +0000)
common/packet.c

index 66a13712107da029ef5ebd1f6396b56b5f9e0bba..f354100ecc6e6ad3cf3897ea8856115a6cec7710 100644 (file)
@@ -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;
   }