Blame view

net/bootp.c 26.2 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;
1752f0fdc   Joe Hershberger   net: Fix unused v...
146

049a95a77   Joe Hershberger   net: cosmetic: Ch...
147
148
149
  	net_copy_ip(&tmp_ip, &bp->bp_siaddr);
  	if (tmp_ip.s_addr != 0)
  		net_copy_ip(&net_server_ip, &bp->bp_siaddr);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
150
151
  	memcpy(net_server_ethaddr,
  	       ((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
ec87b1b39   Stefan Brüns   net: Do not overw...
152
153
154
155
156
  	if (
  #if defined(CONFIG_CMD_DHCP)
  	    !(dhcp_option_overload & OVERLOAD_FILE) &&
  #endif
  	    (strlen(bp->bp_file) > 0)) {
1411157d8   Joe Hershberger   net: cosmetic: Fi...
157
158
  		copy_filename(net_boot_file_name, bp->bp_file,
  			      sizeof(net_boot_file_name));
ec87b1b39   Stefan Brüns   net: Do not overw...
159
  	}
3861aa5ce   wdenk   Initial revision
160

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

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

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

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

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

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

232c150a2   wdenk   Add support for S...
300
301
302
303
304
305
306
307
  	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...
308
  				bootp_process_vendor_field(opt);
232c150a2   wdenk   Add support for S...
309
  		}
3861aa5ce   wdenk   Initial revision
310
  	}
3861aa5ce   wdenk   Initial revision
311

3090b7e36   Joe Hershberger   net: cosmetic: bo...
312
313
  	debug("[BOOTP] Received fields:
  ");
049a95a77   Joe Hershberger   net: cosmetic: Ch...
314
315
316
  	if (net_netmask.s_addr)
  		debug("net_netmask : %pI4
  ", &net_netmask);
232c150a2   wdenk   Add support for S...
317

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

1411157d8   Joe Hershberger   net: cosmetic: Fi...
321
322
323
324
  	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
325

586cbe51a   Joe Hershberger   net: cosmetic: Fi...
326
327
328
  	if (net_hostname[0])
  		debug("net_hostname  : %s
  ", net_hostname);
232c150a2   wdenk   Add support for S...
329

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

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

09e3a67de   Luuk Paulussen   bootp: add ntpser...
338
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
339
340
341
  	if (net_ntp_server)
  		debug("net_ntp_server : %pI4
  ", &net_ntp_server);
09e3a67de   Luuk Paulussen   bootp: add ntpser...
342
  #endif
232c150a2   wdenk   Add support for S...
343
  }
093498669   Simon Glass   Put common autolo...
344

3861aa5ce   wdenk   Initial revision
345
346
347
  /*
   *	Handle a BOOTP received packet.
   */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
348
349
  static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
  			  unsigned src, unsigned len)
3861aa5ce   wdenk   Initial revision
350
  {
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
351
  	struct bootp_hdr *bp;
3861aa5ce   wdenk   Initial revision
352

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

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

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

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

0ebf04c60   Robin Getz   minor debug clean...
378
379
  	debug("Got good BOOTP
  ");
3861aa5ce   wdenk   Initial revision
380

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

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

1fe80d79c   Jon Loeliger   Finally retire cm...
457
  #if defined(CONFIG_BOOTP_VENDOREX)
232c150a2   wdenk   Add support for S...
458
  	u8 *x;
3861aa5ce   wdenk   Initial revision
459
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
460
  #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
77ddac948   Wolfgang Denk   Cleanup for GCC-4.x
461
  	char *hostname;
fe389a82c   stroese   - Added CONFIG_BO...
462
  #endif
3861aa5ce   wdenk   Initial revision
463

232c150a2   wdenk   Add support for S...
464
465
466
467
  	*e++ = 99;		/* RFC1048 Magic Cookie */
  	*e++ = 130;
  	*e++ = 83;
  	*e++ = 99;
3861aa5ce   wdenk   Initial revision
468

232c150a2   wdenk   Add support for S...
469
470
471
  	*e++ = 53;		/* DHCP Message Type */
  	*e++ = 1;
  	*e++ = message_type;
3861aa5ce   wdenk   Initial revision
472

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

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

232c150a2   wdenk   Add support for S...
481
482
483
484
485
486
487
  		*e++ = 54;	/* ServerID */
  		*e++ = 4;
  		*e++ = tmp >> 24;
  		*e++ = tmp >> 16;
  		*e++ = tmp >> 8;
  		*e++ = tmp & 0xff;
  	}
3861aa5ce   wdenk   Initial revision
488

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

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

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

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

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

232c150a2   wdenk   Add support for S...
611
612
613
614
  	*e++ = 99;		/* RFC1048 Magic Cookie */
  	*e++ = 130;
  	*e++ = 83;
  	*e++ = 99;
3861aa5ce   wdenk   Initial revision
615

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

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

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

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

166c409bc   Andre Renaud   net: Handle an em...
672
673
674
675
676
677
678
679
680
  	/*
  	 * 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...
681
  	return e - start;
3861aa5ce   wdenk   Initial revision
682
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
683
  #endif
3861aa5ce   wdenk   Initial revision
684

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

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

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

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

3861aa5ce   wdenk   Initial revision
728
  #endif	/* CONFIG_BOOTP_RANDOM_DELAY */
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
729
730
  	printf("BOOTP broadcast %d
  ", ++bootp_try);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
731
  	pkt = net_tx_packet;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
732
  	memset((void *)pkt, 0, PKTSIZE);
3861aa5ce   wdenk   Initial revision
733

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

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

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

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

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
954
955
  	debug("dhcp_send_request_packet: Sending DHCPREQUEST
  ");
1203fccee   Joe Hershberger   net: cosmetic: Cl...
956
  	pkt = net_tx_packet;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
957
  	memset((void *)pkt, 0, PKTSIZE);
3861aa5ce   wdenk   Initial revision
958

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

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

7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
965
  	bp = (struct bootp_hdr *)pkt;
3861aa5ce   wdenk   Initial revision
966
967
968
969
  	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...
970
  	bp->bp_secs = htons(get_timer(bootp_start) / 1000);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
971
972
  	/* 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
973

c66867039   Wolfgang Denk   Minor code cleanup.
974
  	/*
d82718fed   Wolfgang Denk   Make bootp implem...
975
976
977
  	 * RFC3046 requires Relay Agents to discard packets with
  	 * nonzero and offered giaddr
  	 */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
978
979
  	zero_ip.s_addr = 0;
  	net_write_ip(&bp->bp_giaddr, zero_ip);
d82718fed   Wolfgang Denk   Make bootp implem...
980

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

ae446f562   Joe Hershberger   net: Refactor boo...
998
999
  	iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
  	pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1000
1001
  	bcast_ip.s_addr = 0xFFFFFFFFL;
  	net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
3861aa5ce   wdenk   Initial revision
1002

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

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

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

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

0ebf04c60   Robin Getz   minor debug clean...
1050
1051
  			debug("TRANSITIONING TO REQUESTING STATE
  ");
3861aa5ce   wdenk   Initial revision
1052
  			dhcp_state = REQUESTING;
759a51b4f   stroese   Changed DHCP clie...
1053

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1054
  			net_set_timeout_handler(5000, bootp_timeout_handler);
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
1055
  			dhcp_send_request_packet(bp);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1056
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
3861aa5ce   wdenk   Initial revision
1057
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1058
  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */
3861aa5ce   wdenk   Initial revision
1059
1060
1061
1062
  
  		return;
  		break;
  	case REQUESTING:
0ebf04c60   Robin Getz   minor debug clean...
1063
1064
  		debug("DHCP State: REQUESTING
  ");
3861aa5ce   wdenk   Initial revision
1065

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

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