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>
0efe1bcf5   Alexander Graf   efi_loader: Add n...
12
  #include <efi_loader.h>
3861aa5ce   wdenk   Initial revision
13
  #include <net.h>
346969584   Lukasz Majewski   net: tftp: Move t...
14
  #include <net/tftp.h>
3861aa5ce   wdenk   Initial revision
15
  #include "bootp.h"
2d8d190c8   Uri Mashiach   status_led: Kconf...
16
  #ifdef CONFIG_LED_STATUS
3861aa5ce   wdenk   Initial revision
17
18
  #include <status_led.h>
  #endif
db7720bad   Kim Phillips   net: make net_ran...
19
20
21
  #ifdef CONFIG_BOOTP_RANDOM_DELAY
  #include "net_rand.h"
  #endif
3861aa5ce   wdenk   Initial revision
22

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

f59be6e85   Stephen Warren   net: BOOTP retry ...
25
26
27
28
29
30
31
32
33
34
  /*
   * 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...
35
  #ifndef CONFIG_NET_RETRY_COUNT
3090b7e36   Joe Hershberger   net: cosmetic: bo...
36
  # define TIMEOUT_COUNT	5		/* # of timeouts before giving up */
3861aa5ce   wdenk   Initial revision
37
  #else
232c150a2   wdenk   Add support for S...
38
  # define TIMEOUT_COUNT	(CONFIG_NET_RETRY_COUNT)
3861aa5ce   wdenk   Initial revision
39
  #endif
f59be6e85   Stephen Warren   net: BOOTP retry ...
40
  #define TIMEOUT_MS	((3 + (TIMEOUT_COUNT * 5)) * 1000)
3861aa5ce   wdenk   Initial revision
41

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

3090b7e36   Joe Hershberger   net: cosmetic: bo...
45
  #ifndef CONFIG_DHCP_MIN_EXT_LEN		/* minimal length of extension list */
232c150a2   wdenk   Add support for S...
46
  #define CONFIG_DHCP_MIN_EXT_LEN 64
3861aa5ce   wdenk   Initial revision
47
  #endif
92ac8acc0   Thierry Reding   net: More BOOTP r...
48
49
50
  #ifndef CONFIG_BOOTP_ID_CACHE_SIZE
  #define CONFIG_BOOTP_ID_CACHE_SIZE 4
  #endif
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
51
  u32		bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE];
92ac8acc0   Thierry Reding   net: More BOOTP r...
52
  unsigned int	bootp_num_ids;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
53
  int		bootp_try;
f59be6e85   Stephen Warren   net: BOOTP retry ...
54
55
  ulong		bootp_start;
  ulong		bootp_timeout;
586cbe51a   Joe Hershberger   net: cosmetic: Fi...
56
57
58
  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
59

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

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

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

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

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

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

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

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

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

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

232c150a2   wdenk   Add support for S...
306
307
308
309
310
311
312
313
  	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...
314
  				bootp_process_vendor_field(opt);
232c150a2   wdenk   Add support for S...
315
  		}
3861aa5ce   wdenk   Initial revision
316
  	}
3861aa5ce   wdenk   Initial revision
317

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

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

1411157d8   Joe Hershberger   net: cosmetic: Fi...
327
328
329
330
  	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
331

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1203fccee   Joe Hershberger   net: cosmetic: Cl...
740
  	eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
ae446f562   Joe Hershberger   net: Refactor boo...
741
  	pkt += eth_hdr_size;
3861aa5ce   wdenk   Initial revision
742
743
  
  	/*
3090b7e36   Joe Hershberger   net: cosmetic: bo...
744
745
746
747
  	 * 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
748
749
  	 * C. Hallinan, DS4.COM, Inc.
  	 */
4b11c9166   Joe Hershberger   net: Refactor IP,...
750
  	/* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC,
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
751
  		sizeof (struct bootp_hdr)); */
4b11c9166   Joe Hershberger   net: Refactor IP,...
752
  	iphdr = pkt;	/* We need this later for net_set_udp_header() */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
753
  	pkt += IP_UDP_HDR_SIZE;
3861aa5ce   wdenk   Initial revision
754

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
755
  	bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
756
757
758
759
  	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...
760
761
762
763
764
  	/*
  	 * 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...
765
766
767
768
769
  	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...
770
  	memcpy(bp->bp_chaddr, net_ethaddr, 6);
1411157d8   Joe Hershberger   net: cosmetic: Fi...
771
  	copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
3861aa5ce   wdenk   Initial revision
772
773
  
  	/* Request additional information from the BOOTP/DHCP server */
643d1ab23   Jon Loeliger   net/: Remove obso...
774
  #if defined(CONFIG_CMD_DHCP)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
775
776
  	extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, zero_ip,
  			       zero_ip);
3861aa5ce   wdenk   Initial revision
777
  #else
049a95a77   Joe Hershberger   net: cosmetic: Ch...
778
  	extlen = bootp_extended((u8 *)bp->bp_vend);
610f2e9c2   Jon Loeliger   net/: Remove ling...
779
  #endif
3861aa5ce   wdenk   Initial revision
780
781
782
  
  	/*
  	 *	Bootp ID is the lower 4 bytes of our ethernet address
49f3bdbba   Bartlomiej Sieka   net: express the ...
783
  	 *	plus the current time in ms.
3861aa5ce   wdenk   Initial revision
784
  	 */
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
785
786
787
788
  	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...
789
790
791
  	bootp_id += get_timer(0);
  	bootp_id = htonl(bootp_id);
  	bootp_add_id(bootp_id);
5917e7d16   Sergey Temerkhanov   net: Fix incorrec...
792
  	net_copy_u32(&bp->bp_id, &bootp_id);
3861aa5ce   wdenk   Initial revision
793
794
795
796
797
  
  	/*
  	 * Calculate proper packet lengths taking into account the
  	 * variable size of the options field
  	 */
ae446f562   Joe Hershberger   net: Refactor boo...
798
799
  	iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
  	pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
800
801
  	bcast_ip.s_addr = 0xFFFFFFFFL;
  	net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
802
  	net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
3861aa5ce   wdenk   Initial revision
803

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

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

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

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

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

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
974
  	bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
975
976
977
978
  	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...
979
  	bp->bp_secs = htons(get_timer(bootp_start) / 1000);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
980
981
  	/* 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
982

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

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

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

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

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

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

44c42dd40   Peng Fan   net: bootp: Ignor...
1039
1040
  	if (net_read_ip(&bp->bp_yiaddr).s_addr == 0)
  		return;
3861aa5ce   wdenk   Initial revision
1041
1042
1043
1044
  	switch (dhcp_state) {
  	case SELECTING:
  		/*
  		 * Wait an appropriate time for any potential DHCPOFFER packets
3090b7e36   Joe Hershberger   net: cosmetic: bo...
1045
1046
1047
  		 * 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
1048
  		 */
0ebf04c60   Robin Getz   minor debug clean...
1049
1050
  		debug("DHCP: state=SELECTING bp_file: \"%s\"
  ", bp->bp_file);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1051
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
3861aa5ce   wdenk   Initial revision
1052
  		if (strncmp(bp->bp_file,
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1053
  			    CONFIG_SYS_BOOTFILE_PREFIX,
3090b7e36   Joe Hershberger   net: cosmetic: bo...
1054
  			    strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1055
  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */
774c3e05e   Stefan Brüns   net: parse DHCP o...
1056
  			dhcp_packet_process_options(bp);
0efe1bcf5   Alexander Graf   efi_loader: Add n...
1057
  			efi_net_set_dhcp_ack(pkt, len);
3861aa5ce   wdenk   Initial revision
1058

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

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

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

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