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
75 #include <environment.h>
80 #include <linux/ctype.h>
85 #define ARP_TIMEOUT (5 * SECOND) /* Seconds before trying ARP again */
86 #ifndef CONFIG_NET_RETRY_COUNT
87 # define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */
89 # define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
93 /** BOOTP EXTENTIONS **/
95 IPaddr_t NetOurSubnetMask
=0; /* Our subnet mask (0=unknown) */
96 IPaddr_t NetOurGatewayIP
=0; /* Our gateways IP address */
97 IPaddr_t NetOurDNSIP
=0; /* Our DNS IP address */
98 #ifdef CONFIG_BOOTP_DNS2
99 IPaddr_t NetOurDNS2IP
=0; /* Our 2nd DNS IP address */
101 char NetOurNISDomain
[32]={0,}; /* Our NIS domain */
102 char NetOurHostName
[32]={0,}; /* Our hostname */
103 char NetOurRootPath
[64]={0,}; /* Our bootpath */
105 /** END OF BOOTP EXTENTIONS **/
107 ulong NetBootFileXferSize
; /* The actual transferred size of the bootfile (in bytes) */
108 uchar NetOurEther
[6]; /* Our ethernet address */
109 uchar NetServerEther
[6] = /* Boot server enet address */
110 { 0, 0, 0, 0, 0, 0 };
111 IPaddr_t NetOurIP
; /* Our IP addr (0 = unknown) */
112 IPaddr_t NetServerIP
; /* Our IP addr (0 = unknown) */
113 uchar
*NetRxPkt
; /* Current receive packet */
114 int NetRxPktLen
; /* Current rx packet length */
115 unsigned NetIPID
; /* IP packet ID */
116 uchar NetBcastAddr
[6] = /* Ethernet bcast address */
117 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
118 uchar NetEtherNullAddr
[6] =
119 { 0, 0, 0, 0, 0, 0 };
120 int NetState
; /* Network loop state */
122 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
123 ushort NetOurVLAN
= 0xFFFF; /* default is without VLAN */
124 ushort NetOurNativeVLAN
= 0xFFFF; /* ditto */
126 char BootFile
[128]; /* Boot File name */
128 uchar PktBuf
[(PKTBUFSRX
+1) * PKTSIZE_ALIGN
+ PKTALIGN
];
130 uchar
*NetRxPackets
[PKTBUFSRX
]; /* Receive packets */
132 static rxhand_f
*packetHandler
; /* Current RX packet handler */
133 static thand_f
*timeHandler
; /* Current timeout handler */
134 static uint64_t timeStart
; /* Time base value */
135 static uint64_t timeDelta
; /* Current timeout value */
136 uchar
*NetTxPacket
= 0; /* THE transmit packet */
138 static int net_check_prereq (proto_t protocol
);
140 /**********************************************************************/
142 IPaddr_t NetArpWaitPacketIP
;
143 IPaddr_t NetArpWaitReplyIP
;
144 uchar
*NetArpWaitPacketMAC
; /* MAC address of waiting packet's destination */
145 uchar
*NetArpWaitTxPacket
; /* THE transmit packet */
146 int NetArpWaitTxPacketSize
;
147 uchar NetArpWaitPacketBuf
[PKTSIZE_ALIGN
+ PKTALIGN
];
148 uint64_t NetArpWaitTimerStart
;
150 void ArpRequest (void)
156 pr_debug("ARP broadcast\n");
160 pkt
+= NetSetEther (pkt
, NetBcastAddr
, PROT_ARP
);
164 arp
->ar_hrd
= htons (ARP_ETHER
);
165 arp
->ar_pro
= htons (PROT_IP
);
168 arp
->ar_op
= htons (ARPOP_REQUEST
);
170 memcpy (&arp
->ar_data
[0], NetOurEther
, 6); /* source ET addr */
171 NetWriteIP ((uchar
*) & arp
->ar_data
[6], NetOurIP
); /* source IP addr */
172 for (i
= 10; i
< 16; ++i
) {
173 arp
->ar_data
[i
] = 0; /* dest ET addr = 0 */
176 if ((NetArpWaitPacketIP
& NetOurSubnetMask
) !=
177 (NetOurIP
& NetOurSubnetMask
)) {
178 if (NetOurGatewayIP
== 0) {
179 puts ("## Warning: gatewayip needed but not set\n");
180 NetArpWaitReplyIP
= NetArpWaitPacketIP
;
182 NetArpWaitReplyIP
= NetOurGatewayIP
;
185 NetArpWaitReplyIP
= NetArpWaitPacketIP
;
188 NetWriteIP ((uchar
*) & arp
->ar_data
[16], NetArpWaitReplyIP
);
189 (void) eth_send (NetTxPacket
, (pkt
- NetTxPacket
) + ARP_HDR_SIZE
);
192 /**********************************************************************/
194 * Main network processing loop.
197 int NetLoopInit(proto_t protocol
)
199 struct eth_device
*eth_current
= eth_get_current();
205 printf("Current ethernet device not set!\n");
209 ip
= dev_get_param_ip(ð_current
->dev
, "ipaddr");
210 NetCopyIP(&NetOurIP
, &ip
);
212 /* XXX problem with bss workaround */
213 NetArpWaitPacketMAC
= NULL
;
214 NetArpWaitTxPacket
= NULL
;
215 NetArpWaitPacketIP
= 0;
216 NetArpWaitReplyIP
= 0;
219 * Setup packet buffers, aligned correctly.
221 NetTxPacket
= &PktBuf
[0] + (PKTALIGN
- 1);
222 NetTxPacket
-= (ulong
)NetTxPacket
% PKTALIGN
;
223 for (i
= 0; i
< PKTBUFSRX
; i
++) {
224 NetRxPackets
[i
] = NetTxPacket
+ (i
+1)*PKTSIZE_ALIGN
;
227 NetArpWaitTxPacket
= &NetArpWaitPacketBuf
[0] + (PKTALIGN
- 1);
228 NetArpWaitTxPacket
-= (ulong
)NetArpWaitTxPacket
% PKTALIGN
;
229 NetArpWaitTxPacketSize
= 0;
231 string_to_ethaddr(dev_get_param(ð_get_current()->dev
, "ethaddr"),
234 NetState
= NETLOOP_CONTINUE
;
236 NetOurGatewayIP
= dev_get_param_ip(ð_current
->dev
, "gateway");
237 NetOurSubnetMask
= dev_get_param_ip(ð_current
->dev
, "netmask");
238 NetOurVLAN
= getenv_VLAN("vlan");
239 NetOurNativeVLAN
= getenv_VLAN("nvlan");
240 NetServerIP
= dev_get_param_ip(ð_current
->dev
, "serverip");
242 ret
= net_check_prereq(protocol
);
250 * Start the ball rolling with the given start function. From
251 * here on, this code is a state machine driven by received
252 * packets and timer events.
255 NetBootFileXferSize
= 0;
258 * Main packet reception loop. Loop receiving packets until
259 * someone sets `NetState' to a state that terminates.
263 #ifdef CONFIG_SHOW_ACTIVITY
265 extern void show_activity(int arg
);
270 * Check the ethernet for a new packet. The ethernet
271 * receive routine will process it.
276 * Abort if ctrl-c was pressed.
283 /* check for arp timeout */
284 if (NetArpWaitPacketIP
&&
285 is_timeout(NetArpWaitTimerStart
, ARP_TIMEOUT
)) {
286 NetArpWaitTimerStart
= get_time_ns();
291 * Check for a timeout, and run the timeout handler
294 if (timeHandler
&& is_timeout(timeStart
, timeDelta
)) {
297 timeHandler
= (thand_f
*)0;
303 case NETLOOP_SUCCESS
:
304 if (NetBootFileXferSize
> 0) {
306 printf("Bytes transferred = %ld (%lx hex)\n",
308 NetBootFileXferSize
);
309 sprintf(buf
, "0x%lx", NetBootFileXferSize
);
310 setenv("filesize", buf
);
312 return NetBootFileXferSize
;
320 /**********************************************************************/
326 NetSetHandler(rxhand_f
* f
)
333 NetSetTimeout(uint64_t iv
, thand_f
* f
)
336 timeHandler
= (thand_f
*)0;
339 timeStart
= get_time_ns();
346 NetSendPacket(uchar
* pkt
, int len
)
348 (void) eth_send(pkt
, len
);
352 NetSendUDPPacket(uchar
*ether
, IPaddr_t dest
, int dport
, int sport
, int len
)
356 /* convert to new style broadcast */
360 /* if broadcast, make the ether address a broadcast and don't do ARP */
361 if (dest
== 0xFFFFFFFF)
362 ether
= NetBcastAddr
;
364 /* if MAC address was not discovered yet, save the packet and do an ARP request */
365 if (memcmp(ether
, NetEtherNullAddr
, 6) == 0) {
366 pr_debug("sending ARP for %08lx\n", dest
);
368 NetArpWaitPacketIP
= dest
;
369 NetArpWaitPacketMAC
= ether
;
371 pkt
= NetArpWaitTxPacket
;
372 pkt
+= NetSetEther (pkt
, NetArpWaitPacketMAC
, PROT_IP
);
374 NetSetIP (pkt
, dest
, dport
, sport
, len
);
375 memcpy(pkt
+ IP_HDR_SIZE
, (uchar
*)NetTxPacket
+ (pkt
- (uchar
*)NetArpWaitTxPacket
) + IP_HDR_SIZE
, len
);
377 /* size of the waiting packet */
378 NetArpWaitTxPacketSize
= (pkt
- NetArpWaitTxPacket
) + IP_HDR_SIZE
+ len
;
380 /* and do the ARP request */
381 NetArpWaitTimerStart
= get_time_ns();
383 return 1; /* waiting */
386 pr_debug("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n",
387 dest
, ether
[0], ether
[1], ether
[2], ether
[3], ether
[4], ether
[5]);
389 pkt
= (uchar
*)NetTxPacket
;
390 pkt
+= NetSetEther (pkt
, ether
, PROT_IP
);
391 NetSetIP (pkt
, dest
, dport
, sport
, len
);
392 (void) eth_send(NetTxPacket
, (pkt
- NetTxPacket
) + IP_HDR_SIZE
+ len
);
394 return 0; /* transmitted */
398 NetReceive(uchar
* inpkt
, int len
)
406 ushort cti
= 0, vlanid
= VLAN_NONE
, myvlanid
, mynvlanid
;
408 pr_debug("packet received\n");
412 et
= (Ethernet_t
*)inpkt
;
414 /* too small packet? */
415 if (len
< ETHER_HDR_SIZE
)
418 myvlanid
= ntohs(NetOurVLAN
);
419 if (myvlanid
== (ushort
)-1)
420 myvlanid
= VLAN_NONE
;
421 mynvlanid
= ntohs(NetOurNativeVLAN
);
422 if (mynvlanid
== (ushort
)-1)
423 mynvlanid
= VLAN_NONE
;
425 x
= ntohs(et
->et_protlen
);
427 pr_debug("packet received\n");
431 * Got a 802 packet. Check the other protocol field.
433 x
= ntohs(et
->et_prot
);
435 ip
= (IP_t
*)(inpkt
+ E802_HDR_SIZE
);
436 len
-= E802_HDR_SIZE
;
438 } else if (x
!= PROT_VLAN
) { /* normal packet */
439 ip
= (IP_t
*)(inpkt
+ ETHER_HDR_SIZE
);
440 len
-= ETHER_HDR_SIZE
;
442 } else { /* VLAN packet */
443 VLAN_Ethernet_t
*vet
= (VLAN_Ethernet_t
*)et
;
445 pr_debug("VLAN packet received\n");
447 /* too small packet? */
448 if (len
< VLAN_ETHER_HDR_SIZE
)
451 /* if no VLAN active */
452 if ((ntohs(NetOurVLAN
) & VLAN_IDMASK
) == VLAN_NONE
456 cti
= ntohs(vet
->vet_tag
);
457 vlanid
= cti
& VLAN_IDMASK
;
458 x
= ntohs(vet
->vet_type
);
460 ip
= (IP_t
*)(inpkt
+ VLAN_ETHER_HDR_SIZE
);
461 len
-= VLAN_ETHER_HDR_SIZE
;
464 pr_debug("Receive from protocol 0x%x\n", x
);
466 if ((myvlanid
& VLAN_IDMASK
) != VLAN_NONE
) {
467 if (vlanid
== VLAN_NONE
)
468 vlanid
= (mynvlanid
& VLAN_IDMASK
);
470 if (vlanid
!= (myvlanid
& VLAN_IDMASK
))
478 * We have to deal with two types of ARP packets:
479 * - REQUEST packets will be answered by sending our
480 * IP address - if we know it.
481 * - REPLY packets are expected only after we asked
482 * for the TFTP server's or the gateway's ethernet
483 * address; so if we receive such a packet, we set
484 * the server ethernet address
486 pr_debug("Got ARP\n");
489 if (len
< ARP_HDR_SIZE
) {
490 printf("bad length %d < %d\n", len
, ARP_HDR_SIZE
);
493 if (ntohs(arp
->ar_hrd
) != ARP_ETHER
) {
496 if (ntohs(arp
->ar_pro
) != PROT_IP
) {
499 if (arp
->ar_hln
!= 6) {
502 if (arp
->ar_pln
!= 4) {
510 if (NetReadIP(&arp
->ar_data
[16]) != NetOurIP
) {
514 switch (ntohs(arp
->ar_op
)) {
515 case ARPOP_REQUEST
: /* reply with our IP address */
516 pr_debug("Got ARP REQUEST, return our IP\n");
519 pkt
+= NetSetEther(pkt
, et
->et_src
, PROT_ARP
);
520 arp
->ar_op
= htons(ARPOP_REPLY
);
521 memcpy (&arp
->ar_data
[10], &arp
->ar_data
[0], 6);
522 NetCopyIP(&arp
->ar_data
[16], &arp
->ar_data
[6]);
523 memcpy (&arp
->ar_data
[ 0], NetOurEther
, 6);
524 NetCopyIP(&arp
->ar_data
[ 6], &NetOurIP
);
525 memcpy(NetTxPacket
, et
, (pkt
- (uchar
*)et
) + ARP_HDR_SIZE
);
526 eth_send((uchar
*)NetTxPacket
, (pkt
- (uchar
*)et
) + ARP_HDR_SIZE
);
529 case ARPOP_REPLY
: /* arp reply */
530 /* are we waiting for a reply */
531 if (!NetArpWaitPacketIP
|| !NetArpWaitPacketMAC
)
533 pr_debug("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",
534 arp
->ar_data
[0], arp
->ar_data
[1],
535 arp
->ar_data
[2], arp
->ar_data
[3],
536 arp
->ar_data
[4], arp
->ar_data
[5]);
538 tmp
= NetReadIP(&arp
->ar_data
[6]);
540 /* matched waiting packet's address */
541 if (tmp
== NetArpWaitReplyIP
) {
542 pr_debug("Got it\n");
544 /* save address for later use */
545 memcpy(NetArpWaitPacketMAC
, &arp
->ar_data
[0], 6);
547 /* modify header, and transmit it */
548 memcpy(((Ethernet_t
*)NetArpWaitTxPacket
)->et_dest
, NetArpWaitPacketMAC
, 6);
549 (void) eth_send(NetArpWaitTxPacket
, NetArpWaitTxPacketSize
);
551 /* no arp request pending now */
552 NetArpWaitPacketIP
= 0;
553 NetArpWaitTxPacketSize
= 0;
554 NetArpWaitPacketMAC
= NULL
;
559 pr_debug("Unexpected ARP opcode 0x%x\n", ntohs(arp
->ar_op
));
565 pr_debug("Got RARP\n");
568 if (len
< ARP_HDR_SIZE
) {
569 printf("bad length %d < %d\n", len
, ARP_HDR_SIZE
);
573 if ((ntohs(arp
->ar_op
) != RARPOP_REPLY
) ||
574 (ntohs(arp
->ar_hrd
) != ARP_ETHER
) ||
575 (ntohs(arp
->ar_pro
) != PROT_IP
) ||
576 (arp
->ar_hln
!= 6) || (arp
->ar_pln
!= 4)) {
578 puts ("invalid RARP header\n");
580 NetCopyIP(&NetOurIP
, &arp
->ar_data
[16]);
581 if (NetServerIP
== 0)
582 NetCopyIP(&NetServerIP
, &arp
->ar_data
[ 6]);
583 memcpy (NetServerEther
, &arp
->ar_data
[ 0], 6);
585 (*packetHandler
)(0,0,0,0);
590 pr_debug("Got IP\n");
592 if (len
< IP_HDR_SIZE
) {
593 debug ("len bad %d < %d\n", len
, IP_HDR_SIZE
);
596 if (len
< ntohs(ip
->ip_len
)) {
597 printf("len bad %d < %d\n", len
, ntohs(ip
->ip_len
));
600 len
= ntohs(ip
->ip_len
);
602 pr_debug("len=%d, v=%02x\n", len
, ip
->ip_hl_v
& 0xff);
604 if ((ip
->ip_hl_v
& 0xf0) != 0x40) {
607 if (ip
->ip_off
& htons(0x1fff)) { /* Can't deal w/ fragments */
610 if (!NetCksumOk((uchar
*)ip
, IP_HDR_SIZE_NO_UDP
/ 2)) {
611 puts ("checksum bad\n");
614 tmp
= NetReadIP(&ip
->ip_dst
);
615 if (NetOurIP
&& tmp
!= NetOurIP
&& tmp
!= 0xFFFFFFFF) {
619 * watch for ICMP host redirects
621 * There is no real handler code (yet). We just watch
622 * for ICMP host redirect messages. In case anybody
623 * sees these messages: please contact me
624 * (wd@denx.de), or - even better - send me the
625 * necessary fixes :-)
627 * Note: in all cases where I have seen this so far
628 * it was a problem with the router configuration,
629 * for instance when a router was configured in the
630 * BOOTP reply, but the TFTP server was on the same
631 * subnet. So this is probably a warning that your
632 * configuration might be wrong. But I'm not really
633 * sure if there aren't any other situations.
635 if (ip
->ip_p
== IPPROTO_ICMP
) {
636 ICMP_t
*icmph
= (ICMP_t
*)&(ip
->udp_src
);
638 switch (icmph
->type
) {
640 if (icmph
->code
!= ICMP_REDIR_HOST
)
642 puts (" ICMP Host Redirect to ");
643 print_IPaddr(icmph
->un
.gateway
);
646 #ifdef CONFIG_NET_PING
647 case ICMP_ECHO_REPLY
:
649 * IP header OK. Pass the packet to the current handler.
651 /* XXX point to ip packet */
652 (*packetHandler
)((uchar
*)ip
, 0, 0, 0);
658 } else if (ip
->ip_p
!= IPPROTO_UDP
) { /* Only UDP packets */
662 #ifdef CONFIG_UDP_CHECKSUM
663 if (ip
->udp_xsum
!= 0) {
669 xsum
+= (ntohs(ip
->udp_len
));
670 xsum
+= (ntohl(ip
->ip_src
) >> 16) & 0x0000ffff;
671 xsum
+= (ntohl(ip
->ip_src
) >> 0) & 0x0000ffff;
672 xsum
+= (ntohl(ip
->ip_dst
) >> 16) & 0x0000ffff;
673 xsum
+= (ntohl(ip
->ip_dst
) >> 0) & 0x0000ffff;
675 sumlen
= ntohs(ip
->udp_len
);
676 sumptr
= (ushort
*) &(ip
->udp_src
);
682 xsum
+= ntohs(sumdata
);
688 sumdata
= *(unsigned char *) sumptr
;
689 sumdata
= (sumdata
<< 8) & 0xff00;
692 while ((xsum
>> 16) != 0) {
693 xsum
= (xsum
& 0x0000ffff) + ((xsum
>> 16) & 0x0000ffff);
695 if ((xsum
!= 0x00000000) && (xsum
!= 0x0000ffff)) {
696 printf(" UDP wrong checksum %08x %08x\n", xsum
, ntohs(ip
->udp_xsum
));
702 * IP header OK. Pass the packet to the current handler.
704 (*packetHandler
)((uchar
*)ip
+IP_HDR_SIZE
,
707 ntohs(ip
->udp_len
) - 8);
713 /**********************************************************************/
715 static int net_check_prereq (proto_t protocol
)
717 struct eth_device
*edev
= eth_get_current();
721 #ifdef CONFIG_NET_NFS
726 if (NetServerIP
== 0) {
727 printf("*** ERROR: `%s.serverip' not set\n", dev_id(&edev
->dev
));
732 printf("*** ERROR: `%s.ipaddr' not set\n", dev_id(&edev
->dev
));
740 if (memcmp (NetOurEther
, "\0\0\0\0\0\0", 6) == 0) {
741 printf("*** ERROR: `%s.ethaddr' not set\n", dev_id(&edev
->dev
));
749 return -1; /* not reached */
751 /**********************************************************************/
754 NetCksumOk(uchar
* ptr
, int len
)
756 return !((NetCksum(ptr
, len
) + 1) & 0xfffe);
761 NetCksum(uchar
* ptr
, int len
)
764 ushort
*p
= (ushort
*)ptr
;
769 xsum
= (xsum
& 0xffff) + (xsum
>> 16);
770 xsum
= (xsum
& 0xffff) + (xsum
>> 16);
771 return xsum
& 0xffff;
779 myvlanid
= ntohs(NetOurVLAN
);
780 if (myvlanid
== (ushort
)-1)
781 myvlanid
= VLAN_NONE
;
783 return ((myvlanid
& VLAN_IDMASK
) == VLAN_NONE
) ? ETHER_HDR_SIZE
: VLAN_ETHER_HDR_SIZE
;
787 NetSetEther(uchar
* xet
, uchar
* addr
, uint prot
)
789 Ethernet_t
*et
= (Ethernet_t
*)xet
;
792 myvlanid
= ntohs(NetOurVLAN
);
793 if (myvlanid
== (ushort
)-1)
794 myvlanid
= VLAN_NONE
;
796 memcpy (et
->et_dest
, addr
, 6);
797 memcpy (et
->et_src
, NetOurEther
, 6);
798 if ((myvlanid
& VLAN_IDMASK
) == VLAN_NONE
) {
799 et
->et_protlen
= htons(prot
);
800 return ETHER_HDR_SIZE
;
802 VLAN_Ethernet_t
*vet
= (VLAN_Ethernet_t
*)xet
;
804 vet
->vet_vlan_type
= htons(PROT_VLAN
);
805 vet
->vet_tag
= htons((0 << 5) | (myvlanid
& VLAN_IDMASK
));
806 vet
->vet_type
= htons(prot
);
807 return VLAN_ETHER_HDR_SIZE
;
812 NetSetIP(uchar
* xip
, IPaddr_t dest
, int dport
, int sport
, int len
)
814 IP_t
*ip
= (IP_t
*)xip
;
817 * If the data is an odd number of bytes, zero the
818 * byte after the last byte so that the checksum
822 xip
[IP_HDR_SIZE
+ len
] = 0;
825 * Construct an IP and UDP header.
826 * (need to set no fragment bit - XXX)
828 ip
->ip_hl_v
= 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */
830 ip
->ip_len
= htons(IP_HDR_SIZE
+ len
);
831 ip
->ip_id
= htons(NetIPID
++);
832 ip
->ip_off
= htons(0x4000); /* No fragmentation */
834 ip
->ip_p
= 17; /* UDP */
836 NetCopyIP((void*)&ip
->ip_src
, &NetOurIP
); /* already in network byte order */
837 NetCopyIP((void*)&ip
->ip_dst
, &dest
); /* - "" - */
838 ip
->udp_src
= htons(sport
);
839 ip
->udp_dst
= htons(dport
);
840 ip
->udp_len
= htons(8 + len
);
842 ip
->ip_sum
= ~NetCksum((uchar
*)ip
, IP_HDR_SIZE_NO_UDP
/ 2);
845 char *ip_to_string (IPaddr_t x
, char *s
)
848 sprintf (s
, "%d.%d.%d.%d",
849 (int) ((x
>> 24) & 0xff),
850 (int) ((x
>> 16) & 0xff),
851 (int) ((x
>> 8) & 0xff), (int) ((x
>> 0) & 0xff)
856 int string_to_ip(const char *s
, IPaddr_t
*ip
)
865 for (i
= 0; i
< 4; i
++) {
871 val
= simple_strtoul(s
, &e
, 10);
873 addr
|= (val
& 0xFF);
875 if (*e
!= '.' && i
!= 3)
885 void VLAN_to_string(ushort x
, char *s
)
895 sprintf(s
, "%d", x
& VLAN_IDMASK
);
898 ushort
string_to_VLAN(const char *s
)
903 return htons(VLAN_NONE
);
905 if (*s
< '0' || *s
> '9')
908 id
= (ushort
)simple_strtoul(s
, NULL
, 10);
913 void print_IPaddr (IPaddr_t x
)
917 ip_to_string (x
, tmp
);
922 ushort
getenv_VLAN(char *var
)
924 return string_to_VLAN(getenv(var
));
927 int string_to_ethaddr(const char *str
, char *enetaddr
)
932 if (!str
|| strlen(str
) != 17)
935 if (str
[2] != ':' || str
[5] != ':' || str
[8] != ':' ||
936 str
[11] != ':' || str
[14] != ':')
939 for (reg
= 0; reg
< 6; ++reg
) {
940 enetaddr
[reg
] = simple_strtoul (str
, &e
, 16);
947 void ethaddr_to_string(const unsigned char *enetaddr
, char *str
)
949 sprintf (str
, "%02X:%02X:%02X:%02X:%02X:%02X",
950 enetaddr
[0], enetaddr
[1], enetaddr
[2], enetaddr
[3],
951 enetaddr
[4], enetaddr
[5]);
954 void net_update_env(void)
956 struct eth_device
*edev
= eth_get_current();
958 NetOurIP
= dev_get_param_ip(&edev
->dev
, "ipaddr");
959 NetServerIP
= dev_get_param_ip(&edev
->dev
, "serverip");
960 NetOurGatewayIP
= dev_get_param_ip(&edev
->dev
, "gateway");
961 NetOurSubnetMask
= dev_get_param_ip(&edev
->dev
, "netmask");
963 string_to_ethaddr(dev_get_param(&edev
->dev
, "ethaddr"),