2 * Copied from Linux Monitor (LiMon) - Networking.
4 * Copyright 1994 - 2000 Neil Russell.
6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
14 * The user interface supports commands for BOOTP, RARP, and TFTP.
15 * Also, we support ARP internally. Depending on available data,
16 * these interact as follows:
20 * Prerequisites: - own ethernet address
21 * We want: - own IP address
22 * - TFTP server IP address
28 * Prerequisites: - own ethernet address
29 * We want: - own IP address
30 * - TFTP server IP address
35 * Prerequisites: - own ethernet address
37 * - TFTP server IP address
38 * We want: - TFTP server ethernet address
43 * Prerequisites: - own ethernet address
44 * We want: - IP, Netmask, ServerIP, Gateway IP
45 * - bootfilename, lease time
50 * Prerequisites: - own ethernet address
52 * - TFTP server IP address
53 * - TFTP server ethernet address
54 * - name of bootfile (if unknown, we use a default name
55 * derived from our own IP address)
56 * We want: - load the boot file
61 * Prerequisites: - own ethernet address
63 * - name of bootfile (if unknown, we use a default name
64 * derived from our own IP address)
65 * We want: - load the boot file
70 * Prerequisites: - own ethernet address
72 * We want: - network time
81 #include <environment.h>
86 #include <linux/ctype.h>
91 #ifdef CONFIG_STATUS_LED
92 #include <status_led.h>
95 #ifdef CONFIG_NET_SNTP
99 #define ARP_TIMEOUT (5 * SECOND) /* Seconds before trying ARP again */
100 #ifndef CONFIG_NET_RETRY_COUNT
101 # define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */
103 # define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
107 /** BOOTP EXTENTIONS **/
109 IPaddr_t NetOurSubnetMask
=0; /* Our subnet mask (0=unknown) */
110 IPaddr_t NetOurGatewayIP
=0; /* Our gateways IP address */
111 IPaddr_t NetOurDNSIP
=0; /* Our DNS IP address */
112 #ifdef CONFIG_BOOTP_DNS2
113 IPaddr_t NetOurDNS2IP
=0; /* Our 2nd DNS IP address */
115 char NetOurNISDomain
[32]={0,}; /* Our NIS domain */
116 char NetOurHostName
[32]={0,}; /* Our hostname */
117 char NetOurRootPath
[64]={0,}; /* Our bootpath */
118 ushort NetBootFileSize
=0; /* Our bootfile size in blocks */
120 /** END OF BOOTP EXTENTIONS **/
122 ulong NetBootFileXferSize
; /* The actual transferred size of the bootfile (in bytes) */
123 uchar NetOurEther
[6]; /* Our ethernet address */
124 uchar NetServerEther
[6] = /* Boot server enet address */
125 { 0, 0, 0, 0, 0, 0 };
126 IPaddr_t NetOurIP
; /* Our IP addr (0 = unknown) */
127 IPaddr_t NetServerIP
; /* Our IP addr (0 = unknown) */
128 uchar
*NetRxPkt
; /* Current receive packet */
129 int NetRxPktLen
; /* Current rx packet length */
130 unsigned NetIPID
; /* IP packet ID */
131 uchar NetBcastAddr
[6] = /* Ethernet bcast address */
132 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
133 uchar NetEtherNullAddr
[6] =
134 { 0, 0, 0, 0, 0, 0 };
135 int NetState
; /* Network loop state */
137 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
138 ushort NetOurVLAN
= 0xFFFF; /* default is without VLAN */
139 ushort NetOurNativeVLAN
= 0xFFFF; /* ditto */
141 char BootFile
[128]; /* Boot File name */
143 #ifdef CONFIG_NET_PING
144 IPaddr_t NetPingIP
; /* the ip address to ping */
146 extern void PingStart(void);
149 #ifdef CONFIG_NET_SNTP
150 IPaddr_t NetNtpServerIP
; /* NTP server IP address */
151 int NetTimeOffset
=0; /* offset time from UTC */
154 #ifdef CONFIG_NETCONSOLE
156 int nc_input_packet(uchar
*pkt
, unsigned dest
, unsigned src
, unsigned len
);
159 uchar PktBuf
[(PKTBUFSRX
+1) * PKTSIZE_ALIGN
+ PKTALIGN
];
161 uchar
*NetRxPackets
[PKTBUFSRX
]; /* Receive packets */
163 static rxhand_f
*packetHandler
; /* Current RX packet handler */
164 static thand_f
*timeHandler
; /* Current timeout handler */
165 static uint64_t timeStart
; /* Time base value */
166 static uint64_t timeDelta
; /* Current timeout value */
167 uchar
*NetTxPacket
= 0; /* THE transmit packet */
169 static int net_check_prereq (proto_t protocol
);
171 /**********************************************************************/
173 IPaddr_t NetArpWaitPacketIP
;
174 IPaddr_t NetArpWaitReplyIP
;
175 uchar
*NetArpWaitPacketMAC
; /* MAC address of waiting packet's destination */
176 uchar
*NetArpWaitTxPacket
; /* THE transmit packet */
177 int NetArpWaitTxPacketSize
;
178 uchar NetArpWaitPacketBuf
[PKTSIZE_ALIGN
+ PKTALIGN
];
179 uint64_t NetArpWaitTimerStart
;
182 void ArpRequest (void)
189 printf ("ARP broadcast %d\n", NetArpWaitTry
);
193 pkt
+= NetSetEther (pkt
, NetBcastAddr
, PROT_ARP
);
197 arp
->ar_hrd
= htons (ARP_ETHER
);
198 arp
->ar_pro
= htons (PROT_IP
);
201 arp
->ar_op
= htons (ARPOP_REQUEST
);
203 memcpy (&arp
->ar_data
[0], NetOurEther
, 6); /* source ET addr */
204 NetWriteIP ((uchar
*) & arp
->ar_data
[6], NetOurIP
); /* source IP addr */
205 for (i
= 10; i
< 16; ++i
) {
206 arp
->ar_data
[i
] = 0; /* dest ET addr = 0 */
209 if ((NetArpWaitPacketIP
& NetOurSubnetMask
) !=
210 (NetOurIP
& NetOurSubnetMask
)) {
211 if (NetOurGatewayIP
== 0) {
212 puts ("## Warning: gatewayip needed but not set\n");
213 NetArpWaitReplyIP
= NetArpWaitPacketIP
;
215 NetArpWaitReplyIP
= NetOurGatewayIP
;
218 NetArpWaitReplyIP
= NetArpWaitPacketIP
;
221 NetWriteIP ((uchar
*) & arp
->ar_data
[16], NetArpWaitReplyIP
);
222 (void) eth_send (NetTxPacket
, (pkt
- NetTxPacket
) + ARP_HDR_SIZE
);
225 void ArpTimeoutCheck(void)
227 if (!NetArpWaitPacketIP
)
230 /* check for arp timeout */
231 if (is_timeout(NetArpWaitTimerStart
, ARP_TIMEOUT
)) {
234 if (NetArpWaitTry
>= ARP_TIMEOUT_COUNT
) {
235 puts ("\nARP Retry count exceeded; starting again\n");
239 NetArpWaitTimerStart
= get_time_ns();
245 /**********************************************************************/
247 * Main network processing loop.
251 NetLoop(proto_t protocol
)
253 struct eth_device
*eth_current
= eth_get_current();
257 printf("Current ethernet device not set!\n");
261 ip
= dev_get_param_ip(ð_current
->dev
, "ipaddr");
262 NetCopyIP(&NetOurIP
, &ip
);
264 /* XXX problem with bss workaround */
265 NetArpWaitPacketMAC
= NULL
;
266 NetArpWaitTxPacket
= NULL
;
267 NetArpWaitPacketIP
= 0;
268 NetArpWaitReplyIP
= 0;
269 NetArpWaitTxPacket
= NULL
;
275 * Setup packet buffers, aligned correctly.
277 NetTxPacket
= &PktBuf
[0] + (PKTALIGN
- 1);
278 NetTxPacket
-= (ulong
)NetTxPacket
% PKTALIGN
;
279 for (i
= 0; i
< PKTBUFSRX
; i
++) {
280 NetRxPackets
[i
] = NetTxPacket
+ (i
+1)*PKTSIZE_ALIGN
;
284 if (!NetArpWaitTxPacket
) {
285 NetArpWaitTxPacket
= &NetArpWaitPacketBuf
[0] + (PKTALIGN
- 1);
286 NetArpWaitTxPacket
-= (ulong
)NetArpWaitTxPacket
% PKTALIGN
;
287 NetArpWaitTxPacketSize
= 0;
294 string_to_ethaddr(dev_get_param(ð_get_current()->dev
, "ethaddr"),
297 NetState
= NETLOOP_CONTINUE
;
299 NetOurGatewayIP
= dev_get_param_ip(ð_current
->dev
, "gateway");
300 NetOurSubnetMask
= dev_get_param_ip(ð_current
->dev
, "netmask");
301 NetOurVLAN
= getenv_VLAN("vlan");
302 NetOurNativeVLAN
= getenv_VLAN("nvlan");
303 NetServerIP
= dev_get_param_ip(ð_current
->dev
, "serverip");
306 * Start the ball rolling with the given start function. From
307 * here on, this code is a state machine driven by received
308 * packets and timer events.
311 switch (net_check_prereq (protocol
)) {
313 /* network not configured */
318 #ifdef CONFIG_NET_TFTP
320 /* always use ARP to get server ethernet address */
324 #ifdef CONFIG_NET_DHCP
326 /* Start with a clean slate... */
329 DhcpRequest(); /* Basically same as BOOTP */
332 #ifdef CONFIG_NET_BOOTP
338 #ifdef CONFIG_NET_RARP
345 #ifdef CONFIG_NET_PING
350 #ifdef CONFIG_NET_NFS
355 #ifdef CONFIG_NETCONSOLE
360 #ifdef CONFIG_NET_SNTP
369 NetBootFileXferSize
= 0;
374 * Main packet reception loop. Loop receiving packets until
375 * someone sets `NetState' to a state that terminates.
379 #ifdef CONFIG_SHOW_ACTIVITY
381 extern void show_activity(int arg
);
386 * Check the ethernet for a new packet. The ethernet
387 * receive routine will process it.
392 * Abort if ctrl-c was pressed.
403 * Check for a timeout, and run the timeout handler
406 if (timeHandler
&& is_timeout(timeStart
, timeDelta
)) {
409 timeHandler
= (thand_f
*)0;
416 case NETLOOP_RESTART
:
419 case NETLOOP_SUCCESS
:
420 if (NetBootFileXferSize
> 0) {
422 printf("Bytes transferred = %ld (%lx hex)\n",
424 NetBootFileXferSize
);
425 sprintf(buf
, "0x%lx", NetBootFileXferSize
);
426 setenv("filesize", buf
);
429 return NetBootFileXferSize
;
438 /**********************************************************************/
441 startAgainTimeout(void)
443 NetState
= NETLOOP_RESTART
;
447 startAgainHandler(uchar
* pkt
, unsigned dest
, unsigned src
, unsigned len
)
449 /* Totally ignore the packet */
452 void NetStartAgain (void)
455 int noretry
= 0, once
= 0;
457 if ((nretry
= getenv ("netretry")) != NULL
) {
458 noretry
= (strcmp (nretry
, "no") == 0);
459 once
= (strcmp (nretry
, "once") == 0);
463 NetState
= NETLOOP_FAIL
;
466 NetSetTimeout (10 * SECOND
, startAgainTimeout
);
467 NetSetHandler (startAgainHandler
);
470 /**********************************************************************/
476 NetSetHandler(rxhand_f
* f
)
483 NetSetTimeout(uint64_t iv
, thand_f
* f
)
486 timeHandler
= (thand_f
*)0;
489 timeStart
= get_time_ns();
496 NetSendPacket(uchar
* pkt
, int len
)
498 (void) eth_send(pkt
, len
);
502 NetSendUDPPacket(uchar
*ether
, IPaddr_t dest
, int dport
, int sport
, int len
)
506 /* convert to new style broadcast */
510 /* if broadcast, make the ether address a broadcast and don't do ARP */
511 if (dest
== 0xFFFFFFFF)
512 ether
= NetBcastAddr
;
514 /* if MAC address was not discovered yet, save the packet and do an ARP request */
515 if (memcmp(ether
, NetEtherNullAddr
, 6) == 0) {
518 printf("sending ARP for %08lx\n", dest
);
520 NetArpWaitPacketIP
= dest
;
521 NetArpWaitPacketMAC
= ether
;
523 pkt
= NetArpWaitTxPacket
;
524 pkt
+= NetSetEther (pkt
, NetArpWaitPacketMAC
, PROT_IP
);
526 NetSetIP (pkt
, dest
, dport
, sport
, len
);
527 memcpy(pkt
+ IP_HDR_SIZE
, (uchar
*)NetTxPacket
+ (pkt
- (uchar
*)NetArpWaitTxPacket
) + IP_HDR_SIZE
, len
);
529 /* size of the waiting packet */
530 NetArpWaitTxPacketSize
= (pkt
- NetArpWaitTxPacket
) + IP_HDR_SIZE
+ len
;
532 /* and do the ARP request */
534 NetArpWaitTimerStart
= get_time_ns();
536 return 1; /* waiting */
540 printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n",
541 dest
, ether
[0], ether
[1], ether
[2], ether
[3], ether
[4], ether
[5]);
544 pkt
= (uchar
*)NetTxPacket
;
545 pkt
+= NetSetEther (pkt
, ether
, PROT_IP
);
546 NetSetIP (pkt
, dest
, dport
, sport
, len
);
547 (void) eth_send(NetTxPacket
, (pkt
- NetTxPacket
) + IP_HDR_SIZE
+ len
);
549 return 0; /* transmitted */
553 NetReceive(uchar
* inpkt
, int len
)
561 ushort cti
= 0, vlanid
= VLAN_NONE
, myvlanid
, mynvlanid
;
564 printf("packet received\n");
569 et
= (Ethernet_t
*)inpkt
;
571 /* too small packet? */
572 if (len
< ETHER_HDR_SIZE
)
575 myvlanid
= ntohs(NetOurVLAN
);
576 if (myvlanid
== (ushort
)-1)
577 myvlanid
= VLAN_NONE
;
578 mynvlanid
= ntohs(NetOurNativeVLAN
);
579 if (mynvlanid
== (ushort
)-1)
580 mynvlanid
= VLAN_NONE
;
582 x
= ntohs(et
->et_protlen
);
585 printf("packet received\n");
590 * Got a 802 packet. Check the other protocol field.
592 x
= ntohs(et
->et_prot
);
594 ip
= (IP_t
*)(inpkt
+ E802_HDR_SIZE
);
595 len
-= E802_HDR_SIZE
;
597 } else if (x
!= PROT_VLAN
) { /* normal packet */
598 ip
= (IP_t
*)(inpkt
+ ETHER_HDR_SIZE
);
599 len
-= ETHER_HDR_SIZE
;
601 } else { /* VLAN packet */
602 VLAN_Ethernet_t
*vet
= (VLAN_Ethernet_t
*)et
;
605 printf("VLAN packet received\n");
607 /* too small packet? */
608 if (len
< VLAN_ETHER_HDR_SIZE
)
611 /* if no VLAN active */
612 if ((ntohs(NetOurVLAN
) & VLAN_IDMASK
) == VLAN_NONE
616 cti
= ntohs(vet
->vet_tag
);
617 vlanid
= cti
& VLAN_IDMASK
;
618 x
= ntohs(vet
->vet_type
);
620 ip
= (IP_t
*)(inpkt
+ VLAN_ETHER_HDR_SIZE
);
621 len
-= VLAN_ETHER_HDR_SIZE
;
625 printf("Receive from protocol 0x%x\n", x
);
628 if ((myvlanid
& VLAN_IDMASK
) != VLAN_NONE
) {
629 if (vlanid
== VLAN_NONE
)
630 vlanid
= (mynvlanid
& VLAN_IDMASK
);
632 if (vlanid
!= (myvlanid
& VLAN_IDMASK
))
640 * We have to deal with two types of ARP packets:
641 * - REQUEST packets will be answered by sending our
642 * IP address - if we know it.
643 * - REPLY packets are expected only after we asked
644 * for the TFTP server's or the gateway's ethernet
645 * address; so if we receive such a packet, we set
646 * the server ethernet address
652 if (len
< ARP_HDR_SIZE
) {
653 printf("bad length %d < %d\n", len
, ARP_HDR_SIZE
);
656 if (ntohs(arp
->ar_hrd
) != ARP_ETHER
) {
659 if (ntohs(arp
->ar_pro
) != PROT_IP
) {
662 if (arp
->ar_hln
!= 6) {
665 if (arp
->ar_pln
!= 4) {
673 if (NetReadIP(&arp
->ar_data
[16]) != NetOurIP
) {
677 switch (ntohs(arp
->ar_op
)) {
678 case ARPOP_REQUEST
: /* reply with our IP address */
680 puts ("Got ARP REQUEST, return our IP\n");
683 pkt
+= NetSetEther(pkt
, et
->et_src
, PROT_ARP
);
684 arp
->ar_op
= htons(ARPOP_REPLY
);
685 memcpy (&arp
->ar_data
[10], &arp
->ar_data
[0], 6);
686 NetCopyIP(&arp
->ar_data
[16], &arp
->ar_data
[6]);
687 memcpy (&arp
->ar_data
[ 0], NetOurEther
, 6);
688 NetCopyIP(&arp
->ar_data
[ 6], &NetOurIP
);
689 (void) eth_send((uchar
*)et
, (pkt
- (uchar
*)et
) + ARP_HDR_SIZE
);
692 case ARPOP_REPLY
: /* arp reply */
693 /* are we waiting for a reply */
694 if (!NetArpWaitPacketIP
|| !NetArpWaitPacketMAC
)
697 printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",
698 arp
->ar_data
[0], arp
->ar_data
[1],
699 arp
->ar_data
[2], arp
->ar_data
[3],
700 arp
->ar_data
[4], arp
->ar_data
[5]);
703 tmp
= NetReadIP(&arp
->ar_data
[6]);
705 /* matched waiting packet's address */
706 if (tmp
== NetArpWaitReplyIP
) {
710 /* save address for later use */
711 memcpy(NetArpWaitPacketMAC
, &arp
->ar_data
[0], 6);
713 #ifdef CONFIG_NETCONSOLE
714 (*packetHandler
)(0,0,0,0);
716 /* modify header, and transmit it */
717 memcpy(((Ethernet_t
*)NetArpWaitTxPacket
)->et_dest
, NetArpWaitPacketMAC
, 6);
718 (void) eth_send(NetArpWaitTxPacket
, NetArpWaitTxPacketSize
);
720 /* no arp request pending now */
721 NetArpWaitPacketIP
= 0;
722 NetArpWaitTxPacketSize
= 0;
723 NetArpWaitPacketMAC
= NULL
;
729 printf("Unexpected ARP opcode 0x%x\n", ntohs(arp
->ar_op
));
740 if (len
< ARP_HDR_SIZE
) {
741 printf("bad length %d < %d\n", len
, ARP_HDR_SIZE
);
745 if ((ntohs(arp
->ar_op
) != RARPOP_REPLY
) ||
746 (ntohs(arp
->ar_hrd
) != ARP_ETHER
) ||
747 (ntohs(arp
->ar_pro
) != PROT_IP
) ||
748 (arp
->ar_hln
!= 6) || (arp
->ar_pln
!= 4)) {
750 puts ("invalid RARP header\n");
752 NetCopyIP(&NetOurIP
, &arp
->ar_data
[16]);
753 if (NetServerIP
== 0)
754 NetCopyIP(&NetServerIP
, &arp
->ar_data
[ 6]);
755 memcpy (NetServerEther
, &arp
->ar_data
[ 0], 6);
757 (*packetHandler
)(0,0,0,0);
765 if (len
< IP_HDR_SIZE
) {
766 debug ("len bad %d < %d\n", len
, IP_HDR_SIZE
);
769 if (len
< ntohs(ip
->ip_len
)) {
770 printf("len bad %d < %d\n", len
, ntohs(ip
->ip_len
));
773 len
= ntohs(ip
->ip_len
);
775 printf("len=%d, v=%02x\n", len
, ip
->ip_hl_v
& 0xff);
777 if ((ip
->ip_hl_v
& 0xf0) != 0x40) {
780 if (ip
->ip_off
& htons(0x1fff)) { /* Can't deal w/ fragments */
783 if (!NetCksumOk((uchar
*)ip
, IP_HDR_SIZE_NO_UDP
/ 2)) {
784 puts ("checksum bad\n");
787 tmp
= NetReadIP(&ip
->ip_dst
);
788 if (NetOurIP
&& tmp
!= NetOurIP
&& tmp
!= 0xFFFFFFFF) {
792 * watch for ICMP host redirects
794 * There is no real handler code (yet). We just watch
795 * for ICMP host redirect messages. In case anybody
796 * sees these messages: please contact me
797 * (wd@denx.de), or - even better - send me the
798 * necessary fixes :-)
800 * Note: in all cases where I have seen this so far
801 * it was a problem with the router configuration,
802 * for instance when a router was configured in the
803 * BOOTP reply, but the TFTP server was on the same
804 * subnet. So this is probably a warning that your
805 * configuration might be wrong. But I'm not really
806 * sure if there aren't any other situations.
808 if (ip
->ip_p
== IPPROTO_ICMP
) {
809 ICMP_t
*icmph
= (ICMP_t
*)&(ip
->udp_src
);
811 switch (icmph
->type
) {
813 if (icmph
->code
!= ICMP_REDIR_HOST
)
815 puts (" ICMP Host Redirect to ");
816 print_IPaddr(icmph
->un
.gateway
);
819 #ifdef CONFIG_NET_PING
820 case ICMP_ECHO_REPLY
:
822 * IP header OK. Pass the packet to the current handler.
824 /* XXX point to ip packet */
825 (*packetHandler
)((uchar
*)ip
, 0, 0, 0);
831 } else if (ip
->ip_p
!= IPPROTO_UDP
) { /* Only UDP packets */
835 #ifdef CONFIG_UDP_CHECKSUM
836 if (ip
->udp_xsum
!= 0) {
842 xsum
+= (ntohs(ip
->udp_len
));
843 xsum
+= (ntohl(ip
->ip_src
) >> 16) & 0x0000ffff;
844 xsum
+= (ntohl(ip
->ip_src
) >> 0) & 0x0000ffff;
845 xsum
+= (ntohl(ip
->ip_dst
) >> 16) & 0x0000ffff;
846 xsum
+= (ntohl(ip
->ip_dst
) >> 0) & 0x0000ffff;
848 sumlen
= ntohs(ip
->udp_len
);
849 sumptr
= (ushort
*) &(ip
->udp_src
);
855 xsum
+= ntohs(sumdata
);
861 sumdata
= *(unsigned char *) sumptr
;
862 sumdata
= (sumdata
<< 8) & 0xff00;
865 while ((xsum
>> 16) != 0) {
866 xsum
= (xsum
& 0x0000ffff) + ((xsum
>> 16) & 0x0000ffff);
868 if ((xsum
!= 0x00000000) && (xsum
!= 0x0000ffff)) {
869 printf(" UDP wrong checksum %08x %08x\n", xsum
, ntohs(ip
->udp_xsum
));
875 #ifdef CONFIG_NETCONSOLE
876 nc_input_packet((uchar
*)ip
+IP_HDR_SIZE
,
879 ntohs(ip
->udp_len
) - 8);
882 * IP header OK. Pass the packet to the current handler.
884 (*packetHandler
)((uchar
*)ip
+IP_HDR_SIZE
,
887 ntohs(ip
->udp_len
) - 8);
893 /**********************************************************************/
895 static int net_check_prereq (proto_t protocol
)
897 struct eth_device
*edev
= eth_get_current();
901 #ifdef CONFIG_NET_PING
903 if (NetPingIP
== 0) {
904 puts ("*** ERROR: ping address not given\n");
909 #ifdef CONFIG_NET_SNTP
911 if (NetNtpServerIP
== 0) {
912 puts ("*** ERROR: NTP server address not given\n");
917 #ifdef CONFIG_NET_NFS
922 if (NetServerIP
== 0) {
923 printf("*** ERROR: `%s.serverip' not set\n", dev_id(&edev
->dev
));
929 printf("*** ERROR: `%s.ipaddr' not set\n", dev_id(&edev
->dev
));
937 if (memcmp (NetOurEther
, "\0\0\0\0\0\0", 6) == 0) {
938 printf("*** ERROR: `%s.ethaddr' not set\n", dev_id(&edev
->dev
));
947 /**********************************************************************/
950 NetCksumOk(uchar
* ptr
, int len
)
952 return !((NetCksum(ptr
, len
) + 1) & 0xfffe);
957 NetCksum(uchar
* ptr
, int len
)
960 ushort
*p
= (ushort
*)ptr
;
965 xsum
= (xsum
& 0xffff) + (xsum
>> 16);
966 xsum
= (xsum
& 0xffff) + (xsum
>> 16);
967 return (xsum
& 0xffff);
975 myvlanid
= ntohs(NetOurVLAN
);
976 if (myvlanid
== (ushort
)-1)
977 myvlanid
= VLAN_NONE
;
979 return ((myvlanid
& VLAN_IDMASK
) == VLAN_NONE
) ? ETHER_HDR_SIZE
: VLAN_ETHER_HDR_SIZE
;
983 NetSetEther(uchar
* xet
, uchar
* addr
, uint prot
)
985 Ethernet_t
*et
= (Ethernet_t
*)xet
;
988 myvlanid
= ntohs(NetOurVLAN
);
989 if (myvlanid
== (ushort
)-1)
990 myvlanid
= VLAN_NONE
;
992 memcpy (et
->et_dest
, addr
, 6);
993 memcpy (et
->et_src
, NetOurEther
, 6);
994 if ((myvlanid
& VLAN_IDMASK
) == VLAN_NONE
) {
995 et
->et_protlen
= htons(prot
);
996 return ETHER_HDR_SIZE
;
998 VLAN_Ethernet_t
*vet
= (VLAN_Ethernet_t
*)xet
;
1000 vet
->vet_vlan_type
= htons(PROT_VLAN
);
1001 vet
->vet_tag
= htons((0 << 5) | (myvlanid
& VLAN_IDMASK
));
1002 vet
->vet_type
= htons(prot
);
1003 return VLAN_ETHER_HDR_SIZE
;
1008 NetSetIP(uchar
* xip
, IPaddr_t dest
, int dport
, int sport
, int len
)
1010 IP_t
*ip
= (IP_t
*)xip
;
1013 * If the data is an odd number of bytes, zero the
1014 * byte after the last byte so that the checksum
1018 xip
[IP_HDR_SIZE
+ len
] = 0;
1021 * Construct an IP and UDP header.
1022 * (need to set no fragment bit - XXX)
1024 ip
->ip_hl_v
= 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */
1026 ip
->ip_len
= htons(IP_HDR_SIZE
+ len
);
1027 ip
->ip_id
= htons(NetIPID
++);
1028 ip
->ip_off
= htons(0x4000); /* No fragmentation */
1030 ip
->ip_p
= 17; /* UDP */
1032 NetCopyIP((void*)&ip
->ip_src
, &NetOurIP
); /* already in network byte order */
1033 NetCopyIP((void*)&ip
->ip_dst
, &dest
); /* - "" - */
1034 ip
->udp_src
= htons(sport
);
1035 ip
->udp_dst
= htons(dport
);
1036 ip
->udp_len
= htons(8 + len
);
1038 ip
->ip_sum
= ~NetCksum((uchar
*)ip
, IP_HDR_SIZE_NO_UDP
/ 2);
1041 char *ip_to_string (IPaddr_t x
, char *s
)
1044 sprintf (s
, "%d.%d.%d.%d",
1045 (int) ((x
>> 24) & 0xff),
1046 (int) ((x
>> 16) & 0xff),
1047 (int) ((x
>> 8) & 0xff), (int) ((x
>> 0) & 0xff)
1052 int string_to_ip(const char *s
, IPaddr_t
*ip
)
1061 for (i
= 0; i
< 4; i
++) {
1067 val
= simple_strtoul(s
, &e
, 10);
1069 addr
|= (val
& 0xFF);
1071 if (*e
!= '.' && i
!= 3)
1081 void VLAN_to_string(ushort x
, char *s
)
1085 if (x
== (ushort
)-1)
1091 sprintf(s
, "%d", x
& VLAN_IDMASK
);
1094 ushort
string_to_VLAN(const char *s
)
1099 return htons(VLAN_NONE
);
1101 if (*s
< '0' || *s
> '9')
1104 id
= (ushort
)simple_strtoul(s
, NULL
, 10);
1109 void print_IPaddr (IPaddr_t x
)
1113 ip_to_string (x
, tmp
);
1118 ushort
getenv_VLAN(char *var
)
1120 return (string_to_VLAN(getenv(var
)));
1123 int string_to_ethaddr(const char *str
, char *enetaddr
)
1128 if (!str
|| strlen(str
) != 17)
1131 if (str
[2] != ':' || str
[5] != ':' || str
[8] != ':' ||
1132 str
[11] != ':' || str
[14] != ':')
1135 for (reg
= 0; reg
< 6; ++reg
) {
1136 enetaddr
[reg
] = simple_strtoul (str
, &e
, 16);
1143 void ethaddr_to_string(const unsigned char *enetaddr
, char *str
)
1145 sprintf (str
, "%02X:%02X:%02X:%02X:%02X:%02X",
1146 enetaddr
[0], enetaddr
[1], enetaddr
[2], enetaddr
[3],
1147 enetaddr
[4], enetaddr
[5]);