Blame view

net/bootp.c 22.7 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
12
13
14
  #include <common.h>
  #include <command.h>
  #include <net.h>
  #include "bootp.h"
  #include "tftp.h"
232c150a2   wdenk   Add support for S...
15
  #include "nfs.h"
3861aa5ce   wdenk   Initial revision
16
17
18
  #ifdef CONFIG_STATUS_LED
  #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

49f3bdbba   Bartlomiej Sieka   net: express the ...
25
  #define TIMEOUT		5000UL	/* Milliseconds before trying BOOTP again */
232c150a2   wdenk   Add support for S...
26
  #ifndef CONFIG_NET_RETRY_COUNT
3090b7e36   Joe Hershberger   net: cosmetic: bo...
27
  # define TIMEOUT_COUNT	5		/* # of timeouts before giving up */
3861aa5ce   wdenk   Initial revision
28
  #else
232c150a2   wdenk   Add support for S...
29
  # define TIMEOUT_COUNT	(CONFIG_NET_RETRY_COUNT)
3861aa5ce   wdenk   Initial revision
30
  #endif
3090b7e36   Joe Hershberger   net: cosmetic: bo...
31
32
  #define PORT_BOOTPS	67		/* BOOTP server UDP port */
  #define PORT_BOOTPC	68		/* BOOTP client UDP port */
3861aa5ce   wdenk   Initial revision
33

3090b7e36   Joe Hershberger   net: cosmetic: bo...
34
  #ifndef CONFIG_DHCP_MIN_EXT_LEN		/* minimal length of extension list */
232c150a2   wdenk   Add support for S...
35
  #define CONFIG_DHCP_MIN_EXT_LEN 64
3861aa5ce   wdenk   Initial revision
36
37
38
39
  #endif
  
  ulong		BootpID;
  int		BootpTry;
3861aa5ce   wdenk   Initial revision
40

643d1ab23   Jon Loeliger   net/: Remove obso...
41
  #if defined(CONFIG_CMD_DHCP)
063705908   Kim Phillips   net/: sparse fixes
42
43
44
  static dhcp_state_t dhcp_state = INIT;
  static unsigned long dhcp_leasetime;
  static IPaddr_t NetDHCPServerIP;
03eb129f8   Luca Ceresoli   NET: pass source ...
45
46
  static void DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
  			unsigned len);
3861aa5ce   wdenk   Initial revision
47
48
  
  /* For Debug */
3e38691e8   wdenk   * Patch by Arun D...
49
50
  #if 0
  static char *dhcpmsg2str(int type)
3861aa5ce   wdenk   Initial revision
51
52
  {
  	switch (type) {
232c150a2   wdenk   Add support for S...
53
54
55
56
57
58
59
  	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
60
61
62
  	default: return "UNKNOWN/INVALID MSG TYPE"; break;
  	}
  }
3e38691e8   wdenk   * Patch by Arun D...
63
  #endif
610f2e9c2   Jon Loeliger   net/: Remove ling...
64
  #endif
3861aa5ce   wdenk   Initial revision
65
66
67
  
  static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
  {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
68
  	struct Bootp_t *bp = (struct Bootp_t *) pkt;
3861aa5ce   wdenk   Initial revision
69
70
71
72
  	int retval = 0;
  
  	if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
  		retval = -1;
f8315731d   Joe Hershberger   net: cosmetic: Re...
73
  	else if (len < sizeof(struct Bootp_t) - OPT_FIELD_SIZE)
3861aa5ce   wdenk   Initial revision
74
75
  		retval = -2;
  	else if (bp->bp_op != OP_BOOTREQUEST &&
3090b7e36   Joe Hershberger   net: cosmetic: bo...
76
77
78
79
  			bp->bp_op != OP_BOOTREPLY &&
  			bp->bp_op != DHCP_OFFER &&
  			bp->bp_op != DHCP_ACK &&
  			bp->bp_op != DHCP_NAK)
3861aa5ce   wdenk   Initial revision
80
  		retval = -3;
3861aa5ce   wdenk   Initial revision
81
82
83
84
  	else if (bp->bp_htype != HWT_ETHER)
  		retval = -4;
  	else if (bp->bp_hlen != HWL_ETHER)
  		retval = -5;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
85
  	else if (NetReadLong((ulong *)&bp->bp_id) != BootpID)
3861aa5ce   wdenk   Initial revision
86
  		retval = -6;
3861aa5ce   wdenk   Initial revision
87

0ebf04c60   Robin Getz   minor debug clean...
88
89
  	debug("Filtering pkt = %d
  ", retval);
3861aa5ce   wdenk   Initial revision
90
91
92
93
94
95
96
  
  	return retval;
  }
  
  /*
   * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
   */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
97
  static void BootpCopyNetParams(struct Bootp_t *bp)
3861aa5ce   wdenk   Initial revision
98
  {
5d110f0aa   Wilson Callan   New CONFIG_BOOTP_...
99
  #if !defined(CONFIG_BOOTP_SERVERIP)
1752f0fdc   Joe Hershberger   net: Fix unused v...
100
  	IPaddr_t tmp_ip;
3d3befa75   wdenk   * Patch by Philip...
101
102
103
  	NetCopyIP(&tmp_ip, &bp->bp_siaddr);
  	if (tmp_ip != 0)
  		NetCopyIP(&NetServerIP, &bp->bp_siaddr);
cb487f566   Joe Hershberger   net: cosmetic: Un...
104
  	memcpy(NetServerEther, ((struct ethernet_hdr *)NetRxPacket)->et_src, 6);
5d110f0aa   Wilson Callan   New CONFIG_BOOTP_...
105
  #endif
1752f0fdc   Joe Hershberger   net: Fix unused v...
106
  	NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
3d3befa75   wdenk   * Patch by Philip...
107
  	if (strlen(bp->bp_file) > 0)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
108
  		copy_filename(BootFile, bp->bp_file, sizeof(BootFile));
3861aa5ce   wdenk   Initial revision
109

0ebf04c60   Robin Getz   minor debug clean...
110
111
  	debug("Bootfile: %s
  ", BootFile);
3861aa5ce   wdenk   Initial revision
112
113
  
  	/* Propagate to environment:
8bde7f776   wdenk   * Code cleanup:
114
  	 * don't delete exising entry when BOOTP / DHCP reply does
3861aa5ce   wdenk   Initial revision
115
116
  	 * not contain a new value
  	 */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
117
118
  	if (*BootFile)
  		setenv("bootfile", BootFile);
3861aa5ce   wdenk   Initial revision
119
  }
3090b7e36   Joe Hershberger   net: cosmetic: bo...
120
  static int truncate_sz(const char *name, int maxlen, int curlen)
3861aa5ce   wdenk   Initial revision
121
122
  {
  	if (curlen >= maxlen) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
123
124
125
  		printf("*** WARNING: %s is too long (%d - max: %d)"
  			" - truncated
  ", name, curlen, maxlen);
3861aa5ce   wdenk   Initial revision
126
127
  		curlen = maxlen - 1;
  	}
3090b7e36   Joe Hershberger   net: cosmetic: bo...
128
  	return curlen;
3861aa5ce   wdenk   Initial revision
129
  }
643d1ab23   Jon Loeliger   net/: Remove obso...
130
  #if !defined(CONFIG_CMD_DHCP)
3861aa5ce   wdenk   Initial revision
131

3090b7e36   Joe Hershberger   net: cosmetic: bo...
132
  static void BootpVendorFieldProcess(u8 *ext)
3861aa5ce   wdenk   Initial revision
133
  {
232c150a2   wdenk   Add support for S...
134
  	int size = *(ext + 1);
3861aa5ce   wdenk   Initial revision
135

0ebf04c60   Robin Getz   minor debug clean...
136
137
  	debug("[BOOTP] Processing extension %d... (%d bytes)
  ", *ext,
3090b7e36   Joe Hershberger   net: cosmetic: bo...
138
  		*(ext + 1));
3861aa5ce   wdenk   Initial revision
139

232c150a2   wdenk   Add support for S...
140
  	NetBootFileSize = 0;
3861aa5ce   wdenk   Initial revision
141

232c150a2   wdenk   Add support for S...
142
143
  	switch (*ext) {
  		/* Fixed length fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
144
  	case 1:			/* Subnet mask */
3861aa5ce   wdenk   Initial revision
145
  		if (NetOurSubnetMask == 0)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
146
  			NetCopyIP(&NetOurSubnetMask, (IPaddr_t *) (ext + 2));
3861aa5ce   wdenk   Initial revision
147
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
148
  	case 2:			/* Time offset - Not yet supported */
3861aa5ce   wdenk   Initial revision
149
  		break;
232c150a2   wdenk   Add support for S...
150
  		/* Variable length fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
151
152
153
  	case 3:			/* Gateways list */
  		if (NetOurGatewayIP == 0)
  			NetCopyIP(&NetOurGatewayIP, (IPaddr_t *) (ext + 2));
3861aa5ce   wdenk   Initial revision
154
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
155
  	case 4:			/* Time server - Not yet supported */
3861aa5ce   wdenk   Initial revision
156
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
157
  	case 5:			/* IEN-116 name server - Not yet supported */
3861aa5ce   wdenk   Initial revision
158
159
  		break;
  	case 6:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
160
161
  		if (NetOurDNSIP == 0)
  			NetCopyIP(&NetOurDNSIP, (IPaddr_t *) (ext + 2));
1fe80d79c   Jon Loeliger   Finally retire cm...
162
  #if defined(CONFIG_BOOTP_DNS2)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
163
164
  		if ((NetOurDNS2IP == 0) && (size > 4))
  			NetCopyIP(&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));
fe389a82c   stroese   - Added CONFIG_BO...
165
  #endif
3861aa5ce   wdenk   Initial revision
166
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
167
  	case 7:			/* Log server - Not yet supported */
3861aa5ce   wdenk   Initial revision
168
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
169
  	case 8:			/* Cookie/Quote server - Not yet supported */
3861aa5ce   wdenk   Initial revision
170
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
171
  	case 9:			/* LPR server - Not yet supported */
3861aa5ce   wdenk   Initial revision
172
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
173
  	case 10:		/* Impress server - Not yet supported */
3861aa5ce   wdenk   Initial revision
174
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
175
  	case 11:		/* RPL server - Not yet supported */
3861aa5ce   wdenk   Initial revision
176
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
177
  	case 12:		/* Host name */
3861aa5ce   wdenk   Initial revision
178
  		if (NetOurHostName[0] == 0) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
179
180
181
  			size = truncate_sz("Host Name",
  				sizeof(NetOurHostName), size);
  			memcpy(&NetOurHostName, ext + 2, size);
232c150a2   wdenk   Add support for S...
182
  			NetOurHostName[size] = 0;
3861aa5ce   wdenk   Initial revision
183
184
  		}
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
185
  	case 13:		/* Boot file size */
3861aa5ce   wdenk   Initial revision
186
  		if (size == 2)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
187
  			NetBootFileSize = ntohs(*(ushort *) (ext + 2));
3861aa5ce   wdenk   Initial revision
188
  		else if (size == 4)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
189
  			NetBootFileSize = ntohl(*(ulong *) (ext + 2));
3861aa5ce   wdenk   Initial revision
190
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
191
  	case 14:		/* Merit dump file - Not yet supported */
3861aa5ce   wdenk   Initial revision
192
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
193
  	case 15:		/* Domain name - Not yet supported */
3861aa5ce   wdenk   Initial revision
194
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
195
  	case 16:		/* Swap server - Not yet supported */
3861aa5ce   wdenk   Initial revision
196
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
197
  	case 17:		/* Root path */
3861aa5ce   wdenk   Initial revision
198
  		if (NetOurRootPath[0] == 0) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
199
200
201
  			size = truncate_sz("Root Path",
  				sizeof(NetOurRootPath), size);
  			memcpy(&NetOurRootPath, ext + 2, size);
232c150a2   wdenk   Add support for S...
202
  			NetOurRootPath[size] = 0;
3861aa5ce   wdenk   Initial revision
203
204
  		}
  		break;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
205
  	case 18:		/* Extension path - Not yet supported */
3861aa5ce   wdenk   Initial revision
206
  		/*
8bde7f776   wdenk   * Code cleanup:
207
208
209
  		 * 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
210
211
  		 */
  		break;
232c150a2   wdenk   Add support for S...
212
  		/* IP host layer fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
213
  	case 40:		/* NIS Domain name */
3861aa5ce   wdenk   Initial revision
214
  		if (NetOurNISDomain[0] == 0) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
215
216
217
  			size = truncate_sz("NIS Domain Name",
  				sizeof(NetOurNISDomain), size);
  			memcpy(&NetOurNISDomain, ext + 2, size);
232c150a2   wdenk   Add support for S...
218
  			NetOurNISDomain[size] = 0;
3861aa5ce   wdenk   Initial revision
219
220
  		}
  		break;
09e3a67de   Luuk Paulussen   bootp: add ntpser...
221
222
223
224
225
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
  	case 42:	/* NTP server IP */
  		NetCopyIP(&NetNtpServerIP, (IPaddr_t *) (ext + 2));
  		break;
  #endif
232c150a2   wdenk   Add support for S...
226
  		/* Application layer fields */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
227
  	case 43:		/* Vendor specific info - Not yet supported */
3861aa5ce   wdenk   Initial revision
228
  		/*
8bde7f776   wdenk   * Code cleanup:
229
230
  		 * Binary information to exchange specific
  		 * product information.
3861aa5ce   wdenk   Initial revision
231
232
  		 */
  		break;
232c150a2   wdenk   Add support for S...
233
234
  		/* Reserved (custom) fields (128..254) */
  	}
3861aa5ce   wdenk   Initial revision
235
  }
3090b7e36   Joe Hershberger   net: cosmetic: bo...
236
  static void BootpVendorProcess(u8 *ext, int size)
3861aa5ce   wdenk   Initial revision
237
  {
232c150a2   wdenk   Add support for S...
238
  	u8 *end = ext + size;
3861aa5ce   wdenk   Initial revision
239

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

232c150a2   wdenk   Add support for S...
243
244
245
246
247
248
249
250
  	while ((ext < end) && (*ext != 0xff)) {
  		if (*ext == 0) {
  			ext++;
  		} else {
  			u8 *opt = ext;
  
  			ext += ext[1] + 2;
  			if (ext <= end)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
251
  				BootpVendorFieldProcess(opt);
232c150a2   wdenk   Add support for S...
252
  		}
3861aa5ce   wdenk   Initial revision
253
  	}
3861aa5ce   wdenk   Initial revision
254

3090b7e36   Joe Hershberger   net: cosmetic: bo...
255
256
  	debug("[BOOTP] Received fields:
  ");
b6446b677   Mike Frysinger   convert print_IPa...
257
  	if (NetOurSubnetMask)
0ebf04c60   Robin Getz   minor debug clean...
258
259
  		debug("NetOurSubnetMask : %pI4
  ", &NetOurSubnetMask);
232c150a2   wdenk   Add support for S...
260

b6446b677   Mike Frysinger   convert print_IPa...
261
  	if (NetOurGatewayIP)
0ebf04c60   Robin Getz   minor debug clean...
262
  		debug("NetOurGatewayIP	: %pI4", &NetOurGatewayIP);
232c150a2   wdenk   Add support for S...
263

0ebf04c60   Robin Getz   minor debug clean...
264
265
266
  	if (NetBootFileSize)
  		debug("NetBootFileSize : %d
  ", NetBootFileSize);
3861aa5ce   wdenk   Initial revision
267

0ebf04c60   Robin Getz   minor debug clean...
268
269
270
  	if (NetOurHostName[0])
  		debug("NetOurHostName  : %s
  ", NetOurHostName);
232c150a2   wdenk   Add support for S...
271

0ebf04c60   Robin Getz   minor debug clean...
272
273
274
  	if (NetOurRootPath[0])
  		debug("NetOurRootPath  : %s
  ", NetOurRootPath);
232c150a2   wdenk   Add support for S...
275

0ebf04c60   Robin Getz   minor debug clean...
276
277
278
  	if (NetOurNISDomain[0])
  		debug("NetOurNISDomain : %s
  ", NetOurNISDomain);
232c150a2   wdenk   Add support for S...
279

0ebf04c60   Robin Getz   minor debug clean...
280
281
282
  	if (NetBootFileSize)
  		debug("NetBootFileSize: %d
  ", NetBootFileSize);
09e3a67de   Luuk Paulussen   bootp: add ntpser...
283
284
285
286
287
288
  
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
  	if (NetNtpServerIP)
  		debug("NetNtpServerIP : %pI4
  ", &NetNtpServerIP);
  #endif
232c150a2   wdenk   Add support for S...
289
  }
093498669   Simon Glass   Put common autolo...
290

3861aa5ce   wdenk   Initial revision
291
292
293
294
  /*
   *	Handle a BOOTP received packet.
   */
  static void
03eb129f8   Luca Ceresoli   NET: pass source ...
295
296
  BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
  	     unsigned len)
3861aa5ce   wdenk   Initial revision
297
  {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
298
  	struct Bootp_t *bp;
3861aa5ce   wdenk   Initial revision
299

0ebf04c60   Robin Getz   minor debug clean...
300
301
  	debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)
  ",
3090b7e36   Joe Hershberger   net: cosmetic: bo...
302
  		src, dest, len, sizeof(struct Bootp_t));
3861aa5ce   wdenk   Initial revision
303

3090b7e36   Joe Hershberger   net: cosmetic: bo...
304
  	bp = (struct Bootp_t *)pkt;
3861aa5ce   wdenk   Initial revision
305

3090b7e36   Joe Hershberger   net: cosmetic: bo...
306
307
  	/* Filter out pkts we don't want */
  	if (BootpCheckPkt(pkt, dest, src, len))
3861aa5ce   wdenk   Initial revision
308
309
310
  		return;
  
  	/*
232c150a2   wdenk   Add support for S...
311
  	 *	Got a good BOOTP reply.	 Copy the data into our variables.
3861aa5ce   wdenk   Initial revision
312
313
  	 */
  #ifdef CONFIG_STATUS_LED
3090b7e36   Joe Hershberger   net: cosmetic: bo...
314
  	status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
3861aa5ce   wdenk   Initial revision
315
316
317
318
319
  #endif
  
  	BootpCopyNetParams(bp);		/* Store net parameters from reply */
  
  	/* Retrieve extended information (we must parse the vendor area) */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
320
  	if (NetReadLong((ulong *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
77ddac948   Wolfgang Denk   Cleanup for GCC-4.x
321
  		BootpVendorProcess((uchar *)&bp->bp_vend[4], len);
3861aa5ce   wdenk   Initial revision
322
323
  
  	NetSetTimeout(0, (thand_f *)0);
573f14fe4   Simon Glass   bootstage: Plumb ...
324
  	bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop");
3861aa5ce   wdenk   Initial revision
325

0ebf04c60   Robin Getz   minor debug clean...
326
327
  	debug("Got good BOOTP
  ");
3861aa5ce   wdenk   Initial revision
328

e4a3d57dc   Simon Glass   net: Export auto_...
329
  	net_auto_load();
3861aa5ce   wdenk   Initial revision
330
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
331
  #endif
3861aa5ce   wdenk   Initial revision
332
333
334
335
336
337
338
339
  
  /*
   *	Timeout on BOOTP/DHCP request.
   */
  static void
  BootpTimeout(void)
  {
  	if (BootpTry >= TIMEOUT_COUNT) {
2c00e099f   Joe Hershberger   net: Add option C...
340
341
342
343
  #ifdef CONFIG_BOOTP_MAY_FAIL
  		puts("
  Retry count exceeded
  ");
b977aa80b   benoit.thebaudeau@advans   net: bootp: fix b...
344
  		net_set_state(NETLOOP_FAIL);
2c00e099f   Joe Hershberger   net: Add option C...
345
  #else
3090b7e36   Joe Hershberger   net: cosmetic: bo...
346
347
348
349
  		puts("
  Retry count exceeded; starting again
  ");
  		NetStartAgain();
2c00e099f   Joe Hershberger   net: Add option C...
350
  #endif
3861aa5ce   wdenk   Initial revision
351
  	} else {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
352
353
  		NetSetTimeout(TIMEOUT, BootpTimeout);
  		BootpRequest();
3861aa5ce   wdenk   Initial revision
354
355
  	}
  }
9ace17c88   Ilya Yanok   net/bootp: add VC...
356
357
358
359
360
361
362
363
  #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)
3861aa5ce   wdenk   Initial revision
364
365
366
  /*
   *	Initialize BOOTP extension fields in the request.
   */
643d1ab23   Jon Loeliger   net/: Remove obso...
367
  #if defined(CONFIG_CMD_DHCP)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
368
369
  static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID,
  			IPaddr_t RequestedIP)
3861aa5ce   wdenk   Initial revision
370
  {
232c150a2   wdenk   Add support for S...
371
372
  	u8 *start = e;
  	u8 *cnt;
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
373
374
  #if defined(CONFIG_BOOTP_PXE)
  	char *uuid;
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
375
376
  	u16 clientarch;
  #endif
232c150a2   wdenk   Add support for S...
377

1fe80d79c   Jon Loeliger   Finally retire cm...
378
  #if defined(CONFIG_BOOTP_VENDOREX)
232c150a2   wdenk   Add support for S...
379
  	u8 *x;
3861aa5ce   wdenk   Initial revision
380
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
381
  #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
77ddac948   Wolfgang Denk   Cleanup for GCC-4.x
382
  	char *hostname;
fe389a82c   stroese   - Added CONFIG_BO...
383
  #endif
3861aa5ce   wdenk   Initial revision
384

232c150a2   wdenk   Add support for S...
385
386
387
388
  	*e++ = 99;		/* RFC1048 Magic Cookie */
  	*e++ = 130;
  	*e++ = 83;
  	*e++ = 99;
3861aa5ce   wdenk   Initial revision
389

232c150a2   wdenk   Add support for S...
390
391
392
  	*e++ = 53;		/* DHCP Message Type */
  	*e++ = 1;
  	*e++ = message_type;
3861aa5ce   wdenk   Initial revision
393

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

232c150a2   wdenk   Add support for S...
399
  	if (ServerID) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
400
  		int tmp = ntohl(ServerID);
3861aa5ce   wdenk   Initial revision
401

232c150a2   wdenk   Add support for S...
402
403
404
405
406
407
408
  		*e++ = 54;	/* ServerID */
  		*e++ = 4;
  		*e++ = tmp >> 24;
  		*e++ = tmp >> 16;
  		*e++ = tmp >> 8;
  		*e++ = tmp & 0xff;
  	}
3861aa5ce   wdenk   Initial revision
409

232c150a2   wdenk   Add support for S...
410
  	if (RequestedIP) {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
411
  		int tmp = ntohl(RequestedIP);
3861aa5ce   wdenk   Initial revision
412

232c150a2   wdenk   Add support for S...
413
414
415
416
417
418
419
  		*e++ = 50;	/* Requested IP */
  		*e++ = 4;
  		*e++ = tmp >> 24;
  		*e++ = tmp >> 16;
  		*e++ = tmp >> 8;
  		*e++ = tmp & 0xff;
  	}
1fe80d79c   Jon Loeliger   Finally retire cm...
420
  #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
421
422
423
  	hostname = getenv("hostname");
  	if (hostname) {
  		int hostnamelen = strlen(hostname);
232c150a2   wdenk   Add support for S...
424
425
426
  
  		*e++ = 12;	/* Hostname */
  		*e++ = hostnamelen;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
427
  		memcpy(e, hostname, hostnamelen);
232c150a2   wdenk   Add support for S...
428
429
  		e += hostnamelen;
  	}
fe389a82c   stroese   - Added CONFIG_BO...
430
  #endif
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
  #if defined(CONFIG_BOOTP_PXE)
  	clientarch = CONFIG_BOOTP_PXE_CLIENTARCH;
  	*e++ = 93;	/* Client System Architecture */
  	*e++ = 2;
  	*e++ = (clientarch >> 8) & 0xff;
  	*e++ = clientarch & 0xff;
  
  	*e++ = 94;	/* Client Network Interface Identifier */
  	*e++ = 3;
  	*e++ = 1;	/* type field for UNDI */
  	*e++ = 0;	/* major revision */
  	*e++ = 0;	/* minor revision */
  
  	uuid = getenv("pxeuuid");
  
  	if (uuid) {
  		if (uuid_str_valid(uuid)) {
  			*e++ = 97;	/* Client Machine Identifier */
  			*e++ = 17;
  			*e++ = 0;	/* type 0 - UUID */
  
  			uuid_str_to_bin(uuid, e);
  			e += 16;
  		} else {
  			printf("Invalid pxeuuid: %s
  ", uuid);
  		}
  	}
9ace17c88   Ilya Yanok   net/bootp: add VC...
459
  #endif
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
460

9ace17c88   Ilya Yanok   net/bootp: add VC...
461
462
  #ifdef CONFIG_BOOTP_VCI_STRING
  	put_vci(e, CONFIG_BOOTP_VCI_STRING);
d2b5d5c4c   Jason Hobbs   net: bootp: add P...
463
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
464
  #if defined(CONFIG_BOOTP_VENDOREX)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
465
466
  	x = dhcp_vendorex_prep(e);
  	if (x)
232c150a2   wdenk   Add support for S...
467
  		return x - start;
3861aa5ce   wdenk   Initial revision
468
  #endif
232c150a2   wdenk   Add support for S...
469
470
471
  	*e++ = 55;		/* Parameter Request List */
  	 cnt = e++;		/* Pointer to count of requested items */
  	*cnt = 0;
1fe80d79c   Jon Loeliger   Finally retire cm...
472
  #if defined(CONFIG_BOOTP_SUBNETMASK)
232c150a2   wdenk   Add support for S...
473
474
  	*e++  = 1;		/* Subnet Mask */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
475
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
476
  #if defined(CONFIG_BOOTP_TIMEOFFSET)
ea287debe   wdenk   * Patch by Masami...
477
478
479
  	*e++  = 2;
  	*cnt += 1;
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
480
  #if defined(CONFIG_BOOTP_GATEWAY)
232c150a2   wdenk   Add support for S...
481
482
  	*e++  = 3;		/* Router Option */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
483
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
484
  #if defined(CONFIG_BOOTP_DNS)
232c150a2   wdenk   Add support for S...
485
486
  	*e++  = 6;		/* DNS Server(s) */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
487
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
488
  #if defined(CONFIG_BOOTP_HOSTNAME)
232c150a2   wdenk   Add support for S...
489
490
  	*e++  = 12;		/* Hostname */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
491
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
492
  #if defined(CONFIG_BOOTP_BOOTFILESIZE)
232c150a2   wdenk   Add support for S...
493
494
  	*e++  = 13;		/* Boot File Size */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
495
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
496
  #if defined(CONFIG_BOOTP_BOOTPATH)
232c150a2   wdenk   Add support for S...
497
498
  	*e++  = 17;		/* Boot path */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
499
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
500
  #if defined(CONFIG_BOOTP_NISDOMAIN)
232c150a2   wdenk   Add support for S...
501
502
  	*e++  = 40;		/* NIS Domain name request */
  	*cnt += 1;
3861aa5ce   wdenk   Initial revision
503
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
504
  #if defined(CONFIG_BOOTP_NTPSERVER)
ea287debe   wdenk   * Patch by Masami...
505
506
507
  	*e++  = 42;
  	*cnt += 1;
  #endif
258ccd681   Jason Liu   net: Fix potentia...
508
509
510
  	/* no options, so back up to avoid sending an empty request list */
  	if (*cnt == 0)
  		e -= 2;
232c150a2   wdenk   Add support for S...
511
  	*e++  = 255;		/* End of the list */
3861aa5ce   wdenk   Initial revision
512

232c150a2   wdenk   Add support for S...
513
  	/* Pad to minimal length */
3861aa5ce   wdenk   Initial revision
514
  #ifdef	CONFIG_DHCP_MIN_EXT_LEN
21076f61c   Simon Glass   Fix bad padding o...
515
  	while ((e - start) < CONFIG_DHCP_MIN_EXT_LEN)
232c150a2   wdenk   Add support for S...
516
  		*e++ = 0;
3861aa5ce   wdenk   Initial revision
517
  #endif
232c150a2   wdenk   Add support for S...
518
  	return e - start;
3861aa5ce   wdenk   Initial revision
519
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
520
  #else
3861aa5ce   wdenk   Initial revision
521
  /*
3090b7e36   Joe Hershberger   net: cosmetic: bo...
522
   * Warning: no field size check - change CONFIG_BOOTP_* at your own risk!
3861aa5ce   wdenk   Initial revision
523
   */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
524
  static int BootpExtended(u8 *e)
3861aa5ce   wdenk   Initial revision
525
  {
232c150a2   wdenk   Add support for S...
526
  	u8 *start = e;
3861aa5ce   wdenk   Initial revision
527

232c150a2   wdenk   Add support for S...
528
529
530
531
  	*e++ = 99;		/* RFC1048 Magic Cookie */
  	*e++ = 130;
  	*e++ = 83;
  	*e++ = 99;
3861aa5ce   wdenk   Initial revision
532

643d1ab23   Jon Loeliger   net/: Remove obso...
533
  #if defined(CONFIG_CMD_DHCP)
232c150a2   wdenk   Add support for S...
534
535
536
537
538
539
  	*e++ = 53;		/* DHCP Message Type */
  	*e++ = 1;
  	*e++ = DHCP_DISCOVER;
  
  	*e++ = 57;		/* Maximum DHCP Message Size */
  	*e++ = 2;
f8315731d   Joe Hershberger   net: cosmetic: Re...
540
541
  	*e++ = (576 - 312 + OPT_FIELD_SIZE) >> 16;
  	*e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
610f2e9c2   Jon Loeliger   net/: Remove ling...
542
  #endif
3861aa5ce   wdenk   Initial revision
543

7ac2fe2da   Ilya Yanok   OMAP: networking ...
544
545
546
547
548
  #if defined(CONFIG_BOOTP_VCI_STRING) || \
  	(defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING))
  #ifdef CONFIG_SPL_BUILD
  	put_vci(e, CONFIG_SPL_NET_VCI_STRING);
  #else
9ace17c88   Ilya Yanok   net/bootp: add VC...
549
550
  	put_vci(e, CONFIG_BOOTP_VCI_STRING);
  #endif
7ac2fe2da   Ilya Yanok   OMAP: networking ...
551
  #endif
9ace17c88   Ilya Yanok   net/bootp: add VC...
552

1fe80d79c   Jon Loeliger   Finally retire cm...
553
  #if defined(CONFIG_BOOTP_SUBNETMASK)
232c150a2   wdenk   Add support for S...
554
555
556
  	*e++ = 1;		/* Subnet mask request */
  	*e++ = 4;
  	e   += 4;
3861aa5ce   wdenk   Initial revision
557
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
558
  #if defined(CONFIG_BOOTP_GATEWAY)
232c150a2   wdenk   Add support for S...
559
560
561
  	*e++ = 3;		/* Default gateway request */
  	*e++ = 4;
  	e   += 4;
3861aa5ce   wdenk   Initial revision
562
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
563
  #if defined(CONFIG_BOOTP_DNS)
232c150a2   wdenk   Add support for S...
564
565
566
  	*e++ = 6;		/* Domain Name Server */
  	*e++ = 4;
  	e   += 4;
3861aa5ce   wdenk   Initial revision
567
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
568
  #if defined(CONFIG_BOOTP_HOSTNAME)
232c150a2   wdenk   Add support for S...
569
570
571
  	*e++ = 12;		/* Host name request */
  	*e++ = 32;
  	e   += 32;
3861aa5ce   wdenk   Initial revision
572
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
573
  #if defined(CONFIG_BOOTP_BOOTFILESIZE)
232c150a2   wdenk   Add support for S...
574
575
576
  	*e++ = 13;		/* Boot file size */
  	*e++ = 2;
  	e   += 2;
3861aa5ce   wdenk   Initial revision
577
  #endif
1fe80d79c   Jon Loeliger   Finally retire cm...
578
  #if defined(CONFIG_BOOTP_BOOTPATH)
232c150a2   wdenk   Add support for S...
579
580
581
  	*e++ = 17;		/* Boot path */
  	*e++ = 32;
  	e   += 32;
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
586
  	*e++ = 40;		/* NIS Domain name request */
  	*e++ = 32;
  	e   += 32;
3861aa5ce   wdenk   Initial revision
587
  #endif
09e3a67de   Luuk Paulussen   bootp: add ntpser...
588
589
590
591
592
  #if defined(CONFIG_BOOTP_NTPSERVER)
  	*e++ = 42;
  	*e++ = 4;
  	e   += 4;
  #endif
3861aa5ce   wdenk   Initial revision
593

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
  	return e - start;
3861aa5ce   wdenk   Initial revision
597
  }
610f2e9c2   Jon Loeliger   net/: Remove ling...
598
  #endif
3861aa5ce   wdenk   Initial revision
599
600
  
  void
3090b7e36   Joe Hershberger   net: cosmetic: bo...
601
  BootpRequest(void)
3861aa5ce   wdenk   Initial revision
602
  {
db288a960   Joe Hershberger   net: Remove volat...
603
  	uchar *pkt, *iphdr;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
604
  	struct Bootp_t *bp;
ae446f562   Joe Hershberger   net: Refactor boo...
605
606
  	int extlen, pktlen, iplen;
  	int eth_hdr_size;
eafc8db0e   Joe Hershberger   net: Move MAC-see...
607
608
609
  #ifdef CONFIG_BOOTP_RANDOM_DELAY
  	ulong i, rand_ms;
  #endif
3861aa5ce   wdenk   Initial revision
610

573f14fe4   Simon Glass   bootstage: Plumb ...
611
  	bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
643d1ab23   Jon Loeliger   net/: Remove obso...
612
  #if defined(CONFIG_CMD_DHCP)
3861aa5ce   wdenk   Initial revision
613
614
615
616
  	dhcp_state = INIT;
  #endif
  
  #ifdef CONFIG_BOOTP_RANDOM_DELAY		/* Random BOOTP delay */
eafc8db0e   Joe Hershberger   net: Move MAC-see...
617
618
  	if (BootpTry == 0)
  		srand_mac();
3861aa5ce   wdenk   Initial revision
619

eafc8db0e   Joe Hershberger   net: Move MAC-see...
620
621
622
623
  	if (BootpTry <= 2)	/* Start with max 1024 * 1ms */
  		rand_ms = rand() >> (22 - BootpTry);
  	else		/* After 3rd BOOTP request max 8192 * 1ms */
  		rand_ms = rand() >> 19;
3861aa5ce   wdenk   Initial revision
624

eafc8db0e   Joe Hershberger   net: Move MAC-see...
625
626
627
  	printf("Random delay: %ld ms...
  ", rand_ms);
  	for (i = 0; i < rand_ms; i++)
3861aa5ce   wdenk   Initial revision
628
  		udelay(1000); /*Wait 1ms*/
3090b7e36   Joe Hershberger   net: cosmetic: bo...
629

3861aa5ce   wdenk   Initial revision
630
631
632
633
634
  #endif	/* CONFIG_BOOTP_RANDOM_DELAY */
  
  	printf("BOOTP broadcast %d
  ", ++BootpTry);
  	pkt = NetTxPacket;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
635
  	memset((void *)pkt, 0, PKTSIZE);
3861aa5ce   wdenk   Initial revision
636

ae446f562   Joe Hershberger   net: Refactor boo...
637
638
  	eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP);
  	pkt += eth_hdr_size;
3861aa5ce   wdenk   Initial revision
639
640
  
  	/*
3090b7e36   Joe Hershberger   net: cosmetic: bo...
641
642
643
644
  	 * 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
645
646
  	 * C. Hallinan, DS4.COM, Inc.
  	 */
4b11c9166   Joe Hershberger   net: Refactor IP,...
647
  	/* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC,
3090b7e36   Joe Hershberger   net: cosmetic: bo...
648
  		sizeof (struct Bootp_t)); */
4b11c9166   Joe Hershberger   net: Refactor IP,...
649
  	iphdr = pkt;	/* We need this later for net_set_udp_header() */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
650
  	pkt += IP_UDP_HDR_SIZE;
3861aa5ce   wdenk   Initial revision
651

3090b7e36   Joe Hershberger   net: cosmetic: bo...
652
  	bp = (struct Bootp_t *)pkt;
3861aa5ce   wdenk   Initial revision
653
654
655
656
  	bp->bp_op = OP_BOOTREQUEST;
  	bp->bp_htype = HWT_ETHER;
  	bp->bp_hlen = HWL_ETHER;
  	bp->bp_hops = 0;
49f3bdbba   Bartlomiej Sieka   net: express the ...
657
  	bp->bp_secs = htons(get_timer(0) / 1000);
3861aa5ce   wdenk   Initial revision
658
659
660
661
  	NetWriteIP(&bp->bp_ciaddr, 0);
  	NetWriteIP(&bp->bp_yiaddr, 0);
  	NetWriteIP(&bp->bp_siaddr, 0);
  	NetWriteIP(&bp->bp_giaddr, 0);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
662
663
  	memcpy(bp->bp_chaddr, NetOurEther, 6);
  	copy_filename(bp->bp_file, BootFile, sizeof(bp->bp_file));
3861aa5ce   wdenk   Initial revision
664
665
  
  	/* Request additional information from the BOOTP/DHCP server */
643d1ab23   Jon Loeliger   net/: Remove obso...
666
  #if defined(CONFIG_CMD_DHCP)
ae446f562   Joe Hershberger   net: Refactor boo...
667
  	extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0);
3861aa5ce   wdenk   Initial revision
668
  #else
ae446f562   Joe Hershberger   net: Refactor boo...
669
  	extlen = BootpExtended((u8 *)bp->bp_vend);
610f2e9c2   Jon Loeliger   net/: Remove ling...
670
  #endif
3861aa5ce   wdenk   Initial revision
671
672
673
  
  	/*
  	 *	Bootp ID is the lower 4 bytes of our ethernet address
49f3bdbba   Bartlomiej Sieka   net: express the ...
674
  	 *	plus the current time in ms.
3861aa5ce   wdenk   Initial revision
675
676
677
678
679
680
  	 */
  	BootpID = ((ulong)NetOurEther[2] << 24)
  		| ((ulong)NetOurEther[3] << 16)
  		| ((ulong)NetOurEther[4] << 8)
  		| (ulong)NetOurEther[5];
  	BootpID += get_timer(0);
232c150a2   wdenk   Add support for S...
681
  	BootpID	 = htonl(BootpID);
3861aa5ce   wdenk   Initial revision
682
683
684
685
686
687
  	NetCopyLong(&bp->bp_id, &BootpID);
  
  	/*
  	 * Calculate proper packet lengths taking into account the
  	 * variable size of the options field
  	 */
ae446f562   Joe Hershberger   net: Refactor boo...
688
689
  	iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
  	pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
4b11c9166   Joe Hershberger   net: Refactor IP,...
690
  	net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
49f3bdbba   Bartlomiej Sieka   net: express the ...
691
  	NetSetTimeout(SELECT_TIMEOUT, BootpTimeout);
3861aa5ce   wdenk   Initial revision
692

643d1ab23   Jon Loeliger   net/: Remove obso...
693
  #if defined(CONFIG_CMD_DHCP)
3861aa5ce   wdenk   Initial revision
694
  	dhcp_state = SELECTING;
ece223b52   Joe Hershberger   net: Refactor to ...
695
  	net_set_udp_handler(DhcpHandler);
3861aa5ce   wdenk   Initial revision
696
  #else
ece223b52   Joe Hershberger   net: Refactor to ...
697
  	net_set_udp_handler(BootpHandler);
610f2e9c2   Jon Loeliger   net/: Remove ling...
698
  #endif
3861aa5ce   wdenk   Initial revision
699
700
  	NetSendPacket(NetTxPacket, pktlen);
  }
643d1ab23   Jon Loeliger   net/: Remove obso...
701
  #if defined(CONFIG_CMD_DHCP)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
702
  static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp)
3861aa5ce   wdenk   Initial revision
703
  {
3e38691e8   wdenk   * Patch by Arun D...
704
  	uchar *end = popt + BOOTP_HDR_SIZE;
3861aa5ce   wdenk   Initial revision
705
  	int oplen, size;
d8d8724be   Wolfgang Denk   net/bootp.c: fix ...
706
707
708
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
  	int *to_ptr;
  #endif
3861aa5ce   wdenk   Initial revision
709

232c150a2   wdenk   Add support for S...
710
  	while (popt < end && *popt != 0xff) {
3861aa5ce   wdenk   Initial revision
711
  		oplen = *(popt + 1);
232c150a2   wdenk   Add support for S...
712
713
  		switch (*popt) {
  		case 1:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
714
  			NetCopyIP(&NetOurSubnetMask, (popt + 2));
232c150a2   wdenk   Add support for S...
715
  			break;
1fe80d79c   Jon Loeliger   Finally retire cm...
716
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
ea287debe   wdenk   * Patch by Masami...
717
  		case 2:		/* Time offset	*/
d8d8724be   Wolfgang Denk   net/bootp.c: fix ...
718
  			to_ptr = &NetTimeOffset;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
719
720
  			NetCopyLong((ulong *)to_ptr, (ulong *)(popt + 2));
  			NetTimeOffset = ntohl(NetTimeOffset);
ea287debe   wdenk   * Patch by Masami...
721
722
  			break;
  #endif
232c150a2   wdenk   Add support for S...
723
  		case 3:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
724
  			NetCopyIP(&NetOurGatewayIP, (popt + 2));
232c150a2   wdenk   Add support for S...
725
726
  			break;
  		case 6:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
727
  			NetCopyIP(&NetOurDNSIP, (popt + 2));
1fe80d79c   Jon Loeliger   Finally retire cm...
728
  #if defined(CONFIG_BOOTP_DNS2)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
729
730
  			if (*(popt + 1) > 4)
  				NetCopyIP(&NetOurDNS2IP, (popt + 2 + 4));
fe389a82c   stroese   - Added CONFIG_BO...
731
  #endif
232c150a2   wdenk   Add support for S...
732
733
  			break;
  		case 12:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
734
735
736
  			size = truncate_sz("Host Name",
  				sizeof(NetOurHostName), oplen);
  			memcpy(&NetOurHostName, popt + 2, size);
232c150a2   wdenk   Add support for S...
737
738
739
740
741
  			NetOurHostName[size] = 0;
  			break;
  		case 15:	/* Ignore Domain Name Option */
  			break;
  		case 17:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
742
743
744
  			size = truncate_sz("Root Path",
  				sizeof(NetOurRootPath), oplen);
  			memcpy(&NetOurRootPath, popt + 2, size);
232c150a2   wdenk   Add support for S...
745
746
  			NetOurRootPath[size] = 0;
  			break;
ee0f60df0   Brian Rzycki   net: Quietly igno...
747
748
  		case 28:	/* Ignore Broadcast Address Option */
  			break;
1fe80d79c   Jon Loeliger   Finally retire cm...
749
  #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
ea287debe   wdenk   * Patch by Masami...
750
  		case 42:	/* NTP server IP */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
751
  			NetCopyIP(&NetNtpServerIP, (popt + 2));
ea287debe   wdenk   * Patch by Masami...
752
753
  			break;
  #endif
232c150a2   wdenk   Add support for S...
754
  		case 51:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
755
  			NetCopyLong(&dhcp_leasetime, (ulong *) (popt + 2));
232c150a2   wdenk   Add support for S...
756
757
758
759
  			break;
  		case 53:	/* Ignore Message Type Option */
  			break;
  		case 54:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
760
  			NetCopyIP(&NetDHCPServerIP, (popt + 2));
232c150a2   wdenk   Add support for S...
761
762
763
764
765
  			break;
  		case 58:	/* Ignore Renewal Time Option */
  			break;
  		case 59:	/* Ignore Rebinding Time Option */
  			break;
3b2e4fd9b   Wolfgang Denk   Add support for t...
766
767
768
769
770
771
772
773
774
  		case 66:	/* Ignore TFTP server name */
  			break;
  		case 67:	/* vendor opt bootfile */
  			/*
  			 * I can't use dhcp_vendorex_proc here because I need
  			 * to write into the bootp packet - even then I had to
  			 * pass the bootp packet pointer into here as the
  			 * second arg
  			 */
3090b7e36   Joe Hershberger   net: cosmetic: bo...
775
  			size = truncate_sz("Opt Boot File",
3b2e4fd9b   Wolfgang Denk   Add support for t...
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
  					    sizeof(bp->bp_file),
  					    oplen);
  			if (bp->bp_file[0] == '\0' && size > 0) {
  				/*
  				 * only use vendor boot file if we didn't
  				 * receive a boot file in the main non-vendor
  				 * part of the packet - god only knows why
  				 * some vendors chose not to use this perfectly
  				 * good spot to store the boot file (join on
  				 * Tru64 Unix) it seems mind bogglingly crazy
  				 * to me
  				 */
  				printf("*** WARNING: using vendor "
  					"optional boot file
  ");
  				memcpy(bp->bp_file, popt + 2, size);
  				bp->bp_file[size] = '\0';
  			}
  			break;
232c150a2   wdenk   Add support for S...
795
  		default:
1fe80d79c   Jon Loeliger   Finally retire cm...
796
  #if defined(CONFIG_BOOTP_VENDOREX)
3090b7e36   Joe Hershberger   net: cosmetic: bo...
797
  			if (dhcp_vendorex_proc(popt))
8bde7f776   wdenk   * Code cleanup:
798
  				break;
3861aa5ce   wdenk   Initial revision
799
  #endif
3090b7e36   Joe Hershberger   net: cosmetic: bo...
800
801
802
  			printf("*** Unhandled DHCP Option in OFFER/ACK:"
  				" %d
  ", *popt);
232c150a2   wdenk   Add support for S...
803
  			break;
3861aa5ce   wdenk   Initial revision
804
805
806
807
808
809
810
  		}
  		popt += oplen + 2;	/* Process next option */
  	}
  }
  
  static int DhcpMessageType(unsigned char *popt)
  {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
811
  	if (NetReadLong((ulong *)popt) != htonl(BOOTP_VENDOR_MAGIC))
3861aa5ce   wdenk   Initial revision
812
813
814
  		return -1;
  
  	popt += 4;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
815
816
  	while (*popt != 0xff) {
  		if (*popt == 53)	/* DHCP Message Type */
3861aa5ce   wdenk   Initial revision
817
818
819
820
821
  			return *(popt + 2);
  		popt += *(popt + 1) + 2;	/* Scan through all options */
  	}
  	return -1;
  }
3090b7e36   Joe Hershberger   net: cosmetic: bo...
822
  static void DhcpSendRequestPkt(struct Bootp_t *bp_offer)
3861aa5ce   wdenk   Initial revision
823
  {
db288a960   Joe Hershberger   net: Remove volat...
824
  	uchar *pkt, *iphdr;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
825
  	struct Bootp_t *bp;
3861aa5ce   wdenk   Initial revision
826
  	int pktlen, iplen, extlen;
ae446f562   Joe Hershberger   net: Refactor boo...
827
  	int eth_hdr_size;
47cd00fa7   wdenk   * Patches by Robe...
828
  	IPaddr_t OfferedIP;
3861aa5ce   wdenk   Initial revision
829

0ebf04c60   Robin Getz   minor debug clean...
830
831
  	debug("DhcpSendRequestPkt: Sending DHCPREQUEST
  ");
3861aa5ce   wdenk   Initial revision
832
  	pkt = NetTxPacket;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
833
  	memset((void *)pkt, 0, PKTSIZE);
3861aa5ce   wdenk   Initial revision
834

ae446f562   Joe Hershberger   net: Refactor boo...
835
836
  	eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP);
  	pkt += eth_hdr_size;
3861aa5ce   wdenk   Initial revision
837

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

3090b7e36   Joe Hershberger   net: cosmetic: bo...
841
  	bp = (struct Bootp_t *)pkt;
3861aa5ce   wdenk   Initial revision
842
843
844
845
  	bp->bp_op = OP_BOOTREQUEST;
  	bp->bp_htype = HWT_ETHER;
  	bp->bp_hlen = HWL_ETHER;
  	bp->bp_hops = 0;
49f3bdbba   Bartlomiej Sieka   net: express the ...
846
  	bp->bp_secs = htons(get_timer(0) / 1000);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
847
848
  	/* 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
849

c66867039   Wolfgang Denk   Minor code cleanup.
850
  	/*
d82718fed   Wolfgang Denk   Make bootp implem...
851
852
853
854
  	 * RFC3046 requires Relay Agents to discard packets with
  	 * nonzero and offered giaddr
  	 */
  	NetWriteIP(&bp->bp_giaddr, 0);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
855
  	memcpy(bp->bp_chaddr, NetOurEther, 6);
3861aa5ce   wdenk   Initial revision
856
857
858
859
860
861
862
863
864
865
  
  	/*
  	 * ID is the id of the OFFER packet
  	 */
  
  	NetCopyLong(&bp->bp_id, &bp_offer->bp_id);
  
  	/*
  	 * Copy options from OFFER packet if present
  	 */
e5c794e49   Justin Flammia   DHCP Client Fix
866
867
868
  
  	/* Copy offered IP into the parameters request list */
  	NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
869
870
  	extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST,
  		NetDHCPServerIP, OfferedIP);
3861aa5ce   wdenk   Initial revision
871

ae446f562   Joe Hershberger   net: Refactor boo...
872
873
  	iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
  	pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
4b11c9166   Joe Hershberger   net: Refactor IP,...
874
  	net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
3861aa5ce   wdenk   Initial revision
875

d9a2f416d   Aras Vaichas   DHCP request fix ...
876
877
878
  #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...
879
880
  	debug("Transmitting DHCPREQUEST packet: len = %d
  ", pktlen);
3861aa5ce   wdenk   Initial revision
881
882
883
884
885
886
887
  	NetSendPacket(NetTxPacket, pktlen);
  }
  
  /*
   *	Handle DHCP received packets.
   */
  static void
03eb129f8   Luca Ceresoli   NET: pass source ...
888
889
  DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
  	    unsigned len)
3861aa5ce   wdenk   Initial revision
890
  {
3090b7e36   Joe Hershberger   net: cosmetic: bo...
891
  	struct Bootp_t *bp = (struct Bootp_t *)pkt;
3861aa5ce   wdenk   Initial revision
892

0ebf04c60   Robin Getz   minor debug clean...
893
894
  	debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d
  ",
3861aa5ce   wdenk   Initial revision
895
  		src, dest, len, dhcp_state);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
896
897
  	/* Filter out pkts we don't want */
  	if (BootpCheckPkt(pkt, dest, src, len))
3861aa5ce   wdenk   Initial revision
898
  		return;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
899
900
901
  	debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state:"
  		" %d
  ", src, dest, len, dhcp_state);
3861aa5ce   wdenk   Initial revision
902
903
904
905
906
  
  	switch (dhcp_state) {
  	case SELECTING:
  		/*
  		 * Wait an appropriate time for any potential DHCPOFFER packets
3090b7e36   Joe Hershberger   net: cosmetic: bo...
907
908
909
  		 * 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
910
  		 */
0ebf04c60   Robin Getz   minor debug clean...
911
912
  		debug("DHCP: state=SELECTING bp_file: \"%s\"
  ", bp->bp_file);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
913
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
3861aa5ce   wdenk   Initial revision
914
  		if (strncmp(bp->bp_file,
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
915
  			    CONFIG_SYS_BOOTFILE_PREFIX,
3090b7e36   Joe Hershberger   net: cosmetic: bo...
916
  			    strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
917
  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */
3861aa5ce   wdenk   Initial revision
918

0ebf04c60   Robin Getz   minor debug clean...
919
920
  			debug("TRANSITIONING TO REQUESTING STATE
  ");
3861aa5ce   wdenk   Initial revision
921
  			dhcp_state = REQUESTING;
759a51b4f   stroese   Changed DHCP clie...
922

3090b7e36   Joe Hershberger   net: cosmetic: bo...
923
924
  			if (NetReadLong((ulong *)&bp->bp_vend[0]) ==
  						htonl(BOOTP_VENDOR_MAGIC))
3b2e4fd9b   Wolfgang Denk   Add support for t...
925
  				DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
3861aa5ce   wdenk   Initial revision
926

49f3bdbba   Bartlomiej Sieka   net: express the ...
927
  			NetSetTimeout(TIMEOUT, BootpTimeout);
3861aa5ce   wdenk   Initial revision
928
  			DhcpSendRequestPkt(bp);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
929
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
3861aa5ce   wdenk   Initial revision
930
  		}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
931
  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */
3861aa5ce   wdenk   Initial revision
932
933
934
935
  
  		return;
  		break;
  	case REQUESTING:
0ebf04c60   Robin Getz   minor debug clean...
936
937
  		debug("DHCP State: REQUESTING
  ");
3861aa5ce   wdenk   Initial revision
938

3090b7e36   Joe Hershberger   net: cosmetic: bo...
939
940
941
  		if (DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK) {
  			if (NetReadLong((ulong *)&bp->bp_vend[0]) ==
  						htonl(BOOTP_VENDOR_MAGIC))
3b2e4fd9b   Wolfgang Denk   Add support for t...
942
  				DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
3090b7e36   Joe Hershberger   net: cosmetic: bo...
943
944
  			/* Store net params from reply */
  			BootpCopyNetParams(bp);
3861aa5ce   wdenk   Initial revision
945
  			dhcp_state = BOUND;
3090b7e36   Joe Hershberger   net: cosmetic: bo...
946
947
948
  			printf("DHCP client bound to address %pI4
  ",
  				&NetOurIP);
573f14fe4   Simon Glass   bootstage: Plumb ...
949
  			bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
3090b7e36   Joe Hershberger   net: cosmetic: bo...
950
  				"bootp_stop");
3861aa5ce   wdenk   Initial revision
951

e4a3d57dc   Simon Glass   net: Export auto_...
952
  			net_auto_load();
3861aa5ce   wdenk   Initial revision
953
954
955
  			return;
  		}
  		break;
51dfe1382   Remy Bohmer   Fix bogus error m...
956
957
958
  	case BOUND:
  		/* DHCP client bound to address */
  		break;
3861aa5ce   wdenk   Initial revision
959
  	default:
3090b7e36   Joe Hershberger   net: cosmetic: bo...
960
961
  		puts("DHCP: INVALID STATE
  ");
3861aa5ce   wdenk   Initial revision
962
963
964
965
966
967
968
969
970
  		break;
  	}
  
  }
  
  void DhcpRequest(void)
  {
  	BootpRequest();
  }
992742a5b   Wolfgang Denk   Cleanup coding st...
971
  #endif	/* CONFIG_CMD_DHCP */