--- arp.c
+++ arp.c	2012/04/27 12:29:26
@@ -236,10 +236,14 @@ int arp_claim (interface_t *iface, struc
 
 			memset (reply, 0, iface->buffer_length);
 			if ((bytes = get_packet (iface, (unsigned char *) reply,
-						 buffer,
+						 iface->buffer_length, buffer,
 						 &buflen, &bufpos)) == -1)
 				break;
 
+			/* check that we've got complete arp header */
+			if ((size_t) bytes < sizeof (*reply))
+				continue;
+
 			/* Only these types are recognised */
 			if (reply->ar_op != htons (ARPOP_REPLY))
 				continue;
@@ -249,7 +253,7 @@ int arp_claim (interface_t *iface, struc
 				continue;
 			if (reply->ar_pln != sizeof (address))
 				continue;
-			if ((unsigned) bytes < sizeof (reply) + 
+			if ((size_t) bytes < sizeof (*reply) + 
 			    2 * (4 + reply->ar_hln))
 				continue;
 
--- client.c
+++ client.c	2012/04/27 12:16:13
@@ -1016,7 +1016,7 @@ static int handle_packet (state_t *state
 
 	do {
 		if (get_packet (iface, (unsigned char *) &message,
-				state->buffer,
+				sizeof(message), state->buffer,
 				&state->buffer_len, &state->buffer_pos) == -1)
 			break;
 
--- dhcp.c
+++ dhcp.c	2012/04/27 13:17:13
@@ -180,6 +180,13 @@ ssize_t send_message (const interface_t
 			if (set_mtu (iface->name, MTU_MIN) == 0)
 				sz = MTU_MIN;
 		}
+		else if(sz > (sizeof(dhcpmessage_t) + DHCP_UDP_LEN)) {
+			/*
+			 * bigger dhcp messages are not supported,
+			 * so don't indicate more (full MTU) ...
+			 */
+			sz = sizeof(dhcpmessage_t) + DHCP_UDP_LEN;
+		}
 		sz = htons (sz);
 		memcpy (p, &sz, 2);
 		p += 2;
--- socket.c
+++ socket.c	2012/04/27 13:39:56
@@ -359,7 +359,7 @@ ssize_t send_packet (const interface_t *
 /* BPF requires that we read the entire buffer.
  * So we pass the buffer in the API so we can loop on >1 dhcp packet. */
 ssize_t get_packet (const interface_t *iface, unsigned char *data,
-		    unsigned char *buffer,
+		    size_t data_len, unsigned char *buffer,
 		    size_t *buffer_len, size_t *buffer_pos)
 {
 	union
@@ -407,6 +407,8 @@ ssize_t get_packet (const interface_t *i
 		if (hdr.hw->ether_type == htons (ETHERTYPE_ARP)) {
 			len = bpf.packet->bh_caplen - 
 				sizeof (*hdr.hw);
+			if(len > data_len)
+				break;
 			memcpy (data, payload, len);
 			have_data = true;
 		} else {
@@ -420,6 +422,8 @@ ssize_t get_packet (const interface_t *i
 				len = ntohs (pay.packet->ip.ip_len) -
 					sizeof (pay.packet->ip) -
 					sizeof (pay.packet->udp);
+				if(len > data_len)
+					break;
 				memcpy (data, &pay.packet->dhcp, len);
 				have_data = true;
 			}
@@ -596,7 +600,7 @@ ssize_t send_packet (const interface_t *
 /* Linux has no need for the buffer as we can read as much as we want.
  * We only have the buffer listed to keep the same API. */
 ssize_t get_packet (const interface_t *iface, unsigned char *data,
-		    unsigned char *buffer,
+		    size_t data_len, unsigned char *buffer,
 		    size_t *buffer_len, size_t *buffer_pos)
 {
 	ssize_t bytes;
@@ -641,9 +645,18 @@ ssize_t get_packet (const interface_t *i
 		}
 	}
 
+#if 0
+	logger (LOG_DEBUG, "received packet of %zd bytes", bytes);
+#endif
+
 	*buffer_len = bytes;
 	/* If it's an ARP reply, then just send it back */
 	if (iface->socket_protocol == ETHERTYPE_ARP) {
+		if((size_t)bytes > data_len) {
+			logger (LOG_DEBUG, "packet too long (%zd), ignoring",
+					   bytes);
+			return (-1);
+		}
 		memcpy (data, buffer, bytes);
 		return (bytes);
 	}
@@ -666,6 +679,18 @@ ssize_t get_packet (const interface_t *i
 
 	bytes = ntohs (pay.packet->ip.ip_len) -
 		(sizeof (pay.packet->ip) + sizeof (pay.packet->udp));
+
+	if((size_t)bytes > data_len) {
+		logger (LOG_DEBUG, "dhcp message too long for us (%zd bytes), ignoring",
+					bytes);
+		return (-1);
+	}
+#if 0
+      	else {
+		logger (LOG_DEBUG, "received dhcp message (%zd bytes)",
+			bytes);
+	}
+#endif
 	memcpy (data, &pay.packet->dhcp, bytes);
 	return (bytes);
 }
--- socket.h
+++ socket.h	2012/04/27 13:37:06
@@ -41,6 +41,6 @@ void make_dhcp_packet(struct udp_dhcp_pa
 int open_socket (interface_t *iface, int protocol);
 ssize_t send_packet (const interface_t *iface, int type,
 		     const unsigned char *data, size_t len);
-ssize_t get_packet (const interface_t *iface, unsigned char *data,
+ssize_t get_packet (const interface_t *iface, unsigned char *data, size_t data_len,
 		    unsigned char *buffer, size_t *buffer_len, size_t *buffer_pos);
 #endif
