From: Stefan Brüns Date: Thu, 3 Sep 2015 22:31:49 +0000 (+0200) Subject: net: parse DHCP options from overloaded file/sname fields X-Git-Tag: v2016.01-rc1~154^2~15 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=774c3e05ec0a9c298e14681fb662c392842c2ced;p=u-boot 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 Acked-by: Joe Hershberger --- diff --git a/net/bootp.c b/net/bootp.c index 9cf0d64025..8aeddb08ea 100644 --- a/net/bootp.c +++ b/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;