*** From dhcp-server -- To unsubscribe, see the end of this message. ***

I don't actually see anything bad about the packet that's being sent
to the client, but it's possible that the checksum is screwed up.   I
will be releasing a new patchlevel that fixes the UDP checksum bug
shortly, but since you're losing right now, here's a patch that should
bring you up to the latest version of packet.c, with the correct UDP
checksum.

                               _MelloN_

Index: packet.c
===================================================================
RCS file: /proj/src/isc/cvs-1/DHCP/common/packet.c,v
retrieving revision 1.18.2.2
retrieving revision 1.18.2.4
diff -c -r1.18.2.2 -r1.18.2.4
*** packet.c    1999/03/26 16:52:39     1.18.2.2
--- packet.c    1999/04/24 15:31:47     1.18.2.4
***************
*** 42,48 ****
  
  #ifndef lint
  static char copyright[] =
! "$Id: packet.c,v 1.18.2.2 1999/03/26 16:52:39 mellon Exp $ Copyright (c) 1996 The 
Internet Software Consortium.  All rights reserved.\n";
  #endif /* not lint */
  
  #include "dhcpd.h"
--- 42,48 ----
  
  #ifndef lint
  static char copyright[] =
! "$Id: packet.c,v 1.18.2.4 1999/04/24 15:31:47 mellon Exp $ Copyright (c) 1996 The 
Internet Software Consortium.  All rights reserved.\n";
  #endif /* not lint */
  
  #include "dhcpd.h"
***************
*** 72,77 ****
--- 72,80 ----
                debug ("sum = %x", sum);
  #endif
                sum += (u_int16_t) ntohs(*((u_int16_t *)(buf + i)));
+               /* Add carry. */
+               if (sum > 0xFFFF)
+                       sum -= 0xFFFF;
        }       
  
        /* If there's a single byte left over, checksum it, too.   Network
***************
*** 81,93 ****
                debug ("sum = %x", sum);
  #endif
                sum += buf [i] << 8;
        }
        
        return sum;
  }
  
! /* Fold the upper sixteen bits of the checksum down into the lower bits,
!    complement the sum, and then put it into network byte order. */
  
  u_int32_t wrapsum (sum)
        u_int32_t sum;
--- 84,98 ----
                debug ("sum = %x", sum);
  #endif
                sum += buf [i] << 8;
+               /* Add carry. */
+               if (sum > 0xFFFF)
+                       sum -= 0xFFFF;
        }
        
        return sum;
  }
  
! /* Finish computing the sum, and then put it into network byte order. */
  
  u_int32_t wrapsum (sum)
        u_int32_t sum;
***************
*** 96,113 ****
        debug ("wrapsum (%x)", sum);
  #endif
  
!       while (sum > 0x10000) {
!               sum = (sum >> 16) + (sum & 0xFFFF);
  #ifdef DEBUG_CHECKSUM_VERBOSE
-               debug ("sum = %x", sum);
- #endif
-               sum += (sum >> 16);
- #ifdef DEBUG_CHECKSUM_VERBOSE
-               debug ("sum = %x", sum);
- #endif
-       }
-       sum = sum ^ 0xFFFF;
- #ifdef DEBUG_CHECKSUM_VERBOSE
        debug ("sum = %x", sum);
  #endif
        
--- 101,108 ----
        debug ("wrapsum (%x)", sum);
  #endif
  
!       sum = ~sum & 0xFFFF;
  #ifdef DEBUG_CHECKSUM_VERBOSE
        debug ("sum = %x", sum);
  #endif
        
***************
*** 237,256 ****
  
  /* UDP header and IP header decoded together for convenience. */
  
! ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len)
        struct interface_info *interface;
        unsigned char *buf;
        int bufix;
        struct sockaddr_in *from;
        unsigned char *data;
!       int len;
  {
    struct ip *ip;
    struct udphdr *udp;
    u_int32_t ip_len = (buf [bufix] & 0xf) << 2;
    u_int32_t sum, usum;
!   static int packets_seen;
!   static int packets_bad_checksum;
  
    ip = (struct ip *)(buf + bufix);
    udp = (struct udphdr *)(buf + bufix + ip_len);
--- 232,256 ----
  
  /* UDP header and IP header decoded together for convenience. */
  
! 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 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);
***************
*** 266,279 ****
  #endif /* USERLAND_FILTER */
  
    /* Check the IP header checksum - it should be zero. */
    if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
!         if (packets_seen &&
!             (++packets_seen / ++packets_bad_checksum) < 2)
!                 note ("Bad IP checksum: %x",
!                       wrapsum (checksum (buf + bufix, sizeof *ip, 0)));
          return -1;
    }
  
    /* Copy out the IP source address... */
    memcpy (&from -> sin_addr, &ip -> ip_src, 4);
  
--- 266,288 ----
  #endif /* USERLAND_FILTER */
  
    /* Check the IP header checksum - it should be zero. */
+   ++ip_packets_seen;
    if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
!         ++ip_packets_bad_checksum;
!         if (ip_packets_seen > 4 &&
!             (ip_packets_seen / ip_packets_bad_checksum) < 2) {
!                 note ("%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)
+         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);
  
***************
*** 283,289 ****
  
    if (!data) {
          data = buf + bufix + ip_len + sizeof *udp;
!         len -= ip_len + sizeof *udp;
    }
  
    usum = udp -> uh_sum;
--- 292,314 ----
  
    if (!data) {
          data = buf + bufix + ip_len + sizeof *udp;
!         len = ntohs (udp -> uh_ulen) - sizeof *udp;
!         ++udp_packets_length_checked;
!         if (len + data > buf + bufix + buflen) {
!                 ++udp_packets_length_overflow;
!                 if (udp_packets_length_checked > 4 &&
!                     (udp_packets_length_checked /
!                      udp_packets_length_overflow) < 2) {
!                         note ("%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 + bufix + buflen)
!                 debug ("accepting packet with data after udp payload.");
    }
  
    usum = udp -> uh_sum;
***************
*** 298,309 ****
                                               (u_int32_t)
                                               ntohs (udp -> uh_ulen)))));
  
    if (usum && usum != sum) {
!         static int packets_seen;
!         static int packets_bad_checksum;
!         if (packets_seen &&
!             (++packets_seen / ++packets_bad_checksum) < 2)
!                 note ("Bad udp checksum: %x %x", usum, sum);
          return -1;
    }
  
--- 323,337 ----
                                               (u_int32_t)
                                               ntohs (udp -> uh_ulen)))));
  
+   udp_packets_seen++;
    if (usum && usum != sum) {
!         udp_packets_bad_checksum++;
!         if (udp_packets_seen > 4 &&
!             (udp_packets_seen / udp_packets_bad_checksum) < 2) {
!                 note ("%d bad udp checksums in %d packets",
!                       udp_packets_bad_checksum, udp_packets_seen);
!                 udp_packets_seen = udp_packets_bad_checksum = 0;
!         }
          return -1;
    }
  


------------------------------------------------------------------------------
To unsubscribe from this list, please visit http://www.fugue.com/dhcp/lists
If you are without web access, or if you are having trouble with the web page,
please send mail to [EMAIL PROTECTED]   Please try to use the web
page first - it will take a long time for your request to be processed by hand.

Archives for this mailing list are available at 
http://www.webnology.com/list-archives/dhcp/dhcp-server

------------------------------------------------------------------------------

Reply via email to