Blame view

net/bootp.c 26.5 KB
3861aa5ce   wdenk   Initial revision
1
2
3
4
5
6
7
  /*
   *	Based on LiMon - BOOTP.
   *
   *	Copyright 1994, 1995, 2000 Neil Russell.
   *	(See License)
   *	Copyright 2000 Roland Borde
   *	Copyright 2000 Paolo Scaffardi
232c150a2   wdenk   Add support for S...
8
   *	Copyright 2000-2004 Wolfgang Denk, wd@denx.de
3861aa5ce   wdenk   Initial revision
9
   */
3861aa5ce   wdenk   Initial revision
10
11
  #include <common.h>
  #include <command.h>
9eef56dbe   Simon Glass   env: Move env_get...
12
  #include <env.h>
0efe1bcf5   Alexander Graf   efi_loader: Add n...
13
  #include <efi_loader.h>
3861aa5ce   wdenk   Initial revision
14
  #include <net.h>
346969584   Lukasz Majewski   net: tftp: Move t...
15
  #include <net/tftp.h>
3861aa5ce   wdenk   Initial revision
16
  #include "bootp.h"
2d8d190c8   Uri Mashiach   status_led: Kconf...
17
  #ifdef CONFIG_LED_STATUS
3861aa5ce   wdenk   Initial revision
18
19
  #include <status_led.h>
  #endif
db7720bad   Kim Phillips   net: make net_ran...
20
21
22
  #ifdef CONFIG_BOOTP_RANDOM_DELAY
  #include "net_rand.h"
  #endif
3861aa5ce   wdenk   Initial revision
23

3090b7e36   Joe Hershberger   net: cosmetic: bo...
24
  #define BOOTP_VENDOR_MAGIC	0x63825363	/* RFC1048 Magic Cookie */
3861aa5ce   wdenk   Initial revision
25

f59be6e85   Stephen Warren   net: BOOTP retry ...
26
27
28
29
30
31
32
33
34
35
  /*
   * The timeout for the initial BOOTP/DHCP request used to be described by a
   * counter of fixed-length timeout periods. TIMEOUT_COUNT represents
   * that counter
   *
   * Now that the timeout periods are variable (exponential backoff and retry)
   * we convert the timeout count to the absolute time it would have take to
   * execute that many retries, and keep sending retry packets until that time
   * is reached.
   */
232c150a2   wdenk   Add support for S...
36
  #ifndef CONFIG_NET_RETRY_COUNT
3090b7e36   Joe Hershberger   net: cosmetic: bo...
37
  # define TIMEOUT_COUNT	5		/* # of timeouts before giving up */
3861aa5ce   wdenk   Initial revision
38
  #else
232c150a2   wdenk   Add support for S...
39
  # define TIMEOUT_COUNT	(CONFIG_NET_RETRY_COUNT)
3861aa5ce   wdenk   Initial revision
40
  #endif
f59be6e85   Stephen Warren   net: BOOTP retry ...
41
  #define TIMEOUT_MS	((3 + (TIMEOUT_COUNT * 5)) * 1000)
3861aa5ce   wdenk   Initial revision
42

3090b7e36   Joe Hershberger   net: cosmetic: bo...
43
44
  #define PORT_BOOTPS	67		/* BOOTP server UDP port */
  #define PORT_BOOTPC	68		/* BOOTP client UDP port */
3861aa5ce   wdenk   Initial revision
45

3090b7e36   Joe Hershberger   net: cosmetic: bo...
46
  #ifndef CONFIG_DHCP_MIN_EXT_LEN		/* minimal length of extension list */
232c150a2   wdenk   Add support for S...
47
  #define CONFIG_DHCP_MIN_EXT_LEN 64
3861aa5ce   wdenk   Initial revision
48
  #endif
92ac8acc0   Thierry Reding   net: More BOOTP r...
49
50
51
  #ifndef CONFIG_BOOTP_ID_CACHE_SIZE
  #define CONFIG_BOOTP_ID_CACHE_SIZE 4
  #endif
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
52
  u32		bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE];
92ac8acc0   Thierry Reding   net: More BOOTP r...
53
  unsigned int	bootp_num_ids;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
54
  int		bootp_try;
f59be6e85   Stephen Warren   net: BOOTP retry ...
55
56
  ulong		bootp_start;
  ulong		bootp_timeout;
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
57
58
59
  char net_nis_domain[32] = {0,}; /* Our NIS domain */
  char net_hostname[32] = {0,}; /* Our hostname */
  char net_root_path[64] = {0,}; /* Our bootpath */
3861aa5ce   wdenk   Initial revision
60

50768f5b0   Alexandre Messier   net: bootp: Add e...
61
  static ulong time_taken_max;
643d1ab23   Jon Loeliger   net/: Remove obso...
62
  #if defined(CONFIG_CMD_DHCP)
063705908   Kim Phillips   net/: sparse fixes
63
  static dhcp_state_t dhcp_state = INIT;
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
64
  static u32 dhcp_leasetime;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
65
  static struct in_addr dhcp_server_ip;
ec87b1b39   Stefan Brüns   net: Do not overw...
66
67
68
  static u8 dhcp_option_overload;
  #define OVERLOAD_FILE 1
  #define OVERLOAD_SNAME 2
049a95a77   Joe Hershberger   net: cosmetic: Ch...
69
70
  static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
  			unsigned src, unsigned len);
3861aa5ce   wdenk   Initial revision
71
72
  
  /* For Debug */
3e38691e8   wdenk   * Patch by Arun D...
73
74
  #if 0
  static char *dhcpmsg2str(int type)
3861aa5ce   wdenk   Initial revision
75
76
  {
  	switch (type) {
232c150a2   wdenk   Add support for S...
77
78
79
80
81
82
83
  	case 1:	 return "DHCPDISCOVER"; break;
  	case 2:	 return "DHCPOFFER";	break;
  	case 3:	 return "DHCPREQUEST";	break;
  	case 4:	 return "DHCPDECLINE";	break;
  	case 5:	 return "DHCPACK";	break;
  	case 6:	 return "DHCPNACK";	break;
  	case 7:	 return "DHCPRELEASE";	break;
3861aa5ce   wdenk   Initial revision
84
85
86
  	default: return "UNKNOWN/INVALID MSG TYPE"; break;
  	}
  }
3e38691e8   wdenk   * Patch by Arun D...
87
  #endif
610f2e9c2   Jon Loeliger   net/: Remove ling...
88
  #endif
3861aa5ce   wdenk   Initial revision
89

92ac8acc0   Thierry Reding   net: More BOOTP r...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  static void bootp_add_id(ulong id)
  {
  	if (bootp_num_ids >= ARRAY_SIZE(bootp_ids)) {
  		size_t size = sizeof(bootp_ids) - sizeof(id);
  
  		memmove(bootp_ids, &bootp_ids[1], size);
  		bootp_ids[bootp_num_ids - 1] = id;
  	} else {
  		bootp_ids[bootp_num_ids] = id;
  		bootp_num_ids++;
  	}
  }
  
  static bool bootp_match_id(ulong id)
  {
  	unsigned int i;
  
  	for (i = 0; i < bootp_num_ids; i++)
  		if (bootp_ids[i] == id)
  			return true;
  
  	return false;
  }
867d6ae2c   Stefan Brüns   net: reject Bootp...
113
114
  static int check_reply_packet(uchar *pkt, unsigned dest, unsigned src,
  			      unsigned len)
3861aa5ce   wdenk   Initial revision
115
  {
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
116
  	struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
117
118
119
120
  	int retval = 0;
  
  	if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
  		retval = -1;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
121
  	else if (len < sizeof(struct bootp_hdr) - OPT_FIELD_SIZE)
3861aa5ce   wdenk   Initial revision
122
  		retval = -2;
867d6ae2c   Stefan Brüns   net: reject Bootp...
123
  	else if (bp->bp_op != OP_BOOTREPLY)
3861aa5ce   wdenk   Initial revision
124
  		retval = -3;
3861aa5ce   wdenk   Initial revision
125
126
127
128
  	else if (bp->bp_htype != HWT_ETHER)
  		retval = -4;
  	else if (bp->bp_hlen != HWL_ETHER)
  		retval = -5;
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
129
  	else if (!bootp_match_id(net_read_u32(&bp->bp_id)))
3861aa5ce   wdenk   Initial revision
130
  		retval = -6;
214cc905d   Anton Persson   bootp: Prevent u-...
131
132
  	else if (memcmp(bp->bp_chaddr, net_ethaddr, HWL_ETHER) != 0)
  		retval = -7;
3861aa5ce   wdenk   Initial revision
133

0ebf04c60   Robin Getz   minor debug clean...
134
135
  	debug("Filtering pkt = %d
  ", retval);
3861aa5ce   wdenk   Initial revision
136
137
138
139
140
141
142
  
  	return retval;
  }
  
  /*
   * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
   */
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
143
  static void store_net_params(struct bootp_hdr *bp)
3861aa5ce   wdenk   Initial revision
144
  {
5d110f0aa   Wilson Callan   New CONFIG_BOOTP_...
145
  #if !defined(CONFIG_BOOTP_SERVERIP)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
146
  	struct in_addr tmp_ip;
bdce340cc   Alexander Graf   net: Add option t...
147
148
149
150
151
  	bool overwrite_serverip = true;
  
  #if defined(CONFIG_BOOTP_PREFER_SERVERIP)
  	overwrite_serverip = false;
  #endif
1752f0fdc   Joe Hershberger   net: Fix unused v...
152

049a95a77   Joe Hershberger   net: cosmetic: Ch...
153
  	net_copy_ip(&tmp_ip, &bp->bp_siaddr);
bdce340cc   Alexander Graf   net: Add option t...
154
  	if (tmp_ip.s_addr != 0 && (overwrite_serverip || !net_server_ip.s_addr))
049a95a77   Joe Hershberger   net: cosmetic: Ch...
155
  		net_copy_ip(&net_server_ip, &bp->bp_siaddr);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
156
157
  	memcpy(net_server_ethaddr,
  	       ((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
ec87b1b39   Stefan Brüns   net: Do not overw...
158
159
160
161
  	if (
  #if defined(CONFIG_CMD_DHCP)
  	    !(dhcp_option_overload & OVERLOAD_FILE) &&
  #endif
449312c1c   Alexander Graf   net: Prefer comma...
162
163
  	    (strlen(bp->bp_file) > 0) &&
  	    !net_boot_file_name_explicit) {
1411157d8   Joe Hershberger   net: cosmetic: Fi...
164
165
  		copy_filename(net_boot_file_name, bp->bp_file,
  			      sizeof(net_boot_file_name));
ec87b1b39   Stefan Brüns   net: Do not overw...
166
  	}
3861aa5ce   wdenk   Initial revision
167

1411157d8   Joe Hershberger   net: cosmetic: Fi...
168
169
  	debug("net_boot_file_name: %s
  ", net_boot_file_name);
3861aa5ce   wdenk   Initial revision
170
171
  
  	/* Propagate to environment:
8bde7f776   wdenk   * Code cleanup:
172
  	 * don't delete exising entry when BOOTP / DHCP reply does
3861aa5ce   wdenk   Initial revision
173
174
  	 * not contain a new value
  	 */
1411157d8   Joe Hershberger   net: cosmetic: Fi...
175
  	if (*net_boot_file_name)
382bee57f   Simon Glass   env: Rename seten...
176
  		env_set("bootfile", net_boot_file_name);
ecec4e9c8   Wu, Josh   net: bootp: as CO...
177
  #endif
049a95a77   Joe Hershberger   net: cosmetic: Ch...
178
  	net_copy_ip(&net_ip, &bp->bp_yiaddr);
3861aa5ce   wdenk   Initial revision
179
  }
3090b7e36   Joe Hershberger   net: cosmetic: bo...
180
  static int truncate_sz(const char *name, int maxlen, int curlen)
3861aa5ce   wdenk   Initial revision
181
182
  {
  	if (curlen >= maxlen) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
183
184
185
  		printf("*** WARNING: %s is too long (%d - max: %d)"
  			" - truncated
  ", name, curlen, maxlen);
3861aa5ce   wdenk   Initial revision
186
187
  		curlen = maxlen - 1;
  	}
3090b7e36   Joe Hershberger   net: cosmetic: bo...
188
  	return curlen;
3861aa5ce   wdenk   Initial revision
189
  }
643d1ab23   Jon Loeliger   net/: Remove obso...
190
  #if !defined(CONFIG_CMD_DHCP)
3861aa5ce   wdenk   Initial revision
191

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
192
  static void bootp_process_vendor_field(u8 *ext)
3861aa5ce   wdenk   Initial revision
193
  {
232c150a2   wdenk   Add support for S...
194
  	int size = *(ext + 1);
3861aa5ce   wdenk   Initial revision
195

0ebf04c60   Robin Getz   minor debug clean...
196
197
  	debug("[BOOTP] Processing extension %d... (%d bytes)
  ", *ext,
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
198
  	      *(ext + 1));
3861aa5ce   wdenk   Initial revision
199

1411157d8   Joe Hershberger   net: cosmetic: Fi...
200
  	net_boot_file_expected_size_in_blocks = 0;
3861aa5ce   wdenk   Initial revision
201

232c150a2   wdenk   Add support for S...
202
203
  	switch (*ext) {
  		/* Fixed length fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
204
  	case 1:			/* Subnet mask */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
205
206
  		if (net_netmask.s_addr == 0)
  			net_copy_ip(&net_netmask, (struct in_addr *)(ext + 2));
3861aa5ce   wdenk   Initial revision
207
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
208
  	case 2:			/* Time offset - Not yet supported */
3861aa5ce   wdenk   Initial revision
209
  		break;
232c150a2   wdenk   Add support for S...
210
  		/* Variable length fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
211
  	case 3:			/* Gateways list */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
212
213
  		if (net_gateway.s_addr == 0)
  			net_copy_ip(&net_gateway, (struct in_addr *)(ext + 2));
3861aa5ce   wdenk   Initial revision
214
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
215
  	case 4:			/* Time server - Not yet supported */
3861aa5ce   wdenk   Initial revision
216
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
217
  	case 5:			/* IEN-116 name server - Not yet supported */
3861aa5ce   wdenk   Initial revision
218
219
  		break;
  	case 6:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
220
221
222
  		if (net_dns_server.s_addr == 0)
  			net_copy_ip(&net_dns_server,
  				    (struct in_addr *)(ext + 2));
1fe80d79c   Jon Loeliger   Finally retire cm...
223
  #if defined(CONFIG_BOOTP_DNS2)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
224
225
226
  		if ((net_dns_server2.s_addr == 0) && (size > 4))
  			net_copy_ip(&net_dns_server2,
  				    (struct in_addr *)(ext + 2 + 4));
fe389a82c   stroese   - Added CONFIG_BO...
227
  #endif
3861aa5ce   wdenk   Initial revision
228
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
229
  	case 7:			/* Log server - Not yet supported */
3861aa5ce   wdenk   Initial revision
230
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
231
  	case 8:			/* Cookie/Quote server - Not yet supported */
3861aa5ce   wdenk   Initial revision
232
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
233
  	case 9:			/* LPR server - Not yet supported */
3861aa5ce   wdenk   Initial revision
234
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
235
  	case 10:		/* Impress server - Not yet supported */
3861aa5ce   wdenk   Initial revision
236
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
237
  	case 11:		/* RPL server - Not yet supported */
3861aa5ce   wdenk   Initial revision
238
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
239
  	case 12:		/* Host name */
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
240
  		if (net_hostname[0] == 0) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
241
  			size = truncate_sz("Host Name",
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
242
243
244
  				sizeof(net_hostname), size);
  			memcpy(&net_hostname, ext + 2, size);
  			net_hostname[size] = 0;
3861aa5ce   wdenk   Initial revision
245
246
  		}
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
247
  	case 13:		/* Boot file size */
3861aa5ce   wdenk   Initial revision
248
  		if (size == 2)
1411157d8   Joe Hershberger   net: cosmetic: Fi...
249
250
  			net_boot_file_expected_size_in_blocks =
  				ntohs(*(ushort *)(ext + 2));
3861aa5ce   wdenk   Initial revision
251
  		else if (size == 4)
1411157d8   Joe Hershberger   net: cosmetic: Fi...
252
253
  			net_boot_file_expected_size_in_blocks =
  				ntohl(*(ulong *)(ext + 2));
3861aa5ce   wdenk   Initial revision
254
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
255
  	case 14:		/* Merit dump file - Not yet supported */
3861aa5ce   wdenk   Initial revision
256
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
257
  	case 15:		/* Domain name - Not yet supported */
3861aa5ce   wdenk   Initial revision
258
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
259
  	case 16:		/* Swap server - Not yet supported */
3861aa5ce   wdenk   Initial revision
260
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
261
  	case 17:		/* Root path */
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
262
  		if (net_root_path[0] == 0) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
263
  			size = truncate_sz("Root Path",
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
264
265
266
  				sizeof(net_root_path), size);
  			memcpy(&net_root_path, ext + 2, size);
  			net_root_path[size] = 0;
3861aa5ce   wdenk   Initial revision
267
268
  		}
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
269
  	case 18:		/* Extension path - Not yet supported */
3861aa5ce   wdenk   Initial revision
270
  		/*
8bde7f776   wdenk   * Code cleanup:
271
272
273
  		 * This can be used to send the information of the
  		 * vendor area in another file that the client can
  		 * access via TFTP.
3861aa5ce   wdenk   Initial revision
274
275
  		 */
  		break;
232c150a2   wdenk   Add support for S...
276
  		/* IP host layer fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
277
  	case 40:		/* NIS Domain name */
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
278
  		if (net_nis_domain[0] == 0) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
279
  			size = truncate_sz("NIS Domain Name",
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
280
281
282
  				sizeof(net_nis_domain), size);
  			memcpy(&net_nis_domain, ext + 2, size);
  			net_nis_domain[size] = 0;
3861aa5ce   wdenk   Initial revision
283
284
  		}
  		break;
09e3a67de   Luuk Paulussen   bootp: add ntpser...
285
286
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
  	case 42:	/* NTP server IP */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
287
  		net_copy_ip(&net_ntp_server, (struct in_addr *)(ext + 2));
09e3a67de   Luuk Paulussen   bootp: add ntpser...
288
289
  		break;
  #endif
232c150a2   wdenk   Add support for S...
290
  		/* Application layer fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
291
  	case 43:		/* Vendor specific info - Not yet supported */
3861aa5ce   wdenk   Initial revision
292
  		/*
8bde7f776   wdenk   * Code cleanup:
293
294
  		 * Binary information to exchange specific
  		 * product information.
3861aa5ce   wdenk   Initial revision
295
296
  		 */
  		break;
232c150a2   wdenk   Add support for S...
297
298
  		/* Reserved (custom) fields (128..254) */
  	}
3861aa5ce   wdenk   Initial revision
299
  }
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
300
  static void bootp_process_vendor(u8 *ext, int size)
3861aa5ce   wdenk   Initial revision
301
  {
232c150a2   wdenk   Add support for S...
302
  	u8 *end = ext + size;
3861aa5ce   wdenk   Initial revision
303

0ebf04c60   Robin Getz   minor debug clean...
304
305
  	debug("[BOOTP] Checking extension (%d bytes)...
  ", size);
3861aa5ce   wdenk   Initial revision
306

232c150a2   wdenk   Add support for S...
307
308
309
310
311
312
313
314
  	while ((ext < end) && (*ext != 0xff)) {
  		if (*ext == 0) {
  			ext++;
  		} else {
  			u8 *opt = ext;
  
  			ext += ext[1] + 2;
  			if (ext <= end)
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
315
  				bootp_process_vendor_field(opt);
232c150a2   wdenk   Add support for S...
316
  		}
3861aa5ce   wdenk   Initial revision
317
  	}
3861aa5ce   wdenk   Initial revision
318

3090b7e36   Joe Hershberger   net: cosmetic: bo...
319
320
  	debug("[BOOTP] Received fields:
  ");
049a95a77   Joe Hershberger   net: cosmetic: Ch...
321
322
323
  	if (net_netmask.s_addr)
  		debug("net_netmask : %pI4
  ", &net_netmask);
232c150a2   wdenk   Add support for S...
324

049a95a77   Joe Hershberger   net: cosmetic: Ch...
325
326
  	if (net_gateway.s_addr)
  		debug("net_gateway	: %pI4", &net_gateway);
232c150a2   wdenk   Add support for S...
327

1411157d8   Joe Hershberger   net: cosmetic: Fi...
328
329
330
331
  	if (net_boot_file_expected_size_in_blocks)
  		debug("net_boot_file_expected_size_in_blocks : %d
  ",
  		      net_boot_file_expected_size_in_blocks);
3861aa5ce   wdenk   Initial revision
332

586cbe51a   Joe Hershberger   net: cosmetic: Fi...
333
334
335
  	if (net_hostname[0])
  		debug("net_hostname  : %s
  ", net_hostname);
232c150a2   wdenk   Add support for S...
336

586cbe51a   Joe Hershberger   net: cosmetic: Fi...
337
338
339
  	if (net_root_path[0])
  		debug("net_root_path  : %s
  ", net_root_path);
232c150a2   wdenk   Add support for S...
340

586cbe51a   Joe Hershberger   net: cosmetic: Fi...
341
342
343
  	if (net_nis_domain[0])
  		debug("net_nis_domain : %s
  ", net_nis_domain);
232c150a2   wdenk   Add support for S...
344

09e3a67de   Luuk Paulussen   bootp: add ntpser...
345
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
4b4dc5211   Chris Packham   net: bootp: Fix c...
346
  	if (net_ntp_server.s_addr)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
347
348
  		debug("net_ntp_server : %pI4
  ", &net_ntp_server);
09e3a67de   Luuk Paulussen   bootp: add ntpser...
349
  #endif
232c150a2   wdenk   Add support for S...
350
  }
093498669   Simon Glass   Put common autolo...
351

3861aa5ce   wdenk   Initial revision
352
353
354
  /*
   *	Handle a BOOTP received packet.
   */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
355
356
  static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
  			  unsigned src, unsigned len)
3861aa5ce   wdenk   Initial revision
357
  {
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
358
  	struct bootp_hdr *bp;
3861aa5ce   wdenk   Initial revision
359

0ebf04c60   Robin Getz   minor debug clean...
360
361
  	debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)
  ",
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
362
  	      src, dest, len, sizeof(struct bootp_hdr));
3861aa5ce   wdenk   Initial revision
363

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
364
  	bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
365

3090b7e36   Joe Hershberger   net: cosmetic: bo...
366
  	/* Filter out pkts we don't want */
867d6ae2c   Stefan Brüns   net: reject Bootp...
367
  	if (check_reply_packet(pkt, dest, src, len))
3861aa5ce   wdenk   Initial revision
368
369
370
  		return;
  
  	/*
232c150a2   wdenk   Add support for S...
371
  	 *	Got a good BOOTP reply.	 Copy the data into our variables.
3861aa5ce   wdenk   Initial revision
372
  	 */
2d8d190c8   Uri Mashiach   status_led: Kconf...
373
374
  #if defined(CONFIG_LED_STATUS) && defined(CONFIG_LED_STATUS_BOOT_ENABLE)
  	status_led_set(CONFIG_LED_STATUS_BOOT, CONFIG_LED_STATUS_OFF);
3861aa5ce   wdenk   Initial revision
375
  #endif
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
376
  	store_net_params(bp);		/* Store net parameters from reply */
3861aa5ce   wdenk   Initial revision
377
378
  
  	/* Retrieve extended information (we must parse the vendor area) */
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
379
  	if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
380
  		bootp_process_vendor((uchar *)&bp->bp_vend[4], len);
3861aa5ce   wdenk   Initial revision
381

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
382
  	net_set_timeout_handler(0, (thand_f *)0);
573f14fe4   Simon Glass   bootstage: Plumb ...
383
  	bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop");
3861aa5ce   wdenk   Initial revision
384

0ebf04c60   Robin Getz   minor debug clean...
385
386
  	debug("Got good BOOTP
  ");
3861aa5ce   wdenk   Initial revision
387

e4a3d57dc   Simon Glass   net: Export auto_...
388
  	net_auto_load();
3861aa5ce   wdenk   Initial revision
389
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
390
  #endif
3861aa5ce   wdenk   Initial revision
391
392
393
394
  
  /*
   *	Timeout on BOOTP/DHCP request.
   */
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
395
  static void bootp_timeout_handler(void)
3861aa5ce   wdenk   Initial revision
396
  {
f59be6e85   Stephen Warren   net: BOOTP retry ...
397
  	ulong time_taken = get_timer(bootp_start);
50768f5b0   Alexandre Messier   net: bootp: Add e...
398
  	if (time_taken >= time_taken_max) {
2c00e099f   Joe Hershberger   net: Add option C...
399
  #ifdef CONFIG_BOOTP_MAY_FAIL
2099b9f27   Joe Hershberger   net: dhcp: Allow ...
400
401
402
403
404
405
406
407
408
409
  		char *ethrotate;
  
  		ethrotate = env_get("ethrotate");
  		if ((ethrotate && strcmp(ethrotate, "no") == 0) ||
  		    net_restart_wrap) {
  			puts("
  Retry time exceeded
  ");
  			net_set_state(NETLOOP_FAIL);
  		} else
2c00e099f   Joe Hershberger   net: Add option C...
410
  #endif
2099b9f27   Joe Hershberger   net: dhcp: Allow ...
411
412
413
414
415
416
  		{
  			puts("
  Retry time exceeded; starting again
  ");
  			net_start_again();
  		}
3861aa5ce   wdenk   Initial revision
417
  	} else {
f59be6e85   Stephen Warren   net: BOOTP retry ...
418
  		bootp_timeout *= 2;
92ac8acc0   Thierry Reding   net: More BOOTP r...
419
420
  		if (bootp_timeout > 2000)
  			bootp_timeout = 2000;
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
421
  		net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
422
  		bootp_request();
3861aa5ce   wdenk   Initial revision
423
424
  	}
  }
9ace17c88   Ilya Yanok   net/bootp: add VC...
425
426
427
428
429
430
431
432
  #define put_vci(e, str)						\
  	do {							\
  		size_t vci_strlen = strlen(str);		\
  		*e++ = 60;	/* Vendor Class Identifier */	\
  		*e++ = vci_strlen;				\
  		memcpy(e, str, vci_strlen);			\
  		e += vci_strlen;				\
  	} while (0)
4570a993d   Alexander Graf   bootp: Move vendo...
433
434
  static u8 *add_vci(u8 *e)
  {
20898ea93   Alexander Graf   distro: Add efi p...
435
  	char *vci = NULL;
00caae6d4   Simon Glass   env: Rename geten...
436
  	char *env_vci = env_get("bootp_vci");
20898ea93   Alexander Graf   distro: Add efi p...
437

4570a993d   Alexander Graf   bootp: Move vendo...
438
  #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING)
20898ea93   Alexander Graf   distro: Add efi p...
439
  	vci = CONFIG_SPL_NET_VCI_STRING;
4570a993d   Alexander Graf   bootp: Move vendo...
440
  #elif defined(CONFIG_BOOTP_VCI_STRING)
20898ea93   Alexander Graf   distro: Add efi p...
441
  	vci = CONFIG_BOOTP_VCI_STRING;
4570a993d   Alexander Graf   bootp: Move vendo...
442
  #endif
20898ea93   Alexander Graf   distro: Add efi p...
443
444
445
446
447
  	if (env_vci)
  		vci = env_vci;
  
  	if (vci)
  		put_vci(e, vci);
4570a993d   Alexander Graf   bootp: Move vendo...
448
449
  	return e;
  }
3861aa5ce   wdenk   Initial revision
450
451
452
  /*
   *	Initialize BOOTP extension fields in the request.
   */
643d1ab23   Jon Loeliger   net/: Remove obso...
453
  #if defined(CONFIG_CMD_DHCP)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
454
455
  static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
  			struct in_addr requested_ip)
3861aa5ce   wdenk   Initial revision
456
  {
232c150a2   wdenk   Add support for S...
457
458
  	u8 *start = e;
  	u8 *cnt;
bc6fc28b8   Alexander Graf   net: Optionally u...
459
  #ifdef CONFIG_LIB_UUID
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
460
  	char *uuid;
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
461
  #endif
bc6fc28b8   Alexander Graf   net: Optionally u...
462
  	int clientarch = -1;
232c150a2   wdenk   Add support for S...
463

1fe80d79c   Jon Loeliger   Finally retire cm...
464
  #if defined(CONFIG_BOOTP_VENDOREX)
232c150a2   wdenk   Add support for S...
465
  	u8 *x;
3861aa5ce   wdenk   Initial revision
466
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
467
  #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
77ddac948   Wolfgang Denk   Cleanup for GCC-4.x
468
  	char *hostname;
fe389a82c   stroese   - Added CONFIG_BO...
469
  #endif
3861aa5ce   wdenk   Initial revision
470

232c150a2   wdenk   Add support for S...
471
472
473
474
  	*e++ = 99;		/* RFC1048 Magic Cookie */
  	*e++ = 130;
  	*e++ = 83;
  	*e++ = 99;
3861aa5ce   wdenk   Initial revision
475

232c150a2   wdenk   Add support for S...
476
477
478
  	*e++ = 53;		/* DHCP Message Type */
  	*e++ = 1;
  	*e++ = message_type;
3861aa5ce   wdenk   Initial revision
479

232c150a2   wdenk   Add support for S...
480
481
  	*e++ = 57;		/* Maximum DHCP Message Size */
  	*e++ = 2;
f8315731d   Joe Hershberger   net: cosmetic: Re...
482
483
  	*e++ = (576 - 312 + OPT_FIELD_SIZE) >> 8;
  	*e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
3861aa5ce   wdenk   Initial revision
484

049a95a77   Joe Hershberger   net: cosmetic: Ch...
485
486
  	if (server_ip.s_addr) {
  		int tmp = ntohl(server_ip.s_addr);
3861aa5ce   wdenk   Initial revision
487

232c150a2   wdenk   Add support for S...
488
489
490
491
492
493
494
  		*e++ = 54;	/* ServerID */
  		*e++ = 4;
  		*e++ = tmp >> 24;
  		*e++ = tmp >> 16;
  		*e++ = tmp >> 8;
  		*e++ = tmp & 0xff;
  	}
3861aa5ce   wdenk   Initial revision
495

049a95a77   Joe Hershberger   net: cosmetic: Ch...
496
497
  	if (requested_ip.s_addr) {
  		int tmp = ntohl(requested_ip.s_addr);
3861aa5ce   wdenk   Initial revision
498

232c150a2   wdenk   Add support for S...
499
500
501
502
503
504
505
  		*e++ = 50;	/* Requested IP */
  		*e++ = 4;
  		*e++ = tmp >> 24;
  		*e++ = tmp >> 16;
  		*e++ = tmp >> 8;
  		*e++ = tmp & 0xff;
  	}
1fe80d79c   Jon Loeliger   Finally retire cm...
506
  #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
00caae6d4   Simon Glass   env: Rename geten...
507
  	hostname = env_get("hostname");
3090b7e36   Joe Hershberger   net: cosmetic: bo...
508
509
  	if (hostname) {
  		int hostnamelen = strlen(hostname);
232c150a2   wdenk   Add support for S...
510
511
512
  
  		*e++ = 12;	/* Hostname */
  		*e++ = hostnamelen;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
513
  		memcpy(e, hostname, hostnamelen);
232c150a2   wdenk   Add support for S...
514
515
  		e += hostnamelen;
  	}
fe389a82c   stroese   - Added CONFIG_BO...
516
  #endif
bc6fc28b8   Alexander Graf   net: Optionally u...
517
  #ifdef CONFIG_BOOTP_PXE_CLIENTARCH
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
518
  	clientarch = CONFIG_BOOTP_PXE_CLIENTARCH;
bc6fc28b8   Alexander Graf   net: Optionally u...
519
  #endif
00caae6d4   Simon Glass   env: Rename geten...
520
  	if (env_get("bootp_arch"))
bfebc8c96   Simon Glass   env: Rename geten...
521
  		clientarch = env_get_ulong("bootp_arch", 16, clientarch);
bc6fc28b8   Alexander Graf   net: Optionally u...
522
523
524
525
526
527
528
  
  	if (clientarch > 0) {
  		*e++ = 93;	/* Client System Architecture */
  		*e++ = 2;
  		*e++ = (clientarch >> 8) & 0xff;
  		*e++ = clientarch & 0xff;
  	}
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
529
530
531
532
533
534
  
  	*e++ = 94;	/* Client Network Interface Identifier */
  	*e++ = 3;
  	*e++ = 1;	/* type field for UNDI */
  	*e++ = 0;	/* major revision */
  	*e++ = 0;	/* minor revision */
bc6fc28b8   Alexander Graf   net: Optionally u...
535
  #ifdef CONFIG_LIB_UUID
00caae6d4   Simon Glass   env: Rename geten...
536
  	uuid = env_get("pxeuuid");
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
537
538
539
540
541
542
  
  	if (uuid) {
  		if (uuid_str_valid(uuid)) {
  			*e++ = 97;	/* Client Machine Identifier */
  			*e++ = 17;
  			*e++ = 0;	/* type 0 - UUID */
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
543
  			uuid_str_to_bin(uuid, e, UUID_STR_FORMAT_STD);
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
544
545
546
547
548
549
  			e += 16;
  		} else {
  			printf("Invalid pxeuuid: %s
  ", uuid);
  		}
  	}
9ace17c88   Ilya Yanok   net/bootp: add VC...
550
  #endif
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
551

4570a993d   Alexander Graf   bootp: Move vendo...
552
  	e = add_vci(e);
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
553

1fe80d79c   Jon Loeliger   Finally retire cm...
554
  #if defined(CONFIG_BOOTP_VENDOREX)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
555
556
  	x = dhcp_vendorex_prep(e);
  	if (x)
232c150a2   wdenk   Add support for S...
557
  		return x - start;
3861aa5ce   wdenk   Initial revision
558
  #endif
232c150a2   wdenk   Add support for S...
559
560
561
  	*e++ = 55;		/* Parameter Request List */
  	 cnt = e++;		/* Pointer to count of requested items */
  	*cnt = 0;
1fe80d79c   Jon Loeliger   Finally retire cm...
562
  #if defined(CONFIG_BOOTP_SUBNETMASK)
232c150a2   wdenk   Add support for S...
563
564
  	*e++  = 1;		/* Subnet Mask */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
565
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
566
  #if defined(CONFIG_BOOTP_TIMEOFFSET)
ea287debe   wdenk   * Patch by Masami...
567
568
569
  	*e++  = 2;
  	*cnt += 1;
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
570
  #if defined(CONFIG_BOOTP_GATEWAY)
232c150a2   wdenk   Add support for S...
571
572
  	*e++  = 3;		/* Router Option */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
573
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
574
  #if defined(CONFIG_BOOTP_DNS)
232c150a2   wdenk   Add support for S...
575
576
  	*e++  = 6;		/* DNS Server(s) */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
577
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
578
  #if defined(CONFIG_BOOTP_HOSTNAME)
232c150a2   wdenk   Add support for S...
579
580
  	*e++  = 12;		/* Hostname */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
581
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
582
  #if defined(CONFIG_BOOTP_BOOTFILESIZE)
232c150a2   wdenk   Add support for S...
583
584
  	*e++  = 13;		/* Boot File Size */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
585
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
586
  #if defined(CONFIG_BOOTP_BOOTPATH)
232c150a2   wdenk   Add support for S...
587
588
  	*e++  = 17;		/* Boot path */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
589
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
590
  #if defined(CONFIG_BOOTP_NISDOMAIN)
232c150a2   wdenk   Add support for S...
591
592
  	*e++  = 40;		/* NIS Domain name request */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
593
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
594
  #if defined(CONFIG_BOOTP_NTPSERVER)
ea287debe   wdenk   * Patch by Masami...
595
596
597
  	*e++  = 42;
  	*cnt += 1;
  #endif
258ccd681   Jason Liu   net: Fix potentia...
598
599
600
  	/* no options, so back up to avoid sending an empty request list */
  	if (*cnt == 0)
  		e -= 2;
232c150a2   wdenk   Add support for S...
601
  	*e++  = 255;		/* End of the list */
3861aa5ce   wdenk   Initial revision
602

232c150a2   wdenk   Add support for S...
603
  	/* Pad to minimal length */
3861aa5ce   wdenk   Initial revision
604
  #ifdef	CONFIG_DHCP_MIN_EXT_LEN
21076f61c   Simon Glass   Fix bad padding o...
605
  	while ((e - start) < CONFIG_DHCP_MIN_EXT_LEN)
232c150a2   wdenk   Add support for S...
606
  		*e++ = 0;
3861aa5ce   wdenk   Initial revision
607
  #endif
232c150a2   wdenk   Add support for S...
608
  	return e - start;
3861aa5ce   wdenk   Initial revision
609
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
610
  #else
3861aa5ce   wdenk   Initial revision
611
  /*
3090b7e36   Joe Hershberger   net: cosmetic: bo...
612
   * Warning: no field size check - change CONFIG_BOOTP_* at your own risk!
3861aa5ce   wdenk   Initial revision
613
   */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
614
  static int bootp_extended(u8 *e)
3861aa5ce   wdenk   Initial revision
615
  {
232c150a2   wdenk   Add support for S...
616
  	u8 *start = e;
3861aa5ce   wdenk   Initial revision
617

232c150a2   wdenk   Add support for S...
618
619
620
621
  	*e++ = 99;		/* RFC1048 Magic Cookie */
  	*e++ = 130;
  	*e++ = 83;
  	*e++ = 99;
3861aa5ce   wdenk   Initial revision
622

643d1ab23   Jon Loeliger   net/: Remove obso...
623
  #if defined(CONFIG_CMD_DHCP)
232c150a2   wdenk   Add support for S...
624
625
626
627
628
629
  	*e++ = 53;		/* DHCP Message Type */
  	*e++ = 1;
  	*e++ = DHCP_DISCOVER;
  
  	*e++ = 57;		/* Maximum DHCP Message Size */
  	*e++ = 2;
f8315731d   Joe Hershberger   net: cosmetic: Re...
630
631
  	*e++ = (576 - 312 + OPT_FIELD_SIZE) >> 16;
  	*e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
610f2e9c2   Jon Loeliger   net/: Remove ling...
632
  #endif
3861aa5ce   wdenk   Initial revision
633

4570a993d   Alexander Graf   bootp: Move vendo...
634
  	add_vci(e);
9ace17c88   Ilya Yanok   net/bootp: add VC...
635

1fe80d79c   Jon Loeliger   Finally retire cm...
636
  #if defined(CONFIG_BOOTP_SUBNETMASK)
232c150a2   wdenk   Add support for S...
637
638
639
  	*e++ = 1;		/* Subnet mask request */
  	*e++ = 4;
  	e   += 4;
3861aa5ce   wdenk   Initial revision
640
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
641
  #if defined(CONFIG_BOOTP_GATEWAY)
232c150a2   wdenk   Add support for S...
642
643
644
  	*e++ = 3;		/* Default gateway request */
  	*e++ = 4;
  	e   += 4;
3861aa5ce   wdenk   Initial revision
645
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
646
  #if defined(CONFIG_BOOTP_DNS)
232c150a2   wdenk   Add support for S...
647
648
649
  	*e++ = 6;		/* Domain Name Server */
  	*e++ = 4;
  	e   += 4;
3861aa5ce   wdenk   Initial revision
650
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
651
  #if defined(CONFIG_BOOTP_HOSTNAME)
232c150a2   wdenk   Add support for S...
652
653
654
  	*e++ = 12;		/* Host name request */
  	*e++ = 32;
  	e   += 32;
3861aa5ce   wdenk   Initial revision
655
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
656
  #if defined(CONFIG_BOOTP_BOOTFILESIZE)
232c150a2   wdenk   Add support for S...
657
658
659
  	*e++ = 13;		/* Boot file size */
  	*e++ = 2;
  	e   += 2;
3861aa5ce   wdenk   Initial revision
660
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
661
  #if defined(CONFIG_BOOTP_BOOTPATH)
232c150a2   wdenk   Add support for S...
662
663
664
  	*e++ = 17;		/* Boot path */
  	*e++ = 32;
  	e   += 32;
3861aa5ce   wdenk   Initial revision
665
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
666
  #if defined(CONFIG_BOOTP_NISDOMAIN)
232c150a2   wdenk   Add support for S...
667
668
669
  	*e++ = 40;		/* NIS Domain name request */
  	*e++ = 32;
  	e   += 32;
3861aa5ce   wdenk   Initial revision
670
  #endif
09e3a67de   Luuk Paulussen   bootp: add ntpser...
671
672
673
674
675
  #if defined(CONFIG_BOOTP_NTPSERVER)
  	*e++ = 42;
  	*e++ = 4;
  	e   += 4;
  #endif
3861aa5ce   wdenk   Initial revision
676

232c150a2   wdenk   Add support for S...
677
  	*e++ = 255;		/* End of the list */
3861aa5ce   wdenk   Initial revision
678

166c409bc   Andre Renaud   net: Handle an em...
679
680
681
682
683
684
685
686
687
  	/*
  	 * 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
  ");
  		e -= 3;
  	}
232c150a2   wdenk   Add support for S...
688
  	return e - start;
3861aa5ce   wdenk   Initial revision
689
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
690
  #endif
3861aa5ce   wdenk   Initial revision
691

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
692
  void bootp_reset(void)
f59be6e85   Stephen Warren   net: BOOTP retry ...
693
  {
92ac8acc0   Thierry Reding   net: More BOOTP r...
694
  	bootp_num_ids = 0;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
695
  	bootp_try = 0;
f59be6e85   Stephen Warren   net: BOOTP retry ...
696
  	bootp_start = get_timer(0);
92ac8acc0   Thierry Reding   net: More BOOTP r...
697
  	bootp_timeout = 250;
f59be6e85   Stephen Warren   net: BOOTP retry ...
698
  }
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
699
  void bootp_request(void)
3861aa5ce   wdenk   Initial revision
700
  {
db288a960   Joe Hershberger   net: Remove volat...
701
  	uchar *pkt, *iphdr;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
702
  	struct bootp_hdr *bp;
ae446f562   Joe Hershberger   net: Refactor boo...
703
704
  	int extlen, pktlen, iplen;
  	int eth_hdr_size;
eafc8db0e   Joe Hershberger   net: Move MAC-see...
705
  #ifdef CONFIG_BOOTP_RANDOM_DELAY
8e8d73b4a   Pavel Machek   bootp can use mdelay
706
  	ulong rand_ms;
eafc8db0e   Joe Hershberger   net: Move MAC-see...
707
  #endif
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
708
  	u32 bootp_id;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
709
710
  	struct in_addr zero_ip;
  	struct in_addr bcast_ip;
50768f5b0   Alexandre Messier   net: bootp: Add e...
711
  	char *ep;  /* Environment pointer */
3861aa5ce   wdenk   Initial revision
712

573f14fe4   Simon Glass   bootstage: Plumb ...
713
  	bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
643d1ab23   Jon Loeliger   net/: Remove obso...
714
  #if defined(CONFIG_CMD_DHCP)
3861aa5ce   wdenk   Initial revision
715
716
  	dhcp_state = INIT;
  #endif
00caae6d4   Simon Glass   env: Rename geten...
717
  	ep = env_get("bootpretryperiod");
50768f5b0   Alexandre Messier   net: bootp: Add e...
718
719
720
721
  	if (ep != NULL)
  		time_taken_max = simple_strtoul(ep, NULL, 10);
  	else
  		time_taken_max = TIMEOUT_MS;
3861aa5ce   wdenk   Initial revision
722
  #ifdef CONFIG_BOOTP_RANDOM_DELAY		/* Random BOOTP delay */
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
723
  	if (bootp_try == 0)
eafc8db0e   Joe Hershberger   net: Move MAC-see...
724
  		srand_mac();
3861aa5ce   wdenk   Initial revision
725

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
726
727
  	if (bootp_try <= 2)	/* Start with max 1024 * 1ms */
  		rand_ms = rand() >> (22 - bootp_try);
eafc8db0e   Joe Hershberger   net: Move MAC-see...
728
729
  	else		/* After 3rd BOOTP request max 8192 * 1ms */
  		rand_ms = rand() >> 19;
3861aa5ce   wdenk   Initial revision
730

eafc8db0e   Joe Hershberger   net: Move MAC-see...
731
732
  	printf("Random delay: %ld ms...
  ", rand_ms);
8e8d73b4a   Pavel Machek   bootp can use mdelay
733
  	mdelay(rand_ms);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
734

3861aa5ce   wdenk   Initial revision
735
  #endif	/* CONFIG_BOOTP_RANDOM_DELAY */
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
736
737
  	printf("BOOTP broadcast %d
  ", ++bootp_try);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
738
  	pkt = net_tx_packet;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
739
  	memset((void *)pkt, 0, PKTSIZE);
3861aa5ce   wdenk   Initial revision
740

1203fccee   Joe Hershberger   net: cosmetic: Cl...
741
  	eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
ae446f562   Joe Hershberger   net: Refactor boo...
742
  	pkt += eth_hdr_size;
3861aa5ce   wdenk   Initial revision
743
744
  
  	/*
3090b7e36   Joe Hershberger   net: cosmetic: bo...
745
746
747
748
  	 * Next line results in incorrect packet size being transmitted,
  	 * resulting in errors in some DHCP servers, reporting missing bytes.
  	 * Size must be set in packet header after extension length has been
  	 * determined.
3861aa5ce   wdenk   Initial revision
749
750
  	 * C. Hallinan, DS4.COM, Inc.
  	 */
4b11c9166   Joe Hershberger   net: Refactor IP,...
751
  	/* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC,
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
752
  		sizeof (struct bootp_hdr)); */
4b11c9166   Joe Hershberger   net: Refactor IP,...
753
  	iphdr = pkt;	/* We need this later for net_set_udp_header() */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
754
  	pkt += IP_UDP_HDR_SIZE;
3861aa5ce   wdenk   Initial revision
755

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
756
  	bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
757
758
759
760
  	bp->bp_op = OP_BOOTREQUEST;
  	bp->bp_htype = HWT_ETHER;
  	bp->bp_hlen = HWL_ETHER;
  	bp->bp_hops = 0;
454d9d3ec   Stefan Brüns   net: send RFC1542...
761
762
763
764
765
  	/*
  	 * according to RFC1542, should be 0 on first request, secs since
  	 * first request otherwise
  	 */
  	bp->bp_secs = htons(get_timer(bootp_start) / 1000);
049a95a77   Joe Hershberger   net: cosmetic: Ch...
766
767
768
769
770
  	zero_ip.s_addr = 0;
  	net_write_ip(&bp->bp_ciaddr, zero_ip);
  	net_write_ip(&bp->bp_yiaddr, zero_ip);
  	net_write_ip(&bp->bp_siaddr, zero_ip);
  	net_write_ip(&bp->bp_giaddr, zero_ip);
0adb5b761   Joe Hershberger   net: cosmetic: Na...
771
  	memcpy(bp->bp_chaddr, net_ethaddr, 6);
1411157d8   Joe Hershberger   net: cosmetic: Fi...
772
  	copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
3861aa5ce   wdenk   Initial revision
773
774
  
  	/* Request additional information from the BOOTP/DHCP server */
643d1ab23   Jon Loeliger   net/: Remove obso...
775
  #if defined(CONFIG_CMD_DHCP)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
776
777
  	extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, zero_ip,
  			       zero_ip);
3861aa5ce   wdenk   Initial revision
778
  #else
049a95a77   Joe Hershberger   net: cosmetic: Ch...
779
  	extlen = bootp_extended((u8 *)bp->bp_vend);
610f2e9c2   Jon Loeliger   net/: Remove ling...
780
  #endif
3861aa5ce   wdenk   Initial revision
781
782
783
  
  	/*
  	 *	Bootp ID is the lower 4 bytes of our ethernet address
49f3bdbba   Bartlomiej Sieka   net: express the ...
784
  	 *	plus the current time in ms.
3861aa5ce   wdenk   Initial revision
785
  	 */
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
786
787
788
789
  	bootp_id = ((u32)net_ethaddr[2] << 24)
  		| ((u32)net_ethaddr[3] << 16)
  		| ((u32)net_ethaddr[4] << 8)
  		| (u32)net_ethaddr[5];
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
790
791
792
  	bootp_id += get_timer(0);
  	bootp_id = htonl(bootp_id);
  	bootp_add_id(bootp_id);
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
793
  	net_copy_u32(&bp->bp_id, &bootp_id);
3861aa5ce   wdenk   Initial revision
794
795
796
797
798
  
  	/*
  	 * Calculate proper packet lengths taking into account the
  	 * variable size of the options field
  	 */
ae446f562   Joe Hershberger   net: Refactor boo...
799
800
  	iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
  	pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
801
802
  	bcast_ip.s_addr = 0xFFFFFFFFL;
  	net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
803
  	net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
3861aa5ce   wdenk   Initial revision
804

643d1ab23   Jon Loeliger   net/: Remove obso...
805
  #if defined(CONFIG_CMD_DHCP)
3861aa5ce   wdenk   Initial revision
806
  	dhcp_state = SELECTING;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
807
  	net_set_udp_handler(dhcp_handler);
3861aa5ce   wdenk   Initial revision
808
  #else
049a95a77   Joe Hershberger   net: cosmetic: Ch...
809
  	net_set_udp_handler(bootp_handler);
610f2e9c2   Jon Loeliger   net/: Remove ling...
810
  #endif
1203fccee   Joe Hershberger   net: cosmetic: Cl...
811
  	net_send_packet(net_tx_packet, pktlen);
3861aa5ce   wdenk   Initial revision
812
  }
643d1ab23   Jon Loeliger   net/: Remove obso...
813
  #if defined(CONFIG_CMD_DHCP)
774c3e05e   Stefan Brüns   net: parse DHCP o...
814
  static void dhcp_process_options(uchar *popt, uchar *end)
3861aa5ce   wdenk   Initial revision
815
  {
3861aa5ce   wdenk   Initial revision
816
  	int oplen, size;
d8d8724be   Wolfgang Denk   net/bootp.c: fix ...
817
818
819
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
  	int *to_ptr;
  #endif
3861aa5ce   wdenk   Initial revision
820

232c150a2   wdenk   Add support for S...
821
  	while (popt < end && *popt != 0xff) {
3861aa5ce   wdenk   Initial revision
822
  		oplen = *(popt + 1);
232c150a2   wdenk   Add support for S...
823
  		switch (*popt) {
c56eb5731   Stefan Brüns   net: Fix parsing ...
824
825
826
  		case 0:
  			oplen = -1; /* Pad omits len byte */
  			break;
232c150a2   wdenk   Add support for S...
827
  		case 1:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
828
  			net_copy_ip(&net_netmask, (popt + 2));
232c150a2   wdenk   Add support for S...
829
  			break;
1fe80d79c   Jon Loeliger   Finally retire cm...
830
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
ea287debe   wdenk   * Patch by Masami...
831
  		case 2:		/* Time offset	*/
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
832
  			to_ptr = &net_ntp_time_offset;
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
833
  			net_copy_u32((u32 *)to_ptr, (u32 *)(popt + 2));
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
834
  			net_ntp_time_offset = ntohl(net_ntp_time_offset);
ea287debe   wdenk   * Patch by Masami...
835
836
  			break;
  #endif
232c150a2   wdenk   Add support for S...
837
  		case 3:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
838
  			net_copy_ip(&net_gateway, (popt + 2));
232c150a2   wdenk   Add support for S...
839
840
  			break;
  		case 6:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
841
  			net_copy_ip(&net_dns_server, (popt + 2));
1fe80d79c   Jon Loeliger   Finally retire cm...
842
  #if defined(CONFIG_BOOTP_DNS2)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
843
  			if (*(popt + 1) > 4)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
844
  				net_copy_ip(&net_dns_server2, (popt + 2 + 4));
fe389a82c   stroese   - Added CONFIG_BO...
845
  #endif
232c150a2   wdenk   Add support for S...
846
847
  			break;
  		case 12:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
848
  			size = truncate_sz("Host Name",
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
849
850
851
  				sizeof(net_hostname), oplen);
  			memcpy(&net_hostname, popt + 2, size);
  			net_hostname[size] = 0;
232c150a2   wdenk   Add support for S...
852
853
854
855
  			break;
  		case 15:	/* Ignore Domain Name Option */
  			break;
  		case 17:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
856
  			size = truncate_sz("Root Path",
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
857
858
859
  				sizeof(net_root_path), oplen);
  			memcpy(&net_root_path, popt + 2, size);
  			net_root_path[size] = 0;
232c150a2   wdenk   Add support for S...
860
  			break;
ee0f60df0   Brian Rzycki   net: Quietly igno...
861
862
  		case 28:	/* Ignore Broadcast Address Option */
  			break;
1fe80d79c   Jon Loeliger   Finally retire cm...
863
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
ea287debe   wdenk   * Patch by Masami...
864
  		case 42:	/* NTP server IP */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
865
  			net_copy_ip(&net_ntp_server, (popt + 2));
ea287debe   wdenk   * Patch by Masami...
866
867
  			break;
  #endif
232c150a2   wdenk   Add support for S...
868
  		case 51:
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
869
  			net_copy_u32(&dhcp_leasetime, (u32 *)(popt + 2));
232c150a2   wdenk   Add support for S...
870
  			break;
ec87b1b39   Stefan Brüns   net: Do not overw...
871
872
873
  		case 52:
  			dhcp_option_overload = popt[2];
  			break;
232c150a2   wdenk   Add support for S...
874
875
876
  		case 53:	/* Ignore Message Type Option */
  			break;
  		case 54:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
877
  			net_copy_ip(&dhcp_server_ip, (popt + 2));
232c150a2   wdenk   Add support for S...
878
879
880
881
882
  			break;
  		case 58:	/* Ignore Renewal Time Option */
  			break;
  		case 59:	/* Ignore Rebinding Time Option */
  			break;
3b2e4fd9b   Wolfgang Denk   Add support for t...
883
884
  		case 66:	/* Ignore TFTP server name */
  			break;
ec87b1b39   Stefan Brüns   net: Do not overw...
885
  		case 67:	/* Bootfile option */
449312c1c   Alexander Graf   net: Prefer comma...
886
887
888
889
890
891
892
  			if (!net_boot_file_name_explicit) {
  				size = truncate_sz("Bootfile",
  						   sizeof(net_boot_file_name),
  						   oplen);
  				memcpy(&net_boot_file_name, popt + 2, size);
  				net_boot_file_name[size] = 0;
  			}
3b2e4fd9b   Wolfgang Denk   Add support for t...
893
  			break;
232c150a2   wdenk   Add support for S...
894
  		default:
1fe80d79c   Jon Loeliger   Finally retire cm...
895
  #if defined(CONFIG_BOOTP_VENDOREX)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
896
  			if (dhcp_vendorex_proc(popt))
8bde7f776   wdenk   * Code cleanup:
897
  				break;
3861aa5ce   wdenk   Initial revision
898
  #endif
3090b7e36   Joe Hershberger   net: cosmetic: bo...
899
  			printf("*** Unhandled DHCP Option in OFFER/ACK:"
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
900
901
  			       " %d
  ", *popt);
232c150a2   wdenk   Add support for S...
902
  			break;
3861aa5ce   wdenk   Initial revision
903
904
905
906
  		}
  		popt += oplen + 2;	/* Process next option */
  	}
  }
774c3e05e   Stefan Brüns   net: parse DHCP o...
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  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);
  	}
  }
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
935
  static int dhcp_message_type(unsigned char *popt)
3861aa5ce   wdenk   Initial revision
936
  {
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
937
  	if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
3861aa5ce   wdenk   Initial revision
938
939
940
  		return -1;
  
  	popt += 4;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
941
942
  	while (*popt != 0xff) {
  		if (*popt == 53)	/* DHCP Message Type */
3861aa5ce   wdenk   Initial revision
943
  			return *(popt + 2);
c56eb5731   Stefan Brüns   net: Fix parsing ...
944
945
946
947
948
949
950
  		if (*popt == 0)	{
  			/* Pad */
  			popt += 1;
  		} else {
  			/* Scan through all options */
  			popt += *(popt + 1) + 2;
  		}
3861aa5ce   wdenk   Initial revision
951
952
953
  	}
  	return -1;
  }
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
954
  static void dhcp_send_request_packet(struct bootp_hdr *bp_offer)
3861aa5ce   wdenk   Initial revision
955
  {
db288a960   Joe Hershberger   net: Remove volat...
956
  	uchar *pkt, *iphdr;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
957
  	struct bootp_hdr *bp;
3861aa5ce   wdenk   Initial revision
958
  	int pktlen, iplen, extlen;
ae446f562   Joe Hershberger   net: Refactor boo...
959
  	int eth_hdr_size;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
960
961
962
  	struct in_addr offered_ip;
  	struct in_addr zero_ip;
  	struct in_addr bcast_ip;
3861aa5ce   wdenk   Initial revision
963

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
964
965
  	debug("dhcp_send_request_packet: Sending DHCPREQUEST
  ");
1203fccee   Joe Hershberger   net: cosmetic: Cl...
966
  	pkt = net_tx_packet;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
967
  	memset((void *)pkt, 0, PKTSIZE);
3861aa5ce   wdenk   Initial revision
968

1203fccee   Joe Hershberger   net: cosmetic: Cl...
969
  	eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
ae446f562   Joe Hershberger   net: Refactor boo...
970
  	pkt += eth_hdr_size;
3861aa5ce   wdenk   Initial revision
971

3090b7e36   Joe Hershberger   net: cosmetic: bo...
972
  	iphdr = pkt;	/* We'll need this later to set proper pkt size */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
973
  	pkt += IP_UDP_HDR_SIZE;
3861aa5ce   wdenk   Initial revision
974

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
975
  	bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
976
977
978
979
  	bp->bp_op = OP_BOOTREQUEST;
  	bp->bp_htype = HWT_ETHER;
  	bp->bp_hlen = HWL_ETHER;
  	bp->bp_hops = 0;
454d9d3ec   Stefan Brüns   net: send RFC1542...
980
  	bp->bp_secs = htons(get_timer(bootp_start) / 1000);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
981
982
  	/* Do not set the client IP, your IP, or server IP yet, since it
  	 * hasn't been ACK'ed by the server yet */
e5c794e49   Justin Flammia   DHCP Client Fix
983

c66867039   Wolfgang Denk   Minor code cleanup.
984
  	/*
d82718fed   Wolfgang Denk   Make bootp implem...
985
986
987
  	 * RFC3046 requires Relay Agents to discard packets with
  	 * nonzero and offered giaddr
  	 */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
988
989
  	zero_ip.s_addr = 0;
  	net_write_ip(&bp->bp_giaddr, zero_ip);
d82718fed   Wolfgang Denk   Make bootp implem...
990

0adb5b761   Joe Hershberger   net: cosmetic: Na...
991
  	memcpy(bp->bp_chaddr, net_ethaddr, 6);
b2b7fbc33   Alexandre Messier   net: Add bootfile...
992
  	copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
3861aa5ce   wdenk   Initial revision
993
994
995
996
  
  	/*
  	 * ID is the id of the OFFER packet
  	 */
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
997
  	net_copy_u32(&bp->bp_id, &bp_offer->bp_id);
3861aa5ce   wdenk   Initial revision
998
999
1000
1001
  
  	/*
  	 * Copy options from OFFER packet if present
  	 */
e5c794e49   Justin Flammia   DHCP Client Fix
1002
1003
  
  	/* Copy offered IP into the parameters request list */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1004
1005
1006
  	net_copy_ip(&offered_ip, &bp_offer->bp_yiaddr);
  	extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST,
  		dhcp_server_ip, offered_ip);
3861aa5ce   wdenk   Initial revision
1007

ae446f562   Joe Hershberger   net: Refactor boo...
1008
1009
  	iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
  	pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1010
1011
  	bcast_ip.s_addr = 0xFFFFFFFFL;
  	net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
3861aa5ce   wdenk   Initial revision
1012

d9a2f416d   Aras Vaichas   DHCP request fix ...
1013
1014
1015
  #ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY
  	udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);
  #endif	/* CONFIG_BOOTP_DHCP_REQUEST_DELAY */
f9623229f   Joe Hershberger   net: Move debug t...
1016
1017
  	debug("Transmitting DHCPREQUEST packet: len = %d
  ", pktlen);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
1018
  	net_send_packet(net_tx_packet, pktlen);
3861aa5ce   wdenk   Initial revision
1019
1020
1021
1022
1023
  }
  
  /*
   *	Handle DHCP received packets.
   */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1024
1025
  static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
  			 unsigned src, unsigned len)
3861aa5ce   wdenk   Initial revision
1026
  {
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1027
  	struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
1028

0ebf04c60   Robin Getz   minor debug clean...
1029
1030
  	debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d
  ",
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1031
  	      src, dest, len, dhcp_state);
3861aa5ce   wdenk   Initial revision
1032

3090b7e36   Joe Hershberger   net: cosmetic: bo...
1033
  	/* Filter out pkts we don't want */
867d6ae2c   Stefan Brüns   net: reject Bootp...
1034
  	if (check_reply_packet(pkt, dest, src, len))
3861aa5ce   wdenk   Initial revision
1035
  		return;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1036
1037
1038
  	debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: "
  	      "%d
  ", src, dest, len, dhcp_state);
3861aa5ce   wdenk   Initial revision
1039

44c42dd40   Peng Fan   net: bootp: Ignor...
1040
1041
  	if (net_read_ip(&bp->bp_yiaddr).s_addr == 0)
  		return;
3861aa5ce   wdenk   Initial revision
1042
1043
1044
1045
  	switch (dhcp_state) {
  	case SELECTING:
  		/*
  		 * Wait an appropriate time for any potential DHCPOFFER packets
3090b7e36   Joe Hershberger   net: cosmetic: bo...
1046
1047
1048
  		 * to arrive.  Then select one, and generate DHCPREQUEST
  		 * response.  If filename is in format we recognize, assume it
  		 * is a valid OFFER from a server we want.
3861aa5ce   wdenk   Initial revision
1049
  		 */
0ebf04c60   Robin Getz   minor debug clean...
1050
1051
  		debug("DHCP: state=SELECTING bp_file: \"%s\"
  ", bp->bp_file);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1052
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
3861aa5ce   wdenk   Initial revision
1053
  		if (strncmp(bp->bp_file,
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1054
  			    CONFIG_SYS_BOOTFILE_PREFIX,
3090b7e36   Joe Hershberger   net: cosmetic: bo...
1055
  			    strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1056
  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */
774c3e05e   Stefan Brüns   net: parse DHCP o...
1057
  			dhcp_packet_process_options(bp);
0efe1bcf5   Alexander Graf   efi_loader: Add n...
1058
  			efi_net_set_dhcp_ack(pkt, len);
3861aa5ce   wdenk   Initial revision
1059

0ebf04c60   Robin Getz   minor debug clean...
1060
1061
  			debug("TRANSITIONING TO REQUESTING STATE
  ");
3861aa5ce   wdenk   Initial revision
1062
  			dhcp_state = REQUESTING;
759a51b4f   stroese   Changed DHCP clie...
1063

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1064
  			net_set_timeout_handler(5000, bootp_timeout_handler);
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1065
  			dhcp_send_request_packet(bp);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1066
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
3861aa5ce   wdenk   Initial revision
1067
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1068
  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */
3861aa5ce   wdenk   Initial revision
1069
1070
1071
1072
  
  		return;
  		break;
  	case REQUESTING:
0ebf04c60   Robin Getz   minor debug clean...
1073
1074
  		debug("DHCP State: REQUESTING
  ");
3861aa5ce   wdenk   Initial revision
1075

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1076
  		if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
774c3e05e   Stefan Brüns   net: parse DHCP o...
1077
  			dhcp_packet_process_options(bp);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
1078
  			/* Store net params from reply */
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1079
  			store_net_params(bp);
3861aa5ce   wdenk   Initial revision
1080
  			dhcp_state = BOUND;
92ac8acc0   Thierry Reding   net: More BOOTP r...
1081
1082
  			printf("DHCP client bound to address %pI4 (%lu ms)
  ",
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1083
  			       &net_ip, get_timer(bootp_start));
4f28c9b16   Stefan Brüns   net: cancel timeo...
1084
  			net_set_timeout_handler(0, (thand_f *)0);
573f14fe4   Simon Glass   bootstage: Plumb ...
1085
  			bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1086
  					    "bootp_stop");
3861aa5ce   wdenk   Initial revision
1087

e4a3d57dc   Simon Glass   net: Export auto_...
1088
  			net_auto_load();
3861aa5ce   wdenk   Initial revision
1089
1090
1091
  			return;
  		}
  		break;
51dfe1382   Remy Bohmer   Fix bogus error m...
1092
1093
1094
  	case BOUND:
  		/* DHCP client bound to address */
  		break;
3861aa5ce   wdenk   Initial revision
1095
  	default:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
1096
1097
  		puts("DHCP: INVALID STATE
  ");
3861aa5ce   wdenk   Initial revision
1098
1099
  		break;
  	}
3861aa5ce   wdenk   Initial revision
1100
  }
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1101
  void dhcp_request(void)
3861aa5ce   wdenk   Initial revision
1102
  {
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1103
  	bootp_request();
3861aa5ce   wdenk   Initial revision
1104
  }
992742a5b   Wolfgang Denk   Cleanup coding st...
1105
  #endif	/* CONFIG_CMD_DHCP */