1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <command.h>
13#include <net.h>
14#include "bootp.h"
15#include "tftp.h"
16#include "nfs.h"
17#ifdef CONFIG_STATUS_LED
18#include <status_led.h>
19#endif
20
21#define BOOTP_VENDOR_MAGIC 0x63825363
22
23#if defined(CONFIG_CMD_NET)
24
25#define TIMEOUT 5000UL
26#ifndef CONFIG_NET_RETRY_COUNT
27# define TIMEOUT_COUNT 5
28#else
29# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
30#endif
31
32#define PORT_BOOTPS 67
33#define PORT_BOOTPC 68
34
35#ifndef CONFIG_DHCP_MIN_EXT_LEN
36#define CONFIG_DHCP_MIN_EXT_LEN 64
37#endif
38
39ulong BootpID;
40int BootpTry;
41#ifdef CONFIG_BOOTP_RANDOM_DELAY
42ulong seed1, seed2;
43#endif
44
45#if defined(CONFIG_CMD_DHCP)
46dhcp_state_t dhcp_state = INIT;
47unsigned long dhcp_leasetime = 0;
48IPaddr_t NetDHCPServerIP = 0;
49static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len);
50
51
52#if 0
53static char *dhcpmsg2str(int type)
54{
55 switch (type) {
56 case 1: return "DHCPDISCOVER"; break;
57 case 2: return "DHCPOFFER"; break;
58 case 3: return "DHCPREQUEST"; break;
59 case 4: return "DHCPDECLINE"; break;
60 case 5: return "DHCPACK"; break;
61 case 6: return "DHCPNACK"; break;
62 case 7: return "DHCPRELEASE"; break;
63 default: return "UNKNOWN/INVALID MSG TYPE"; break;
64 }
65}
66#endif
67
68#if defined(CONFIG_BOOTP_VENDOREX)
69extern u8 *dhcp_vendorex_prep (u8 *e);
70extern u8 *dhcp_vendorex_proc (u8 *e);
71#endif
72
73#endif
74
75static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
76{
77 Bootp_t *bp = (Bootp_t *) pkt;
78 int retval = 0;
79
80 if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
81 retval = -1;
82 else if (len < sizeof (Bootp_t) - OPT_SIZE)
83 retval = -2;
84 else if (bp->bp_op != OP_BOOTREQUEST &&
85 bp->bp_op != OP_BOOTREPLY &&
86 bp->bp_op != DHCP_OFFER &&
87 bp->bp_op != DHCP_ACK &&
88 bp->bp_op != DHCP_NAK ) {
89 retval = -3;
90 }
91 else if (bp->bp_htype != HWT_ETHER)
92 retval = -4;
93 else if (bp->bp_hlen != HWL_ETHER)
94 retval = -5;
95 else if (NetReadLong((ulong*)&bp->bp_id) != BootpID) {
96 retval = -6;
97 }
98
99 debug("Filtering pkt = %d\n", retval);
100
101 return retval;
102}
103
104
105
106
107static void BootpCopyNetParams(Bootp_t *bp)
108{
109 IPaddr_t tmp_ip;
110
111 NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
112#if !defined(CONFIG_BOOTP_SERVERIP)
113 NetCopyIP(&tmp_ip, &bp->bp_siaddr);
114 if (tmp_ip != 0)
115 NetCopyIP(&NetServerIP, &bp->bp_siaddr);
116 memcpy (NetServerEther, ((Ethernet_t *)NetRxPacket)->et_src, 6);
117#endif
118 if (strlen(bp->bp_file) > 0)
119 copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
120
121 debug("Bootfile: %s\n", BootFile);
122
123
124
125
126
127 if (*BootFile) {
128 setenv ("bootfile", BootFile);
129 }
130}
131
132static int truncate_sz (const char *name, int maxlen, int curlen)
133{
134 if (curlen >= maxlen) {
135 printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n",
136 name, curlen, maxlen);
137 curlen = maxlen - 1;
138 }
139 return (curlen);
140}
141
142#if !defined(CONFIG_CMD_DHCP)
143
144static void BootpVendorFieldProcess (u8 * ext)
145{
146 int size = *(ext + 1);
147
148 debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
149 *(ext + 1));
150
151 NetBootFileSize = 0;
152
153 switch (*ext) {
154
155 case 1:
156 if (NetOurSubnetMask == 0)
157 NetCopyIP (&NetOurSubnetMask, (IPaddr_t *) (ext + 2));
158 break;
159 case 2:
160 break;
161
162 case 3:
163 if (NetOurGatewayIP == 0) {
164 NetCopyIP (&NetOurGatewayIP, (IPaddr_t *) (ext + 2));
165 }
166 break;
167 case 4:
168 break;
169 case 5:
170 break;
171 case 6:
172 if (NetOurDNSIP == 0) {
173 NetCopyIP (&NetOurDNSIP, (IPaddr_t *) (ext + 2));
174 }
175#if defined(CONFIG_BOOTP_DNS2)
176 if ((NetOurDNS2IP == 0) && (size > 4)) {
177 NetCopyIP (&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));
178 }
179#endif
180 break;
181 case 7:
182 break;
183 case 8:
184 break;
185 case 9:
186 break;
187 case 10:
188 break;
189 case 11:
190 break;
191 case 12:
192 if (NetOurHostName[0] == 0) {
193 size = truncate_sz ("Host Name", sizeof (NetOurHostName), size);
194 memcpy (&NetOurHostName, ext + 2, size);
195 NetOurHostName[size] = 0;
196 }
197 break;
198 case 13:
199 if (size == 2)
200 NetBootFileSize = ntohs (*(ushort *) (ext + 2));
201 else if (size == 4)
202 NetBootFileSize = ntohl (*(ulong *) (ext + 2));
203 break;
204 case 14:
205 break;
206 case 15:
207 break;
208 case 16:
209 break;
210 case 17:
211 if (NetOurRootPath[0] == 0) {
212 size = truncate_sz ("Root Path", sizeof (NetOurRootPath), size);
213 memcpy (&NetOurRootPath, ext + 2, size);
214 NetOurRootPath[size] = 0;
215 }
216 break;
217 case 18:
218
219
220
221
222
223 break;
224
225 case 40:
226 if (NetOurNISDomain[0] == 0) {
227 size = truncate_sz ("NIS Domain Name", sizeof (NetOurNISDomain), size);
228 memcpy (&NetOurNISDomain, ext + 2, size);
229 NetOurNISDomain[size] = 0;
230 }
231 break;
232
233 case 43:
234
235
236
237
238 break;
239
240 }
241}
242
243static void BootpVendorProcess (u8 * ext, int size)
244{
245 u8 *end = ext + size;
246
247 debug("[BOOTP] Checking extension (%d bytes)...\n", size);
248
249 while ((ext < end) && (*ext != 0xff)) {
250 if (*ext == 0) {
251 ext++;
252 } else {
253 u8 *opt = ext;
254
255 ext += ext[1] + 2;
256 if (ext <= end)
257 BootpVendorFieldProcess (opt);
258 }
259 }
260
261 debug("[BOOTP] Received fields: \n");
262 if (NetOurSubnetMask)
263 debug("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask);
264
265 if (NetOurGatewayIP)
266 debug("NetOurGatewayIP : %pI4", &NetOurGatewayIP);
267
268 if (NetBootFileSize)
269 debug("NetBootFileSize : %d\n", NetBootFileSize);
270
271 if (NetOurHostName[0])
272 debug("NetOurHostName : %s\n", NetOurHostName);
273
274 if (NetOurRootPath[0])
275 debug("NetOurRootPath : %s\n", NetOurRootPath);
276
277 if (NetOurNISDomain[0])
278 debug("NetOurNISDomain : %s\n", NetOurNISDomain);
279
280 if (NetBootFileSize)
281 debug("NetBootFileSize: %d\n", NetBootFileSize);
282}
283
284
285
286static void
287BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
288{
289 Bootp_t *bp;
290 char *s;
291
292 debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
293 src, dest, len, sizeof (Bootp_t));
294
295 bp = (Bootp_t *)pkt;
296
297 if (BootpCheckPkt(pkt, dest, src, len))
298 return;
299
300
301
302
303#ifdef CONFIG_STATUS_LED
304 status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
305#endif
306
307 BootpCopyNetParams(bp);
308
309
310 if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
311 BootpVendorProcess((uchar *)&bp->bp_vend[4], len);
312
313 NetSetTimeout(0, (thand_f *)0);
314
315 debug("Got good BOOTP\n");
316
317 if ((s = getenv("autoload")) != NULL) {
318 if (*s == 'n') {
319
320
321
322
323 NetState = NETLOOP_SUCCESS;
324 return;
325#if defined(CONFIG_CMD_NFS)
326 } else if (strcmp(s, "NFS") == 0) {
327
328
329
330 NfsStart();
331 return;
332#endif
333 }
334 }
335
336 TftpStart();
337}
338#endif
339
340
341
342
343static void
344BootpTimeout(void)
345{
346 if (BootpTry >= TIMEOUT_COUNT) {
347 puts ("\nRetry count exceeded; starting again\n");
348 NetStartAgain ();
349 } else {
350 NetSetTimeout (TIMEOUT, BootpTimeout);
351 BootpRequest ();
352 }
353}
354
355
356
357
358#if defined(CONFIG_CMD_DHCP)
359static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP)
360{
361 u8 *start = e;
362 u8 *cnt;
363
364#if defined(CONFIG_BOOTP_VENDOREX)
365 u8 *x;
366#endif
367#if defined(CONFIG_BOOTP_SEND_HOSTNAME)
368 char *hostname;
369#endif
370
371 *e++ = 99;
372 *e++ = 130;
373 *e++ = 83;
374 *e++ = 99;
375
376 *e++ = 53;
377 *e++ = 1;
378 *e++ = message_type;
379
380 *e++ = 57;
381 *e++ = 2;
382 *e++ = (576 - 312 + OPT_SIZE) >> 8;
383 *e++ = (576 - 312 + OPT_SIZE) & 0xff;
384
385 if (ServerID) {
386 int tmp = ntohl (ServerID);
387
388 *e++ = 54;
389 *e++ = 4;
390 *e++ = tmp >> 24;
391 *e++ = tmp >> 16;
392 *e++ = tmp >> 8;
393 *e++ = tmp & 0xff;
394 }
395
396 if (RequestedIP) {
397 int tmp = ntohl (RequestedIP);
398
399 *e++ = 50;
400 *e++ = 4;
401 *e++ = tmp >> 24;
402 *e++ = tmp >> 16;
403 *e++ = tmp >> 8;
404 *e++ = tmp & 0xff;
405 }
406#if defined(CONFIG_BOOTP_SEND_HOSTNAME)
407 if ((hostname = getenv ("hostname"))) {
408 int hostnamelen = strlen (hostname);
409
410 *e++ = 12;
411 *e++ = hostnamelen;
412 memcpy (e, hostname, hostnamelen);
413 e += hostnamelen;
414 }
415#endif
416
417#if defined(CONFIG_BOOTP_VENDOREX)
418 if ((x = dhcp_vendorex_prep (e)))
419 return x - start;
420#endif
421
422 *e++ = 55;
423 cnt = e++;
424 *cnt = 0;
425#if defined(CONFIG_BOOTP_SUBNETMASK)
426 *e++ = 1;
427 *cnt += 1;
428#endif
429#if defined(CONFIG_BOOTP_TIMEOFFSET)
430 *e++ = 2;
431 *cnt += 1;
432#endif
433#if defined(CONFIG_BOOTP_GATEWAY)
434 *e++ = 3;
435 *cnt += 1;
436#endif
437#if defined(CONFIG_BOOTP_DNS)
438 *e++ = 6;
439 *cnt += 1;
440#endif
441#if defined(CONFIG_BOOTP_HOSTNAME)
442 *e++ = 12;
443 *cnt += 1;
444#endif
445#if defined(CONFIG_BOOTP_BOOTFILESIZE)
446 *e++ = 13;
447 *cnt += 1;
448#endif
449#if defined(CONFIG_BOOTP_BOOTPATH)
450 *e++ = 17;
451 *cnt += 1;
452#endif
453#if defined(CONFIG_BOOTP_NISDOMAIN)
454 *e++ = 40;
455 *cnt += 1;
456#endif
457#if defined(CONFIG_BOOTP_NTPSERVER)
458 *e++ = 42;
459 *cnt += 1;
460#endif
461 *e++ = 255;
462
463
464#ifdef CONFIG_DHCP_MIN_EXT_LEN
465 while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN)
466 *e++ = 0;
467#endif
468
469 return e - start;
470}
471
472#else
473
474
475
476static int BootpExtended (u8 * e)
477{
478 u8 *start = e;
479
480 *e++ = 99;
481 *e++ = 130;
482 *e++ = 83;
483 *e++ = 99;
484
485#if defined(CONFIG_CMD_DHCP)
486 *e++ = 53;
487 *e++ = 1;
488 *e++ = DHCP_DISCOVER;
489
490 *e++ = 57;
491 *e++ = 2;
492 *e++ = (576 - 312 + OPT_SIZE) >> 16;
493 *e++ = (576 - 312 + OPT_SIZE) & 0xff;
494#endif
495
496#if defined(CONFIG_BOOTP_SUBNETMASK)
497 *e++ = 1;
498 *e++ = 4;
499 e += 4;
500#endif
501
502#if defined(CONFIG_BOOTP_GATEWAY)
503 *e++ = 3;
504 *e++ = 4;
505 e += 4;
506#endif
507
508#if defined(CONFIG_BOOTP_DNS)
509 *e++ = 6;
510 *e++ = 4;
511 e += 4;
512#endif
513
514#if defined(CONFIG_BOOTP_HOSTNAME)
515 *e++ = 12;
516 *e++ = 32;
517 e += 32;
518#endif
519
520#if defined(CONFIG_BOOTP_BOOTFILESIZE)
521 *e++ = 13;
522 *e++ = 2;
523 e += 2;
524#endif
525
526#if defined(CONFIG_BOOTP_BOOTPATH)
527 *e++ = 17;
528 *e++ = 32;
529 e += 32;
530#endif
531
532#if defined(CONFIG_BOOTP_NISDOMAIN)
533 *e++ = 40;
534 *e++ = 32;
535 e += 32;
536#endif
537
538 *e++ = 255;
539
540 return e - start;
541}
542#endif
543
544void
545BootpRequest (void)
546{
547 volatile uchar *pkt, *iphdr;
548 Bootp_t *bp;
549 int ext_len, pktlen, iplen;
550
551#if defined(CONFIG_CMD_DHCP)
552 dhcp_state = INIT;
553#endif
554
555#ifdef CONFIG_BOOTP_RANDOM_DELAY
556 unsigned char bi_enetaddr[6];
557 int reg;
558 ulong tst1, tst2, sum, m_mask, m_value = 0;
559
560 if (BootpTry ==0) {
561
562 eth_getenv_enetaddr("ethaddr", bi_enetaddr);
563
564 debug("BootpRequest => Our Mac: ");
565 for (reg=0; reg<6; reg++)
566 debug("%x%c", bi_enetaddr[reg], reg==5 ? '\n' : ':');
567
568
569 tst1=0;
570 tst2=0;
571 for (reg=2; reg<6; reg++) {
572 tst1 = tst1 << 8;
573 tst1 = tst1 | bi_enetaddr[reg];
574 }
575 for (reg=0; reg<2; reg++) {
576 tst2 = tst2 | bi_enetaddr[reg];
577 tst2 = tst2 << 8;
578 }
579
580 seed1 = tst1^tst2;
581
582
583 m_mask=0x1;
584 for (reg=1;reg<=32;reg++) {
585 m_value |= (m_mask & seed1);
586 seed1 = seed1 >> 1;
587 m_value = m_value << 1;
588 }
589 seed1 = m_value;
590 seed2 = 0xB78D0945;
591 }
592
593
594
595 for (reg=0;reg<=0;reg++) {
596 sum = seed1 + seed2;
597 if (sum < seed1 || sum < seed2)
598 sum++;
599 seed2 = seed1;
600 seed1 = sum;
601
602 if (BootpTry<=2) {
603 sum = sum >> (22-BootpTry);
604 } else {
605 sum = sum >> 19;
606 }
607 }
608
609 printf ("Random delay: %ld ms...\n", sum);
610 for (reg=0; reg <sum; reg++) {
611 udelay(1000);
612 }
613#endif
614
615 printf("BOOTP broadcast %d\n", ++BootpTry);
616 pkt = NetTxPacket;
617 memset ((void*)pkt, 0, PKTSIZE);
618
619 pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP);
620
621
622
623
624
625
626
627
628 iphdr = pkt;
629 pkt += IP_HDR_SIZE;
630
631 bp = (Bootp_t *)pkt;
632 bp->bp_op = OP_BOOTREQUEST;
633 bp->bp_htype = HWT_ETHER;
634 bp->bp_hlen = HWL_ETHER;
635 bp->bp_hops = 0;
636 bp->bp_secs = htons(get_timer(0) / 1000);
637 NetWriteIP(&bp->bp_ciaddr, 0);
638 NetWriteIP(&bp->bp_yiaddr, 0);
639 NetWriteIP(&bp->bp_siaddr, 0);
640 NetWriteIP(&bp->bp_giaddr, 0);
641 memcpy (bp->bp_chaddr, NetOurEther, 6);
642 copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file));
643
644
645#if defined(CONFIG_CMD_DHCP)
646 ext_len = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0);
647#else
648 ext_len = BootpExtended((u8 *)bp->bp_vend);
649#endif
650
651
652
653
654
655 BootpID = ((ulong)NetOurEther[2] << 24)
656 | ((ulong)NetOurEther[3] << 16)
657 | ((ulong)NetOurEther[4] << 8)
658 | (ulong)NetOurEther[5];
659 BootpID += get_timer(0);
660 BootpID = htonl(BootpID);
661 NetCopyLong(&bp->bp_id, &BootpID);
662
663
664
665
666
667 pktlen = ((int)(pkt-NetTxPacket)) + BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len;
668 iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len;
669 NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
670 NetSetTimeout(SELECT_TIMEOUT, BootpTimeout);
671
672#if defined(CONFIG_CMD_DHCP)
673 dhcp_state = SELECTING;
674 NetSetHandler(DhcpHandler);
675#else
676 NetSetHandler(BootpHandler);
677#endif
678 NetSendPacket(NetTxPacket, pktlen);
679}
680
681#if defined(CONFIG_CMD_DHCP)
682static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp)
683{
684 uchar *end = popt + BOOTP_HDR_SIZE;
685 int oplen, size;
686#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
687 int *to_ptr;
688#endif
689
690 while (popt < end && *popt != 0xff) {
691 oplen = *(popt + 1);
692 switch (*popt) {
693 case 1:
694 NetCopyIP (&NetOurSubnetMask, (popt + 2));
695 break;
696#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
697 case 2:
698 to_ptr = &NetTimeOffset;
699 NetCopyLong ((ulong *)to_ptr, (ulong *)(popt + 2));
700 NetTimeOffset = ntohl (NetTimeOffset);
701 break;
702#endif
703 case 3:
704 NetCopyIP (&NetOurGatewayIP, (popt + 2));
705 break;
706 case 6:
707 NetCopyIP (&NetOurDNSIP, (popt + 2));
708#if defined(CONFIG_BOOTP_DNS2)
709 if (*(popt + 1) > 4) {
710 NetCopyIP (&NetOurDNS2IP, (popt + 2 + 4));
711 }
712#endif
713 break;
714 case 12:
715 size = truncate_sz ("Host Name", sizeof (NetOurHostName), oplen);
716 memcpy (&NetOurHostName, popt + 2, size);
717 NetOurHostName[size] = 0;
718 break;
719 case 15:
720 break;
721 case 17:
722 size = truncate_sz ("Root Path", sizeof (NetOurRootPath), oplen);
723 memcpy (&NetOurRootPath, popt + 2, size);
724 NetOurRootPath[size] = 0;
725 break;
726#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
727 case 42:
728 NetCopyIP (&NetNtpServerIP, (popt + 2));
729 break;
730#endif
731 case 51:
732 NetCopyLong (&dhcp_leasetime, (ulong *) (popt + 2));
733 break;
734 case 53:
735 break;
736 case 54:
737 NetCopyIP (&NetDHCPServerIP, (popt + 2));
738 break;
739 case 58:
740 break;
741 case 59:
742 break;
743 case 66:
744 break;
745 case 67:
746
747
748
749
750
751
752 size = truncate_sz ("Opt Boot File",
753 sizeof(bp->bp_file),
754 oplen);
755 if (bp->bp_file[0] == '\0' && size > 0) {
756
757
758
759
760
761
762
763
764
765 printf("*** WARNING: using vendor "
766 "optional boot file\n");
767 memcpy(bp->bp_file, popt + 2, size);
768 bp->bp_file[size] = '\0';
769 }
770 break;
771 default:
772#if defined(CONFIG_BOOTP_VENDOREX)
773 if (dhcp_vendorex_proc (popt))
774 break;
775#endif
776 printf ("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt);
777 break;
778 }
779 popt += oplen + 2;
780 }
781}
782
783static int DhcpMessageType(unsigned char *popt)
784{
785 if (NetReadLong((ulong*)popt) != htonl(BOOTP_VENDOR_MAGIC))
786 return -1;
787
788 popt += 4;
789 while ( *popt != 0xff ) {
790 if ( *popt == 53 )
791 return *(popt + 2);
792 popt += *(popt + 1) + 2;
793 }
794 return -1;
795}
796
797static void DhcpSendRequestPkt(Bootp_t *bp_offer)
798{
799 volatile uchar *pkt, *iphdr;
800 Bootp_t *bp;
801 int pktlen, iplen, extlen;
802 IPaddr_t OfferedIP;
803
804 debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
805 pkt = NetTxPacket;
806 memset ((void*)pkt, 0, PKTSIZE);
807
808 pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP);
809
810 iphdr = pkt;
811 pkt += IP_HDR_SIZE;
812
813 bp = (Bootp_t *)pkt;
814 bp->bp_op = OP_BOOTREQUEST;
815 bp->bp_htype = HWT_ETHER;
816 bp->bp_hlen = HWL_ETHER;
817 bp->bp_hops = 0;
818 bp->bp_secs = htons(get_timer(0) / 1000);
819
820
821
822
823
824
825
826 NetWriteIP(&bp->bp_giaddr, 0);
827
828 memcpy (bp->bp_chaddr, NetOurEther, 6);
829
830
831
832
833
834 NetCopyLong(&bp->bp_id, &bp_offer->bp_id);
835
836
837
838
839
840
841 NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr);
842 extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST, NetDHCPServerIP, OfferedIP);
843
844 pktlen = ((int)(pkt-NetTxPacket)) + BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
845 iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;
846 NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
847
848 debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
849#ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY
850 udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);
851#endif
852 NetSendPacket(NetTxPacket, pktlen);
853}
854
855
856
857
858static void
859DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
860{
861 Bootp_t *bp = (Bootp_t *)pkt;
862
863 debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
864 src, dest, len, dhcp_state);
865
866 if (BootpCheckPkt(pkt, dest, src, len))
867 return;
868
869 debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",
870 src, dest, len, dhcp_state);
871
872 switch (dhcp_state) {
873 case SELECTING:
874
875
876
877
878
879
880 debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);
881#ifdef CONFIG_SYS_BOOTFILE_PREFIX
882 if (strncmp(bp->bp_file,
883 CONFIG_SYS_BOOTFILE_PREFIX,
884 strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0 ) {
885#endif
886
887 debug("TRANSITIONING TO REQUESTING STATE\n");
888 dhcp_state = REQUESTING;
889
890 if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
891 DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
892
893 NetSetTimeout(TIMEOUT, BootpTimeout);
894 DhcpSendRequestPkt(bp);
895#ifdef CONFIG_SYS_BOOTFILE_PREFIX
896 }
897#endif
898
899 return;
900 break;
901 case REQUESTING:
902 debug("DHCP State: REQUESTING\n");
903
904 if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) {
905 char *s;
906
907 if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
908 DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
909 BootpCopyNetParams(bp);
910 dhcp_state = BOUND;
911 printf ("DHCP client bound to address %pI4\n", &NetOurIP);
912
913
914 if ((s = getenv("autoload")) != NULL) {
915 if (*s == 'n') {
916
917
918
919
920 NetState = NETLOOP_SUCCESS;
921 return;
922#if defined(CONFIG_CMD_NFS)
923 } else if (strcmp(s, "NFS") == 0) {
924
925
926
927 NfsStart();
928 return;
929#endif
930 }
931 }
932 TftpStart();
933 return;
934 }
935 break;
936 case BOUND:
937
938 break;
939 default:
940 puts ("DHCP: INVALID STATE\n");
941 break;
942 }
943
944}
945
946void DhcpRequest(void)
947{
948 BootpRequest();
949}
950#endif
951
952#endif
953