diff --git a/common/discover.c b/common/discover.c index c306e28e..cb842020 100644 --- a/common/discover.c +++ b/common/discover.c @@ -22,7 +22,7 @@ #ifndef lint static char copyright[] = -"$Id: discover.c,v 1.15 1999/10/07 06:35:41 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: discover.c,v 1.16 1999/10/08 17:08:33 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -573,6 +573,14 @@ isc_result_t got_one (h) if (result == 0) return ISC_R_UNEXPECTED; + /* If we didn't at least get the fixed portion of the BOOTP + packet, drop the packet. We're allowing packets with no + sname or filename, because we're aware of at least one + client that sends such packets, but this definitely falls + into the category of being forgiving. */ + if (result < DHCP_FIXED_NON_UDP - DHCP_SNAME_LEN - DHCP_FILE_LEN) + return ISC_R_UNEXPECTED; + if (bootp_packet_handler) { ifrom.len = 4; memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len); diff --git a/common/options.c b/common/options.c index a89e737a..7b5a4c45 100644 --- a/common/options.c +++ b/common/options.c @@ -22,7 +22,7 @@ #ifndef lint static char copyright[] = -"$Id: options.c,v 1.47 1999/10/07 06:42:50 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; +"$Id: options.c,v 1.48 1999/10/08 17:08:34 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #define DHCP_OPTION_DATA @@ -1320,27 +1320,34 @@ void do_packet (interface, packet, len, from_port, from, hfrom) log_info ("Discarding packet with bogus hlen."); return; } - if (!parse_options (decoded_packet)) { - if (decoded_packet -> options) - option_state_dereference (&decoded_packet -> options, - "do_packet"); - packet_dereference (&decoded_packet, "do_packet"); - return; - } - if (decoded_packet -> options_valid && - (op = lookup_option (&dhcp_universe, decoded_packet -> options, - DHO_DHCP_MESSAGE_TYPE))) { - struct data_string dp; - memset (&dp, 0, sizeof dp); - evaluate_option_cache (&dp, decoded_packet, (struct lease *)0, - decoded_packet -> options, - (struct option_state *)0, op); - if (dp.len > 0) - decoded_packet -> packet_type = dp.data [0]; - else - decoded_packet -> packet_type = 0; - data_string_forget (&dp, "do_packet"); + /* If there's an option buffer, try to parse it. */ + if (decoded_packet -> packet_length >= DHCP_FIXED_NON_UDP + 4) { + if (!parse_options (decoded_packet)) { + if (decoded_packet -> options) + option_state_dereference + (&decoded_packet -> options, + "do_packet"); + packet_dereference (&decoded_packet, "do_packet"); + return; + } + + if (decoded_packet -> options_valid && + (op = lookup_option (&dhcp_universe, + decoded_packet -> options, + DHO_DHCP_MESSAGE_TYPE))) { + struct data_string dp; + memset (&dp, 0, sizeof dp); + evaluate_option_cache (&dp, decoded_packet, + (struct lease *)0, + decoded_packet -> options, + (struct option_state *)0, op); + if (dp.len > 0) + decoded_packet -> packet_type = dp.data [0]; + else + decoded_packet -> packet_type = 0; + data_string_forget (&dp, "do_packet"); + } } if (decoded_packet -> packet_type)