44cfed0
diff --git a/common/packet.c b/common/packet.c
44cfed0
index b530432..e600e37 100644
44cfed0
--- a/common/packet.c
44cfed0
+++ b/common/packet.c
44cfed0
@@ -220,7 +220,28 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
44cfed0
 	}
44cfed0
 }
44cfed0
 
44cfed0
-/* UDP header and IP header decoded together for convenience. */
44cfed0
+/*!
44cfed0
+ *
44cfed0
+ * \brief UDP header and IP header decoded together for convenience.
44cfed0
+ *
44cfed0
+ * Attempt to decode the UDP and IP headers and, if necessary, checksum
44cfed0
+ * the packet.
44cfed0
+ *
44cfed0
+ * \param inteface - the interface on which the packet was recevied
44cfed0
+ * \param buf - a pointer to the buffer for the received packet
44cfed0
+ * \param bufix - where to start processing the buffer, previous
44cfed0
+ *                routines may have processed parts of the buffer already
44cfed0
+ * \param from - space to return the address of the packet sender
44cfed0
+ * \param buflen - remaining length of the buffer, this will have been
44cfed0
+ *                 decremented by bufix by the caller
44cfed0
+ * \param rbuflen - space to return the length of the payload from the udp
44cfed0
+ *                  header
44cfed0
+ * \param csum_ready - indication if the checksum is valid for use
44cfed0
+ *                     non-zero indicates the checksum should be validated
44cfed0
+ *
44cfed0
+ * \return - the index to the first byte of the udp payload (that is the
44cfed0
+ *           start of the DHCP packet
44cfed0
+ */
44cfed0
 
44cfed0
 ssize_t
44cfed0
 decode_udp_ip_header(struct interface_info *interface,
44cfed0
@@ -231,7 +252,7 @@ decode_udp_ip_header(struct interface_info *interface,
44cfed0
   unsigned char *data;
44cfed0
   struct ip ip;
44cfed0
   struct udphdr udp;
44cfed0
-  unsigned char *upp, *endbuf;
44cfed0
+  unsigned char *upp;
44cfed0
   u_int32_t ip_len, ulen, pkt_len;
44cfed0
   static unsigned int ip_packets_seen = 0;
44cfed0
   static unsigned int ip_packets_bad_checksum = 0;
44cfed0
@@ -241,11 +262,8 @@ decode_udp_ip_header(struct interface_info *interface,
44cfed0
   static unsigned int udp_packets_length_overflow = 0;
44cfed0
   unsigned len;
44cfed0
 
44cfed0
-  /* Designate the end of the input buffer for bounds checks. */
44cfed0
-  endbuf = buf + bufix + buflen;
44cfed0
-
44cfed0
   /* Assure there is at least an IP header there. */
44cfed0
-  if ((buf + bufix + sizeof(ip)) > endbuf)
44cfed0
+  if (sizeof(ip) > buflen)
44cfed0
 	  return -1;
44cfed0
 
44cfed0
   /* Copy the IP header into a stack aligned structure for inspection.
44cfed0
@@ -257,13 +275,17 @@ decode_udp_ip_header(struct interface_info *interface,
44cfed0
   ip_len = (*upp & 0x0f) << 2;
44cfed0
   upp += ip_len;
44cfed0
 
44cfed0
-  /* Check the IP packet length. */
44cfed0
+  /* Check packet lengths are within the buffer:
44cfed0
+   * first the ip header (ip_len)
44cfed0
+   * then the packet length from the ip header (pkt_len)
44cfed0
+   * then the udp header (ip_len + sizeof(udp)
44cfed0
+   * We are liberal in what we accept, the udp payload should fit within
44cfed0
+   * pkt_len, but we only check against the full buffer size.
44cfed0
+   */
44cfed0
   pkt_len = ntohs(ip.ip_len);
44cfed0
-  if (pkt_len > buflen)
44cfed0
-	return -1;
44cfed0
-
44cfed0
-  /* Assure after ip_len bytes that there is enough room for a UDP header. */
44cfed0
-  if ((upp + sizeof(udp)) > endbuf)
44cfed0
+  if ((ip_len > buflen) ||
44cfed0
+      (pkt_len > buflen) ||
44cfed0
+      ((ip_len + sizeof(udp)) > buflen))
44cfed0
 	  return -1;
44cfed0
 
44cfed0
   /* Copy the UDP header into a stack aligned structure for inspection. */
44cfed0
@@ -284,7 +306,8 @@ decode_udp_ip_header(struct interface_info *interface,
44cfed0
 	return -1;
44cfed0
 
44cfed0
   udp_packets_length_checked++;
44cfed0
-  if ((upp + ulen) > endbuf) {
44cfed0
+  /* verify that the payload length from the udp packet fits in the buffer */
44cfed0
+  if ((ip_len + ulen) > buflen) {
44cfed0
 	udp_packets_length_overflow++;
44cfed0
 	if (((udp_packets_length_checked > 4) &&
44cfed0
 	     (udp_packets_length_overflow != 0)) &&