2 * Based on LiMon - BOOTP.
4 * Copyright 1994, 1995, 2000 Neil Russell.
6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2004 Wolfgang Denk, wd@denx.de
12 #define DEBUG 1 /* general debug */
13 #define DEBUG_BOOTP_EXT 1 /* Debug received vendor fields */
16 #ifdef DEBUG_BOOTP_EXT
17 #define debug_ext(fmt,args...) printf (fmt ,##args)
19 #define debug_ext(fmt,args...)
28 #ifdef CONFIG_STATUS_LED
29 #include <status_led.h>
32 #define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */
34 #if (CONFIG_COMMANDS & CFG_CMD_NET)
36 #define TIMEOUT 5 /* Seconds before trying BOOTP again */
37 #ifndef CONFIG_NET_RETRY_COUNT
38 # define TIMEOUT_COUNT 5 /* # of timeouts before giving up */
40 # define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
43 #define PORT_BOOTPS 67 /* BOOTP server UDP port */
44 #define PORT_BOOTPC 68 /* BOOTP client UDP port */
46 #ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */
47 #define CONFIG_DHCP_MIN_EXT_LEN 64
52 #ifdef CONFIG_BOOTP_RANDOM_DELAY
56 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
57 dhcp_state_t dhcp_state = INIT;
58 unsigned long dhcp_leasetime = 0;
59 IPaddr_t NetDHCPServerIP = 0;
60 static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len);
64 static char *dhcpmsg2str(int type)
67 case 1: return "DHCPDISCOVER"; break;
68 case 2: return "DHCPOFFER"; break;
69 case 3: return "DHCPREQUEST"; break;
70 case 4: return "DHCPDECLINE"; break;
71 case 5: return "DHCPACK"; break;
72 case 6: return "DHCPNACK"; break;
73 case 7: return "DHCPRELEASE"; break;
74 default: return "UNKNOWN/INVALID MSG TYPE"; break;
79 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)
80 extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */
81 extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL */
84 #endif /* CFG_CMD_DHCP */
86 static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
88 Bootp_t *bp = (Bootp_t *) pkt;
91 if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
93 else if (len < sizeof (Bootp_t) - OPT_SIZE)
95 else if (bp->bp_op != OP_BOOTREQUEST &&
96 bp->bp_op != OP_BOOTREPLY &&
97 bp->bp_op != DHCP_OFFER &&
98 bp->bp_op != DHCP_ACK &&
99 bp->bp_op != DHCP_NAK ) {
102 else if (bp->bp_htype != HWT_ETHER)
104 else if (bp->bp_hlen != HWL_ETHER)
106 else if (NetReadLong((ulong*)&bp->bp_id) != BootpID) {
110 debug ("Filtering pkt = %d\n", retval);
116 * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
118 static void BootpCopyNetParams(Bootp_t *bp)
122 NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
123 NetCopyIP(&tmp_ip, &bp->bp_siaddr);
125 NetCopyIP(&NetServerIP, &bp->bp_siaddr);
126 memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6);
127 if (strlen(bp->bp_file) > 0)
128 copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
130 debug ("Bootfile: %s\n", BootFile);
132 /* Propagate to environment:
133 * don't delete exising entry when BOOTP / DHCP reply does
134 * not contain a new value
137 setenv ("bootfile", BootFile);
141 static int truncate_sz (const char *name, int maxlen, int curlen)
143 if (curlen >= maxlen) {
144 printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n",
145 name, curlen, maxlen);
151 #if !(CONFIG_COMMANDS & CFG_CMD_DHCP)
153 static void BootpVendorFieldProcess (u8 * ext)
155 int size = *(ext + 1);
157 debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
163 /* Fixed length fields */
164 case 1: /* Subnet mask */
165 if (NetOurSubnetMask == 0)
166 NetCopyIP (&NetOurSubnetMask, (IPaddr_t *) (ext + 2));
168 case 2: /* Time offset - Not yet supported */
170 /* Variable length fields */
171 case 3: /* Gateways list */
172 if (NetOurGatewayIP == 0) {
173 NetCopyIP (&NetOurGatewayIP, (IPaddr_t *) (ext + 2));
176 case 4: /* Time server - Not yet supported */
178 case 5: /* IEN-116 name server - Not yet supported */
181 if (NetOurDNSIP == 0) {
182 NetCopyIP (&NetOurDNSIP, (IPaddr_t *) (ext + 2));
184 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)
185 if ((NetOurDNS2IP == 0) && (size > 4)) {
186 NetCopyIP (&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));
190 case 7: /* Log server - Not yet supported */
192 case 8: /* Cookie/Quote server - Not yet supported */
194 case 9: /* LPR server - Not yet supported */
196 case 10: /* Impress server - Not yet supported */
198 case 11: /* RPL server - Not yet supported */
200 case 12: /* Host name */
201 if (NetOurHostName[0] == 0) {
202 size = truncate_sz ("Host Name", sizeof (NetOurHostName), size);
203 memcpy (&NetOurHostName, ext + 2, size);
204 NetOurHostName[size] = 0;
207 case 13: /* Boot file size */
209 NetBootFileSize = ntohs (*(ushort *) (ext + 2));
211 NetBootFileSize = ntohl (*(ulong *) (ext + 2));
213 case 14: /* Merit dump file - Not yet supported */
215 case 15: /* Domain name - Not yet supported */
217 case 16: /* Swap server - Not yet supported */
219 case 17: /* Root path */
220 if (NetOurRootPath[0] == 0) {
221 size = truncate_sz ("Root Path", sizeof (NetOurRootPath), size);
222 memcpy (&NetOurRootPath, ext + 2, size);
223 NetOurRootPath[size] = 0;
226 case 18: /* Extension path - Not yet supported */
228 * This can be used to send the information of the
229 * vendor area in another file that the client can
233 /* IP host layer fields */
234 case 40: /* NIS Domain name */
235 if (NetOurNISDomain[0] == 0) {
236 size = truncate_sz ("NIS Domain Name", sizeof (NetOurNISDomain), size);
237 memcpy (&NetOurNISDomain, ext + 2, size);
238 NetOurNISDomain[size] = 0;
241 /* Application layer fields */
242 case 43: /* Vendor specific info - Not yet supported */
244 * Binary information to exchange specific
245 * product information.
248 /* Reserved (custom) fields (128..254) */
252 static void BootpVendorProcess (u8 * ext, int size)
254 u8 *end = ext + size;
256 debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size);
258 while ((ext < end) && (*ext != 0xff)) {
266 BootpVendorFieldProcess (opt);
270 #ifdef DEBUG_BOOTP_EXT
271 puts ("[BOOTP] Received fields: \n");
272 if (NetOurSubnetMask) {
273 puts ("NetOurSubnetMask : ");
274 print_IPaddr (NetOurSubnetMask);
278 if (NetOurGatewayIP) {
279 puts ("NetOurGatewayIP : ");
280 print_IPaddr (NetOurGatewayIP);
284 if (NetBootFileSize) {
285 printf ("NetBootFileSize : %d\n", NetBootFileSize);
288 if (NetOurHostName[0]) {
289 printf ("NetOurHostName : %s\n", NetOurHostName);
292 if (NetOurRootPath[0]) {
293 printf ("NetOurRootPath : %s\n", NetOurRootPath);
296 if (NetOurNISDomain[0]) {
297 printf ("NetOurNISDomain : %s\n", NetOurNISDomain);
300 if (NetBootFileSize) {
301 printf ("NetBootFileSize: %d\n", NetBootFileSize);
303 #endif /* DEBUG_BOOTP_EXT */
306 * Handle a BOOTP received packet.
309 BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
314 debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n",
315 src, dest, len, sizeof (Bootp_t));
319 if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */
323 * Got a good BOOTP reply. Copy the data into our variables.
325 #ifdef CONFIG_STATUS_LED
326 status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
329 BootpCopyNetParams(bp); /* Store net parameters from reply */
331 /* Retrieve extended information (we must parse the vendor area) */
332 if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
333 BootpVendorProcess(&bp->bp_vend[4], len);
335 NetSetTimeout(0, (thand_f *)0);
337 debug ("Got good BOOTP\n");
339 if ((s = getenv("autoload")) != NULL) {
342 * Just use BOOTP to configure system;
343 * Do not use TFTP to load the bootfile.
345 NetState = NETLOOP_SUCCESS;
347 #if (CONFIG_COMMANDS & CFG_CMD_NFS)
348 } else if (strcmp(s, "NFS") == 0) {
350 * Use NFS to load the bootfile.
360 #endif /* !CFG_CMD_DHCP */
363 * Timeout on BOOTP/DHCP request.
368 if (BootpTry >= TIMEOUT_COUNT) {
369 puts ("\nRetry count exceeded; starting again\n");
372 NetSetTimeout (TIMEOUT * CFG_HZ, BootpTimeout);
378 * Initialize BOOTP extension fields in the request.
380 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
381 static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP)
386 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)
389 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SEND_HOSTNAME)
393 *e++ = 99; /* RFC1048 Magic Cookie */
398 *e++ = 53; /* DHCP Message Type */
402 *e++ = 57; /* Maximum DHCP Message Size */
404 *e++ = (576 - 312 + OPT_SIZE) >> 8;
405 *e++ = (576 - 312 + OPT_SIZE) & 0xff;
408 int tmp = ntohl (ServerID);
410 *e++ = 54; /* ServerID */
419 int tmp = ntohl (RequestedIP);
421 *e++ = 50; /* Requested IP */
428 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SEND_HOSTNAME)
429 if ((hostname = getenv ("hostname"))) {
430 int hostnamelen = strlen (hostname);
432 *e++ = 12; /* Hostname */
434 memcpy (e, hostname, hostnamelen);
439 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)
440 if ((x = dhcp_vendorex_prep (e)))
444 *e++ = 55; /* Parameter Request List */
445 cnt = e++; /* Pointer to count of requested items */
447 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK)
448 *e++ = 1; /* Subnet Mask */
451 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY)
452 *e++ = 3; /* Router Option */
455 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS)
456 *e++ = 6; /* DNS Server(s) */
459 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME)
460 *e++ = 12; /* Hostname */
463 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE)
464 *e++ = 13; /* Boot File Size */
467 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH)
468 *e++ = 17; /* Boot path */
471 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN)
472 *e++ = 40; /* NIS Domain name request */
475 *e++ = 255; /* End of the list */
477 /* Pad to minimal length */
478 #ifdef CONFIG_DHCP_MIN_EXT_LEN
479 while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN)
486 #else /* CFG_CMD_DHCP */
488 * Warning: no field size check - change CONFIG_BOOTP_MASK at your own risk!
490 static int BootpExtended (u8 * e)
494 *e++ = 99; /* RFC1048 Magic Cookie */
499 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
500 *e++ = 53; /* DHCP Message Type */
502 *e++ = DHCP_DISCOVER;
504 *e++ = 57; /* Maximum DHCP Message Size */
506 *e++ = (576 - 312 + OPT_SIZE) >> 16;
507 *e++ = (576 - 312 + OPT_SIZE) & 0xff;
508 #endif /* CFG_CMD_DHCP */
510 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK)
511 *e++ = 1; /* Subnet mask request */
516 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY)
517 *e++ = 3; /* Default gateway request */
522 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS)
523 *e++ = 6; /* Domain Name Server */
528 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME)
529 *e++ = 12; /* Host name request */
534 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE)
535 *e++ = 13; /* Boot file size */
540 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH)
541 *e++ = 17; /* Boot path */
546 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN)
547 *e++ = 40; /* NIS Domain name request */
552 *e++ = 255; /* End of the list */
556 #endif /* CFG_CMD_DHCP */
561 volatile uchar *pkt, *iphdr;
563 int ext_len, pktlen, iplen;
565 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
569 #ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */
570 unsigned char bi_enetaddr[6];
574 ulong tst1, tst2, sum, m_mask, m_value = 0;
578 reg = getenv_r ("ethaddr", tmp, sizeof(tmp));
579 s = (reg > 0) ? tmp : NULL;
581 for (reg=0; reg<6; ++reg) {
582 bi_enetaddr[reg] = s ? simple_strtoul(s, &e, 16) : 0;
588 puts ("BootpRequest => Our Mac: ");
589 for (reg=0; reg<6; reg++) {
592 reg==5 ? '\n' : ':');
596 /* Mac-Manipulation 2 get seed1 */
599 for (reg=2; reg<6; reg++) {
601 tst1 = tst1 | bi_enetaddr[reg];
603 for (reg=0; reg<2; reg++) {
604 tst2 = tst2 | bi_enetaddr[reg];
612 for (reg=1;reg<=32;reg++) {
613 m_value |= (m_mask & seed1);
615 m_value = m_value << 1;
621 /* Random Number Generator */
623 for (reg=0;reg<=0;reg++) {
625 if (sum < seed1 || sum < seed2)
630 if (BootpTry<=2) { /* Start with max 1024 * 1ms */
631 sum = sum >> (22-BootpTry);
632 } else { /*After 3rd BOOTP request max 8192 * 1ms */
637 printf ("Random delay: %ld ms...\n", sum);
638 for (reg=0; reg <sum; reg++) {
639 udelay(1000); /*Wait 1ms*/
641 #endif /* CONFIG_BOOTP_RANDOM_DELAY */
643 printf("BOOTP broadcast %d\n", ++BootpTry);
645 memset ((void*)pkt, 0, PKTSIZE);
647 pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP);
650 * Next line results in incorrect packet size being transmitted, resulting
651 * in errors in some DHCP servers, reporting missing bytes. Size must be
652 * set in packet header after extension length has been determined.
653 * C. Hallinan, DS4.COM, Inc.
655 /* NetSetIP(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */
656 iphdr = pkt; /* We need this later for NetSetIP() */
660 bp->bp_op = OP_BOOTREQUEST;
661 bp->bp_htype = HWT_ETHER;
662 bp->bp_hlen = HWL_ETHER;
664 bp->bp_secs = htons(get_timer(0) / CFG_HZ);
665 NetWriteIP(&bp->bp_ciaddr, 0);
666 NetWriteIP(&bp->bp_yiaddr, 0);
667 NetWriteIP(&bp->bp_siaddr, 0);
668 NetWriteIP(&bp->bp_giaddr, 0);
669 memcpy (bp->bp_chaddr, NetOurEther, 6);
670 copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file));
672 /* Request additional information from the BOOTP/DHCP server */
673 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
674 ext_len = DhcpExtended(bp->bp_vend, DHCP_DISCOVER, 0, 0);
676 ext_len = BootpExtended(bp->bp_vend);
677 #endif /* CFG_CMD_DHCP */
680 * Bootp ID is the lower 4 bytes of our ethernet address
681 * plus the current time in HZ.
683 BootpID = ((ulong)NetOurEther[2] << 24)
684 | ((ulong)NetOurEther[3] << 16)
685 | ((ulong)NetOurEther[4] << 8)
686 | (ulong)NetOurEther[5];
687 BootpID += get_timer(0);
688 BootpID = htonl(BootpID);
689 NetCopyLong(&bp->bp_id, &BootpID);
692 * Calculate proper packet lengths taking into account the
693 * variable size of the options field
695 pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + ext_len;
696 iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len;
697 NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
698 NetSetTimeout(SELECT_TIMEOUT * CFG_HZ, BootpTimeout);
700 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
701 dhcp_state = SELECTING;
702 NetSetHandler(DhcpHandler);
704 NetSetHandler(BootpHandler);
705 #endif /* CFG_CMD_DHCP */
706 NetSendPacket(NetTxPacket, pktlen);
709 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
710 static void DhcpOptionsProcess (uchar * popt)
712 uchar *end = popt + BOOTP_HDR_SIZE;
715 while (popt < end && *popt != 0xff) {
719 NetCopyIP (&NetOurSubnetMask, (popt + 2));
722 NetCopyIP (&NetOurGatewayIP, (popt + 2));
725 NetCopyIP (&NetOurDNSIP, (popt + 2));
726 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)
727 if (*(popt + 1) > 4) {
728 NetCopyIP (&NetOurDNS2IP, (popt + 2 + 4));
733 size = truncate_sz ("Host Name", sizeof (NetOurHostName), oplen);
734 memcpy (&NetOurHostName, popt + 2, size);
735 NetOurHostName[size] = 0;
737 case 15: /* Ignore Domain Name Option */
740 size = truncate_sz ("Root Path", sizeof (NetOurRootPath), oplen);
741 memcpy (&NetOurRootPath, popt + 2, size);
742 NetOurRootPath[size] = 0;
745 NetCopyLong (&dhcp_leasetime, (ulong *) (popt + 2));
747 case 53: /* Ignore Message Type Option */
750 NetCopyIP (&NetDHCPServerIP, (popt + 2));
752 case 58: /* Ignore Renewal Time Option */
754 case 59: /* Ignore Rebinding Time Option */
757 #if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX)
758 if (dhcp_vendorex_proc (popt))
761 printf ("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt);
764 popt += oplen + 2; /* Process next option */
768 static int DhcpMessageType(unsigned char *popt)
770 if (NetReadLong((ulong*)popt) != htonl(BOOTP_VENDOR_MAGIC))
774 while ( *popt != 0xff ) {
775 if ( *popt == 53 ) /* DHCP Message Type */
777 popt += *(popt + 1) + 2; /* Scan through all options */
782 static void DhcpSendRequestPkt(Bootp_t *bp_offer)
784 volatile uchar *pkt, *iphdr;
786 int pktlen, iplen, extlen;
789 debug ("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
791 memset ((void*)pkt, 0, PKTSIZE);
793 pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP);
795 iphdr = pkt; /* We'll need this later to set proper pkt size */
799 bp->bp_op = OP_BOOTREQUEST;
800 bp->bp_htype = HWT_ETHER;
801 bp->bp_hlen = HWL_ETHER;
803 bp->bp_secs = htons(get_timer(0) / CFG_HZ);
804 NetCopyIP(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */
805 NetCopyIP(&bp->bp_yiaddr, &bp_offer->bp_yiaddr);
806 NetCopyIP(&bp->bp_siaddr, &bp_offer->bp_siaddr);
807 NetCopyIP(&bp->bp_giaddr, &bp_offer->bp_giaddr);
808 memcpy (bp->bp_chaddr, NetOurEther, 6);
811 * ID is the id of the OFFER packet
814 NetCopyLong(&bp->bp_id, &bp_offer->bp_id);
817 * Copy options from OFFER packet if present
819 NetCopyIP(&OfferedIP, &bp->bp_yiaddr);
820 extlen = DhcpExtended(bp->bp_vend, DHCP_REQUEST, NetDHCPServerIP, OfferedIP);
822 pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen;
823 iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
824 NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
826 debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
827 NetSendPacket(NetTxPacket, pktlen);
831 * Handle DHCP received packets.
834 DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
836 Bootp_t *bp = (Bootp_t *)pkt;
838 debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
839 src, dest, len, dhcp_state);
841 if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */
844 debug ("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",
845 src, dest, len, dhcp_state);
847 switch (dhcp_state) {
850 * Wait an appropriate time for any potential DHCPOFFER packets
851 * to arrive. Then select one, and generate DHCPREQUEST response.
852 * If filename is in format we recognize, assume it is a valid
853 * OFFER from a server we want.
855 debug ("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);
856 #ifdef CFG_BOOTFILE_PREFIX
857 if (strncmp(bp->bp_file,
859 strlen(CFG_BOOTFILE_PREFIX)) == 0 ) {
860 #endif /* CFG_BOOTFILE_PREFIX */
862 debug ("TRANSITIONING TO REQUESTING STATE\n");
863 dhcp_state = REQUESTING;
865 if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
866 DhcpOptionsProcess(&bp->bp_vend[4]);
868 BootpCopyNetParams(bp); /* Store net params from reply */
870 NetSetTimeout(TIMEOUT * CFG_HZ, BootpTimeout);
871 DhcpSendRequestPkt(bp);
872 #ifdef CFG_BOOTFILE_PREFIX
874 #endif /* CFG_BOOTFILE_PREFIX */
879 debug ("DHCP State: REQUESTING\n");
881 if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) {
884 if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
885 DhcpOptionsProcess(&bp->bp_vend[4]);
886 BootpCopyNetParams(bp); /* Store net params from reply */
888 puts ("DHCP client bound to address ");
889 print_IPaddr(NetOurIP);
892 /* Obey the 'autoload' setting */
893 if ((s = getenv("autoload")) != NULL) {
896 * Just use BOOTP to configure system;
897 * Do not use TFTP to load the bootfile.
899 NetState = NETLOOP_SUCCESS;
901 #if (CONFIG_COMMANDS & CFG_CMD_NFS)
902 } else if (strcmp(s, "NFS") == 0) {
904 * Use NFS to load the bootfile.
916 puts ("DHCP: INVALID STATE\n");
922 void DhcpRequest(void)
926 #endif /* CFG_CMD_DHCP */
928 #endif /* CFG_CMD_NET */