1 /*
2 * Copied from Linux Monitor (LiMon) - Networking.
3 *
4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License)
6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
10 */
11
12 /*
13 * General Desription:
14 *
15 * The user interface supports commands for BOOTP, RARP, and TFTP.
16 * Also, we support ARP internally. Depending on available data,
17 * these interact as follows:
18 *
19 * BOOTP:
20 *
21 * Prerequisites: - own ethernet address
22 * We want: - own IP address
23 * - TFTP server IP address
24 * - name of bootfile
25 * Next step: ARP
26 *
27 * LINK_LOCAL:
28 *
29 * Prerequisites: - own ethernet address
30 * We want: - own IP address
31 * Next step: ARP
32 *
33 * RARP:
34 *
35 * Prerequisites: - own ethernet address
36 * We want: - own IP address
37 * - TFTP server IP address
38 * Next step: ARP
39 *
40 * ARP:
41 *
42 * Prerequisites: - own ethernet address
43 * - own IP address
44 * - TFTP server IP address
45 * We want: - TFTP server ethernet address
46 * Next step: TFTP
47 *
48 * DHCP:
49 *
50 * Prerequisites: - own ethernet address
51 * We want: - IP, Netmask, ServerIP, Gateway IP
52 * - bootfilename, lease time
53 * Next step: - TFTP
54 *
55 * TFTP:
56 *
57 * Prerequisites: - own ethernet address
58 * - own IP address
59 * - TFTP server IP address
60 * - TFTP server ethernet address
61 * - name of bootfile (if unknown, we use a default name
62 * derived from our own IP address)
63 * We want: - load the boot file
64 * Next step: none
65 *
66 * NFS:
67 *
68 * Prerequisites: - own ethernet address
69 * - own IP address
70 * - name of bootfile (if unknown, we use a default name
71 * derived from our own IP address)
72 * We want: - load the boot file
73 * Next step: none
74 *
75 * SNTP:
76 *
77 * Prerequisites: - own ethernet address
78 * - own IP address
79 * We want: - network time
80 * Next step: none
81 */
82
83
84 #include <common.h>
85 #include <command.h>
86 #include <console.h>
87 #include <environment.h>
88 #include <errno.h>
89 #include <net.h>
90 #if defined(CONFIG_UDP_FUNCTION_FASTBOOT)
91 #include <net/fastboot.h>
92 #endif
93 #include <net/tftp.h>
94 #if defined(CONFIG_LED_STATUS)
95 #include <miiphy.h>
96 #include <status_led.h>
97 #endif
98 #include <watchdog.h>
99 #include <linux/compiler.h>
100 #include "arp.h"
101 #include "bootp.h"
102 #include "cdp.h"
103 #if defined(CONFIG_CMD_DNS)
104 #include "dns.h"
105 #endif
106 #include "link_local.h"
107 #include "nfs.h"
108 #include "ping.h"
109 #include "rarp.h"
110 #if defined(CONFIG_CMD_SNTP)
111 #include "sntp.h"
112 #endif
113
114 DECLARE_GLOBAL_DATA_PTR;
115
116 /** BOOTP EXTENTIONS **/
117
118 /* Our subnet mask (0=unknown) */
119 struct in_addr net_netmask;
120 /* Our gateways IP address */
121 struct in_addr net_gateway;
122 /* Our DNS IP address */
123 struct in_addr net_dns_server;
124 #if defined(CONFIG_BOOTP_DNS2)
125 /* Our 2nd DNS IP address */
126 struct in_addr net_dns_server2;
127 #endif
128
129 #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP */
130 struct in_addr net_mcast_addr;
131 #endif
132
133 /** END OF BOOTP EXTENTIONS **/
134
135 /* Our ethernet address */
136 u8 net_ethaddr[6];
137 /* Boot server enet address */
138 u8 net_server_ethaddr[6];
139 /* Our IP addr (0 = unknown) */
140 struct in_addr net_ip;
141 /* Server IP addr (0 = unknown) */
142 struct in_addr net_server_ip;
143 /* Current receive packet */
144 uchar *net_rx_packet;
145 /* Current rx packet length */
146 int net_rx_packet_len;
147 /* IP packet ID */
148 static unsigned net_ip_id;
149 /* Ethernet bcast address */
150 const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
151 const u8 net_null_ethaddr[6];
152 #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
153 void (*push_packet)(void *, int len) = 0;
154 #endif
155 /* Network loop state */
156 enum net_loop_state net_state;
157 /* Tried all network devices */
158 int net_restart_wrap;
159 /* Network loop restarted */
160 static int net_restarted;
161 /* At least one device configured */
162 static int net_dev_exists;
163
164 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
165 /* default is without VLAN */
166 ushort net_our_vlan = 0xFFFF;
167 /* ditto */
168 ushort net_native_vlan = 0xFFFF;
169
170 /* Boot File name */
171 char net_boot_file_name[1024];
172 /* The actual transferred size of the bootfile (in bytes) */
173 u32 net_boot_file_size;
174 /* Boot file size in blocks as reported by the DHCP server */
175 u32 net_boot_file_expected_size_in_blocks;
176
177 #if defined(CONFIG_CMD_SNTP)
178 /* NTP server IP address */
179 struct in_addr net_ntp_server;
180 /* offset time from UTC */
181 int net_ntp_time_offset;
182 #endif
183
184 static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
185 /* Receive packets */
186 uchar *net_rx_packets[PKTBUFSRX];
187 /* Current UDP RX packet handler */
188 static rxhand_f *udp_packet_handler;
189 /* Current ARP RX packet handler */
190 static rxhand_f *arp_packet_handler;
191 #ifdef CONFIG_CMD_TFTPPUT
192 /* Current ICMP rx handler */
193 static rxhand_icmp_f *packet_icmp_handler;
194 #endif
195 /* Current timeout handler */
196 static thand_f *time_handler;
197 /* Time base value */
198 static ulong time_start;
199 /* Current timeout value */
200 static ulong time_delta;
201 /* THE transmit packet */
202 uchar *net_tx_packet;
203
204 static int net_check_prereq(enum proto_t protocol);
205
206 static int net_try_count;
207
208 int __maybe_unused net_busy_flag;
209
210 /**********************************************************************/
211
on_bootfile(const char * name,const char * value,enum env_op op,int flags)212 static int on_bootfile(const char *name, const char *value, enum env_op op,
213 int flags)
214 {
215 if (flags & H_PROGRAMMATIC)
216 return 0;
217
218 switch (op) {
219 case env_op_create:
220 case env_op_overwrite:
221 copy_filename(net_boot_file_name, value,
222 sizeof(net_boot_file_name));
223 break;
224 default:
225 break;
226 }
227
228 return 0;
229 }
230 U_BOOT_ENV_CALLBACK(bootfile, on_bootfile);
231
on_ipaddr(const char * name,const char * value,enum env_op op,int flags)232 static int on_ipaddr(const char *name, const char *value, enum env_op op,
233 int flags)
234 {
235 if (flags & H_PROGRAMMATIC)
236 return 0;
237
238 net_ip = string_to_ip(value);
239
240 return 0;
241 }
242 U_BOOT_ENV_CALLBACK(ipaddr, on_ipaddr);
243
on_gatewayip(const char * name,const char * value,enum env_op op,int flags)244 static int on_gatewayip(const char *name, const char *value, enum env_op op,
245 int flags)
246 {
247 if (flags & H_PROGRAMMATIC)
248 return 0;
249
250 net_gateway = string_to_ip(value);
251
252 return 0;
253 }
254 U_BOOT_ENV_CALLBACK(gatewayip, on_gatewayip);
255
on_netmask(const char * name,const char * value,enum env_op op,int flags)256 static int on_netmask(const char *name, const char *value, enum env_op op,
257 int flags)
258 {
259 if (flags & H_PROGRAMMATIC)
260 return 0;
261
262 net_netmask = string_to_ip(value);
263
264 return 0;
265 }
266 U_BOOT_ENV_CALLBACK(netmask, on_netmask);
267
on_serverip(const char * name,const char * value,enum env_op op,int flags)268 static int on_serverip(const char *name, const char *value, enum env_op op,
269 int flags)
270 {
271 if (flags & H_PROGRAMMATIC)
272 return 0;
273
274 net_server_ip = string_to_ip(value);
275
276 return 0;
277 }
278 U_BOOT_ENV_CALLBACK(serverip, on_serverip);
279
on_nvlan(const char * name,const char * value,enum env_op op,int flags)280 static int on_nvlan(const char *name, const char *value, enum env_op op,
281 int flags)
282 {
283 if (flags & H_PROGRAMMATIC)
284 return 0;
285
286 net_native_vlan = string_to_vlan(value);
287
288 return 0;
289 }
290 U_BOOT_ENV_CALLBACK(nvlan, on_nvlan);
291
on_vlan(const char * name,const char * value,enum env_op op,int flags)292 static int on_vlan(const char *name, const char *value, enum env_op op,
293 int flags)
294 {
295 if (flags & H_PROGRAMMATIC)
296 return 0;
297
298 net_our_vlan = string_to_vlan(value);
299
300 return 0;
301 }
302 U_BOOT_ENV_CALLBACK(vlan, on_vlan);
303
304 #if defined(CONFIG_CMD_DNS)
on_dnsip(const char * name,const char * value,enum env_op op,int flags)305 static int on_dnsip(const char *name, const char *value, enum env_op op,
306 int flags)
307 {
308 if (flags & H_PROGRAMMATIC)
309 return 0;
310
311 net_dns_server = string_to_ip(value);
312
313 return 0;
314 }
315 U_BOOT_ENV_CALLBACK(dnsip, on_dnsip);
316 #endif
317
318 /*
319 * Check if autoload is enabled. If so, use either NFS or TFTP to download
320 * the boot file.
321 */
net_auto_load(void)322 void net_auto_load(void)
323 {
324 #if defined(CONFIG_CMD_NFS)
325 const char *s = env_get("autoload");
326
327 if (s != NULL && strcmp(s, "NFS") == 0) {
328 /*
329 * Use NFS to load the bootfile.
330 */
331 nfs_start();
332 return;
333 }
334 #endif
335 if (env_get_yesno("autoload") == 0) {
336 /*
337 * Just use BOOTP/RARP to configure system;
338 * Do not use TFTP to load the bootfile.
339 */
340 net_set_state(NETLOOP_SUCCESS);
341 return;
342 }
343 tftp_start(TFTPGET);
344 }
345
net_init_loop(void)346 static void net_init_loop(void)
347 {
348 if (eth_get_dev())
349 memcpy(net_ethaddr, eth_get_ethaddr(), 6);
350
351 return;
352 }
353
net_clear_handlers(void)354 static void net_clear_handlers(void)
355 {
356 net_set_udp_handler(NULL);
357 net_set_arp_handler(NULL);
358 net_set_timeout_handler(0, NULL);
359 }
360
net_cleanup_loop(void)361 static void net_cleanup_loop(void)
362 {
363 net_clear_handlers();
364 }
365
net_init(void)366 void net_init(void)
367 {
368 static int first_call = 1;
369
370 if (first_call) {
371 /*
372 * Setup packet buffers, aligned correctly.
373 */
374 int i;
375
376 net_tx_packet = &net_pkt_buf[0] + (PKTALIGN - 1);
377 net_tx_packet -= (ulong)net_tx_packet % PKTALIGN;
378 for (i = 0; i < PKTBUFSRX; i++) {
379 net_rx_packets[i] = net_tx_packet +
380 (i + 1) * PKTSIZE_ALIGN;
381 }
382 arp_init();
383 net_clear_handlers();
384
385 /* Only need to setup buffer pointers once. */
386 first_call = 0;
387 }
388
389 net_init_loop();
390 }
391
392 /**********************************************************************/
393 /*
394 * Main network processing loop.
395 */
396
net_loop(enum proto_t protocol)397 int net_loop(enum proto_t protocol)
398 {
399 int ret = -EINVAL;
400
401 net_restarted = 0;
402 net_dev_exists = 0;
403 net_try_count = 1;
404 debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n");
405
406 bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
407 net_init();
408 if (eth_is_on_demand_init() || protocol != NETCONS) {
409 eth_halt();
410 eth_set_current();
411 ret = eth_init();
412 if (ret < 0) {
413 eth_halt();
414 return ret;
415 }
416 } else {
417 eth_init_state_only();
418 }
419 restart:
420 #ifdef CONFIG_USB_KEYBOARD
421 net_busy_flag = 0;
422 #endif
423 net_set_state(NETLOOP_CONTINUE);
424
425 /*
426 * Start the ball rolling with the given start function. From
427 * here on, this code is a state machine driven by received
428 * packets and timer events.
429 */
430 debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n");
431 net_init_loop();
432
433 switch (net_check_prereq(protocol)) {
434 case 1:
435 /* network not configured */
436 eth_halt();
437 return -ENODEV;
438
439 case 2:
440 /* network device not configured */
441 break;
442
443 case 0:
444 net_dev_exists = 1;
445 net_boot_file_size = 0;
446 switch (protocol) {
447 case TFTPGET:
448 #ifdef CONFIG_CMD_TFTPPUT
449 case TFTPPUT:
450 #endif
451 /* always use ARP to get server ethernet address */
452 tftp_start(protocol);
453 break;
454 #ifdef CONFIG_CMD_TFTPSRV
455 case TFTPSRV:
456 tftp_start_server();
457 break;
458 #endif
459 #ifdef CONFIG_UDP_FUNCTION_FASTBOOT
460 case FASTBOOT:
461 fastboot_start_server();
462 break;
463 #endif
464 #if defined(CONFIG_CMD_DHCP)
465 case DHCP:
466 bootp_reset();
467 net_ip.s_addr = 0;
468 dhcp_request(); /* Basically same as BOOTP */
469 break;
470 #endif
471
472 case BOOTP:
473 bootp_reset();
474 net_ip.s_addr = 0;
475 bootp_request();
476 break;
477
478 #if defined(CONFIG_CMD_RARP)
479 case RARP:
480 rarp_try = 0;
481 net_ip.s_addr = 0;
482 rarp_request();
483 break;
484 #endif
485 #if defined(CONFIG_CMD_PING)
486 case PING:
487 ping_start();
488 break;
489 #endif
490 #if defined(CONFIG_CMD_NFS)
491 case NFS:
492 nfs_start();
493 break;
494 #endif
495 #if defined(CONFIG_CMD_CDP)
496 case CDP:
497 cdp_start();
498 break;
499 #endif
500 #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
501 case NETCONS:
502 nc_start();
503 break;
504 #endif
505 #if defined(CONFIG_CMD_SNTP)
506 case SNTP:
507 sntp_start();
508 break;
509 #endif
510 #if defined(CONFIG_CMD_DNS)
511 case DNS:
512 dns_start();
513 break;
514 #endif
515 #if defined(CONFIG_CMD_LINK_LOCAL)
516 case LINKLOCAL:
517 link_local_start();
518 break;
519 #endif
520 default:
521 break;
522 }
523
524 break;
525 }
526
527 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
528 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \
529 defined(CONFIG_LED_STATUS) && \
530 defined(CONFIG_LED_STATUS_RED)
531 /*
532 * Echo the inverted link state to the fault LED.
533 */
534 if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR))
535 status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_OFF);
536 else
537 status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_ON);
538 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
539 #endif /* CONFIG_MII, ... */
540 #ifdef CONFIG_USB_KEYBOARD
541 net_busy_flag = 1;
542 #endif
543
544 /*
545 * Main packet reception loop. Loop receiving packets until
546 * someone sets `net_state' to a state that terminates.
547 */
548 for (;;) {
549 WATCHDOG_RESET();
550 #ifdef CONFIG_SHOW_ACTIVITY
551 show_activity(1);
552 #endif
553 if (arp_timeout_check() > 0)
554 time_start = get_timer(0);
555
556 /*
557 * Check the ethernet for a new packet. The ethernet
558 * receive routine will process it.
559 * Most drivers return the most recent packet size, but not
560 * errors that may have happened.
561 */
562 eth_rx();
563
564 /*
565 * Abort if ctrl-c was pressed.
566 */
567 if (ctrlc()) {
568 /* cancel any ARP that may not have completed */
569 net_arp_wait_packet_ip.s_addr = 0;
570
571 net_cleanup_loop();
572 eth_halt();
573 /* Invalidate the last protocol */
574 eth_set_last_protocol(BOOTP);
575
576 puts("\nAbort\n");
577 /* include a debug print as well incase the debug
578 messages are directed to stderr */
579 debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n");
580 ret = -EINTR;
581 goto done;
582 }
583
584 /*
585 * Check for a timeout, and run the timeout handler
586 * if we have one.
587 */
588 if (time_handler &&
589 ((get_timer(0) - time_start) > time_delta)) {
590 thand_f *x;
591
592 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
593 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \
594 defined(CONFIG_LED_STATUS) && \
595 defined(CONFIG_LED_STATUS_RED)
596 /*
597 * Echo the inverted link state to the fault LED.
598 */
599 if (miiphy_link(eth_get_dev()->name,
600 CONFIG_SYS_FAULT_MII_ADDR))
601 status_led_set(CONFIG_LED_STATUS_RED,
602 CONFIG_LED_STATUS_OFF);
603 else
604 status_led_set(CONFIG_LED_STATUS_RED,
605 CONFIG_LED_STATUS_ON);
606 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
607 #endif /* CONFIG_MII, ... */
608 debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n");
609 x = time_handler;
610 time_handler = (thand_f *)0;
611 (*x)();
612 }
613
614 if (net_state == NETLOOP_FAIL)
615 ret = net_start_again();
616
617 switch (net_state) {
618 case NETLOOP_RESTART:
619 net_restarted = 1;
620 goto restart;
621
622 case NETLOOP_SUCCESS:
623 net_cleanup_loop();
624 if (net_boot_file_size > 0) {
625 printf("Bytes transferred = %d (%x hex)\n",
626 net_boot_file_size, net_boot_file_size);
627 env_set_hex("filesize", net_boot_file_size);
628 env_set_hex("fileaddr", load_addr);
629 }
630 if (protocol != NETCONS)
631 eth_halt();
632 else
633 eth_halt_state_only();
634
635 eth_set_last_protocol(protocol);
636
637 ret = net_boot_file_size;
638 debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n");
639 goto done;
640
641 case NETLOOP_FAIL:
642 net_cleanup_loop();
643 /* Invalidate the last protocol */
644 eth_set_last_protocol(BOOTP);
645 debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n");
646 goto done;
647
648 case NETLOOP_CONTINUE:
649 continue;
650 }
651 }
652
653 done:
654 #ifdef CONFIG_USB_KEYBOARD
655 net_busy_flag = 0;
656 #endif
657 #ifdef CONFIG_CMD_TFTPPUT
658 /* Clear out the handlers */
659 net_set_udp_handler(NULL);
660 net_set_icmp_handler(NULL);
661 #endif
662 return ret;
663 }
664
665 /**********************************************************************/
666
start_again_timeout_handler(void)667 static void start_again_timeout_handler(void)
668 {
669 net_set_state(NETLOOP_RESTART);
670 }
671
net_start_again(void)672 int net_start_again(void)
673 {
674 char *nretry;
675 int retry_forever = 0;
676 unsigned long retrycnt = 0;
677 int ret;
678
679 nretry = env_get("netretry");
680 if (nretry) {
681 if (!strcmp(nretry, "yes"))
682 retry_forever = 1;
683 else if (!strcmp(nretry, "no"))
684 retrycnt = 0;
685 else if (!strcmp(nretry, "once"))
686 retrycnt = 1;
687 else
688 retrycnt = simple_strtoul(nretry, NULL, 0);
689 } else {
690 retrycnt = 0;
691 retry_forever = 0;
692 }
693
694 if ((!retry_forever) && (net_try_count >= retrycnt)) {
695 eth_halt();
696 net_set_state(NETLOOP_FAIL);
697 /*
698 * We don't provide a way for the protocol to return an error,
699 * but this is almost always the reason.
700 */
701 return -ETIMEDOUT;
702 }
703
704 net_try_count++;
705
706 eth_halt();
707 #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
708 eth_try_another(!net_restarted);
709 #endif
710 ret = eth_init();
711 if (net_restart_wrap) {
712 net_restart_wrap = 0;
713 if (net_dev_exists) {
714 net_set_timeout_handler(10000UL,
715 start_again_timeout_handler);
716 net_set_udp_handler(NULL);
717 } else {
718 net_set_state(NETLOOP_FAIL);
719 }
720 } else {
721 net_set_state(NETLOOP_RESTART);
722 }
723 return ret;
724 }
725
726 /**********************************************************************/
727 /*
728 * Miscelaneous bits.
729 */
730
dummy_handler(uchar * pkt,unsigned dport,struct in_addr sip,unsigned sport,unsigned len)731 static void dummy_handler(uchar *pkt, unsigned dport,
732 struct in_addr sip, unsigned sport,
733 unsigned len)
734 {
735 }
736
net_get_udp_handler(void)737 rxhand_f *net_get_udp_handler(void)
738 {
739 return udp_packet_handler;
740 }
741
net_set_udp_handler(rxhand_f * f)742 void net_set_udp_handler(rxhand_f *f)
743 {
744 debug_cond(DEBUG_INT_STATE, "--- net_loop UDP handler set (%p)\n", f);
745 if (f == NULL)
746 udp_packet_handler = dummy_handler;
747 else
748 udp_packet_handler = f;
749 }
750
net_get_arp_handler(void)751 rxhand_f *net_get_arp_handler(void)
752 {
753 return arp_packet_handler;
754 }
755
net_set_arp_handler(rxhand_f * f)756 void net_set_arp_handler(rxhand_f *f)
757 {
758 debug_cond(DEBUG_INT_STATE, "--- net_loop ARP handler set (%p)\n", f);
759 if (f == NULL)
760 arp_packet_handler = dummy_handler;
761 else
762 arp_packet_handler = f;
763 }
764
765 #ifdef CONFIG_CMD_TFTPPUT
net_set_icmp_handler(rxhand_icmp_f * f)766 void net_set_icmp_handler(rxhand_icmp_f *f)
767 {
768 packet_icmp_handler = f;
769 }
770 #endif
771
net_set_timeout_handler(ulong iv,thand_f * f)772 void net_set_timeout_handler(ulong iv, thand_f *f)
773 {
774 if (iv == 0) {
775 debug_cond(DEBUG_INT_STATE,
776 "--- net_loop timeout handler cancelled\n");
777 time_handler = (thand_f *)0;
778 } else {
779 debug_cond(DEBUG_INT_STATE,
780 "--- net_loop timeout handler set (%p)\n", f);
781 time_handler = f;
782 time_start = get_timer(0);
783 time_delta = iv * CONFIG_SYS_HZ / 1000;
784 }
785 }
786
net_send_udp_packet(uchar * ether,struct in_addr dest,int dport,int sport,int payload_len)787 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
788 int payload_len)
789 {
790 uchar *pkt;
791 int eth_hdr_size;
792 int pkt_hdr_size;
793
794 /* make sure the net_tx_packet is initialized (net_init() was called) */
795 assert(net_tx_packet != NULL);
796 if (net_tx_packet == NULL)
797 return -1;
798
799 /* convert to new style broadcast */
800 if (dest.s_addr == 0)
801 dest.s_addr = 0xFFFFFFFF;
802
803 /* if broadcast, make the ether address a broadcast and don't do ARP */
804 if (dest.s_addr == 0xFFFFFFFF)
805 ether = (uchar *)net_bcast_ethaddr;
806
807 pkt = (uchar *)net_tx_packet;
808
809 eth_hdr_size = net_set_ether(pkt, ether, PROT_IP);
810 pkt += eth_hdr_size;
811 net_set_udp_header(pkt, dest, dport, sport, payload_len);
812 pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
813
814 /* if MAC address was not discovered yet, do an ARP request */
815 if (memcmp(ether, net_null_ethaddr, 6) == 0) {
816 debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest);
817
818 /* save the ip and eth addr for the packet to send after arp */
819 net_arp_wait_packet_ip = dest;
820 arp_wait_packet_ethaddr = ether;
821
822 /* size of the waiting packet */
823 arp_wait_tx_packet_size = pkt_hdr_size + payload_len;
824
825 /* and do the ARP request */
826 arp_wait_try = 1;
827 arp_wait_timer_start = get_timer(0);
828 arp_request();
829 return 1; /* waiting */
830 } else {
831 debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n",
832 &dest, ether);
833 net_send_packet(net_tx_packet, pkt_hdr_size + payload_len);
834 return 0; /* transmitted */
835 }
836 }
837
838 #ifdef CONFIG_IP_DEFRAG
839 /*
840 * This function collects fragments in a single packet, according
841 * to the algorithm in RFC815. It returns NULL or the pointer to
842 * a complete packet, in static storage
843 */
844 #ifndef CONFIG_NET_MAXDEFRAG
845 #define CONFIG_NET_MAXDEFRAG 16384
846 #endif
847 #define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG)
848
849 #define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
850
851 /*
852 * this is the packet being assembled, either data or frag control.
853 * Fragments go by 8 bytes, so this union must be 8 bytes long
854 */
855 struct hole {
856 /* first_byte is address of this structure */
857 u16 last_byte; /* last byte in this hole + 1 (begin of next hole) */
858 u16 next_hole; /* index of next (in 8-b blocks), 0 == none */
859 u16 prev_hole; /* index of prev, 0 == none */
860 u16 unused;
861 };
862
__net_defragment(struct ip_udp_hdr * ip,int * lenp)863 static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
864 {
865 static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN);
866 static u16 first_hole, total_len;
867 struct hole *payload, *thisfrag, *h, *newh;
868 struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff;
869 uchar *indata = (uchar *)ip;
870 int offset8, start, len, done = 0;
871 u16 ip_off = ntohs(ip->ip_off);
872
873 /* payload starts after IP header, this fragment is in there */
874 payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
875 offset8 = (ip_off & IP_OFFS);
876 thisfrag = payload + offset8;
877 start = offset8 * 8;
878 len = ntohs(ip->ip_len) - IP_HDR_SIZE;
879
880 if (start + len > IP_MAXUDP) /* fragment extends too far */
881 return NULL;
882
883 if (!total_len || localip->ip_id != ip->ip_id) {
884 /* new (or different) packet, reset structs */
885 total_len = 0xffff;
886 payload[0].last_byte = ~0;
887 payload[0].next_hole = 0;
888 payload[0].prev_hole = 0;
889 first_hole = 0;
890 /* any IP header will work, copy the first we received */
891 memcpy(localip, ip, IP_HDR_SIZE);
892 }
893
894 /*
895 * What follows is the reassembly algorithm. We use the payload
896 * array as a linked list of hole descriptors, as each hole starts
897 * at a multiple of 8 bytes. However, last byte can be whatever value,
898 * so it is represented as byte count, not as 8-byte blocks.
899 */
900
901 h = payload + first_hole;
902 while (h->last_byte < start) {
903 if (!h->next_hole) {
904 /* no hole that far away */
905 return NULL;
906 }
907 h = payload + h->next_hole;
908 }
909
910 /* last fragment may be 1..7 bytes, the "+7" forces acceptance */
911 if (offset8 + ((len + 7) / 8) <= h - payload) {
912 /* no overlap with holes (dup fragment?) */
913 return NULL;
914 }
915
916 if (!(ip_off & IP_FLAGS_MFRAG)) {
917 /* no more fragmentss: truncate this (last) hole */
918 total_len = start + len;
919 h->last_byte = start + len;
920 }
921
922 /*
923 * There is some overlap: fix the hole list. This code doesn't
924 * deal with a fragment that overlaps with two different holes
925 * (thus being a superset of a previously-received fragment).
926 */
927
928 if ((h >= thisfrag) && (h->last_byte <= start + len)) {
929 /* complete overlap with hole: remove hole */
930 if (!h->prev_hole && !h->next_hole) {
931 /* last remaining hole */
932 done = 1;
933 } else if (!h->prev_hole) {
934 /* first hole */
935 first_hole = h->next_hole;
936 payload[h->next_hole].prev_hole = 0;
937 } else if (!h->next_hole) {
938 /* last hole */
939 payload[h->prev_hole].next_hole = 0;
940 } else {
941 /* in the middle of the list */
942 payload[h->next_hole].prev_hole = h->prev_hole;
943 payload[h->prev_hole].next_hole = h->next_hole;
944 }
945
946 } else if (h->last_byte <= start + len) {
947 /* overlaps with final part of the hole: shorten this hole */
948 h->last_byte = start;
949
950 } else if (h >= thisfrag) {
951 /* overlaps with initial part of the hole: move this hole */
952 newh = thisfrag + (len / 8);
953 *newh = *h;
954 h = newh;
955 if (h->next_hole)
956 payload[h->next_hole].prev_hole = (h - payload);
957 if (h->prev_hole)
958 payload[h->prev_hole].next_hole = (h - payload);
959 else
960 first_hole = (h - payload);
961
962 } else {
963 /* fragment sits in the middle: split the hole */
964 newh = thisfrag + (len / 8);
965 *newh = *h;
966 h->last_byte = start;
967 h->next_hole = (newh - payload);
968 newh->prev_hole = (h - payload);
969 if (newh->next_hole)
970 payload[newh->next_hole].prev_hole = (newh - payload);
971 }
972
973 /* finally copy this fragment and possibly return whole packet */
974 memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len);
975 if (!done)
976 return NULL;
977
978 localip->ip_len = htons(total_len);
979 *lenp = total_len + IP_HDR_SIZE;
980 return localip;
981 }
982
net_defragment(struct ip_udp_hdr * ip,int * lenp)983 static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
984 int *lenp)
985 {
986 u16 ip_off = ntohs(ip->ip_off);
987 if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
988 return ip; /* not a fragment */
989 return __net_defragment(ip, lenp);
990 }
991
992 #else /* !CONFIG_IP_DEFRAG */
993
net_defragment(struct ip_udp_hdr * ip,int * lenp)994 static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
995 int *lenp)
996 {
997 u16 ip_off = ntohs(ip->ip_off);
998 if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
999 return ip; /* not a fragment */
1000 return NULL;
1001 }
1002 #endif
1003
1004 /**
1005 * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently
1006 * drop others.
1007 *
1008 * @parma ip IP packet containing the ICMP
1009 */
receive_icmp(struct ip_udp_hdr * ip,int len,struct in_addr src_ip,struct ethernet_hdr * et)1010 static void receive_icmp(struct ip_udp_hdr *ip, int len,
1011 struct in_addr src_ip, struct ethernet_hdr *et)
1012 {
1013 struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
1014
1015 switch (icmph->type) {
1016 case ICMP_REDIRECT:
1017 if (icmph->code != ICMP_REDIR_HOST)
1018 return;
1019 printf(" ICMP Host Redirect to %pI4 ",
1020 &icmph->un.gateway);
1021 break;
1022 default:
1023 #if defined(CONFIG_CMD_PING)
1024 ping_receive(et, ip, len);
1025 #endif
1026 #ifdef CONFIG_CMD_TFTPPUT
1027 if (packet_icmp_handler)
1028 packet_icmp_handler(icmph->type, icmph->code,
1029 ntohs(ip->udp_dst), src_ip,
1030 ntohs(ip->udp_src), icmph->un.data,
1031 ntohs(ip->udp_len));
1032 #endif
1033 break;
1034 }
1035 }
1036
net_process_received_packet(uchar * in_packet,int len)1037 void net_process_received_packet(uchar *in_packet, int len)
1038 {
1039 struct ethernet_hdr *et;
1040 struct ip_udp_hdr *ip;
1041 struct in_addr dst_ip;
1042 struct in_addr src_ip;
1043 int eth_proto;
1044 #if defined(CONFIG_CMD_CDP)
1045 int iscdp;
1046 #endif
1047 ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
1048
1049 debug_cond(DEBUG_NET_PKT, "packet received\n");
1050
1051 net_rx_packet = in_packet;
1052 net_rx_packet_len = len;
1053 et = (struct ethernet_hdr *)in_packet;
1054
1055 /* too small packet? */
1056 if (len < ETHER_HDR_SIZE)
1057 return;
1058
1059 #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
1060 if (push_packet) {
1061 (*push_packet)(in_packet, len);
1062 return;
1063 }
1064 #endif
1065
1066 #if defined(CONFIG_CMD_CDP)
1067 /* keep track if packet is CDP */
1068 iscdp = is_cdp_packet(et->et_dest);
1069 #endif
1070
1071 myvlanid = ntohs(net_our_vlan);
1072 if (myvlanid == (ushort)-1)
1073 myvlanid = VLAN_NONE;
1074 mynvlanid = ntohs(net_native_vlan);
1075 if (mynvlanid == (ushort)-1)
1076 mynvlanid = VLAN_NONE;
1077
1078 eth_proto = ntohs(et->et_protlen);
1079
1080 if (eth_proto < 1514) {
1081 struct e802_hdr *et802 = (struct e802_hdr *)et;
1082 /*
1083 * Got a 802.2 packet. Check the other protocol field.
1084 * XXX VLAN over 802.2+SNAP not implemented!
1085 */
1086 eth_proto = ntohs(et802->et_prot);
1087
1088 ip = (struct ip_udp_hdr *)(in_packet + E802_HDR_SIZE);
1089 len -= E802_HDR_SIZE;
1090
1091 } else if (eth_proto != PROT_VLAN) { /* normal packet */
1092 ip = (struct ip_udp_hdr *)(in_packet + ETHER_HDR_SIZE);
1093 len -= ETHER_HDR_SIZE;
1094
1095 } else { /* VLAN packet */
1096 struct vlan_ethernet_hdr *vet =
1097 (struct vlan_ethernet_hdr *)et;
1098
1099 debug_cond(DEBUG_NET_PKT, "VLAN packet received\n");
1100
1101 /* too small packet? */
1102 if (len < VLAN_ETHER_HDR_SIZE)
1103 return;
1104
1105 /* if no VLAN active */
1106 if ((ntohs(net_our_vlan) & VLAN_IDMASK) == VLAN_NONE
1107 #if defined(CONFIG_CMD_CDP)
1108 && iscdp == 0
1109 #endif
1110 )
1111 return;
1112
1113 cti = ntohs(vet->vet_tag);
1114 vlanid = cti & VLAN_IDMASK;
1115 eth_proto = ntohs(vet->vet_type);
1116
1117 ip = (struct ip_udp_hdr *)(in_packet + VLAN_ETHER_HDR_SIZE);
1118 len -= VLAN_ETHER_HDR_SIZE;
1119 }
1120
1121 debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x\n", eth_proto);
1122
1123 #if defined(CONFIG_CMD_CDP)
1124 if (iscdp) {
1125 cdp_receive((uchar *)ip, len);
1126 return;
1127 }
1128 #endif
1129
1130 if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) {
1131 if (vlanid == VLAN_NONE)
1132 vlanid = (mynvlanid & VLAN_IDMASK);
1133 /* not matched? */
1134 if (vlanid != (myvlanid & VLAN_IDMASK))
1135 return;
1136 }
1137
1138 switch (eth_proto) {
1139 case PROT_ARP:
1140 arp_receive(et, ip, len);
1141 break;
1142
1143 #ifdef CONFIG_CMD_RARP
1144 case PROT_RARP:
1145 rarp_receive(ip, len);
1146 break;
1147 #endif
1148 case PROT_IP:
1149 debug_cond(DEBUG_NET_PKT, "Got IP\n");
1150 /* Before we start poking the header, make sure it is there */
1151 if (len < IP_UDP_HDR_SIZE) {
1152 debug("len bad %d < %lu\n", len,
1153 (ulong)IP_UDP_HDR_SIZE);
1154 return;
1155 }
1156 /* Check the packet length */
1157 if (len < ntohs(ip->ip_len)) {
1158 debug("len bad %d < %d\n", len, ntohs(ip->ip_len));
1159 return;
1160 }
1161 len = ntohs(ip->ip_len);
1162 debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n",
1163 len, ip->ip_hl_v & 0xff);
1164
1165 /* Can't deal with anything except IPv4 */
1166 if ((ip->ip_hl_v & 0xf0) != 0x40)
1167 return;
1168 /* Can't deal with IP options (headers != 20 bytes) */
1169 if ((ip->ip_hl_v & 0x0f) > 0x05)
1170 return;
1171 /* Check the Checksum of the header */
1172 if (!ip_checksum_ok((uchar *)ip, IP_HDR_SIZE)) {
1173 debug("checksum bad\n");
1174 return;
1175 }
1176 /* If it is not for us, ignore it */
1177 dst_ip = net_read_ip(&ip->ip_dst);
1178 if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr &&
1179 dst_ip.s_addr != 0xFFFFFFFF) {
1180 #ifdef CONFIG_MCAST_TFTP
1181 if (net_mcast_addr != dst_ip)
1182 #endif
1183 return;
1184 }
1185 /* Read source IP address for later use */
1186 src_ip = net_read_ip(&ip->ip_src);
1187 /*
1188 * The function returns the unchanged packet if it's not
1189 * a fragment, and either the complete packet or NULL if
1190 * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL)
1191 */
1192 ip = net_defragment(ip, &len);
1193 if (!ip)
1194 return;
1195 /*
1196 * watch for ICMP host redirects
1197 *
1198 * There is no real handler code (yet). We just watch
1199 * for ICMP host redirect messages. In case anybody
1200 * sees these messages: please contact me
1201 * (wd@denx.de), or - even better - send me the
1202 * necessary fixes :-)
1203 *
1204 * Note: in all cases where I have seen this so far
1205 * it was a problem with the router configuration,
1206 * for instance when a router was configured in the
1207 * BOOTP reply, but the TFTP server was on the same
1208 * subnet. So this is probably a warning that your
1209 * configuration might be wrong. But I'm not really
1210 * sure if there aren't any other situations.
1211 *
1212 * Simon Glass <sjg@chromium.org>: We get an ICMP when
1213 * we send a tftp packet to a dead connection, or when
1214 * there is no server at the other end.
1215 */
1216 if (ip->ip_p == IPPROTO_ICMP) {
1217 receive_icmp(ip, len, src_ip, et);
1218 return;
1219 } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */
1220 return;
1221 }
1222
1223 debug_cond(DEBUG_DEV_PKT,
1224 "received UDP (to=%pI4, from=%pI4, len=%d)\n",
1225 &dst_ip, &src_ip, len);
1226
1227 #ifdef CONFIG_UDP_CHECKSUM
1228 if (ip->udp_xsum != 0) {
1229 ulong xsum;
1230 ushort *sumptr;
1231 ushort sumlen;
1232
1233 xsum = ip->ip_p;
1234 xsum += (ntohs(ip->udp_len));
1235 xsum += (ntohl(ip->ip_src.s_addr) >> 16) & 0x0000ffff;
1236 xsum += (ntohl(ip->ip_src.s_addr) >> 0) & 0x0000ffff;
1237 xsum += (ntohl(ip->ip_dst.s_addr) >> 16) & 0x0000ffff;
1238 xsum += (ntohl(ip->ip_dst.s_addr) >> 0) & 0x0000ffff;
1239
1240 sumlen = ntohs(ip->udp_len);
1241 sumptr = (ushort *)&(ip->udp_src);
1242
1243 while (sumlen > 1) {
1244 ushort sumdata;
1245
1246 sumdata = *sumptr++;
1247 xsum += ntohs(sumdata);
1248 sumlen -= 2;
1249 }
1250 if (sumlen > 0) {
1251 ushort sumdata;
1252
1253 sumdata = *(unsigned char *)sumptr;
1254 sumdata = (sumdata << 8) & 0xff00;
1255 xsum += sumdata;
1256 }
1257 while ((xsum >> 16) != 0) {
1258 xsum = (xsum & 0x0000ffff) +
1259 ((xsum >> 16) & 0x0000ffff);
1260 }
1261 if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
1262 printf(" UDP wrong checksum %08lx %08x\n",
1263 xsum, ntohs(ip->udp_xsum));
1264 return;
1265 }
1266 }
1267 #endif
1268
1269 #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
1270 nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
1271 src_ip,
1272 ntohs(ip->udp_dst),
1273 ntohs(ip->udp_src),
1274 ntohs(ip->udp_len) - UDP_HDR_SIZE);
1275 #endif
1276 /*
1277 * IP header OK. Pass the packet to the current handler.
1278 */
1279 (*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE,
1280 ntohs(ip->udp_dst),
1281 src_ip,
1282 ntohs(ip->udp_src),
1283 ntohs(ip->udp_len) - UDP_HDR_SIZE);
1284 break;
1285 }
1286 }
1287
1288 /**********************************************************************/
1289
net_check_prereq(enum proto_t protocol)1290 static int net_check_prereq(enum proto_t protocol)
1291 {
1292 switch (protocol) {
1293 /* Fall through */
1294 #if defined(CONFIG_CMD_PING)
1295 case PING:
1296 if (net_ping_ip.s_addr == 0) {
1297 puts("*** ERROR: ping address not given\n");
1298 return 1;
1299 }
1300 goto common;
1301 #endif
1302 #if defined(CONFIG_CMD_SNTP)
1303 case SNTP:
1304 if (net_ntp_server.s_addr == 0) {
1305 puts("*** ERROR: NTP server address not given\n");
1306 return 1;
1307 }
1308 goto common;
1309 #endif
1310 #if defined(CONFIG_CMD_DNS)
1311 case DNS:
1312 if (net_dns_server.s_addr == 0) {
1313 puts("*** ERROR: DNS server address not given\n");
1314 return 1;
1315 }
1316 goto common;
1317 #endif
1318 #if defined(CONFIG_CMD_NFS)
1319 case NFS:
1320 #endif
1321 /* Fall through */
1322 case TFTPGET:
1323 case TFTPPUT:
1324 if (net_server_ip.s_addr == 0) {
1325 puts("*** ERROR: `serverip' not set\n");
1326 return 1;
1327 }
1328 #if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
1329 defined(CONFIG_CMD_DNS)
1330 common:
1331 #endif
1332 /* Fall through */
1333
1334 case NETCONS:
1335 case FASTBOOT:
1336 case TFTPSRV:
1337 if (net_ip.s_addr == 0) {
1338 puts("*** ERROR: `ipaddr' not set\n");
1339 return 1;
1340 }
1341 /* Fall through */
1342
1343 #ifdef CONFIG_CMD_RARP
1344 case RARP:
1345 #endif
1346 case BOOTP:
1347 case CDP:
1348 case DHCP:
1349 case LINKLOCAL:
1350 if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) {
1351 int num = eth_get_dev_index();
1352
1353 switch (num) {
1354 case -1:
1355 puts("*** ERROR: No ethernet found.\n");
1356 return 1;
1357 case 0:
1358 puts("*** ERROR: `ethaddr' not set\n");
1359 break;
1360 default:
1361 printf("*** ERROR: `eth%daddr' not set\n",
1362 num);
1363 break;
1364 }
1365
1366 net_start_again();
1367 return 2;
1368 }
1369 /* Fall through */
1370 default:
1371 return 0;
1372 }
1373 return 0; /* OK */
1374 }
1375 /**********************************************************************/
1376
1377 int
net_eth_hdr_size(void)1378 net_eth_hdr_size(void)
1379 {
1380 ushort myvlanid;
1381
1382 myvlanid = ntohs(net_our_vlan);
1383 if (myvlanid == (ushort)-1)
1384 myvlanid = VLAN_NONE;
1385
1386 return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE :
1387 VLAN_ETHER_HDR_SIZE;
1388 }
1389
net_set_ether(uchar * xet,const uchar * dest_ethaddr,uint prot)1390 int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot)
1391 {
1392 struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
1393 ushort myvlanid;
1394
1395 myvlanid = ntohs(net_our_vlan);
1396 if (myvlanid == (ushort)-1)
1397 myvlanid = VLAN_NONE;
1398
1399 memcpy(et->et_dest, dest_ethaddr, 6);
1400 memcpy(et->et_src, net_ethaddr, 6);
1401 if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
1402 et->et_protlen = htons(prot);
1403 return ETHER_HDR_SIZE;
1404 } else {
1405 struct vlan_ethernet_hdr *vet =
1406 (struct vlan_ethernet_hdr *)xet;
1407
1408 vet->vet_vlan_type = htons(PROT_VLAN);
1409 vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));
1410 vet->vet_type = htons(prot);
1411 return VLAN_ETHER_HDR_SIZE;
1412 }
1413 }
1414
net_update_ether(struct ethernet_hdr * et,uchar * addr,uint prot)1415 int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
1416 {
1417 ushort protlen;
1418
1419 memcpy(et->et_dest, addr, 6);
1420 memcpy(et->et_src, net_ethaddr, 6);
1421 protlen = ntohs(et->et_protlen);
1422 if (protlen == PROT_VLAN) {
1423 struct vlan_ethernet_hdr *vet =
1424 (struct vlan_ethernet_hdr *)et;
1425 vet->vet_type = htons(prot);
1426 return VLAN_ETHER_HDR_SIZE;
1427 } else if (protlen > 1514) {
1428 et->et_protlen = htons(prot);
1429 return ETHER_HDR_SIZE;
1430 } else {
1431 /* 802.2 + SNAP */
1432 struct e802_hdr *et802 = (struct e802_hdr *)et;
1433 et802->et_prot = htons(prot);
1434 return E802_HDR_SIZE;
1435 }
1436 }
1437
net_set_ip_header(uchar * pkt,struct in_addr dest,struct in_addr source)1438 void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
1439 {
1440 struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
1441
1442 /*
1443 * Construct an IP header.
1444 */
1445 /* IP_HDR_SIZE / 4 (not including UDP) */
1446 ip->ip_hl_v = 0x45;
1447 ip->ip_tos = 0;
1448 ip->ip_len = htons(IP_HDR_SIZE);
1449 ip->ip_id = htons(net_ip_id++);
1450 ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */
1451 ip->ip_ttl = 255;
1452 ip->ip_sum = 0;
1453 /* already in network byte order */
1454 net_copy_ip((void *)&ip->ip_src, &source);
1455 /* already in network byte order */
1456 net_copy_ip((void *)&ip->ip_dst, &dest);
1457 }
1458
net_set_udp_header(uchar * pkt,struct in_addr dest,int dport,int sport,int len)1459 void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
1460 int len)
1461 {
1462 struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
1463
1464 /*
1465 * If the data is an odd number of bytes, zero the
1466 * byte after the last byte so that the checksum
1467 * will work.
1468 */
1469 if (len & 1)
1470 pkt[IP_UDP_HDR_SIZE + len] = 0;
1471
1472 net_set_ip_header(pkt, dest, net_ip);
1473 ip->ip_len = htons(IP_UDP_HDR_SIZE + len);
1474 ip->ip_p = IPPROTO_UDP;
1475 ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
1476
1477 ip->udp_src = htons(sport);
1478 ip->udp_dst = htons(dport);
1479 ip->udp_len = htons(UDP_HDR_SIZE + len);
1480 ip->udp_xsum = 0;
1481 }
1482
copy_filename(char * dst,const char * src,int size)1483 void copy_filename(char *dst, const char *src, int size)
1484 {
1485 if (*src && (*src == '"')) {
1486 ++src;
1487 --size;
1488 }
1489
1490 while ((--size > 0) && *src && (*src != '"'))
1491 *dst++ = *src++;
1492 *dst = '\0';
1493 }
1494
1495 #if defined(CONFIG_CMD_NFS) || \
1496 defined(CONFIG_CMD_SNTP) || \
1497 defined(CONFIG_CMD_DNS)
1498 /*
1499 * make port a little random (1024-17407)
1500 * This keeps the math somewhat trivial to compute, and seems to work with
1501 * all supported protocols/clients/servers
1502 */
random_port(void)1503 unsigned int random_port(void)
1504 {
1505 return 1024 + (get_timer(0) % 0x4000);
1506 }
1507 #endif
1508
ip_to_string(struct in_addr x,char * s)1509 void ip_to_string(struct in_addr x, char *s)
1510 {
1511 x.s_addr = ntohl(x.s_addr);
1512 sprintf(s, "%d.%d.%d.%d",
1513 (int) ((x.s_addr >> 24) & 0xff),
1514 (int) ((x.s_addr >> 16) & 0xff),
1515 (int) ((x.s_addr >> 8) & 0xff),
1516 (int) ((x.s_addr >> 0) & 0xff)
1517 );
1518 }
1519
vlan_to_string(ushort x,char * s)1520 void vlan_to_string(ushort x, char *s)
1521 {
1522 x = ntohs(x);
1523
1524 if (x == (ushort)-1)
1525 x = VLAN_NONE;
1526
1527 if (x == VLAN_NONE)
1528 strcpy(s, "none");
1529 else
1530 sprintf(s, "%d", x & VLAN_IDMASK);
1531 }
1532
string_to_vlan(const char * s)1533 ushort string_to_vlan(const char *s)
1534 {
1535 ushort id;
1536
1537 if (s == NULL)
1538 return htons(VLAN_NONE);
1539
1540 if (*s < '0' || *s > '9')
1541 id = VLAN_NONE;
1542 else
1543 id = (ushort)simple_strtoul(s, NULL, 10);
1544
1545 return htons(id);
1546 }
1547
env_get_vlan(char * var)1548 ushort env_get_vlan(char *var)
1549 {
1550 return string_to_vlan(env_get(var));
1551 }
1552