Blame view

net/net.c 34.9 KB
2d966958c   wdenk   Initial revision
1
2
3
4
5
6
7
8
  /*
   *	Copied from Linux Monitor (LiMon) - Networking.
   *
   *	Copyright 1994 - 2000 Neil Russell.
   *	(See License)
   *	Copyright 2000 Roland Borde
   *	Copyright 2000 Paolo Scaffardi
   *	Copyright 2000-2002 Wolfgang Denk, wd@denx.de
2ea910392   Wolfgang Denk   SPDX License clea...
9
   *	SPDX-License-Identifier:	GPL-2.0
2d966958c   wdenk   Initial revision
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   */
  
  /*
   * General Desription:
   *
   * The user interface supports commands for BOOTP, RARP, and TFTP.
   * Also, we support ARP internally. Depending on available data,
   * these interact as follows:
   *
   * BOOTP:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- own IP address
   *			- TFTP server IP address
   *			- name of bootfile
   *	Next step:	ARP
   *
d22c338e0   Joe Hershberger   net: Add link-loc...
27
28
29
30
31
32
   * LINK_LOCAL:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- own IP address
   *	Next step:	ARP
   *
2d966958c   wdenk   Initial revision
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
   * RARP:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- own IP address
   *			- TFTP server IP address
   *	Next step:	ARP
   *
   * ARP:
   *
   *	Prerequisites:	- own ethernet address
   *			- own IP address
   *			- TFTP server IP address
   *	We want:	- TFTP server ethernet address
   *	Next step:	TFTP
   *
   * DHCP:
   *
b2f508075   Wolfgang Denk   Minor code cleanup
50
51
52
53
   *     Prerequisites:	- own ethernet address
   *     We want:		- IP, Netmask, ServerIP, Gateway IP
   *			- bootfilename, lease time
   *     Next step:	- TFTP
2d966958c   wdenk   Initial revision
54
55
56
57
58
59
60
61
62
63
64
   *
   * TFTP:
   *
   *	Prerequisites:	- own ethernet address
   *			- own IP address
   *			- TFTP server IP address
   *			- TFTP server ethernet address
   *			- name of bootfile (if unknown, we use a default name
   *			  derived from our own IP address)
   *	We want:	- load the boot file
   *	Next step:	none
cbd8a35c6   wdenk   * Patch by Masami...
65
66
67
68
69
70
71
72
73
   *
   * NFS:
   *
   *	Prerequisites:	- own ethernet address
   *			- own IP address
   *			- name of bootfile (if unknown, we use a default name
   *			  derived from our own IP address)
   *	We want:	- load the boot file
   *	Next step:	none
ea287debe   wdenk   * Patch by Masami...
74
75
76
   *
   * SNTP:
   *
b2f508075   Wolfgang Denk   Minor code cleanup
77
   *	Prerequisites:	- own ethernet address
ea287debe   wdenk   * Patch by Masami...
78
79
80
   *			- own IP address
   *	We want:	- network time
   *	Next step:	none
2d966958c   wdenk   Initial revision
81
82
83
84
   */
  
  
  #include <common.h>
2d966958c   wdenk   Initial revision
85
  #include <command.h>
24b852a7a   Simon Glass   Move console defi...
86
  #include <console.h>
a9f51c9b4   Joe Hershberger   env: Add a bootfi...
87
  #include <environment.h>
60304592b   Joe Hershberger   net: Improve erro...
88
  #include <errno.h>
2d966958c   wdenk   Initial revision
89
  #include <net.h>
346969584   Lukasz Majewski   net: tftp: Move t...
90
  #include <net/tftp.h>
2d8d190c8   Uri Mashiach   status_led: Kconf...
91
  #if defined(CONFIG_LED_STATUS)
fc3e2165e   wdenk   * Patch by Sangmo...
92
  #include <miiphy.h>
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
93
  #include <status_led.h>
fc3e2165e   wdenk   * Patch by Sangmo...
94
  #endif
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
95
96
97
98
  #include <watchdog.h>
  #include <linux/compiler.h>
  #include "arp.h"
  #include "bootp.h"
f575ae1f7   Joe Hershberger   net: Move CDP out...
99
  #include "cdp.h"
1a32bf418   Robin Getz   Add DNS support
100
101
102
  #if defined(CONFIG_CMD_DNS)
  #include "dns.h"
  #endif
d22c338e0   Joe Hershberger   net: Add link-loc...
103
  #include "link_local.h"
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
104
  #include "nfs.h"
a36b12f95   Joe Hershberger   net: Move PING ou...
105
  #include "ping.h"
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
106
107
108
109
  #include "rarp.h"
  #if defined(CONFIG_CMD_SNTP)
  #include "sntp.h"
  #endif
2d966958c   wdenk   Initial revision
110

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
111
  DECLARE_GLOBAL_DATA_PTR;
2d966958c   wdenk   Initial revision
112
  /** BOOTP EXTENTIONS **/
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
113
  /* Our subnet mask (0=unknown) */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
114
  struct in_addr net_netmask;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
115
  /* Our gateways IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
116
  struct in_addr net_gateway;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
117
  /* Our DNS IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
118
  struct in_addr net_dns_server;
1fe80d79c   Jon Loeliger   Finally retire cm...
119
  #if defined(CONFIG_BOOTP_DNS2)
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
120
  /* Our 2nd DNS IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
121
  struct in_addr net_dns_server2;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
122
  #endif
2d966958c   wdenk   Initial revision
123

53a5c424b   David Updegraff   multicast tftp: R...
124
  #ifdef CONFIG_MCAST_TFTP	/* Multicast TFTP */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
125
  struct in_addr net_mcast_addr;
53a5c424b   David Updegraff   multicast tftp: R...
126
  #endif
2d966958c   wdenk   Initial revision
127
  /** END OF BOOTP EXTENTIONS **/
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
128
  /* Our ethernet address */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
129
  u8 net_ethaddr[6];
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
130
  /* Boot server enet address */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
131
  u8 net_server_ethaddr[6];
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
132
  /* Our IP addr (0 = unknown) */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
133
  struct in_addr	net_ip;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
134
  /* Server IP addr (0 = unknown) */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
135
  struct in_addr	net_server_ip;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
136
  /* Current receive packet */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
137
  uchar *net_rx_packet;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
138
  /* Current rx packet length */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
139
  int		net_rx_packet_len;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
140
  /* IP packet ID */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
141
  static unsigned	net_ip_id;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
142
  /* Ethernet bcast address */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
143
144
  const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  const u8 net_null_ethaddr[6];
0efe1bcf5   Alexander Graf   efi_loader: Add n...
145
  #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
146
  void (*push_packet)(void *, int len) = 0;
f85b60710   Rafal Jaworowski   Introduce new eth...
147
  #endif
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
148
  /* Network loop state */
22f6e99d5   Joe Hershberger   net: Refactor to ...
149
  enum net_loop_state net_state;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
150
  /* Tried all network devices */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
151
  int		net_restart_wrap;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
152
  /* Network loop restarted */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
153
  static int	net_restarted;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
154
  /* At least one device configured */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
155
  static int	net_dev_exists;
2d966958c   wdenk   Initial revision
156

6e5923851   wdenk   * Cleanup, minor ...
157
  /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
158
  /* default is without VLAN */
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
159
  ushort		net_our_vlan = 0xFFFF;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
160
  /* ditto */
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
161
  ushort		net_native_vlan = 0xFFFF;
a3d991bd0   wdenk   Patches by Pantel...
162

3e38e429f   Luca Ceresoli   net/net.c: cosmet...
163
  /* Boot File name */
11a69ff85   Jacob Stiffler   net: Increase the...
164
  char net_boot_file_name[1024];
1411157d8   Joe Hershberger   net: cosmetic: Fi...
165
166
167
168
  /* The actual transferred size of the bootfile (in bytes) */
  u32 net_boot_file_size;
  /* Boot file size in blocks as reported by the DHCP server */
  u32 net_boot_file_expected_size_in_blocks;
2d966958c   wdenk   Initial revision
169

643d1ab23   Jon Loeliger   net/: Remove obso...
170
  #if defined(CONFIG_CMD_SNTP)
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
171
  /* NTP server IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
172
  struct in_addr	net_ntp_server;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
173
  /* offset time from UTC */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
174
  int		net_ntp_time_offset;
ea287debe   wdenk   * Patch by Masami...
175
  #endif
1203fccee   Joe Hershberger   net: cosmetic: Cl...
176
  static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
2a504df00   Joe Hershberger   net: Clean up net...
177
178
  /* Receive packets */
  uchar *net_rx_packets[PKTBUFSRX];
ece223b52   Joe Hershberger   net: Refactor to ...
179
180
181
182
  /* Current UDP RX packet handler */
  static rxhand_f *udp_packet_handler;
  /* Current ARP RX packet handler */
  static rxhand_f *arp_packet_handler;
39bccd21d   Simon Glass   net: Hide more co...
183
  #ifdef CONFIG_CMD_TFTPPUT
ece223b52   Joe Hershberger   net: Refactor to ...
184
185
  /* Current ICMP rx handler */
  static rxhand_icmp_f *packet_icmp_handler;
39bccd21d   Simon Glass   net: Hide more co...
186
  #endif
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
187
  /* Current timeout handler */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
188
  static thand_f *time_handler;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
189
  /* Time base value */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
190
  static ulong	time_start;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
191
  /* Current timeout value */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
192
  static ulong	time_delta;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
193
  /* THE transmit packet */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
194
  uchar *net_tx_packet;
2d966958c   wdenk   Initial revision
195

e4bf0c5cf   Simon Glass   net: tftpput: Ren...
196
  static int net_check_prereq(enum proto_t protocol);
2d966958c   wdenk   Initial revision
197

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
198
  static int net_try_count;
67b96e87d   Remy Bohmer   Repair the 'netre...
199

b63056d6a   Jim Lin   NET: Add net_busy...
200
  int __maybe_unused net_busy_flag;
2d966958c   wdenk   Initial revision
201
  /**********************************************************************/
73a8b27c5   wdenk   * Add support for...
202

a9f51c9b4   Joe Hershberger   env: Add a bootfi...
203
204
205
  static int on_bootfile(const char *name, const char *value, enum env_op op,
  	int flags)
  {
fd3056337   Joe Hershberger   net: Use env call...
206
207
  	if (flags & H_PROGRAMMATIC)
  		return 0;
a9f51c9b4   Joe Hershberger   env: Add a bootfi...
208
209
210
  	switch (op) {
  	case env_op_create:
  	case env_op_overwrite:
484e0dca8   Luo Ji   [iot] [coverity] ...
211
212
213
214
215
  		if (value == NULL)
  			return -1;
  		else
  			copy_filename(net_boot_file_name, value,
  				      sizeof(net_boot_file_name));
a9f51c9b4   Joe Hershberger   env: Add a bootfi...
216
217
218
219
220
221
222
223
  		break;
  	default:
  		break;
  	}
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(bootfile, on_bootfile);
fd3056337   Joe Hershberger   net: Use env call...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
  static int on_ipaddr(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_ip = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(ipaddr, on_ipaddr);
  
  static int on_gatewayip(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_gateway = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(gatewayip, on_gatewayip);
  
  static int on_netmask(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_netmask = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(netmask, on_netmask);
  
  static int on_serverip(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_server_ip = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(serverip, on_serverip);
  
  static int on_nvlan(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_native_vlan = string_to_vlan(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(nvlan, on_nvlan);
  
  static int on_vlan(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_our_vlan = string_to_vlan(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(vlan, on_vlan);
  
  #if defined(CONFIG_CMD_DNS)
  static int on_dnsip(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_dns_server = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(dnsip, on_dnsip);
  #endif
e4a3d57dc   Simon Glass   net: Export auto_...
309
310
311
312
313
314
  /*
   * Check if autoload is enabled. If so, use either NFS or TFTP to download
   * the boot file.
   */
  void net_auto_load(void)
  {
ec8a252cd   Joe Hershberger   env: Use getenv_y...
315
  #if defined(CONFIG_CMD_NFS)
00caae6d4   Simon Glass   env: Rename geten...
316
  	const char *s = env_get("autoload");
e4a3d57dc   Simon Glass   net: Export auto_...
317

ec8a252cd   Joe Hershberger   env: Use getenv_y...
318
319
320
321
  	if (s != NULL && strcmp(s, "NFS") == 0) {
  		/*
  		 * Use NFS to load the bootfile.
  		 */
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
322
  		nfs_start();
ec8a252cd   Joe Hershberger   env: Use getenv_y...
323
324
  		return;
  	}
e4a3d57dc   Simon Glass   net: Export auto_...
325
  #endif
bfebc8c96   Simon Glass   env: Rename geten...
326
  	if (env_get_yesno("autoload") == 0) {
ec8a252cd   Joe Hershberger   env: Use getenv_y...
327
328
329
330
331
332
  		/*
  		 * Just use BOOTP/RARP to configure system;
  		 * Do not use TFTP to load the bootfile.
  		 */
  		net_set_state(NETLOOP_SUCCESS);
  		return;
e4a3d57dc   Simon Glass   net: Export auto_...
333
  	}
8885c5fe9   Joe Hershberger   net: cosmetic: Cl...
334
  	tftp_start(TFTPGET);
e4a3d57dc   Simon Glass   net: Export auto_...
335
  }
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
336
  static void net_init_loop(void)
2f70c49e5   Heiko Schocher   netloop: speed up...
337
  {
7315cfd9e   Jim Lin   NET: Fix system h...
338
  	if (eth_get_dev())
0adb5b761   Joe Hershberger   net: cosmetic: Na...
339
  		memcpy(net_ethaddr, eth_get_ethaddr(), 6);
3c172c4fd   Michael Zaidman   NetLoop initializ...
340

da95427ce   Heiko Schocher   netloop: updates ...
341
  	return;
2f70c49e5   Heiko Schocher   netloop: speed up...
342
  }
ece223b52   Joe Hershberger   net: Refactor to ...
343
344
345
346
  static void net_clear_handlers(void)
  {
  	net_set_udp_handler(NULL);
  	net_set_arp_handler(NULL);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
347
  	net_set_timeout_handler(0, NULL);
ece223b52   Joe Hershberger   net: Refactor to ...
348
349
350
351
352
353
  }
  
  static void net_cleanup_loop(void)
  {
  	net_clear_handlers();
  }
46c495d52   Joe Hershberger   net: Fix net buff...
354
355
356
357
358
359
360
361
362
  void net_init(void)
  {
  	static int first_call = 1;
  
  	if (first_call) {
  		/*
  		 *	Setup packet buffers, aligned correctly.
  		 */
  		int i;
1203fccee   Joe Hershberger   net: cosmetic: Cl...
363
364
  		net_tx_packet = &net_pkt_buf[0] + (PKTALIGN - 1);
  		net_tx_packet -= (ulong)net_tx_packet % PKTALIGN;
2a504df00   Joe Hershberger   net: Clean up net...
365
  		for (i = 0; i < PKTBUFSRX; i++) {
1203fccee   Joe Hershberger   net: cosmetic: Cl...
366
367
  			net_rx_packets[i] = net_tx_packet +
  				(i + 1) * PKTSIZE_ALIGN;
2a504df00   Joe Hershberger   net: Clean up net...
368
  		}
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
369
  		arp_init();
46c495d52   Joe Hershberger   net: Fix net buff...
370
371
372
373
374
  		net_clear_handlers();
  
  		/* Only need to setup buffer pointers once. */
  		first_call = 0;
  	}
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
375
  	net_init_loop();
46c495d52   Joe Hershberger   net: Fix net buff...
376
  }
73a8b27c5   wdenk   * Add support for...
377
  /**********************************************************************/
2d966958c   wdenk   Initial revision
378
379
380
  /*
   *	Main network processing loop.
   */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
381
  int net_loop(enum proto_t protocol)
2d966958c   wdenk   Initial revision
382
  {
60304592b   Joe Hershberger   net: Improve erro...
383
  	int ret = -EINVAL;
2d966958c   wdenk   Initial revision
384

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
385
386
387
388
389
  	net_restarted = 0;
  	net_dev_exists = 0;
  	net_try_count = 1;
  	debug_cond(DEBUG_INT_STATE, "--- net_loop Entry
  ");
73a8b27c5   wdenk   * Add support for...
390

573f14fe4   Simon Glass   bootstage: Plumb ...
391
  	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
46c495d52   Joe Hershberger   net: Fix net buff...
392
  	net_init();
f8be7d659   Joe Hershberger   net: Improve the ...
393
  	if (eth_is_on_demand_init() || protocol != NETCONS) {
b1bf6f2c9   wdenk   * Patch by Richar...
394
  		eth_halt();
f8be7d659   Joe Hershberger   net: Improve the ...
395
  		eth_set_current();
60304592b   Joe Hershberger   net: Improve erro...
396
397
  		ret = eth_init();
  		if (ret < 0) {
f8be7d659   Joe Hershberger   net: Improve the ...
398
  			eth_halt();
60304592b   Joe Hershberger   net: Improve erro...
399
  			return ret;
f8be7d659   Joe Hershberger   net: Improve the ...
400
  		}
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
401
  	} else {
d2eaec600   Joe Hershberger   net: Remove the b...
402
  		eth_init_state_only();
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
403
  	}
2d966958c   wdenk   Initial revision
404
  restart:
b63056d6a   Jim Lin   NET: Add net_busy...
405
406
407
  #ifdef CONFIG_USB_KEYBOARD
  	net_busy_flag = 0;
  #endif
22f6e99d5   Joe Hershberger   net: Refactor to ...
408
  	net_set_state(NETLOOP_CONTINUE);
2d966958c   wdenk   Initial revision
409
410
411
412
413
414
  
  	/*
  	 *	Start the ball rolling with the given start function.  From
  	 *	here on, this code is a state machine driven by received
  	 *	packets and timer events.
  	 */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
415
416
417
  	debug_cond(DEBUG_INT_STATE, "--- net_loop Init
  ");
  	net_init_loop();
2d966958c   wdenk   Initial revision
418

4f63acd06   Luca Ceresoli   net/net.c: cosmet...
419
  	switch (net_check_prereq(protocol)) {
2d966958c   wdenk   Initial revision
420
421
  	case 1:
  		/* network not configured */
b1bf6f2c9   wdenk   * Patch by Richar...
422
  		eth_halt();
60304592b   Joe Hershberger   net: Improve erro...
423
  		return -ENODEV;
2d966958c   wdenk   Initial revision
424

2d966958c   wdenk   Initial revision
425
426
427
  	case 2:
  		/* network device not configured */
  		break;
2d966958c   wdenk   Initial revision
428
429
  
  	case 0:
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
430
  		net_dev_exists = 1;
1411157d8   Joe Hershberger   net: cosmetic: Fi...
431
  		net_boot_file_size = 0;
2d966958c   wdenk   Initial revision
432
  		switch (protocol) {
e4bf0c5cf   Simon Glass   net: tftpput: Ren...
433
  		case TFTPGET:
1fb7cd498   Simon Glass   net: tftpput: imp...
434
435
436
  #ifdef CONFIG_CMD_TFTPPUT
  		case TFTPPUT:
  #endif
2d966958c   wdenk   Initial revision
437
  			/* always use ARP to get server ethernet address */
8885c5fe9   Joe Hershberger   net: cosmetic: Cl...
438
  			tftp_start(protocol);
2d966958c   wdenk   Initial revision
439
  			break;
7a83af07a   Luca Ceresoli   TFTP: add tftpsrv...
440
441
  #ifdef CONFIG_CMD_TFTPSRV
  		case TFTPSRV:
8885c5fe9   Joe Hershberger   net: cosmetic: Cl...
442
  			tftp_start_server();
7a83af07a   Luca Ceresoli   TFTP: add tftpsrv...
443
444
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
445
  #if defined(CONFIG_CMD_DHCP)
2d966958c   wdenk   Initial revision
446
  		case DHCP:
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
447
  			bootp_reset();
049a95a77   Joe Hershberger   net: cosmetic: Ch...
448
  			net_ip.s_addr = 0;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
449
  			dhcp_request();		/* Basically same as BOOTP */
2d966958c   wdenk   Initial revision
450
  			break;
610f2e9c2   Jon Loeliger   net/: Remove ling...
451
  #endif
2d966958c   wdenk   Initial revision
452
453
  
  		case BOOTP:
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
454
  			bootp_reset();
049a95a77   Joe Hershberger   net: cosmetic: Ch...
455
  			net_ip.s_addr = 0;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
456
  			bootp_request();
2d966958c   wdenk   Initial revision
457
  			break;
bf6cb247a   Peter Tyser   rarp: Condtionall...
458
  #if defined(CONFIG_CMD_RARP)
2d966958c   wdenk   Initial revision
459
  		case RARP:
698d78e54   Joe Hershberger   net: cosmetic: Cl...
460
  			rarp_try = 0;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
461
  			net_ip.s_addr = 0;
698d78e54   Joe Hershberger   net: cosmetic: Cl...
462
  			rarp_request();
2d966958c   wdenk   Initial revision
463
  			break;
bf6cb247a   Peter Tyser   rarp: Condtionall...
464
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
465
  #if defined(CONFIG_CMD_PING)
73a8b27c5   wdenk   * Add support for...
466
  		case PING:
a36b12f95   Joe Hershberger   net: Move PING ou...
467
  			ping_start();
73a8b27c5   wdenk   * Add support for...
468
469
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
470
  #if defined(CONFIG_CMD_NFS)
cbd8a35c6   wdenk   * Patch by Masami...
471
  		case NFS:
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
472
  			nfs_start();
cbd8a35c6   wdenk   * Patch by Masami...
473
474
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
475
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
476
  		case CDP:
6aede5b75   Joe Hershberger   net: cosmetic: Cl...
477
  			cdp_start();
a3d991bd0   wdenk   Patches by Pantel...
478
479
  			break;
  #endif
66c89ee31   Holger Dengler   net: Fix compile ...
480
  #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
68ceb29e7   wdenk   Add support for c...
481
  		case NETCONS:
6a38a5f3d   Joe Hershberger   net: cosmetic: Cl...
482
  			nc_start();
68ceb29e7   wdenk   Add support for c...
483
484
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
485
  #if defined(CONFIG_CMD_SNTP)
ea287debe   wdenk   * Patch by Masami...
486
  		case SNTP:
38ba25587   Joe Hershberger   net: cosmetic: Cl...
487
  			sntp_start();
ea287debe   wdenk   * Patch by Masami...
488
489
  			break;
  #endif
1a32bf418   Robin Getz   Add DNS support
490
491
  #if defined(CONFIG_CMD_DNS)
  		case DNS:
786eac5f9   Joe Hershberger   net: cosmetic: Cl...
492
  			dns_start();
1a32bf418   Robin Getz   Add DNS support
493
494
  			break;
  #endif
d22c338e0   Joe Hershberger   net: Add link-loc...
495
496
497
498
499
  #if defined(CONFIG_CMD_LINK_LOCAL)
  		case LINKLOCAL:
  			link_local_start();
  			break;
  #endif
2d966958c   wdenk   Initial revision
500
501
502
  		default:
  			break;
  		}
2d966958c   wdenk   Initial revision
503
504
  		break;
  	}
643d1ab23   Jon Loeliger   net/: Remove obso...
505
  #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
506
  #if	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)	&& \
2d8d190c8   Uri Mashiach   status_led: Kconf...
507
508
  	defined(CONFIG_LED_STATUS)			&& \
  	defined(CONFIG_LED_STATUS_RED)
fc3e2165e   wdenk   * Patch by Sangmo...
509
  	/*
42d1f0394   wdenk   * Patches by Xian...
510
  	 * Echo the inverted link state to the fault LED.
fc3e2165e   wdenk   * Patch by Sangmo...
511
  	 */
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
512
  	if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR))
2d8d190c8   Uri Mashiach   status_led: Kconf...
513
  		status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_OFF);
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
514
  	else
2d8d190c8   Uri Mashiach   status_led: Kconf...
515
  		status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_ON);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
516
  #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
fc3e2165e   wdenk   * Patch by Sangmo...
517
  #endif /* CONFIG_MII, ... */
b63056d6a   Jim Lin   NET: Add net_busy...
518
519
520
  #ifdef CONFIG_USB_KEYBOARD
  	net_busy_flag = 1;
  #endif
2d966958c   wdenk   Initial revision
521
522
523
  
  	/*
  	 *	Main packet reception loop.  Loop receiving packets until
22f6e99d5   Joe Hershberger   net: Refactor to ...
524
  	 *	someone sets `net_state' to a state that terminates.
2d966958c   wdenk   Initial revision
525
526
527
528
  	 */
  	for (;;) {
  		WATCHDOG_RESET();
  #ifdef CONFIG_SHOW_ACTIVITY
48522bb50   Joe Hershberger   net: cosmetic: ne...
529
  		show_activity(1);
2d966958c   wdenk   Initial revision
530
  #endif
c5a75339c   Joe Hershberger   net: Fix delay in...
531
532
  		if (arp_timeout_check() > 0)
  			time_start = get_timer(0);
2d966958c   wdenk   Initial revision
533
534
535
  		/*
  		 *	Check the ethernet for a new packet.  The ethernet
  		 *	receive routine will process it.
60304592b   Joe Hershberger   net: Improve erro...
536
537
  		 *	Most drivers return the most recent packet size, but not
  		 *	errors that may have happened.
2d966958c   wdenk   Initial revision
538
  		 */
40cb90ee2   Guennadi Liakhovetski   net: make ARP tim...
539
  		eth_rx();
2d966958c   wdenk   Initial revision
540
541
542
543
544
  
  		/*
  		 *	Abort if ctrl-c was pressed.
  		 */
  		if (ctrlc()) {
e94070c44   Joe Hershberger   net: Don't copy e...
545
  			/* cancel any ARP that may not have completed */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
546
  			net_arp_wait_packet_ip.s_addr = 0;
e94070c44   Joe Hershberger   net: Don't copy e...
547

ece223b52   Joe Hershberger   net: Refactor to ...
548
  			net_cleanup_loop();
8bde7f776   wdenk   * Code cleanup:
549
  			eth_halt();
f8be7d659   Joe Hershberger   net: Improve the ...
550
551
  			/* Invalidate the last protocol */
  			eth_set_last_protocol(BOOTP);
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
552
553
554
  			puts("
  Abort
  ");
4ef8d53ca   Joe Hershberger   net: Allow filter...
555
556
  			/* include a debug print as well incase the debug
  			   messages are directed to stderr */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
557
558
  			debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!
  ");
19a4fbaad   Michal Simek   net: Return -EINT...
559
  			ret = -EINTR;
4793ee652   Simon Glass   net: tftpput: Add...
560
  			goto done;
2d966958c   wdenk   Initial revision
561
  		}
2d966958c   wdenk   Initial revision
562
563
564
565
  		/*
  		 *	Check for a timeout, and run the timeout handler
  		 *	if we have one.
  		 */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
566
567
  		if (time_handler &&
  		    ((get_timer(0) - time_start) > time_delta)) {
2d966958c   wdenk   Initial revision
568
  			thand_f *x;
643d1ab23   Jon Loeliger   net/: Remove obso...
569
  #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
570
  #if	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)	&& \
2d8d190c8   Uri Mashiach   status_led: Kconf...
571
572
  	defined(CONFIG_LED_STATUS)			&& \
  	defined(CONFIG_LED_STATUS_RED)
fc3e2165e   wdenk   * Patch by Sangmo...
573
  			/*
42d1f0394   wdenk   * Patches by Xian...
574
  			 * Echo the inverted link state to the fault LED.
fc3e2165e   wdenk   * Patch by Sangmo...
575
  			 */
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
576
  			if (miiphy_link(eth_get_dev()->name,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
577
  					CONFIG_SYS_FAULT_MII_ADDR))
2d8d190c8   Uri Mashiach   status_led: Kconf...
578
579
  				status_led_set(CONFIG_LED_STATUS_RED,
  					       CONFIG_LED_STATUS_OFF);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
580
  			else
2d8d190c8   Uri Mashiach   status_led: Kconf...
581
582
  				status_led_set(CONFIG_LED_STATUS_RED,
  					       CONFIG_LED_STATUS_ON);
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
583
  #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
fc3e2165e   wdenk   * Patch by Sangmo...
584
  #endif /* CONFIG_MII, ... */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
585
586
587
588
  			debug_cond(DEBUG_INT_STATE, "--- net_loop timeout
  ");
  			x = time_handler;
  			time_handler = (thand_f *)0;
2d966958c   wdenk   Initial revision
589
590
  			(*x)();
  		}
5c421331d   Joe Hershberger   net: Make netretr...
591
  		if (net_state == NETLOOP_FAIL)
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
592
  			ret = net_start_again();
2d966958c   wdenk   Initial revision
593

22f6e99d5   Joe Hershberger   net: Refactor to ...
594
  		switch (net_state) {
2d966958c   wdenk   Initial revision
595
  		case NETLOOP_RESTART:
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
596
  			net_restarted = 1;
2d966958c   wdenk   Initial revision
597
598
599
  			goto restart;
  
  		case NETLOOP_SUCCESS:
ece223b52   Joe Hershberger   net: Refactor to ...
600
  			net_cleanup_loop();
1411157d8   Joe Hershberger   net: cosmetic: Fi...
601
602
603
604
  			if (net_boot_file_size > 0) {
  				printf("Bytes transferred = %d (%x hex)
  ",
  				       net_boot_file_size, net_boot_file_size);
018f53032   Simon Glass   env: Rename commo...
605
606
  				env_set_hex("filesize", net_boot_file_size);
  				env_set_hex("fileaddr", load_addr);
2d966958c   wdenk   Initial revision
607
  			}
f8be7d659   Joe Hershberger   net: Improve the ...
608
609
610
611
612
613
  			if (protocol != NETCONS)
  				eth_halt();
  			else
  				eth_halt_state_only();
  
  			eth_set_last_protocol(protocol);
1411157d8   Joe Hershberger   net: cosmetic: Fi...
614
  			ret = net_boot_file_size;
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
615
616
  			debug_cond(DEBUG_INT_STATE, "--- net_loop Success!
  ");
4793ee652   Simon Glass   net: tftpput: Add...
617
  			goto done;
2d966958c   wdenk   Initial revision
618
619
  
  		case NETLOOP_FAIL:
ece223b52   Joe Hershberger   net: Refactor to ...
620
  			net_cleanup_loop();
f8be7d659   Joe Hershberger   net: Improve the ...
621
622
  			/* Invalidate the last protocol */
  			eth_set_last_protocol(BOOTP);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
623
624
  			debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!
  ");
4793ee652   Simon Glass   net: tftpput: Add...
625
  			goto done;
22f6e99d5   Joe Hershberger   net: Refactor to ...
626
627
628
  
  		case NETLOOP_CONTINUE:
  			continue;
2d966958c   wdenk   Initial revision
629
630
  		}
  	}
4793ee652   Simon Glass   net: tftpput: Add...
631
632
  
  done:
b63056d6a   Jim Lin   NET: Add net_busy...
633
634
635
  #ifdef CONFIG_USB_KEYBOARD
  	net_busy_flag = 0;
  #endif
39bccd21d   Simon Glass   net: Hide more co...
636
  #ifdef CONFIG_CMD_TFTPPUT
4793ee652   Simon Glass   net: tftpput: Add...
637
  	/* Clear out the handlers */
ece223b52   Joe Hershberger   net: Refactor to ...
638
  	net_set_udp_handler(NULL);
4793ee652   Simon Glass   net: tftpput: Add...
639
  	net_set_icmp_handler(NULL);
39bccd21d   Simon Glass   net: Hide more co...
640
  #endif
4793ee652   Simon Glass   net: tftpput: Add...
641
  	return ret;
2d966958c   wdenk   Initial revision
642
643
644
  }
  
  /**********************************************************************/
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
645
  static void start_again_timeout_handler(void)
2d966958c   wdenk   Initial revision
646
  {
22f6e99d5   Joe Hershberger   net: Refactor to ...
647
  	net_set_state(NETLOOP_RESTART);
2d966958c   wdenk   Initial revision
648
  }
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
649
  int net_start_again(void)
2d966958c   wdenk   Initial revision
650
  {
6e5923851   wdenk   * Cleanup, minor ...
651
  	char *nretry;
67b96e87d   Remy Bohmer   Repair the 'netre...
652
653
  	int retry_forever = 0;
  	unsigned long retrycnt = 0;
60304592b   Joe Hershberger   net: Improve erro...
654
  	int ret;
67b96e87d   Remy Bohmer   Repair the 'netre...
655

00caae6d4   Simon Glass   env: Rename geten...
656
  	nretry = env_get("netretry");
67b96e87d   Remy Bohmer   Repair the 'netre...
657
658
659
660
661
662
663
664
665
  	if (nretry) {
  		if (!strcmp(nretry, "yes"))
  			retry_forever = 1;
  		else if (!strcmp(nretry, "no"))
  			retrycnt = 0;
  		else if (!strcmp(nretry, "once"))
  			retrycnt = 1;
  		else
  			retrycnt = simple_strtoul(nretry, NULL, 0);
5c421331d   Joe Hershberger   net: Make netretr...
666
667
668
669
  	} else {
  		retrycnt = 0;
  		retry_forever = 0;
  	}
67b96e87d   Remy Bohmer   Repair the 'netre...
670

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
671
  	if ((!retry_forever) && (net_try_count >= retrycnt)) {
67b96e87d   Remy Bohmer   Repair the 'netre...
672
  		eth_halt();
22f6e99d5   Joe Hershberger   net: Refactor to ...
673
  		net_set_state(NETLOOP_FAIL);
60304592b   Joe Hershberger   net: Improve erro...
674
675
676
677
678
  		/*
  		 * We don't provide a way for the protocol to return an error,
  		 * but this is almost always the reason.
  		 */
  		return -ETIMEDOUT;
a3d991bd0   wdenk   Patches by Pantel...
679
  	}
67b96e87d   Remy Bohmer   Repair the 'netre...
680

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
681
  	net_try_count++;
67b96e87d   Remy Bohmer   Repair the 'netre...
682

4f63acd06   Luca Ceresoli   net/net.c: cosmet...
683
  	eth_halt();
8b0c5c127   Matthias Fuchs   net: Add CONFIG_N...
684
  #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
685
  	eth_try_another(!net_restarted);
8b0c5c127   Matthias Fuchs   net: Add CONFIG_N...
686
  #endif
60304592b   Joe Hershberger   net: Improve erro...
687
  	ret = eth_init();
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
688
689
690
691
692
  	if (net_restart_wrap) {
  		net_restart_wrap = 0;
  		if (net_dev_exists) {
  			net_set_timeout_handler(10000UL,
  						start_again_timeout_handler);
ece223b52   Joe Hershberger   net: Refactor to ...
693
  			net_set_udp_handler(NULL);
6e5923851   wdenk   * Cleanup, minor ...
694
  		} else {
22f6e99d5   Joe Hershberger   net: Refactor to ...
695
  			net_set_state(NETLOOP_FAIL);
2d966958c   wdenk   Initial revision
696
  		}
6e5923851   wdenk   * Cleanup, minor ...
697
  	} else {
22f6e99d5   Joe Hershberger   net: Refactor to ...
698
  		net_set_state(NETLOOP_RESTART);
2d966958c   wdenk   Initial revision
699
  	}
60304592b   Joe Hershberger   net: Improve erro...
700
  	return ret;
2d966958c   wdenk   Initial revision
701
702
703
704
705
706
  }
  
  /**********************************************************************/
  /*
   *	Miscelaneous bits.
   */
ece223b52   Joe Hershberger   net: Refactor to ...
707
  static void dummy_handler(uchar *pkt, unsigned dport,
049a95a77   Joe Hershberger   net: cosmetic: Ch...
708
  			struct in_addr sip, unsigned sport,
ece223b52   Joe Hershberger   net: Refactor to ...
709
  			unsigned len)
d280d3f43   Joe Hershberger   net: Move ARP out...
710
  {
d280d3f43   Joe Hershberger   net: Move ARP out...
711
  }
ece223b52   Joe Hershberger   net: Refactor to ...
712
713
714
715
  rxhand_f *net_get_udp_handler(void)
  {
  	return udp_packet_handler;
  }
d280d3f43   Joe Hershberger   net: Move ARP out...
716

ece223b52   Joe Hershberger   net: Refactor to ...
717
718
  void net_set_udp_handler(rxhand_f *f)
  {
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
719
720
  	debug_cond(DEBUG_INT_STATE, "--- net_loop UDP handler set (%p)
  ", f);
ece223b52   Joe Hershberger   net: Refactor to ...
721
722
723
724
725
726
727
  	if (f == NULL)
  		udp_packet_handler = dummy_handler;
  	else
  		udp_packet_handler = f;
  }
  
  rxhand_f *net_get_arp_handler(void)
2d966958c   wdenk   Initial revision
728
  {
ece223b52   Joe Hershberger   net: Refactor to ...
729
730
731
732
733
  	return arp_packet_handler;
  }
  
  void net_set_arp_handler(rxhand_f *f)
  {
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
734
735
  	debug_cond(DEBUG_INT_STATE, "--- net_loop ARP handler set (%p)
  ", f);
ece223b52   Joe Hershberger   net: Refactor to ...
736
737
738
739
  	if (f == NULL)
  		arp_packet_handler = dummy_handler;
  	else
  		arp_packet_handler = f;
2d966958c   wdenk   Initial revision
740
  }
39bccd21d   Simon Glass   net: Hide more co...
741
  #ifdef CONFIG_CMD_TFTPPUT
4793ee652   Simon Glass   net: tftpput: Add...
742
743
744
745
  void net_set_icmp_handler(rxhand_icmp_f *f)
  {
  	packet_icmp_handler = f;
  }
39bccd21d   Simon Glass   net: Hide more co...
746
  #endif
2d966958c   wdenk   Initial revision
747

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
748
  void net_set_timeout_handler(ulong iv, thand_f *f)
2d966958c   wdenk   Initial revision
749
750
  {
  	if (iv == 0) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
751
  		debug_cond(DEBUG_INT_STATE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
752
753
754
  			   "--- net_loop timeout handler cancelled
  ");
  		time_handler = (thand_f *)0;
2d966958c   wdenk   Initial revision
755
  	} else {
4ef8d53ca   Joe Hershberger   net: Allow filter...
756
  		debug_cond(DEBUG_INT_STATE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
757
758
759
760
761
  			   "--- net_loop timeout handler set (%p)
  ", f);
  		time_handler = f;
  		time_start = get_timer(0);
  		time_delta = iv * CONFIG_SYS_HZ / 1000;
2d966958c   wdenk   Initial revision
762
763
  	}
  }
1203fccee   Joe Hershberger   net: cosmetic: Cl...
764
  int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
206d07fd7   Joe Hershberger   net: cosmetic: Re...
765
  		int payload_len)
73a8b27c5   wdenk   * Add support for...
766
  {
a3d991bd0   wdenk   Patches by Pantel...
767
  	uchar *pkt;
9214637a5   Joe Hershberger   net: Refactor Net...
768
769
  	int eth_hdr_size;
  	int pkt_hdr_size;
a3d991bd0   wdenk   Patches by Pantel...
770

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
771
  	/* make sure the net_tx_packet is initialized (net_init() was called) */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
772
773
  	assert(net_tx_packet != NULL);
  	if (net_tx_packet == NULL)
46c495d52   Joe Hershberger   net: Fix net buff...
774
  		return -1;
73a8b27c5   wdenk   * Add support for...
775
  	/* convert to new style broadcast */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
776
777
  	if (dest.s_addr == 0)
  		dest.s_addr = 0xFFFFFFFF;
73a8b27c5   wdenk   * Add support for...
778
779
  
  	/* if broadcast, make the ether address a broadcast and don't do ARP */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
780
  	if (dest.s_addr == 0xFFFFFFFF)
0adb5b761   Joe Hershberger   net: cosmetic: Na...
781
  		ether = (uchar *)net_bcast_ethaddr;
73a8b27c5   wdenk   * Add support for...
782

1203fccee   Joe Hershberger   net: cosmetic: Cl...
783
  	pkt = (uchar *)net_tx_packet;
9214637a5   Joe Hershberger   net: Refactor Net...
784

1203fccee   Joe Hershberger   net: cosmetic: Cl...
785
  	eth_hdr_size = net_set_ether(pkt, ether, PROT_IP);
9214637a5   Joe Hershberger   net: Refactor Net...
786
787
788
  	pkt += eth_hdr_size;
  	net_set_udp_header(pkt, dest, dport, sport, payload_len);
  	pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
73a8b27c5   wdenk   * Add support for...
789

e94070c44   Joe Hershberger   net: Don't copy e...
790
  	/* if MAC address was not discovered yet, do an ARP request */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
791
  	if (memcmp(ether, net_null_ethaddr, 6) == 0) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
792
793
  		debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4
  ", &dest);
0ebf04c60   Robin Getz   minor debug clean...
794

9214637a5   Joe Hershberger   net: Refactor Net...
795
  		/* save the ip and eth addr for the packet to send after arp */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
796
  		net_arp_wait_packet_ip = dest;
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
797
  		arp_wait_packet_ethaddr = ether;
a3d991bd0   wdenk   Patches by Pantel...
798

73a8b27c5   wdenk   * Add support for...
799
  		/* size of the waiting packet */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
800
  		arp_wait_tx_packet_size = pkt_hdr_size + payload_len;
73a8b27c5   wdenk   * Add support for...
801
802
  
  		/* and do the ARP request */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
803
804
805
  		arp_wait_try = 1;
  		arp_wait_timer_start = get_timer(0);
  		arp_request();
73a8b27c5   wdenk   * Add support for...
806
  		return 1;	/* waiting */
9214637a5   Joe Hershberger   net: Refactor Net...
807
  	} else {
4ef8d53ca   Joe Hershberger   net: Allow filter...
808
809
  		debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
810
  			   &dest, ether);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
811
  		net_send_packet(net_tx_packet, pkt_hdr_size + payload_len);
9214637a5   Joe Hershberger   net: Refactor Net...
812
  		return 0;	/* transmitted */
73a8b27c5   wdenk   * Add support for...
813
  	}
73a8b27c5   wdenk   * Add support for...
814
  }
5cfaa4e54   Alessandro Rubini   net: defragment I...
815
816
817
818
819
820
821
822
823
  #ifdef CONFIG_IP_DEFRAG
  /*
   * This function collects fragments in a single packet, according
   * to the algorithm in RFC815. It returns NULL or the pointer to
   * a complete packet, in static storage
   */
  #ifndef CONFIG_NET_MAXDEFRAG
  #define CONFIG_NET_MAXDEFRAG 16384
  #endif
aa7a64874   Joe Hershberger   net: Stop includi...
824
  #define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG)
5cfaa4e54   Alessandro Rubini   net: defragment I...
825

c5c59df04   Joe Hershberger   net: cosmetic: Sp...
826
  #define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
5cfaa4e54   Alessandro Rubini   net: defragment I...
827
828
829
830
831
832
833
834
835
836
837
838
  
  /*
   * this is the packet being assembled, either data or frag control.
   * Fragments go by 8 bytes, so this union must be 8 bytes long
   */
  struct hole {
  	/* first_byte is address of this structure */
  	u16 last_byte;	/* last byte in this hole + 1 (begin of next hole) */
  	u16 next_hole;	/* index of next (in 8-b blocks), 0 == none */
  	u16 prev_hole;	/* index of prev, 0 == none */
  	u16 unused;
  };
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
839
  static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
5cfaa4e54   Alessandro Rubini   net: defragment I...
840
  {
48522bb50   Joe Hershberger   net: cosmetic: ne...
841
  	static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN);
5cfaa4e54   Alessandro Rubini   net: defragment I...
842
843
  	static u16 first_hole, total_len;
  	struct hole *payload, *thisfrag, *h, *newh;
594c26f8a   Joe Hershberger   net: cosmetic: Un...
844
  	struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff;
5cfaa4e54   Alessandro Rubini   net: defragment I...
845
846
847
848
849
  	uchar *indata = (uchar *)ip;
  	int offset8, start, len, done = 0;
  	u16 ip_off = ntohs(ip->ip_off);
  
  	/* payload starts after IP header, this fragment is in there */
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
850
  	payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
5cfaa4e54   Alessandro Rubini   net: defragment I...
851
852
853
  	offset8 =  (ip_off & IP_OFFS);
  	thisfrag = payload + offset8;
  	start = offset8 * 8;
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
854
  	len = ntohs(ip->ip_len) - IP_HDR_SIZE;
5cfaa4e54   Alessandro Rubini   net: defragment I...
855
856
857
858
859
860
861
862
863
864
865
866
  
  	if (start + len > IP_MAXUDP) /* fragment extends too far */
  		return NULL;
  
  	if (!total_len || localip->ip_id != ip->ip_id) {
  		/* new (or different) packet, reset structs */
  		total_len = 0xffff;
  		payload[0].last_byte = ~0;
  		payload[0].next_hole = 0;
  		payload[0].prev_hole = 0;
  		first_hole = 0;
  		/* any IP header will work, copy the first we received */
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
867
  		memcpy(localip, ip, IP_HDR_SIZE);
5cfaa4e54   Alessandro Rubini   net: defragment I...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
  	}
  
  	/*
  	 * What follows is the reassembly algorithm. We use the payload
  	 * array as a linked list of hole descriptors, as each hole starts
  	 * at a multiple of 8 bytes. However, last byte can be whatever value,
  	 * so it is represented as byte count, not as 8-byte blocks.
  	 */
  
  	h = payload + first_hole;
  	while (h->last_byte < start) {
  		if (!h->next_hole) {
  			/* no hole that far away */
  			return NULL;
  		}
  		h = payload + h->next_hole;
  	}
e397e59e8   Fillod Stephane   ip/defrag: fix pr...
885
886
  	/* last fragment may be 1..7 bytes, the "+7" forces acceptance */
  	if (offset8 + ((len + 7) / 8) <= h - payload) {
5cfaa4e54   Alessandro Rubini   net: defragment I...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
  		/* no overlap with holes (dup fragment?) */
  		return NULL;
  	}
  
  	if (!(ip_off & IP_FLAGS_MFRAG)) {
  		/* no more fragmentss: truncate this (last) hole */
  		total_len = start + len;
  		h->last_byte = start + len;
  	}
  
  	/*
  	 * There is some overlap: fix the hole list. This code doesn't
  	 * deal with a fragment that overlaps with two different holes
  	 * (thus being a superset of a previously-received fragment).
  	 */
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
902
  	if ((h >= thisfrag) && (h->last_byte <= start + len)) {
5cfaa4e54   Alessandro Rubini   net: defragment I...
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
  		/* complete overlap with hole: remove hole */
  		if (!h->prev_hole && !h->next_hole) {
  			/* last remaining hole */
  			done = 1;
  		} else if (!h->prev_hole) {
  			/* first hole */
  			first_hole = h->next_hole;
  			payload[h->next_hole].prev_hole = 0;
  		} else if (!h->next_hole) {
  			/* last hole */
  			payload[h->prev_hole].next_hole = 0;
  		} else {
  			/* in the middle of the list */
  			payload[h->next_hole].prev_hole = h->prev_hole;
  			payload[h->prev_hole].next_hole = h->next_hole;
  		}
  
  	} else if (h->last_byte <= start + len) {
  		/* overlaps with final part of the hole: shorten this hole */
  		h->last_byte = start;
  
  	} else if (h >= thisfrag) {
  		/* overlaps with initial part of the hole: move this hole */
  		newh = thisfrag + (len / 8);
  		*newh = *h;
  		h = newh;
  		if (h->next_hole)
  			payload[h->next_hole].prev_hole = (h - payload);
  		if (h->prev_hole)
  			payload[h->prev_hole].next_hole = (h - payload);
  		else
  			first_hole = (h - payload);
  
  	} else {
  		/* fragment sits in the middle: split the hole */
  		newh = thisfrag + (len / 8);
  		*newh = *h;
  		h->last_byte = start;
  		h->next_hole = (newh - payload);
  		newh->prev_hole = (h - payload);
  		if (newh->next_hole)
  			payload[newh->next_hole].prev_hole = (newh - payload);
  	}
  
  	/* finally copy this fragment and possibly return whole packet */
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
948
  	memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len);
5cfaa4e54   Alessandro Rubini   net: defragment I...
949
950
951
952
  	if (!done)
  		return NULL;
  
  	localip->ip_len = htons(total_len);
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
953
  	*lenp = total_len + IP_HDR_SIZE;
5cfaa4e54   Alessandro Rubini   net: defragment I...
954
955
  	return localip;
  }
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
956
957
  static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
  	int *lenp)
5cfaa4e54   Alessandro Rubini   net: defragment I...
958
959
960
961
  {
  	u16 ip_off = ntohs(ip->ip_off);
  	if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
  		return ip; /* not a fragment */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
962
  	return __net_defragment(ip, lenp);
5cfaa4e54   Alessandro Rubini   net: defragment I...
963
964
965
  }
  
  #else /* !CONFIG_IP_DEFRAG */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
966
967
  static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
  	int *lenp)
5cfaa4e54   Alessandro Rubini   net: defragment I...
968
969
970
971
972
973
974
  {
  	u16 ip_off = ntohs(ip->ip_off);
  	if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
  		return ip; /* not a fragment */
  	return NULL;
  }
  #endif
a3d991bd0   wdenk   Patches by Pantel...
975

8f79bb17a   Simon Glass   net: tftpput: Mov...
976
977
978
979
980
981
  /**
   * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently
   * drop others.
   *
   * @parma ip	IP packet containing the ICMP
   */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
982
  static void receive_icmp(struct ip_udp_hdr *ip, int len,
049a95a77   Joe Hershberger   net: cosmetic: Ch...
983
  			struct in_addr src_ip, struct ethernet_hdr *et)
8f79bb17a   Simon Glass   net: tftpput: Mov...
984
  {
e0a630795   Joe Hershberger   net: cosmetic: Un...
985
  	struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
8f79bb17a   Simon Glass   net: tftpput: Mov...
986
987
988
989
990
991
  
  	switch (icmph->type) {
  	case ICMP_REDIRECT:
  		if (icmph->code != ICMP_REDIR_HOST)
  			return;
  		printf(" ICMP Host Redirect to %pI4 ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
992
  		       &icmph->un.gateway);
8f79bb17a   Simon Glass   net: tftpput: Mov...
993
  		break;
a36b12f95   Joe Hershberger   net: Move PING ou...
994
  	default:
8f79bb17a   Simon Glass   net: tftpput: Mov...
995
  #if defined(CONFIG_CMD_PING)
a36b12f95   Joe Hershberger   net: Move PING ou...
996
  		ping_receive(et, ip, len);
8f79bb17a   Simon Glass   net: tftpput: Mov...
997
  #endif
39bccd21d   Simon Glass   net: Hide more co...
998
  #ifdef CONFIG_CMD_TFTPPUT
4793ee652   Simon Glass   net: tftpput: Add...
999
1000
  		if (packet_icmp_handler)
  			packet_icmp_handler(icmph->type, icmph->code,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1001
1002
1003
  					    ntohs(ip->udp_dst), src_ip,
  					    ntohs(ip->udp_src), icmph->un.data,
  					    ntohs(ip->udp_len));
39bccd21d   Simon Glass   net: Hide more co...
1004
  #endif
8f79bb17a   Simon Glass   net: tftpput: Mov...
1005
1006
1007
  		break;
  	}
  }
2a504df00   Joe Hershberger   net: Clean up net...
1008
  void net_process_received_packet(uchar *in_packet, int len)
2d966958c   wdenk   Initial revision
1009
  {
cb487f566   Joe Hershberger   net: cosmetic: Un...
1010
  	struct ethernet_hdr *et;
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1011
  	struct ip_udp_hdr *ip;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1012
1013
  	struct in_addr dst_ip;
  	struct in_addr src_ip;
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1014
  	int eth_proto;
643d1ab23   Jon Loeliger   net/: Remove obso...
1015
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1016
1017
1018
  	int iscdp;
  #endif
  	ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
4ef8d53ca   Joe Hershberger   net: Allow filter...
1019
1020
  	debug_cond(DEBUG_NET_PKT, "packet received
  ");
2d966958c   wdenk   Initial revision
1021

1203fccee   Joe Hershberger   net: cosmetic: Cl...
1022
1023
  	net_rx_packet = in_packet;
  	net_rx_packet_len = len;
2a504df00   Joe Hershberger   net: Clean up net...
1024
  	et = (struct ethernet_hdr *)in_packet;
a3d991bd0   wdenk   Patches by Pantel...
1025
1026
1027
1028
  
  	/* too small packet? */
  	if (len < ETHER_HDR_SIZE)
  		return;
0efe1bcf5   Alexander Graf   efi_loader: Add n...
1029
  #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
f85b60710   Rafal Jaworowski   Introduce new eth...
1030
  	if (push_packet) {
2a504df00   Joe Hershberger   net: Clean up net...
1031
  		(*push_packet)(in_packet, len);
f85b60710   Rafal Jaworowski   Introduce new eth...
1032
1033
1034
  		return;
  	}
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
1035
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1036
  	/* keep track if packet is CDP */
173518832   Joe Hershberger   net: Encapsulate ...
1037
  	iscdp = is_cdp_packet(et->et_dest);
a3d991bd0   wdenk   Patches by Pantel...
1038
  #endif
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1039
  	myvlanid = ntohs(net_our_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1040
1041
  	if (myvlanid == (ushort)-1)
  		myvlanid = VLAN_NONE;
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1042
  	mynvlanid = ntohs(net_native_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1043
1044
  	if (mynvlanid == (ushort)-1)
  		mynvlanid = VLAN_NONE;
2d966958c   wdenk   Initial revision
1045

8d353eb86   Joe Hershberger   net: cosmetic: Re...
1046
  	eth_proto = ntohs(et->et_protlen);
2d966958c   wdenk   Initial revision
1047

8d353eb86   Joe Hershberger   net: cosmetic: Re...
1048
  	if (eth_proto < 1514) {
cb487f566   Joe Hershberger   net: cosmetic: Un...
1049
  		struct e802_hdr *et802 = (struct e802_hdr *)et;
2d966958c   wdenk   Initial revision
1050
  		/*
da5ebe2c9   Joe Hershberger   net: cosmetic: Ad...
1051
1052
  		 *	Got a 802.2 packet.  Check the other protocol field.
  		 *	XXX VLAN over 802.2+SNAP not implemented!
2d966958c   wdenk   Initial revision
1053
  		 */
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1054
  		eth_proto = ntohs(et802->et_prot);
a3d991bd0   wdenk   Patches by Pantel...
1055

2a504df00   Joe Hershberger   net: Clean up net...
1056
  		ip = (struct ip_udp_hdr *)(in_packet + E802_HDR_SIZE);
2d966958c   wdenk   Initial revision
1057
  		len -= E802_HDR_SIZE;
a3d991bd0   wdenk   Patches by Pantel...
1058

8d353eb86   Joe Hershberger   net: cosmetic: Re...
1059
  	} else if (eth_proto != PROT_VLAN) {	/* normal packet */
2a504df00   Joe Hershberger   net: Clean up net...
1060
  		ip = (struct ip_udp_hdr *)(in_packet + ETHER_HDR_SIZE);
2d966958c   wdenk   Initial revision
1061
  		len -= ETHER_HDR_SIZE;
a3d991bd0   wdenk   Patches by Pantel...
1062
1063
  
  	} else {			/* VLAN packet */
c68cca35b   Joe Hershberger   net: cosmetic: Un...
1064
1065
  		struct vlan_ethernet_hdr *vet =
  			(struct vlan_ethernet_hdr *)et;
a3d991bd0   wdenk   Patches by Pantel...
1066

4ef8d53ca   Joe Hershberger   net: Allow filter...
1067
1068
  		debug_cond(DEBUG_NET_PKT, "VLAN packet received
  ");
0ebf04c60   Robin Getz   minor debug clean...
1069

a3d991bd0   wdenk   Patches by Pantel...
1070
1071
1072
1073
1074
  		/* too small packet? */
  		if (len < VLAN_ETHER_HDR_SIZE)
  			return;
  
  		/* if no VLAN active */
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1075
  		if ((ntohs(net_our_vlan) & VLAN_IDMASK) == VLAN_NONE
643d1ab23   Jon Loeliger   net/: Remove obso...
1076
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1077
1078
1079
1080
1081
1082
1083
  				&& iscdp == 0
  #endif
  				)
  			return;
  
  		cti = ntohs(vet->vet_tag);
  		vlanid = cti & VLAN_IDMASK;
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1084
  		eth_proto = ntohs(vet->vet_type);
a3d991bd0   wdenk   Patches by Pantel...
1085

2a504df00   Joe Hershberger   net: Clean up net...
1086
  		ip = (struct ip_udp_hdr *)(in_packet + VLAN_ETHER_HDR_SIZE);
a3d991bd0   wdenk   Patches by Pantel...
1087
  		len -= VLAN_ETHER_HDR_SIZE;
2d966958c   wdenk   Initial revision
1088
  	}
4ef8d53ca   Joe Hershberger   net: Allow filter...
1089
1090
  	debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x
  ", eth_proto);
2d966958c   wdenk   Initial revision
1091

643d1ab23   Jon Loeliger   net/: Remove obso...
1092
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1093
  	if (iscdp) {
0b4c5ff4a   Joe Hershberger   net: cosmetic: Re...
1094
  		cdp_receive((uchar *)ip, len);
a3d991bd0   wdenk   Patches by Pantel...
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
  		return;
  	}
  #endif
  
  	if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) {
  		if (vlanid == VLAN_NONE)
  			vlanid = (mynvlanid & VLAN_IDMASK);
  		/* not matched? */
  		if (vlanid != (myvlanid & VLAN_IDMASK))
  			return;
  	}
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1106
  	switch (eth_proto) {
2d966958c   wdenk   Initial revision
1107
  	case PROT_ARP:
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
1108
  		arp_receive(et, ip, len);
289f932c5   wdenk   * Some Cleanup.
1109
  		break;
2d966958c   wdenk   Initial revision
1110

bf6cb247a   Peter Tyser   rarp: Condtionall...
1111
  #ifdef CONFIG_CMD_RARP
2d966958c   wdenk   Initial revision
1112
  	case PROT_RARP:
8b9c53221   Joe Hershberger   net: Move RARP re...
1113
  		rarp_receive(ip, len);
2d966958c   wdenk   Initial revision
1114
  		break;
bf6cb247a   Peter Tyser   rarp: Condtionall...
1115
  #endif
2d966958c   wdenk   Initial revision
1116
  	case PROT_IP:
4ef8d53ca   Joe Hershberger   net: Allow filter...
1117
1118
  		debug_cond(DEBUG_NET_PKT, "Got IP
  ");
5cfaa4e54   Alessandro Rubini   net: defragment I...
1119
  		/* Before we start poking the header, make sure it is there */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1120
1121
1122
  		if (len < IP_UDP_HDR_SIZE) {
  			debug("len bad %d < %lu
  ", len,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1123
  			      (ulong)IP_UDP_HDR_SIZE);
2d966958c   wdenk   Initial revision
1124
1125
  			return;
  		}
5cfaa4e54   Alessandro Rubini   net: defragment I...
1126
  		/* Check the packet length */
2d966958c   wdenk   Initial revision
1127
  		if (len < ntohs(ip->ip_len)) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
1128
1129
  			debug("len bad %d < %d
  ", len, ntohs(ip->ip_len));
2d966958c   wdenk   Initial revision
1130
1131
1132
  			return;
  		}
  		len = ntohs(ip->ip_len);
4ef8d53ca   Joe Hershberger   net: Allow filter...
1133
1134
  		debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1135
  			   len, ip->ip_hl_v & 0xff);
0ebf04c60   Robin Getz   minor debug clean...
1136

5cfaa4e54   Alessandro Rubini   net: defragment I...
1137
  		/* Can't deal with anything except IPv4 */
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
1138
  		if ((ip->ip_hl_v & 0xf0) != 0x40)
2d966958c   wdenk   Initial revision
1139
  			return;
5cfaa4e54   Alessandro Rubini   net: defragment I...
1140
  		/* Can't deal with IP options (headers != 20 bytes) */
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
1141
  		if ((ip->ip_hl_v & 0x0f) > 0x05)
6b52cfe16   Remy Bohmer   Get rid of annoyi...
1142
  			return;
5cfaa4e54   Alessandro Rubini   net: defragment I...
1143
  		/* Check the Checksum of the header */
0da0fcd51   Simon Glass   net: Use new chec...
1144
  		if (!ip_checksum_ok((uchar *)ip, IP_HDR_SIZE)) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
1145
1146
  			debug("checksum bad
  ");
2d966958c   wdenk   Initial revision
1147
1148
  			return;
  		}
5cfaa4e54   Alessandro Rubini   net: defragment I...
1149
  		/* If it is not for us, ignore it */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1150
1151
1152
  		dst_ip = net_read_ip(&ip->ip_dst);
  		if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr &&
  		    dst_ip.s_addr != 0xFFFFFFFF) {
53a5c424b   David Updegraff   multicast tftp: R...
1153
  #ifdef CONFIG_MCAST_TFTP
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1154
  			if (net_mcast_addr != dst_ip)
53a5c424b   David Updegraff   multicast tftp: R...
1155
  #endif
c819abeef   Luca Ceresoli   net/net.c: cosmet...
1156
  				return;
2d966958c   wdenk   Initial revision
1157
  		}
03eb129f8   Luca Ceresoli   NET: pass source ...
1158
  		/* Read source IP address for later use */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1159
  		src_ip = net_read_ip(&ip->ip_src);
2d966958c   wdenk   Initial revision
1160
  		/*
5cfaa4e54   Alessandro Rubini   net: defragment I...
1161
1162
1163
1164
  		 * The function returns the unchanged packet if it's not
  		 * a fragment, and either the complete packet or NULL if
  		 * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL)
  		 */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1165
  		ip = net_defragment(ip, &len);
ccb9ebefb   Luca Ceresoli   net/net.c: cosmet...
1166
  		if (!ip)
5cfaa4e54   Alessandro Rubini   net: defragment I...
1167
1168
  			return;
  		/*
2d966958c   wdenk   Initial revision
1169
1170
  		 * watch for ICMP host redirects
  		 *
8bde7f776   wdenk   * Code cleanup:
1171
1172
1173
1174
1175
  		 * There is no real handler code (yet). We just watch
  		 * for ICMP host redirect messages. In case anybody
  		 * sees these messages: please contact me
  		 * (wd@denx.de), or - even better - send me the
  		 * necessary fixes :-)
2d966958c   wdenk   Initial revision
1176
  		 *
8bde7f776   wdenk   * Code cleanup:
1177
1178
1179
1180
1181
1182
1183
  		 * Note: in all cases where I have seen this so far
  		 * it was a problem with the router configuration,
  		 * for instance when a router was configured in the
  		 * BOOTP reply, but the TFTP server was on the same
  		 * subnet. So this is probably a warning that your
  		 * configuration might be wrong. But I'm not really
  		 * sure if there aren't any other situations.
4793ee652   Simon Glass   net: tftpput: Add...
1184
1185
1186
1187
  		 *
  		 * Simon Glass <sjg@chromium.org>: We get an ICMP when
  		 * we send a tftp packet to a dead connection, or when
  		 * there is no server at the other end.
2d966958c   wdenk   Initial revision
1188
1189
  		 */
  		if (ip->ip_p == IPPROTO_ICMP) {
8f79bb17a   Simon Glass   net: tftpput: Mov...
1190
1191
  			receive_icmp(ip, len, src_ip, et);
  			return;
2d966958c   wdenk   Initial revision
1192
1193
1194
  		} else if (ip->ip_p != IPPROTO_UDP) {	/* Only UDP packets */
  			return;
  		}
4ef8d53ca   Joe Hershberger   net: Allow filter...
1195
  		debug_cond(DEBUG_DEV_PKT,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1196
1197
1198
  			   "received UDP (to=%pI4, from=%pI4, len=%d)
  ",
  			   &dst_ip, &src_ip, len);
4ef8d53ca   Joe Hershberger   net: Allow filter...
1199

8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1200
1201
  #ifdef CONFIG_UDP_CHECKSUM
  		if (ip->udp_xsum != 0) {
b2f508075   Wolfgang Denk   Minor code cleanup
1202
  			ulong   xsum;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1203
1204
1205
1206
1207
  			ushort *sumptr;
  			ushort  sumlen;
  
  			xsum  = ip->ip_p;
  			xsum += (ntohs(ip->udp_len));
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1208
1209
1210
1211
  			xsum += (ntohl(ip->ip_src.s_addr) >> 16) & 0x0000ffff;
  			xsum += (ntohl(ip->ip_src.s_addr) >>  0) & 0x0000ffff;
  			xsum += (ntohl(ip->ip_dst.s_addr) >> 16) & 0x0000ffff;
  			xsum += (ntohl(ip->ip_dst.s_addr) >>  0) & 0x0000ffff;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1212
1213
  
  			sumlen = ntohs(ip->udp_len);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1214
  			sumptr = (ushort *)&(ip->udp_src);
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1215
1216
  
  			while (sumlen > 1) {
b2f508075   Wolfgang Denk   Minor code cleanup
1217
  				ushort sumdata;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1218
1219
1220
1221
1222
1223
  
  				sumdata = *sumptr++;
  				xsum += ntohs(sumdata);
  				sumlen -= 2;
  			}
  			if (sumlen > 0) {
b2f508075   Wolfgang Denk   Minor code cleanup
1224
  				ushort sumdata;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1225

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1226
  				sumdata = *(unsigned char *)sumptr;
b2f508075   Wolfgang Denk   Minor code cleanup
1227
  				sumdata = (sumdata << 8) & 0xff00;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1228
1229
1230
  				xsum += sumdata;
  			}
  			while ((xsum >> 16) != 0) {
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1231
1232
  				xsum = (xsum & 0x0000ffff) +
  				       ((xsum >> 16) & 0x0000ffff);
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1233
1234
  			}
  			if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
9b55a2536   Wolfgang Denk   Fix some more pri...
1235
1236
  				printf(" UDP wrong checksum %08lx %08x
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1237
  				       xsum, ntohs(ip->udp_xsum));
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1238
1239
1240
1241
  				return;
  			}
  		}
  #endif
66c89ee31   Holger Dengler   net: Fix compile ...
1242
  #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1243
  		nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1244
1245
1246
1247
  				src_ip,
  				ntohs(ip->udp_dst),
  				ntohs(ip->udp_src),
  				ntohs(ip->udp_len) - UDP_HDR_SIZE);
68ceb29e7   wdenk   Add support for c...
1248
  #endif
2d966958c   wdenk   Initial revision
1249
  		/*
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1250
  		 * IP header OK.  Pass the packet to the current handler.
2d966958c   wdenk   Initial revision
1251
  		 */
ece223b52   Joe Hershberger   net: Refactor to ...
1252
  		(*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1253
1254
1255
1256
  				      ntohs(ip->udp_dst),
  				      src_ip,
  				      ntohs(ip->udp_src),
  				      ntohs(ip->udp_len) - UDP_HDR_SIZE);
2d966958c   wdenk   Initial revision
1257
1258
1259
  		break;
  	}
  }
2d966958c   wdenk   Initial revision
1260
  /**********************************************************************/
e4bf0c5cf   Simon Glass   net: tftpput: Ren...
1261
  static int net_check_prereq(enum proto_t protocol)
2d966958c   wdenk   Initial revision
1262
1263
  {
  	switch (protocol) {
6e5923851   wdenk   * Cleanup, minor ...
1264
  		/* Fall through */
643d1ab23   Jon Loeliger   net/: Remove obso...
1265
  #if defined(CONFIG_CMD_PING)
73a8b27c5   wdenk   * Add support for...
1266
  	case PING:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1267
  		if (net_ping_ip.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1268
1269
  			puts("*** ERROR: ping address not given
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1270
  			return 1;
6e5923851   wdenk   * Cleanup, minor ...
1271
1272
  		}
  		goto common;
73a8b27c5   wdenk   * Add support for...
1273
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
1274
  #if defined(CONFIG_CMD_SNTP)
ea287debe   wdenk   * Patch by Masami...
1275
  	case SNTP:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1276
  		if (net_ntp_server.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1277
1278
  			puts("*** ERROR: NTP server address not given
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1279
  			return 1;
ea287debe   wdenk   * Patch by Masami...
1280
1281
1282
  		}
  		goto common;
  #endif
1a32bf418   Robin Getz   Add DNS support
1283
1284
  #if defined(CONFIG_CMD_DNS)
  	case DNS:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1285
  		if (net_dns_server.s_addr == 0) {
1a32bf418   Robin Getz   Add DNS support
1286
1287
1288
1289
1290
1291
  			puts("*** ERROR: DNS server address not given
  ");
  			return 1;
  		}
  		goto common;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
1292
  #if defined(CONFIG_CMD_NFS)
cbd8a35c6   wdenk   * Patch by Masami...
1293
1294
  	case NFS:
  #endif
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1295
  		/* Fall through */
e4bf0c5cf   Simon Glass   net: tftpput: Ren...
1296
  	case TFTPGET:
1fb7cd498   Simon Glass   net: tftpput: imp...
1297
  	case TFTPPUT:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1298
  		if (net_server_ip.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1299
1300
  			puts("*** ERROR: `serverip' not set
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1301
  			return 1;
6e5923851   wdenk   * Cleanup, minor ...
1302
  		}
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1303
1304
1305
  #if	defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
  	defined(CONFIG_CMD_DNS)
  common:
73a8b27c5   wdenk   * Add support for...
1306
  #endif
8b6bbe104   Simon Guinot   netconsole: remov...
1307
  		/* Fall through */
73a8b27c5   wdenk   * Add support for...
1308

8b6bbe104   Simon Guinot   netconsole: remov...
1309
  	case NETCONS:
7a83af07a   Luca Ceresoli   TFTP: add tftpsrv...
1310
  	case TFTPSRV:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1311
  		if (net_ip.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1312
1313
  			puts("*** ERROR: `ipaddr' not set
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1314
  			return 1;
6e5923851   wdenk   * Cleanup, minor ...
1315
1316
  		}
  		/* Fall through */
2d966958c   wdenk   Initial revision
1317

bf6cb247a   Peter Tyser   rarp: Condtionall...
1318
  #ifdef CONFIG_CMD_RARP
2d966958c   wdenk   Initial revision
1319
  	case RARP:
bf6cb247a   Peter Tyser   rarp: Condtionall...
1320
  #endif
2d966958c   wdenk   Initial revision
1321
  	case BOOTP:
a3d991bd0   wdenk   Patches by Pantel...
1322
  	case CDP:
bf6cb247a   Peter Tyser   rarp: Condtionall...
1323
  	case DHCP:
d22c338e0   Joe Hershberger   net: Add link-loc...
1324
  	case LINKLOCAL:
0adb5b761   Joe Hershberger   net: cosmetic: Na...
1325
  		if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1326
  			int num = eth_get_dev_index();
2d966958c   wdenk   Initial revision
1327

6e5923851   wdenk   * Cleanup, minor ...
1328
1329
  			switch (num) {
  			case -1:
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1330
1331
  				puts("*** ERROR: No ethernet found.
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1332
  				return 1;
6e5923851   wdenk   * Cleanup, minor ...
1333
  			case 0:
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1334
1335
  				puts("*** ERROR: `ethaddr' not set
  ");
2d966958c   wdenk   Initial revision
1336
  				break;
6e5923851   wdenk   * Cleanup, minor ...
1337
  			default:
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1338
1339
  				printf("*** ERROR: `eth%daddr' not set
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1340
  				       num);
2d966958c   wdenk   Initial revision
1341
  				break;
6e5923851   wdenk   * Cleanup, minor ...
1342
  			}
2d966958c   wdenk   Initial revision
1343

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1344
  			net_start_again();
92895de97   Luca Ceresoli   net/net.c: cosmet...
1345
  			return 2;
6e5923851   wdenk   * Cleanup, minor ...
1346
1347
1348
  		}
  		/* Fall through */
  	default:
92895de97   Luca Ceresoli   net/net.c: cosmet...
1349
  		return 0;
2d966958c   wdenk   Initial revision
1350
  	}
92895de97   Luca Ceresoli   net/net.c: cosmet...
1351
  	return 0;		/* OK */
2d966958c   wdenk   Initial revision
1352
1353
1354
1355
  }
  /**********************************************************************/
  
  int
1203fccee   Joe Hershberger   net: cosmetic: Cl...
1356
  net_eth_hdr_size(void)
a3d991bd0   wdenk   Patches by Pantel...
1357
1358
  {
  	ushort myvlanid;
2d966958c   wdenk   Initial revision
1359

4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1360
  	myvlanid = ntohs(net_our_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1361
1362
  	if (myvlanid == (ushort)-1)
  		myvlanid = VLAN_NONE;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1363
1364
  	return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE :
  		VLAN_ETHER_HDR_SIZE;
a3d991bd0   wdenk   Patches by Pantel...
1365
  }
1203fccee   Joe Hershberger   net: cosmetic: Cl...
1366
  int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot)
2d966958c   wdenk   Initial revision
1367
  {
cb487f566   Joe Hershberger   net: cosmetic: Un...
1368
  	struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
a3d991bd0   wdenk   Patches by Pantel...
1369
  	ushort myvlanid;
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1370
  	myvlanid = ntohs(net_our_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1371
1372
  	if (myvlanid == (ushort)-1)
  		myvlanid = VLAN_NONE;
2d966958c   wdenk   Initial revision
1373

0adb5b761   Joe Hershberger   net: cosmetic: Na...
1374
1375
  	memcpy(et->et_dest, dest_ethaddr, 6);
  	memcpy(et->et_src, net_ethaddr, 6);
a3d991bd0   wdenk   Patches by Pantel...
1376
  	if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
c819abeef   Luca Ceresoli   net/net.c: cosmet...
1377
  		et->et_protlen = htons(prot);
a3d991bd0   wdenk   Patches by Pantel...
1378
1379
  		return ETHER_HDR_SIZE;
  	} else {
c68cca35b   Joe Hershberger   net: cosmetic: Un...
1380
1381
  		struct vlan_ethernet_hdr *vet =
  			(struct vlan_ethernet_hdr *)xet;
2d966958c   wdenk   Initial revision
1382

a3d991bd0   wdenk   Patches by Pantel...
1383
1384
1385
1386
1387
1388
  		vet->vet_vlan_type = htons(PROT_VLAN);
  		vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));
  		vet->vet_type = htons(prot);
  		return VLAN_ETHER_HDR_SIZE;
  	}
  }
2d966958c   wdenk   Initial revision
1389

e71110158   Joe Hershberger   net: Add net_upda...
1390
1391
1392
1393
1394
  int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
  {
  	ushort protlen;
  
  	memcpy(et->et_dest, addr, 6);
0adb5b761   Joe Hershberger   net: cosmetic: Na...
1395
  	memcpy(et->et_src, net_ethaddr, 6);
e71110158   Joe Hershberger   net: Add net_upda...
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
  	protlen = ntohs(et->et_protlen);
  	if (protlen == PROT_VLAN) {
  		struct vlan_ethernet_hdr *vet =
  			(struct vlan_ethernet_hdr *)et;
  		vet->vet_type = htons(prot);
  		return VLAN_ETHER_HDR_SIZE;
  	} else if (protlen > 1514) {
  		et->et_protlen = htons(prot);
  		return ETHER_HDR_SIZE;
  	} else {
  		/* 802.2 + SNAP */
  		struct e802_hdr *et802 = (struct e802_hdr *)et;
  		et802->et_prot = htons(prot);
  		return E802_HDR_SIZE;
  	}
  }
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1412
  void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
2d966958c   wdenk   Initial revision
1413
  {
4b11c9166   Joe Hershberger   net: Refactor IP,...
1414
  	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
2d966958c   wdenk   Initial revision
1415
1416
  
  	/*
4b11c9166   Joe Hershberger   net: Refactor IP,...
1417
  	 *	Construct an IP header.
2d966958c   wdenk   Initial revision
1418
  	 */
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1419
1420
  	/* IP_HDR_SIZE / 4 (not including UDP) */
  	ip->ip_hl_v  = 0x45;
2d966958c   wdenk   Initial revision
1421
  	ip->ip_tos   = 0;
4b11c9166   Joe Hershberger   net: Refactor IP,...
1422
  	ip->ip_len   = htons(IP_HDR_SIZE);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1423
  	ip->ip_id    = htons(net_ip_id++);
e0c07b868   Peter Tyser   net: Define IP fl...
1424
  	ip->ip_off   = htons(IP_FLAGS_DFRAG);	/* Don't fragment */
2d966958c   wdenk   Initial revision
1425
  	ip->ip_ttl   = 255;
2d966958c   wdenk   Initial revision
1426
  	ip->ip_sum   = 0;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1427
  	/* already in network byte order */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1428
  	net_copy_ip((void *)&ip->ip_src, &source);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1429
  	/* already in network byte order */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1430
  	net_copy_ip((void *)&ip->ip_dst, &dest);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1431
  }
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1432
  void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
4b11c9166   Joe Hershberger   net: Refactor IP,...
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
  			int len)
  {
  	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
  
  	/*
  	 *	If the data is an odd number of bytes, zero the
  	 *	byte after the last byte so that the checksum
  	 *	will work.
  	 */
  	if (len & 1)
  		pkt[IP_UDP_HDR_SIZE + len] = 0;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1444
  	net_set_ip_header(pkt, dest, net_ip);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1445
1446
  	ip->ip_len   = htons(IP_UDP_HDR_SIZE + len);
  	ip->ip_p     = IPPROTO_UDP;
0da0fcd51   Simon Glass   net: Use new chec...
1447
  	ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1448

2d966958c   wdenk   Initial revision
1449
1450
  	ip->udp_src  = htons(sport);
  	ip->udp_dst  = htons(dport);
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1451
  	ip->udp_len  = htons(UDP_HDR_SIZE + len);
2d966958c   wdenk   Initial revision
1452
  	ip->udp_xsum = 0;
2d966958c   wdenk   Initial revision
1453
  }
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1454
  void copy_filename(char *dst, const char *src, int size)
2d966958c   wdenk   Initial revision
1455
1456
1457
1458
1459
  {
  	if (*src && (*src == '"')) {
  		++src;
  		--size;
  	}
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
1460
  	while ((--size > 0) && *src && (*src != '"'))
2d966958c   wdenk   Initial revision
1461
  		*dst++ = *src++;
2d966958c   wdenk   Initial revision
1462
1463
  	*dst = '\0';
  }
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1464
1465
1466
  #if	defined(CONFIG_CMD_NFS)		|| \
  	defined(CONFIG_CMD_SNTP)	|| \
  	defined(CONFIG_CMD_DNS)
1a32bf418   Robin Getz   Add DNS support
1467
  /*
9739946cc   Robin Getz   ./net/net.c - mak...
1468
1469
1470
   * make port a little random (1024-17407)
   * This keeps the math somewhat trivial to compute, and seems to work with
   * all supported protocols/clients/servers
1a32bf418   Robin Getz   Add DNS support
1471
1472
1473
   */
  unsigned int random_port(void)
  {
9739946cc   Robin Getz   ./net/net.c - mak...
1474
  	return 1024 + (get_timer(0) % 0x4000);
1a32bf418   Robin Getz   Add DNS support
1475
1476
  }
  #endif
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1477
  void ip_to_string(struct in_addr x, char *s)
2d966958c   wdenk   Initial revision
1478
  {
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1479
  	x.s_addr = ntohl(x.s_addr);
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1480
  	sprintf(s, "%d.%d.%d.%d",
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1481
1482
1483
1484
  		(int) ((x.s_addr >> 24) & 0xff),
  		(int) ((x.s_addr >> 16) & 0xff),
  		(int) ((x.s_addr >> 8) & 0xff),
  		(int) ((x.s_addr >> 0) & 0xff)
6e5923851   wdenk   * Cleanup, minor ...
1485
  	);
2d966958c   wdenk   Initial revision
1486
  }
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1487
  void vlan_to_string(ushort x, char *s)
a3d991bd0   wdenk   Patches by Pantel...
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
  {
  	x = ntohs(x);
  
  	if (x == (ushort)-1)
  		x = VLAN_NONE;
  
  	if (x == VLAN_NONE)
  		strcpy(s, "none");
  	else
  		sprintf(s, "%d", x & VLAN_IDMASK);
  }
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1499
  ushort string_to_vlan(const char *s)
a3d991bd0   wdenk   Patches by Pantel...
1500
1501
1502
1503
  {
  	ushort id;
  
  	if (s == NULL)
b9711de10   wdenk   * Patch by John K...
1504
  		return htons(VLAN_NONE);
a3d991bd0   wdenk   Patches by Pantel...
1505
1506
1507
1508
1509
  
  	if (*s < '0' || *s > '9')
  		id = VLAN_NONE;
  	else
  		id = (ushort)simple_strtoul(s, NULL, 10);
b9711de10   wdenk   * Patch by John K...
1510
  	return htons(id);
a3d991bd0   wdenk   Patches by Pantel...
1511
  }
723806cc5   Simon Glass   env: Rename some ...
1512
  ushort env_get_vlan(char *var)
a3d991bd0   wdenk   Patches by Pantel...
1513
  {
00caae6d4   Simon Glass   env: Rename geten...
1514
  	return string_to_vlan(env_get(var));
a3d991bd0   wdenk   Patches by Pantel...
1515
  }