net: parse DHCP options from overloaded file/sname fields

If Option 52 in the vendor option field signals overloading
of the file and/or sname fields, these field may contain
additional options. Formatting of file/sname contained options
is the same as in the vendor options field, but without the
leading magic.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
master
Stefan Brüns 9 years ago committed by Joe Hershberger
parent ec87b1b39b
commit 774c3e05ec
  1. 42
      net/bootp.c

@ -773,14 +773,12 @@ void bootp_request(void)
}
#if defined(CONFIG_CMD_DHCP)
static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
static void dhcp_process_options(uchar *popt, uchar *end)
{
uchar *end = popt + BOOTP_HDR_SIZE;
int oplen, size;
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
int *to_ptr;
#endif
dhcp_option_overload = 0;
while (popt < end && *popt != 0xff) {
oplen = *(popt + 1);
@ -865,6 +863,35 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
}
}
static void dhcp_packet_process_options(struct bootp_hdr *bp)
{
uchar *popt = (uchar *)&bp->bp_vend[4];
uchar *end = popt + BOOTP_HDR_SIZE;
if (net_read_u32((u32 *)&bp->bp_vend[0]) != htonl(BOOTP_VENDOR_MAGIC))
return;
dhcp_option_overload = 0;
/*
* The 'options' field MUST be interpreted first, 'file' next,
* 'sname' last.
*/
dhcp_process_options(popt, end);
if (dhcp_option_overload & OVERLOAD_FILE) {
popt = (uchar *)bp->bp_file;
end = popt + sizeof(bp->bp_file);
dhcp_process_options(popt, end);
}
if (dhcp_option_overload & OVERLOAD_SNAME) {
popt = (uchar *)bp->bp_sname;
end = popt + sizeof(bp->bp_sname);
dhcp_process_options(popt, end);
}
}
static int dhcp_message_type(unsigned char *popt)
{
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
@ -982,14 +1009,11 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
CONFIG_SYS_BOOTFILE_PREFIX,
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
dhcp_packet_process_options(bp);
debug("TRANSITIONING TO REQUESTING STATE\n");
dhcp_state = REQUESTING;
if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
htonl(BOOTP_VENDOR_MAGIC))
dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
net_set_timeout_handler(5000, bootp_timeout_handler);
dhcp_send_request_packet(bp);
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
@ -1002,9 +1026,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
debug("DHCP State: REQUESTING\n");
if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
htonl(BOOTP_VENDOR_MAGIC))
dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
dhcp_packet_process_options(bp);
/* Store net params from reply */
store_net_params(bp);
dhcp_state = BOUND;

Loading…
Cancel
Save