2c918d83796ca6704b95f5ab0244deb712f7bdce
[platform/kernel/u-boot.git] / net / bootp.c
1 /*
2  *      Based on LiMon - BOOTP.
3  *
4  *      Copyright 1994, 1995, 2000 Neil Russell.
5  *      (See License)
6  *      Copyright 2000 Roland Borde
7  *      Copyright 2000 Paolo Scaffardi
8  *      Copyright 2000-2004 Wolfgang Denk, wd@denx.de
9  */
10
11 #include <common.h>
12 #include <command.h>
13 #include <env.h>
14 #include <efi_loader.h>
15 #include <net.h>
16 #include <rand.h>
17 #include <uuid.h>
18 #include <net/tftp.h>
19 #include "bootp.h"
20 #ifdef CONFIG_LED_STATUS
21 #include <status_led.h>
22 #endif
23 #ifdef CONFIG_BOOTP_RANDOM_DELAY
24 #include "net_rand.h"
25 #endif
26
27 #define BOOTP_VENDOR_MAGIC      0x63825363      /* RFC1048 Magic Cookie */
28
29 /*
30  * The timeout for the initial BOOTP/DHCP request used to be described by a
31  * counter of fixed-length timeout periods. TIMEOUT_COUNT represents
32  * that counter
33  *
34  * Now that the timeout periods are variable (exponential backoff and retry)
35  * we convert the timeout count to the absolute time it would have take to
36  * execute that many retries, and keep sending retry packets until that time
37  * is reached.
38  */
39 #ifndef CONFIG_NET_RETRY_COUNT
40 # define TIMEOUT_COUNT  5               /* # of timeouts before giving up */
41 #else
42 # define TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT)
43 #endif
44 #define TIMEOUT_MS      ((3 + (TIMEOUT_COUNT * 5)) * 1000)
45
46 #define PORT_BOOTPS     67              /* BOOTP server UDP port */
47 #define PORT_BOOTPC     68              /* BOOTP client UDP port */
48
49 #ifndef CONFIG_DHCP_MIN_EXT_LEN         /* minimal length of extension list */
50 #define CONFIG_DHCP_MIN_EXT_LEN 64
51 #endif
52
53 #ifndef CONFIG_BOOTP_ID_CACHE_SIZE
54 #define CONFIG_BOOTP_ID_CACHE_SIZE 4
55 #endif
56
57 u32             bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE];
58 unsigned int    bootp_num_ids;
59 int             bootp_try;
60 ulong           bootp_start;
61 ulong           bootp_timeout;
62 char net_nis_domain[32] = {0,}; /* Our NIS domain */
63 char net_hostname[32] = {0,}; /* Our hostname */
64 char net_root_path[64] = {0,}; /* Our bootpath */
65
66 static ulong time_taken_max;
67
68 #if defined(CONFIG_CMD_DHCP)
69 static dhcp_state_t dhcp_state = INIT;
70 static u32 dhcp_leasetime;
71 static struct in_addr dhcp_server_ip;
72 static u8 dhcp_option_overload;
73 #define OVERLOAD_FILE 1
74 #define OVERLOAD_SNAME 2
75 static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
76                         unsigned src, unsigned len);
77
78 /* For Debug */
79 #if 0
80 static char *dhcpmsg2str(int type)
81 {
82         switch (type) {
83         case 1:  return "DHCPDISCOVER"; break;
84         case 2:  return "DHCPOFFER";    break;
85         case 3:  return "DHCPREQUEST";  break;
86         case 4:  return "DHCPDECLINE";  break;
87         case 5:  return "DHCPACK";      break;
88         case 6:  return "DHCPNACK";     break;
89         case 7:  return "DHCPRELEASE";  break;
90         default: return "UNKNOWN/INVALID MSG TYPE"; break;
91         }
92 }
93 #endif
94 #endif
95
96 static void bootp_add_id(ulong id)
97 {
98         if (bootp_num_ids >= ARRAY_SIZE(bootp_ids)) {
99                 size_t size = sizeof(bootp_ids) - sizeof(id);
100
101                 memmove(bootp_ids, &bootp_ids[1], size);
102                 bootp_ids[bootp_num_ids - 1] = id;
103         } else {
104                 bootp_ids[bootp_num_ids] = id;
105                 bootp_num_ids++;
106         }
107 }
108
109 static bool bootp_match_id(ulong id)
110 {
111         unsigned int i;
112
113         for (i = 0; i < bootp_num_ids; i++)
114                 if (bootp_ids[i] == id)
115                         return true;
116
117         return false;
118 }
119
120 static int check_reply_packet(uchar *pkt, unsigned dest, unsigned src,
121                               unsigned len)
122 {
123         struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
124         int retval = 0;
125
126         if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
127                 retval = -1;
128         else if (len < sizeof(struct bootp_hdr) - OPT_FIELD_SIZE)
129                 retval = -2;
130         else if (bp->bp_op != OP_BOOTREPLY)
131                 retval = -3;
132         else if (bp->bp_htype != HWT_ETHER)
133                 retval = -4;
134         else if (bp->bp_hlen != HWL_ETHER)
135                 retval = -5;
136         else if (!bootp_match_id(net_read_u32(&bp->bp_id)))
137                 retval = -6;
138         else if (memcmp(bp->bp_chaddr, net_ethaddr, HWL_ETHER) != 0)
139                 retval = -7;
140
141         debug("Filtering pkt = %d\n", retval);
142
143         return retval;
144 }
145
146 /*
147  * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
148  */
149 static void store_net_params(struct bootp_hdr *bp)
150 {
151 #if !defined(CONFIG_BOOTP_SERVERIP)
152         struct in_addr tmp_ip;
153         bool overwrite_serverip = true;
154
155 #if defined(CONFIG_BOOTP_PREFER_SERVERIP)
156         overwrite_serverip = false;
157 #endif
158
159         net_copy_ip(&tmp_ip, &bp->bp_siaddr);
160         if (tmp_ip.s_addr != 0 && (overwrite_serverip || !net_server_ip.s_addr))
161                 net_copy_ip(&net_server_ip, &bp->bp_siaddr);
162         memcpy(net_server_ethaddr,
163                ((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
164         if (
165 #if defined(CONFIG_CMD_DHCP)
166             !(dhcp_option_overload & OVERLOAD_FILE) &&
167 #endif
168             (strlen(bp->bp_file) > 0) &&
169             !net_boot_file_name_explicit) {
170                 copy_filename(net_boot_file_name, bp->bp_file,
171                               sizeof(net_boot_file_name));
172         }
173
174         debug("net_boot_file_name: %s\n", net_boot_file_name);
175
176         /* Propagate to environment:
177          * don't delete exising entry when BOOTP / DHCP reply does
178          * not contain a new value
179          */
180         if (*net_boot_file_name)
181                 env_set("bootfile", net_boot_file_name);
182 #endif
183         net_copy_ip(&net_ip, &bp->bp_yiaddr);
184 }
185
186 static int truncate_sz(const char *name, int maxlen, int curlen)
187 {
188         if (curlen >= maxlen) {
189                 printf("*** WARNING: %s is too long (%d - max: %d)"
190                         " - truncated\n", name, curlen, maxlen);
191                 curlen = maxlen - 1;
192         }
193         return curlen;
194 }
195
196 #if !defined(CONFIG_CMD_DHCP)
197
198 static void bootp_process_vendor_field(u8 *ext)
199 {
200         int size = *(ext + 1);
201
202         debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
203               *(ext + 1));
204
205         net_boot_file_expected_size_in_blocks = 0;
206
207         switch (*ext) {
208                 /* Fixed length fields */
209         case 1:                 /* Subnet mask */
210                 if (net_netmask.s_addr == 0)
211                         net_copy_ip(&net_netmask, (struct in_addr *)(ext + 2));
212                 break;
213         case 2:                 /* Time offset - Not yet supported */
214                 break;
215                 /* Variable length fields */
216         case 3:                 /* Gateways list */
217                 if (net_gateway.s_addr == 0)
218                         net_copy_ip(&net_gateway, (struct in_addr *)(ext + 2));
219                 break;
220         case 4:                 /* Time server - Not yet supported */
221                 break;
222         case 5:                 /* IEN-116 name server - Not yet supported */
223                 break;
224         case 6:
225                 if (net_dns_server.s_addr == 0)
226                         net_copy_ip(&net_dns_server,
227                                     (struct in_addr *)(ext + 2));
228 #if defined(CONFIG_BOOTP_DNS2)
229                 if ((net_dns_server2.s_addr == 0) && (size > 4))
230                         net_copy_ip(&net_dns_server2,
231                                     (struct in_addr *)(ext + 2 + 4));
232 #endif
233                 break;
234         case 7:                 /* Log server - Not yet supported */
235                 break;
236         case 8:                 /* Cookie/Quote server - Not yet supported */
237                 break;
238         case 9:                 /* LPR server - Not yet supported */
239                 break;
240         case 10:                /* Impress server - Not yet supported */
241                 break;
242         case 11:                /* RPL server - Not yet supported */
243                 break;
244         case 12:                /* Host name */
245                 if (net_hostname[0] == 0) {
246                         size = truncate_sz("Host Name",
247                                 sizeof(net_hostname), size);
248                         memcpy(&net_hostname, ext + 2, size);
249                         net_hostname[size] = 0;
250                 }
251                 break;
252         case 13:                /* Boot file size */
253                 if (size == 2)
254                         net_boot_file_expected_size_in_blocks =
255                                 ntohs(*(ushort *)(ext + 2));
256                 else if (size == 4)
257                         net_boot_file_expected_size_in_blocks =
258                                 ntohl(*(ulong *)(ext + 2));
259                 break;
260         case 14:                /* Merit dump file - Not yet supported */
261                 break;
262         case 15:                /* Domain name - Not yet supported */
263                 break;
264         case 16:                /* Swap server - Not yet supported */
265                 break;
266         case 17:                /* Root path */
267                 if (net_root_path[0] == 0) {
268                         size = truncate_sz("Root Path",
269                                 sizeof(net_root_path), size);
270                         memcpy(&net_root_path, ext + 2, size);
271                         net_root_path[size] = 0;
272                 }
273                 break;
274         case 18:                /* Extension path - Not yet supported */
275                 /*
276                  * This can be used to send the information of the
277                  * vendor area in another file that the client can
278                  * access via TFTP.
279                  */
280                 break;
281                 /* IP host layer fields */
282         case 40:                /* NIS Domain name */
283                 if (net_nis_domain[0] == 0) {
284                         size = truncate_sz("NIS Domain Name",
285                                 sizeof(net_nis_domain), size);
286                         memcpy(&net_nis_domain, ext + 2, size);
287                         net_nis_domain[size] = 0;
288                 }
289                 break;
290 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
291         case 42:        /* NTP server IP */
292                 net_copy_ip(&net_ntp_server, (struct in_addr *)(ext + 2));
293                 break;
294 #endif
295                 /* Application layer fields */
296         case 43:                /* Vendor specific info - Not yet supported */
297                 /*
298                  * Binary information to exchange specific
299                  * product information.
300                  */
301                 break;
302                 /* Reserved (custom) fields (128..254) */
303         }
304 }
305
306 static void bootp_process_vendor(u8 *ext, int size)
307 {
308         u8 *end = ext + size;
309
310         debug("[BOOTP] Checking extension (%d bytes)...\n", size);
311
312         while ((ext < end) && (*ext != 0xff)) {
313                 if (*ext == 0) {
314                         ext++;
315                 } else {
316                         u8 *opt = ext;
317
318                         ext += ext[1] + 2;
319                         if (ext <= end)
320                                 bootp_process_vendor_field(opt);
321                 }
322         }
323
324         debug("[BOOTP] Received fields:\n");
325         if (net_netmask.s_addr)
326                 debug("net_netmask : %pI4\n", &net_netmask);
327
328         if (net_gateway.s_addr)
329                 debug("net_gateway      : %pI4", &net_gateway);
330
331         if (net_boot_file_expected_size_in_blocks)
332                 debug("net_boot_file_expected_size_in_blocks : %d\n",
333                       net_boot_file_expected_size_in_blocks);
334
335         if (net_hostname[0])
336                 debug("net_hostname  : %s\n", net_hostname);
337
338         if (net_root_path[0])
339                 debug("net_root_path  : %s\n", net_root_path);
340
341         if (net_nis_domain[0])
342                 debug("net_nis_domain : %s\n", net_nis_domain);
343
344 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
345         if (net_ntp_server.s_addr)
346                 debug("net_ntp_server : %pI4\n", &net_ntp_server);
347 #endif
348 }
349
350 /*
351  *      Handle a BOOTP received packet.
352  */
353 static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
354                           unsigned src, unsigned len)
355 {
356         struct bootp_hdr *bp;
357
358         debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
359               src, dest, len, sizeof(struct bootp_hdr));
360
361         bp = (struct bootp_hdr *)pkt;
362
363         /* Filter out pkts we don't want */
364         if (check_reply_packet(pkt, dest, src, len))
365                 return;
366
367         /*
368          *      Got a good BOOTP reply.  Copy the data into our variables.
369          */
370 #if defined(CONFIG_LED_STATUS) && defined(CONFIG_LED_STATUS_BOOT_ENABLE)
371         status_led_set(CONFIG_LED_STATUS_BOOT, CONFIG_LED_STATUS_OFF);
372 #endif
373
374         store_net_params(bp);           /* Store net parameters from reply */
375
376         /* Retrieve extended information (we must parse the vendor area) */
377         if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
378                 bootp_process_vendor((uchar *)&bp->bp_vend[4], len);
379
380         net_set_timeout_handler(0, (thand_f *)0);
381         bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop");
382
383         debug("Got good BOOTP\n");
384
385         net_auto_load();
386 }
387 #endif
388
389 /*
390  *      Timeout on BOOTP/DHCP request.
391  */
392 static void bootp_timeout_handler(void)
393 {
394         ulong time_taken = get_timer(bootp_start);
395
396         if (time_taken >= time_taken_max) {
397 #ifdef CONFIG_BOOTP_MAY_FAIL
398                 char *ethrotate;
399
400                 ethrotate = env_get("ethrotate");
401                 if ((ethrotate && strcmp(ethrotate, "no") == 0) ||
402                     net_restart_wrap) {
403                         puts("\nRetry time exceeded\n");
404                         net_set_state(NETLOOP_FAIL);
405                 } else
406 #endif
407                 {
408                         puts("\nRetry time exceeded; starting again\n");
409                         net_start_again();
410                 }
411         } else {
412                 bootp_timeout *= 2;
413                 if (bootp_timeout > 2000)
414                         bootp_timeout = 2000;
415                 net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
416                 bootp_request();
417         }
418 }
419
420 #define put_vci(e, str)                                         \
421         do {                                                    \
422                 size_t vci_strlen = strlen(str);                \
423                 *e++ = 60;      /* Vendor Class Identifier */   \
424                 *e++ = vci_strlen;                              \
425                 memcpy(e, str, vci_strlen);                     \
426                 e += vci_strlen;                                \
427         } while (0)
428
429 static u8 *add_vci(u8 *e)
430 {
431         char *vci = NULL;
432         char *env_vci = env_get("bootp_vci");
433
434 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING)
435         vci = CONFIG_SPL_NET_VCI_STRING;
436 #elif defined(CONFIG_BOOTP_VCI_STRING)
437         vci = CONFIG_BOOTP_VCI_STRING;
438 #endif
439
440         if (env_vci)
441                 vci = env_vci;
442
443         if (vci)
444                 put_vci(e, vci);
445
446         return e;
447 }
448
449 /*
450  *      Initialize BOOTP extension fields in the request.
451  */
452 #if defined(CONFIG_CMD_DHCP)
453 static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
454                         struct in_addr requested_ip)
455 {
456         u8 *start = e;
457         u8 *cnt;
458 #ifdef CONFIG_LIB_UUID
459         char *uuid;
460 #endif
461         int clientarch = -1;
462
463 #if defined(CONFIG_BOOTP_VENDOREX)
464         u8 *x;
465 #endif
466 #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
467         char *hostname;
468 #endif
469
470         *e++ = 99;              /* RFC1048 Magic Cookie */
471         *e++ = 130;
472         *e++ = 83;
473         *e++ = 99;
474
475         *e++ = 53;              /* DHCP Message Type */
476         *e++ = 1;
477         *e++ = message_type;
478
479         *e++ = 57;              /* Maximum DHCP Message Size */
480         *e++ = 2;
481         *e++ = (576 - 312 + OPT_FIELD_SIZE) >> 8;
482         *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
483
484         if (server_ip.s_addr) {
485                 int tmp = ntohl(server_ip.s_addr);
486
487                 *e++ = 54;      /* ServerID */
488                 *e++ = 4;
489                 *e++ = tmp >> 24;
490                 *e++ = tmp >> 16;
491                 *e++ = tmp >> 8;
492                 *e++ = tmp & 0xff;
493         }
494
495         if (requested_ip.s_addr) {
496                 int tmp = ntohl(requested_ip.s_addr);
497
498                 *e++ = 50;      /* Requested IP */
499                 *e++ = 4;
500                 *e++ = tmp >> 24;
501                 *e++ = tmp >> 16;
502                 *e++ = tmp >> 8;
503                 *e++ = tmp & 0xff;
504         }
505 #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
506         hostname = env_get("hostname");
507         if (hostname) {
508                 int hostnamelen = strlen(hostname);
509
510                 *e++ = 12;      /* Hostname */
511                 *e++ = hostnamelen;
512                 memcpy(e, hostname, hostnamelen);
513                 e += hostnamelen;
514         }
515 #endif
516
517 #ifdef CONFIG_BOOTP_PXE_CLIENTARCH
518         clientarch = CONFIG_BOOTP_PXE_CLIENTARCH;
519 #endif
520
521         if (env_get("bootp_arch"))
522                 clientarch = env_get_ulong("bootp_arch", 16, clientarch);
523
524         if (clientarch > 0) {
525                 *e++ = 93;      /* Client System Architecture */
526                 *e++ = 2;
527                 *e++ = (clientarch >> 8) & 0xff;
528                 *e++ = clientarch & 0xff;
529         }
530
531         *e++ = 94;      /* Client Network Interface Identifier */
532         *e++ = 3;
533         *e++ = 1;       /* type field for UNDI */
534         *e++ = 0;       /* major revision */
535         *e++ = 0;       /* minor revision */
536
537 #ifdef CONFIG_LIB_UUID
538         uuid = env_get("pxeuuid");
539
540         if (uuid) {
541                 if (uuid_str_valid(uuid)) {
542                         *e++ = 97;      /* Client Machine Identifier */
543                         *e++ = 17;
544                         *e++ = 0;       /* type 0 - UUID */
545
546                         uuid_str_to_bin(uuid, e, UUID_STR_FORMAT_STD);
547                         e += 16;
548                 } else {
549                         printf("Invalid pxeuuid: %s\n", uuid);
550                 }
551         }
552 #endif
553
554         e = add_vci(e);
555
556 #if defined(CONFIG_BOOTP_VENDOREX)
557         x = dhcp_vendorex_prep(e);
558         if (x)
559                 return x - start;
560 #endif
561
562         *e++ = 55;              /* Parameter Request List */
563          cnt = e++;             /* Pointer to count of requested items */
564         *cnt = 0;
565 #if defined(CONFIG_BOOTP_SUBNETMASK)
566         *e++  = 1;              /* Subnet Mask */
567         *cnt += 1;
568 #endif
569 #if defined(CONFIG_BOOTP_TIMEOFFSET)
570         *e++  = 2;
571         *cnt += 1;
572 #endif
573 #if defined(CONFIG_BOOTP_GATEWAY)
574         *e++  = 3;              /* Router Option */
575         *cnt += 1;
576 #endif
577 #if defined(CONFIG_BOOTP_DNS)
578         *e++  = 6;              /* DNS Server(s) */
579         *cnt += 1;
580 #endif
581 #if defined(CONFIG_BOOTP_HOSTNAME)
582         *e++  = 12;             /* Hostname */
583         *cnt += 1;
584 #endif
585 #if defined(CONFIG_BOOTP_BOOTFILESIZE)
586         *e++  = 13;             /* Boot File Size */
587         *cnt += 1;
588 #endif
589 #if defined(CONFIG_BOOTP_BOOTPATH)
590         *e++  = 17;             /* Boot path */
591         *cnt += 1;
592 #endif
593 #if defined(CONFIG_BOOTP_NISDOMAIN)
594         *e++  = 40;             /* NIS Domain name request */
595         *cnt += 1;
596 #endif
597 #if defined(CONFIG_BOOTP_NTPSERVER)
598         *e++  = 42;
599         *cnt += 1;
600 #endif
601         /* no options, so back up to avoid sending an empty request list */
602         if (*cnt == 0)
603                 e -= 2;
604
605         *e++  = 255;            /* End of the list */
606
607         /* Pad to minimal length */
608 #ifdef  CONFIG_DHCP_MIN_EXT_LEN
609         while ((e - start) < CONFIG_DHCP_MIN_EXT_LEN)
610                 *e++ = 0;
611 #endif
612
613         return e - start;
614 }
615
616 #else
617 /*
618  * Warning: no field size check - change CONFIG_BOOTP_* at your own risk!
619  */
620 static int bootp_extended(u8 *e)
621 {
622         u8 *start = e;
623
624         *e++ = 99;              /* RFC1048 Magic Cookie */
625         *e++ = 130;
626         *e++ = 83;
627         *e++ = 99;
628
629 #if defined(CONFIG_CMD_DHCP)
630         *e++ = 53;              /* DHCP Message Type */
631         *e++ = 1;
632         *e++ = DHCP_DISCOVER;
633
634         *e++ = 57;              /* Maximum DHCP Message Size */
635         *e++ = 2;
636         *e++ = (576 - 312 + OPT_FIELD_SIZE) >> 16;
637         *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
638 #endif
639
640         add_vci(e);
641
642 #if defined(CONFIG_BOOTP_SUBNETMASK)
643         *e++ = 1;               /* Subnet mask request */
644         *e++ = 4;
645         e   += 4;
646 #endif
647
648 #if defined(CONFIG_BOOTP_GATEWAY)
649         *e++ = 3;               /* Default gateway request */
650         *e++ = 4;
651         e   += 4;
652 #endif
653
654 #if defined(CONFIG_BOOTP_DNS)
655         *e++ = 6;               /* Domain Name Server */
656         *e++ = 4;
657         e   += 4;
658 #endif
659
660 #if defined(CONFIG_BOOTP_HOSTNAME)
661         *e++ = 12;              /* Host name request */
662         *e++ = 32;
663         e   += 32;
664 #endif
665
666 #if defined(CONFIG_BOOTP_BOOTFILESIZE)
667         *e++ = 13;              /* Boot file size */
668         *e++ = 2;
669         e   += 2;
670 #endif
671
672 #if defined(CONFIG_BOOTP_BOOTPATH)
673         *e++ = 17;              /* Boot path */
674         *e++ = 32;
675         e   += 32;
676 #endif
677
678 #if defined(CONFIG_BOOTP_NISDOMAIN)
679         *e++ = 40;              /* NIS Domain name request */
680         *e++ = 32;
681         e   += 32;
682 #endif
683 #if defined(CONFIG_BOOTP_NTPSERVER)
684         *e++ = 42;
685         *e++ = 4;
686         e   += 4;
687 #endif
688
689         *e++ = 255;             /* End of the list */
690
691         /*
692          * If nothing in list, remove it altogether. Some DHCP servers get
693          * upset by this minor faux pas and do not respond at all.
694          */
695         if (e == start + 3) {
696                 printf("*** Warning: no DHCP options requested\n");
697                 e -= 3;
698         }
699
700         return e - start;
701 }
702 #endif
703
704 void bootp_reset(void)
705 {
706         bootp_num_ids = 0;
707         bootp_try = 0;
708         bootp_start = get_timer(0);
709         bootp_timeout = 250;
710 }
711
712 void bootp_request(void)
713 {
714         uchar *pkt, *iphdr;
715         struct bootp_hdr *bp;
716         int extlen, pktlen, iplen;
717         int eth_hdr_size;
718 #ifdef CONFIG_BOOTP_RANDOM_DELAY
719         ulong rand_ms;
720 #endif
721         u32 bootp_id;
722         struct in_addr zero_ip;
723         struct in_addr bcast_ip;
724         char *ep;  /* Environment pointer */
725
726         bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
727 #if defined(CONFIG_CMD_DHCP)
728         dhcp_state = INIT;
729 #endif
730
731         ep = env_get("bootpretryperiod");
732         if (ep != NULL)
733                 time_taken_max = simple_strtoul(ep, NULL, 10);
734         else
735                 time_taken_max = TIMEOUT_MS;
736
737 #ifdef CONFIG_BOOTP_RANDOM_DELAY                /* Random BOOTP delay */
738         if (bootp_try == 0)
739                 srand_mac();
740
741         if (bootp_try <= 2)     /* Start with max 1024 * 1ms */
742                 rand_ms = rand() >> (22 - bootp_try);
743         else            /* After 3rd BOOTP request max 8192 * 1ms */
744                 rand_ms = rand() >> 19;
745
746         printf("Random delay: %ld ms...\n", rand_ms);
747         mdelay(rand_ms);
748
749 #endif  /* CONFIG_BOOTP_RANDOM_DELAY */
750
751         printf("BOOTP broadcast %d\n", ++bootp_try);
752         pkt = net_tx_packet;
753         memset((void *)pkt, 0, PKTSIZE);
754
755         eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
756         pkt += eth_hdr_size;
757
758         /*
759          * Next line results in incorrect packet size being transmitted,
760          * resulting in errors in some DHCP servers, reporting missing bytes.
761          * Size must be set in packet header after extension length has been
762          * determined.
763          * C. Hallinan, DS4.COM, Inc.
764          */
765         /* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC,
766                 sizeof (struct bootp_hdr)); */
767         iphdr = pkt;    /* We need this later for net_set_udp_header() */
768         pkt += IP_UDP_HDR_SIZE;
769
770         bp = (struct bootp_hdr *)pkt;
771         bp->bp_op = OP_BOOTREQUEST;
772         bp->bp_htype = HWT_ETHER;
773         bp->bp_hlen = HWL_ETHER;
774         bp->bp_hops = 0;
775         /*
776          * according to RFC1542, should be 0 on first request, secs since
777          * first request otherwise
778          */
779         bp->bp_secs = htons(get_timer(bootp_start) / 1000);
780         zero_ip.s_addr = 0;
781         net_write_ip(&bp->bp_ciaddr, zero_ip);
782         net_write_ip(&bp->bp_yiaddr, zero_ip);
783         net_write_ip(&bp->bp_siaddr, zero_ip);
784         net_write_ip(&bp->bp_giaddr, zero_ip);
785         memcpy(bp->bp_chaddr, net_ethaddr, 6);
786         copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
787
788         /* Request additional information from the BOOTP/DHCP server */
789 #if defined(CONFIG_CMD_DHCP)
790         extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, zero_ip,
791                                zero_ip);
792 #else
793         extlen = bootp_extended((u8 *)bp->bp_vend);
794 #endif
795
796         /*
797          *      Bootp ID is the lower 4 bytes of our ethernet address
798          *      plus the current time in ms.
799          */
800         bootp_id = ((u32)net_ethaddr[2] << 24)
801                 | ((u32)net_ethaddr[3] << 16)
802                 | ((u32)net_ethaddr[4] << 8)
803                 | (u32)net_ethaddr[5];
804         bootp_id += get_timer(0);
805         bootp_id = htonl(bootp_id);
806         bootp_add_id(bootp_id);
807         net_copy_u32(&bp->bp_id, &bootp_id);
808
809         /*
810          * Calculate proper packet lengths taking into account the
811          * variable size of the options field
812          */
813         iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
814         pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
815         bcast_ip.s_addr = 0xFFFFFFFFL;
816         net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
817         net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
818
819 #if defined(CONFIG_CMD_DHCP)
820         dhcp_state = SELECTING;
821         net_set_udp_handler(dhcp_handler);
822 #else
823         net_set_udp_handler(bootp_handler);
824 #endif
825         net_send_packet(net_tx_packet, pktlen);
826 }
827
828 #if defined(CONFIG_CMD_DHCP)
829 static void dhcp_process_options(uchar *popt, uchar *end)
830 {
831         int oplen, size;
832 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
833         int *to_ptr;
834 #endif
835
836         while (popt < end && *popt != 0xff) {
837                 oplen = *(popt + 1);
838                 switch (*popt) {
839                 case 0:
840                         oplen = -1; /* Pad omits len byte */
841                         break;
842                 case 1:
843                         net_copy_ip(&net_netmask, (popt + 2));
844                         break;
845 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
846                 case 2:         /* Time offset  */
847                         to_ptr = &net_ntp_time_offset;
848                         net_copy_u32((u32 *)to_ptr, (u32 *)(popt + 2));
849                         net_ntp_time_offset = ntohl(net_ntp_time_offset);
850                         break;
851 #endif
852                 case 3:
853                         net_copy_ip(&net_gateway, (popt + 2));
854                         break;
855                 case 6:
856                         net_copy_ip(&net_dns_server, (popt + 2));
857 #if defined(CONFIG_BOOTP_DNS2)
858                         if (*(popt + 1) > 4)
859                                 net_copy_ip(&net_dns_server2, (popt + 2 + 4));
860 #endif
861                         break;
862                 case 12:
863                         size = truncate_sz("Host Name",
864                                 sizeof(net_hostname), oplen);
865                         memcpy(&net_hostname, popt + 2, size);
866                         net_hostname[size] = 0;
867                         break;
868                 case 15:        /* Ignore Domain Name Option */
869                         break;
870                 case 17:
871                         size = truncate_sz("Root Path",
872                                 sizeof(net_root_path), oplen);
873                         memcpy(&net_root_path, popt + 2, size);
874                         net_root_path[size] = 0;
875                         break;
876                 case 28:        /* Ignore Broadcast Address Option */
877                         break;
878 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
879                 case 42:        /* NTP server IP */
880                         net_copy_ip(&net_ntp_server, (popt + 2));
881                         break;
882 #endif
883                 case 51:
884                         net_copy_u32(&dhcp_leasetime, (u32 *)(popt + 2));
885                         break;
886                 case 52:
887                         dhcp_option_overload = popt[2];
888                         break;
889                 case 53:        /* Ignore Message Type Option */
890                         break;
891                 case 54:
892                         net_copy_ip(&dhcp_server_ip, (popt + 2));
893                         break;
894                 case 58:        /* Ignore Renewal Time Option */
895                         break;
896                 case 59:        /* Ignore Rebinding Time Option */
897                         break;
898                 case 66:        /* Ignore TFTP server name */
899                         break;
900                 case 67:        /* Bootfile option */
901                         if (!net_boot_file_name_explicit) {
902                                 size = truncate_sz("Bootfile",
903                                                    sizeof(net_boot_file_name),
904                                                    oplen);
905                                 memcpy(&net_boot_file_name, popt + 2, size);
906                                 net_boot_file_name[size] = 0;
907                         }
908                         break;
909                 default:
910 #if defined(CONFIG_BOOTP_VENDOREX)
911                         if (dhcp_vendorex_proc(popt))
912                                 break;
913 #endif
914                         printf("*** Unhandled DHCP Option in OFFER/ACK:"
915                                " %d\n", *popt);
916                         break;
917                 }
918                 popt += oplen + 2;      /* Process next option */
919         }
920 }
921
922 static void dhcp_packet_process_options(struct bootp_hdr *bp)
923 {
924         uchar *popt = (uchar *)&bp->bp_vend[4];
925         uchar *end = popt + BOOTP_HDR_SIZE;
926
927         if (net_read_u32((u32 *)&bp->bp_vend[0]) != htonl(BOOTP_VENDOR_MAGIC))
928                 return;
929
930         dhcp_option_overload = 0;
931
932         /*
933          * The 'options' field MUST be interpreted first, 'file' next,
934          * 'sname' last.
935          */
936         dhcp_process_options(popt, end);
937
938         if (dhcp_option_overload & OVERLOAD_FILE) {
939                 popt = (uchar *)bp->bp_file;
940                 end = popt + sizeof(bp->bp_file);
941                 dhcp_process_options(popt, end);
942         }
943
944         if (dhcp_option_overload & OVERLOAD_SNAME) {
945                 popt = (uchar *)bp->bp_sname;
946                 end = popt + sizeof(bp->bp_sname);
947                 dhcp_process_options(popt, end);
948         }
949 }
950
951 static int dhcp_message_type(unsigned char *popt)
952 {
953         if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
954                 return -1;
955
956         popt += 4;
957         while (*popt != 0xff) {
958                 if (*popt == 53)        /* DHCP Message Type */
959                         return *(popt + 2);
960                 if (*popt == 0) {
961                         /* Pad */
962                         popt += 1;
963                 } else {
964                         /* Scan through all options */
965                         popt += *(popt + 1) + 2;
966                 }
967         }
968         return -1;
969 }
970
971 static void dhcp_send_request_packet(struct bootp_hdr *bp_offer)
972 {
973         uchar *pkt, *iphdr;
974         struct bootp_hdr *bp;
975         int pktlen, iplen, extlen;
976         int eth_hdr_size;
977         struct in_addr offered_ip;
978         struct in_addr zero_ip;
979         struct in_addr bcast_ip;
980
981         debug("dhcp_send_request_packet: Sending DHCPREQUEST\n");
982         pkt = net_tx_packet;
983         memset((void *)pkt, 0, PKTSIZE);
984
985         eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
986         pkt += eth_hdr_size;
987
988         iphdr = pkt;    /* We'll need this later to set proper pkt size */
989         pkt += IP_UDP_HDR_SIZE;
990
991         bp = (struct bootp_hdr *)pkt;
992         bp->bp_op = OP_BOOTREQUEST;
993         bp->bp_htype = HWT_ETHER;
994         bp->bp_hlen = HWL_ETHER;
995         bp->bp_hops = 0;
996         bp->bp_secs = htons(get_timer(bootp_start) / 1000);
997         /* Do not set the client IP, your IP, or server IP yet, since it
998          * hasn't been ACK'ed by the server yet */
999
1000         /*
1001          * RFC3046 requires Relay Agents to discard packets with
1002          * nonzero and offered giaddr
1003          */
1004         zero_ip.s_addr = 0;
1005         net_write_ip(&bp->bp_giaddr, zero_ip);
1006
1007         memcpy(bp->bp_chaddr, net_ethaddr, 6);
1008         copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
1009
1010         /*
1011          * ID is the id of the OFFER packet
1012          */
1013
1014         net_copy_u32(&bp->bp_id, &bp_offer->bp_id);
1015
1016         /*
1017          * Copy options from OFFER packet if present
1018          */
1019
1020         /* Copy offered IP into the parameters request list */
1021         net_copy_ip(&offered_ip, &bp_offer->bp_yiaddr);
1022         extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST,
1023                 dhcp_server_ip, offered_ip);
1024
1025         iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
1026         pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
1027         bcast_ip.s_addr = 0xFFFFFFFFL;
1028         net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
1029
1030 #ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY
1031         udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);
1032 #endif  /* CONFIG_BOOTP_DHCP_REQUEST_DELAY */
1033         debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
1034         net_send_packet(net_tx_packet, pktlen);
1035 }
1036
1037 /*
1038  *      Handle DHCP received packets.
1039  */
1040 static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
1041                          unsigned src, unsigned len)
1042 {
1043         struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
1044
1045         debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
1046               src, dest, len, dhcp_state);
1047
1048         /* Filter out pkts we don't want */
1049         if (check_reply_packet(pkt, dest, src, len))
1050                 return;
1051
1052         debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: "
1053               "%d\n", src, dest, len, dhcp_state);
1054
1055         if (net_read_ip(&bp->bp_yiaddr).s_addr == 0)
1056                 return;
1057
1058         switch (dhcp_state) {
1059         case SELECTING:
1060                 /*
1061                  * Wait an appropriate time for any potential DHCPOFFER packets
1062                  * to arrive.  Then select one, and generate DHCPREQUEST
1063                  * response.  If filename is in format we recognize, assume it
1064                  * is a valid OFFER from a server we want.
1065                  */
1066                 debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);
1067 #ifdef CONFIG_SYS_BOOTFILE_PREFIX
1068                 if (strncmp(bp->bp_file,
1069                             CONFIG_SYS_BOOTFILE_PREFIX,
1070                             strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
1071 #endif  /* CONFIG_SYS_BOOTFILE_PREFIX */
1072                         dhcp_packet_process_options(bp);
1073                         efi_net_set_dhcp_ack(pkt, len);
1074
1075                         debug("TRANSITIONING TO REQUESTING STATE\n");
1076                         dhcp_state = REQUESTING;
1077
1078                         net_set_timeout_handler(5000, bootp_timeout_handler);
1079                         dhcp_send_request_packet(bp);
1080 #ifdef CONFIG_SYS_BOOTFILE_PREFIX
1081                 }
1082 #endif  /* CONFIG_SYS_BOOTFILE_PREFIX */
1083
1084                 return;
1085                 break;
1086         case REQUESTING:
1087                 debug("DHCP State: REQUESTING\n");
1088
1089                 if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
1090                         dhcp_packet_process_options(bp);
1091                         /* Store net params from reply */
1092                         store_net_params(bp);
1093                         dhcp_state = BOUND;
1094                         printf("DHCP client bound to address %pI4 (%lu ms)\n",
1095                                &net_ip, get_timer(bootp_start));
1096                         net_set_timeout_handler(0, (thand_f *)0);
1097                         bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
1098                                             "bootp_stop");
1099
1100                         net_auto_load();
1101                         return;
1102                 }
1103                 break;
1104         case BOUND:
1105                 /* DHCP client bound to address */
1106                 break;
1107         default:
1108                 puts("DHCP: INVALID STATE\n");
1109                 break;
1110         }
1111 }
1112
1113 void dhcp_request(void)
1114 {
1115         bootp_request();
1116 }
1117 #endif  /* CONFIG_CMD_DHCP */