X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=net%2Fbootp.c;h=73370a13fe7de813f9bb6ec7ff9daad7982b9047;hb=f86474e28185a1f31a2c993fa0f34b1a94c8c6e0;hp=9cf0d640259b9545d3bc002e03265f2a2918befb;hpb=ec87b1b39b786cb61c5acc01542119663fb157c0;p=u-boot diff --git a/net/bootp.c b/net/bootp.c index 9cf0d64025..73370a13fe 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -10,11 +10,12 @@ #include #include +#include #include #include #include "bootp.h" #include "nfs.h" -#ifdef CONFIG_STATUS_LED +#ifdef CONFIG_LED_STATUS #include #endif #ifdef CONFIG_BOOTP_RANDOM_DELAY @@ -60,6 +61,8 @@ char net_nis_domain[32] = {0,}; /* Our NIS domain */ char net_hostname[32] = {0,}; /* Our hostname */ char net_root_path[64] = {0,}; /* Our bootpath */ +static ulong time_taken_max; + #if defined(CONFIG_CMD_DHCP) static dhcp_state_t dhcp_state = INIT; static u32 dhcp_leasetime; @@ -130,6 +133,8 @@ static int check_reply_packet(uchar *pkt, unsigned dest, unsigned src, retval = -5; else if (!bootp_match_id(net_read_u32(&bp->bp_id))) retval = -6; + else if (memcmp(bp->bp_chaddr, net_ethaddr, HWL_ETHER) != 0) + retval = -7; debug("Filtering pkt = %d\n", retval); @@ -165,7 +170,7 @@ static void store_net_params(struct bootp_hdr *bp) * not contain a new value */ if (*net_boot_file_name) - setenv("bootfile", net_boot_file_name); + env_set("bootfile", net_boot_file_name); #endif net_copy_ip(&net_ip, &bp->bp_yiaddr); } @@ -354,8 +359,8 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip, /* * Got a good BOOTP reply. Copy the data into our variables. */ -#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) - status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); +#if defined(CONFIG_LED_STATUS) && defined(CONFIG_LED_STATUS_BOOT_ENABLE) + status_led_set(CONFIG_LED_STATUS_BOOT, CONFIG_LED_STATUS_OFF); #endif store_net_params(bp); /* Store net parameters from reply */ @@ -380,7 +385,7 @@ static void bootp_timeout_handler(void) { ulong time_taken = get_timer(bootp_start); - if (time_taken >= TIMEOUT_MS) { + if (time_taken >= time_taken_max) { #ifdef CONFIG_BOOTP_MAY_FAIL puts("\nRetry time exceeded\n"); net_set_state(NETLOOP_FAIL); @@ -406,6 +411,26 @@ static void bootp_timeout_handler(void) e += vci_strlen; \ } while (0) +static u8 *add_vci(u8 *e) +{ + char *vci = NULL; + char *env_vci = env_get("bootp_vci"); + +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING) + vci = CONFIG_SPL_NET_VCI_STRING; +#elif defined(CONFIG_BOOTP_VCI_STRING) + vci = CONFIG_BOOTP_VCI_STRING; +#endif + + if (env_vci) + vci = env_vci; + + if (vci) + put_vci(e, vci); + + return e; +} + /* * Initialize BOOTP extension fields in the request. */ @@ -415,10 +440,10 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, { u8 *start = e; u8 *cnt; -#if defined(CONFIG_BOOTP_PXE) +#ifdef CONFIG_LIB_UUID char *uuid; - u16 clientarch; #endif + int clientarch = -1; #if defined(CONFIG_BOOTP_VENDOREX) u8 *x; @@ -463,7 +488,7 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, *e++ = tmp & 0xff; } #if defined(CONFIG_BOOTP_SEND_HOSTNAME) - hostname = getenv("hostname"); + hostname = env_get("hostname"); if (hostname) { int hostnamelen = strlen(hostname); @@ -474,12 +499,19 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, } #endif -#if defined(CONFIG_BOOTP_PXE) +#ifdef CONFIG_BOOTP_PXE_CLIENTARCH clientarch = CONFIG_BOOTP_PXE_CLIENTARCH; - *e++ = 93; /* Client System Architecture */ - *e++ = 2; - *e++ = (clientarch >> 8) & 0xff; - *e++ = clientarch & 0xff; +#endif + + if (env_get("bootp_arch")) + clientarch = env_get_ulong("bootp_arch", 16, clientarch); + + if (clientarch > 0) { + *e++ = 93; /* Client System Architecture */ + *e++ = 2; + *e++ = (clientarch >> 8) & 0xff; + *e++ = clientarch & 0xff; + } *e++ = 94; /* Client Network Interface Identifier */ *e++ = 3; @@ -487,7 +519,8 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, *e++ = 0; /* major revision */ *e++ = 0; /* minor revision */ - uuid = getenv("pxeuuid"); +#ifdef CONFIG_LIB_UUID + uuid = env_get("pxeuuid"); if (uuid) { if (uuid_str_valid(uuid)) { @@ -503,11 +536,7 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, } #endif -#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING) - put_vci(e, CONFIG_SPL_NET_VCI_STRING); -#elif defined(CONFIG_BOOTP_VCI_STRING) - put_vci(e, CONFIG_BOOTP_VCI_STRING); -#endif + e = add_vci(e); #if defined(CONFIG_BOOTP_VENDOREX) x = dhcp_vendorex_prep(e); @@ -593,14 +622,7 @@ static int bootp_extended(u8 *e) *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff; #endif -#if defined(CONFIG_BOOTP_VCI_STRING) || \ - (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING)) -#ifdef CONFIG_SPL_BUILD - put_vci(e, CONFIG_SPL_NET_VCI_STRING); -#else - put_vci(e, CONFIG_BOOTP_VCI_STRING); -#endif -#endif + add_vci(e); #if defined(CONFIG_BOOTP_SUBNETMASK) *e++ = 1; /* Subnet mask request */ @@ -651,6 +673,15 @@ static int bootp_extended(u8 *e) *e++ = 255; /* End of the list */ + /* + * If nothing in list, remove it altogether. Some DHCP servers get + * upset by this minor faux pas and do not respond at all. + */ + if (e == start + 3) { + printf("*** Warning: no DHCP options requested\n"); + e -= 3; + } + return e - start; } #endif @@ -675,12 +706,19 @@ void bootp_request(void) u32 bootp_id; struct in_addr zero_ip; struct in_addr bcast_ip; + char *ep; /* Environment pointer */ bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start"); #if defined(CONFIG_CMD_DHCP) dhcp_state = INIT; #endif + ep = env_get("bootpretryperiod"); + if (ep != NULL) + time_taken_max = simple_strtoul(ep, NULL, 10); + else + time_taken_max = TIMEOUT_MS; + #ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */ if (bootp_try == 0) srand_mac(); @@ -773,14 +811,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 +901,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)) @@ -922,6 +987,7 @@ static void dhcp_send_request_packet(struct bootp_hdr *bp_offer) net_write_ip(&bp->bp_giaddr, zero_ip); memcpy(bp->bp_chaddr, net_ethaddr, 6); + copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file)); /* * ID is the id of the OFFER packet @@ -968,6 +1034,9 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip, debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: " "%d\n", src, dest, len, dhcp_state); + if (net_read_ip(&bp->bp_yiaddr).s_addr == 0) + return; + switch (dhcp_state) { case SELECTING: /* @@ -982,14 +1051,12 @@ 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); + efi_net_set_dhcp_ack(pkt, len); 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 +1069,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;