diff -brNu u-boot-0.3.0-orig/common/cmd_net.c u-boot-0.3.0-1/common/cmd_net.c --- u-boot-0.3.0-orig/common/cmd_net.c Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/common/cmd_net.c Mon Jun 2 11:49:10 2003 @@ -95,6 +95,10 @@ ip_to_string (NetOurDNSIP, tmp); setenv("dnsip", tmp); } + + if (NetOurNISDomain[0]) + setenv("domain", NetOurNISDomain); + } static int netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) @@ -164,5 +168,28 @@ #endif return rcode; } + +#if (CONFIG_COMMANDS & CFG_CMD_PING) +int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + if (argc < 2) + return -1; + + NetPingIP = string_to_ip(argv[1]); + if (NetPingIP == 0) { + printf ("Usage:\n%s\n", cmdtp->usage); + return -1; + } + + if (NetLoop(PING) < 0) { + printf("ping failed; host %s is not alive\n", argv[1]); + return 1; + } + + printf("host %s is alive\n", argv[1]); + + return 0; +} +#endif /* CFG_CMD_PING */ #endif /* CFG_CMD_NET */ diff -brNu u-boot-0.3.0-orig/common/command.c u-boot-0.3.0-1/common/command.c --- u-boot-0.3.0-orig/common/command.c Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/common/command.c Mon Jun 2 11:49:57 2003 @@ -312,6 +312,7 @@ CMD_TBL_NANDBOOT CMD_TBL_NEXT CMD_TBL_NM + CMD_TBL_PING CMD_TBL_PCI CMD_TBL_PRINTENV CMD_TBL_PROTECT diff -brNu u-boot-0.3.0-orig/include/cmd_confdefs.h u-boot-0.3.0-1/include/cmd_confdefs.h --- u-boot-0.3.0-orig/include/cmd_confdefs.h Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/include/cmd_confdefs.h Mon Jun 2 11:49:27 2003 @@ -80,6 +80,8 @@ #define CFG_CMD_VFD 0x0000400000000000 /* VFD support (TRAB) */ #define CFG_CMD_NAND 0x0000800000000000 /* NAND support */ +#define CFG_CMD_PING 0x0002000000000000 /* ping support */ + #define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */ /* Commands that are considered "non-standard" for some reason @@ -116,7 +118,8 @@ CFG_CMD_SDRAM | \ CFG_CMD_SPI | \ CFG_CMD_USB | \ - CFG_CMD_VFD ) + CFG_CMD_VFD | \ + CFG_CMD_PING) /* Default configuration */ diff -brNu u-boot-0.3.0-orig/include/cmd_net.h u-boot-0.3.0-1/include/cmd_net.h --- u-boot-0.3.0-orig/include/cmd_net.h Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/include/cmd_net.h Mon Jun 2 11:49:43 2003 @@ -64,11 +64,24 @@ #define CMD_TBL_DHCP #endif /* CFG_CMD_DHCP */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) +#define CMD_TBL_PING MK_CMD_TBL_ENTRY( \ + "ping", 4, 2, 1, do_ping, \ + "ping - check if host is reachable\n", \ + "host\n" \ +), + +int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#else +#define CMD_TBL_PING +#endif /* CFG_CMD_PING */ + #else #define CMD_TBL_BOOTP #define CMD_TBL_TFTPB #define CMD_TBL_RARPB #define CMD_TBL_DHCP +#define CMD_TBL_PING #endif /* CFG_CMD_NET */ #endif diff -brNu u-boot-0.3.0-orig/include/net.h u-boot-0.3.0-1/include/net.h --- u-boot-0.3.0-orig/include/net.h Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/include/net.h Mon Jun 2 11:48:53 2003 @@ -203,7 +203,9 @@ /* * ICMP stuff (just enough to handle (host) redirect messages) */ +#define ICMP_ECHO_REPLY 0 /* Echo reply */ #define ICMP_REDIRECT 5 /* Redirect (change route) */ +#define ICMP_ECHO_REQUEST 8 /* Echo request */ /* Codes for REDIRECT. */ #define ICMP_REDIR_NET 0 /* Redirect Net */ @@ -295,11 +297,15 @@ extern int NetRestartWrap; /* Tried all network devices */ #endif -typedef enum { BOOTP, RARP, ARP, TFTP, DHCP } proto_t; +typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS } proto_t; /* from net/net.c */ extern char BootFile[128]; /* Boot File name */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) +extern IPaddr_t NetPingIP; /* the ip address to ping */ +#endif + /* Initialize the network adapter */ extern int NetLoop(proto_t); @@ -326,6 +332,9 @@ /* Transmit "NetTxPacket" */ extern void NetSendPacket(volatile uchar *, int); +/* Transmit UDP packet, performing ARP request if needed */ +extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len); + /* Processes a received packet */ extern void NetReceive(volatile uchar *, int); @@ -375,6 +384,9 @@ /* Convert an IP address to a string */ extern void ip_to_string (IPaddr_t x, char *s); + +/* Convert a string to ip address */ +extern IPaddr_t string_to_ip(char *s); /* read an IP address from a environment variable */ extern IPaddr_t getenv_IPaddr (char *); diff -brNu u-boot-0.3.0-orig/net/Makefile u-boot-0.3.0-1/net/Makefile --- u-boot-0.3.0-orig/net/Makefile Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/net/Makefile Mon Jun 2 11:48:53 2003 @@ -27,7 +27,7 @@ LIB = libnet.a -OBJS = net.o tftp.o bootp.o rarp.o arp.o eth.o +OBJS = net.o tftp.o bootp.o rarp.o eth.o all: $(LIB) $(LIB): $(START) $(OBJS) diff -brNu u-boot-0.3.0-orig/net/arp.c u-boot-0.3.0-1/net/arp.c --- u-boot-0.3.0-orig/net/arp.c Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/net/arp.c Thu Jan 1 02:00:00 1970 @@ -1,120 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include "bootp.h" -#include "tftp.h" -#include "arp.h" - -#if (CONFIG_COMMANDS & CFG_CMD_NET) - -#define TIMEOUT 5 /* Seconds before trying ARP again */ -#ifndef CONFIG_NET_RETRY_COUNT -# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ -#else -# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) -#endif - -static void ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len); -static void ArpTimeout(void); - -int ArpTry = 0; - -/* - * Handle a ARP received packet. - */ -static void -ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len) -{ - /* Check if the frame is really an ARP reply */ - if (memcmp (NetServerEther, NetBcastAddr, 6) != 0) { -#ifdef DEBUG - printf("Got good ARP - start TFTP\n"); -#endif - TftpStart (); - } -} - - -/* - * Timeout on ARP request. - */ -static void -ArpTimeout(void) -{ - if (ArpTry >= TIMEOUT_COUNT) { - puts ("\nRetry count exceeded; starting again\n"); - NetStartAgain (); - } else { - NetSetTimeout (TIMEOUT * CFG_HZ, ArpTimeout); - ArpRequest (); - } -} - - -void -ArpRequest (void) -{ - int i; - volatile uchar *pkt; - ARP_t * arp; - - printf("ARP broadcast %d\n", ++ArpTry); - pkt = NetTxPacket; - - NetSetEther(pkt, NetBcastAddr, PROT_ARP); - pkt += ETHER_HDR_SIZE; - - arp = (ARP_t *)pkt; - - arp->ar_hrd = htons(ARP_ETHER); - arp->ar_pro = htons(PROT_IP); - arp->ar_hln = 6; - arp->ar_pln = 4; - arp->ar_op = htons(ARPOP_REQUEST); - - memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ - NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr */ - for (i=10; i<16; ++i) { - arp->ar_data[i] = 0; /* dest ET addr = 0 */ - } - - if((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { - if (NetOurGatewayIP == 0) { - puts ("## Warning: gatewayip needed but not set\n"); - } - NetWriteIP((uchar*)&arp->ar_data[16], NetOurGatewayIP); - } else { - NetWriteIP((uchar*)&arp->ar_data[16], NetServerIP); - } - - - NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); - - NetSetTimeout(TIMEOUT * CFG_HZ, ArpTimeout); - NetSetHandler(ArpHandler); -} - -#endif /* CFG_CMD_NET */ diff -brNu u-boot-0.3.0-orig/net/arp.h u-boot-0.3.0-1/net/arp.h --- u-boot-0.3.0-orig/net/arp.h Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/net/arp.h Thu Jan 1 02:00:00 1970 @@ -1,40 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#ifndef __ARP_H__ -#define __ARP_H__ - -/**********************************************************************/ -/* - * Global functions and variables. - */ - -extern int ArpTry; - -extern void ArpRequest (void); /* Send a ARP request */ - -/**********************************************************************/ - -#endif /* __ARP_H__ */ - diff -brNu u-boot-0.3.0-orig/net/bootp.c u-boot-0.3.0-1/net/bootp.c --- u-boot-0.3.0-orig/net/bootp.c Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/net/bootp.c Mon Jun 2 11:48:53 2003 @@ -24,7 +24,6 @@ #include #include "bootp.h" #include "tftp.h" -#include "arp.h" #ifdef CONFIG_STATUS_LED #include #endif @@ -335,10 +334,7 @@ return; } - /* Send ARP request to get TFTP server ethernet address. - * This automagically starts TFTP, too. - */ - ArpRequest(); + TftpStart(); } #endif /* !CFG_CMD_DHCP */ @@ -866,10 +862,7 @@ NetState = NETLOOP_SUCCESS; return; } - /* Send ARP request to get TFTP server ethernet address. - * This automagically starts TFTP, too. - */ - ArpRequest(); + TftpStart(); return; } break; diff -brNu u-boot-0.3.0-orig/net/net.c u-boot-0.3.0-1/net/net.c --- u-boot-0.3.0-orig/net/net.c Tue Apr 22 11:35:09 2003 +++ u-boot-0.3.0-1/net/net.c Mon Jun 2 11:48:53 2003 @@ -65,10 +65,16 @@ #include "bootp.h" #include "tftp.h" #include "rarp.h" -#include "arp.h" #if (CONFIG_COMMANDS & CFG_CMD_NET) +#define ARP_TIMEOUT 5 /* Seconds before trying ARP again */ +#ifndef CONFIG_NET_RETRY_COUNT +# define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */ +#else +# define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) +#endif + #if 0 #define ET_DEBUG #endif @@ -88,7 +94,7 @@ ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ uchar NetOurEther[6]; /* Our ethernet address */ uchar NetServerEther[6] = /* Boot server enet address */ - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + { 0, 0, 0, 0, 0, 0 }; IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ volatile uchar *NetRxPkt; /* Current receive packet */ @@ -96,6 +102,8 @@ unsigned NetIPID; /* IP packet ID */ uchar NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +uchar NetEtherNullAddr[6] = + { 0, 0, 0, 0, 0, 0 }; int NetState; /* Network loop state */ #ifdef CONFIG_NET_MULTI int NetRestartWrap = 0; /* Tried all network devices */ @@ -105,6 +113,12 @@ char BootFile[128]; /* Boot File name */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) +IPaddr_t NetPingIP; /* the ip address to ping */ + +static void PingStart(void); +#endif + volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ @@ -117,6 +131,81 @@ static int net_check_prereq (proto_t protocol); /**********************************************************************/ + +IPaddr_t NetArpWaitPacketIP; +IPaddr_t NetArpWaitReplyIP; +uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */ +uchar *NetArpWaitTxPacket; /* THE transmit packet */ +int NetArpWaitTxPacketSize; +uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; +ulong NetArpWaitTimerStart; +int NetArpWaitTry; + +void ArpRequest(void) +{ + int i; + volatile uchar *pkt; + ARP_t * arp; + +#ifdef ET_DEBUG + printf("ARP broadcast %d\n", NetArpWaitTry); +#endif + pkt = NetTxPacket; + + NetSetEther(pkt, NetBcastAddr, PROT_ARP); + pkt += ETHER_HDR_SIZE; + + arp = (ARP_t *)pkt; + + arp->ar_hrd = htons(ARP_ETHER); + arp->ar_pro = htons(PROT_IP); + arp->ar_hln = 6; + arp->ar_pln = 4; + arp->ar_op = htons(ARPOP_REQUEST); + + memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ + NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr */ + for (i=10; i<16; ++i) { + arp->ar_data[i] = 0; /* dest ET addr = 0 */ + } + + if((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { + if (NetOurGatewayIP == 0) { + puts ("## Warning: gatewayip needed but not set\n"); + } + NetArpWaitReplyIP = NetOurGatewayIP; + } else + NetArpWaitReplyIP = NetArpWaitPacketIP; + + NetWriteIP((uchar*)&arp->ar_data[16], NetArpWaitReplyIP); + (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); +} + +void ArpTimeoutCheck(void) +{ + ulong t; + + if (!NetArpWaitPacketIP) + return; + + t = get_timer(0); + + /* check for arp timeout */ + if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) { + NetArpWaitTry++; + + if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { + puts ("\nARP Retry count exceeded; starting again\n"); + NetArpWaitTry = 0; + NetStartAgain(); + } else { + NetArpWaitTimerStart = t; + ArpRequest(); + } + } +} + +/**********************************************************************/ /* * Main network processing loop. */ @@ -133,6 +222,14 @@ NetDevExists = 0; #endif + /* XXX problem with bss workaround */ + NetArpWaitPacketMAC = NULL; + NetArpWaitTxPacket = NULL; + NetArpWaitPacketIP = 0; + NetArpWaitReplyIP = 0; + NetArpWaitTxPacket = NULL; + NetTxPacket = NULL; + if (!NetTxPacket) { int i; @@ -144,6 +241,13 @@ for (i = 0; i < PKTBUFSRX; i++) { NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; } + + } + + if (!NetArpWaitTxPacket) { + NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); + NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; + NetArpWaitTxPacketSize = 0; } eth_halt(); @@ -165,11 +269,27 @@ */ switch (protocol) { +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: +#endif case TFTP: NetCopyIP(&NetOurIP, &bd->bi_ip_addr); - NetServerIP = getenv_IPaddr ("serverip"); NetOurGatewayIP = getenv_IPaddr ("gatewayip"); NetOurSubnetMask= getenv_IPaddr ("netmask"); + + switch (protocol) { + case TFTP: + NetServerIP = getenv_IPaddr ("serverip"); + break; +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: + /* nothing */ + break; +#endif + default: + break; + } + break; case BOOTP: case RARP: @@ -202,8 +322,7 @@ switch (protocol) { case TFTP: /* always use ARP to get server ethernet address */ - ArpTry = 0; - ArpRequest (); + TftpStart(); break; #if (CONFIG_COMMANDS & CFG_CMD_DHCP) @@ -224,6 +343,11 @@ RarpTry = 0; RarpRequest (); break; +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: + PingStart(); + break; +#endif default: break; } @@ -260,6 +384,7 @@ return (-1); } + ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler @@ -376,7 +501,138 @@ (void) eth_send(pkt, len); } +int +NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) +{ + /* convert to new style broadcast */ + if (dest == 0) + dest = 0xFFFFFFFF; + + /* if broadcast, make the ether address a broadcast and don't do ARP */ + if (dest == 0xFFFFFFFF) + ether = NetBcastAddr; + + /* if MAC address was not discovered yet, save the packet and do an ARP request */ + if (memcmp(ether, NetEtherNullAddr, 6) == 0) { +#ifdef ET_DEBUG + printf("sending ARP for %08lx\n", dest); +#endif + + NetArpWaitPacketIP = dest; + NetArpWaitPacketMAC = ether; + NetSetEther (NetArpWaitTxPacket, NetArpWaitPacketMAC, PROT_IP); + NetSetIP (NetArpWaitTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); + memcpy(NetArpWaitTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, + (uchar *)NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, len); + + /* size of the waiting packet */ + NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE + len; + + /* and do the ARP request */ + NetArpWaitTry = 1; + NetArpWaitTimerStart = get_timer(0); + ArpRequest(); + return 1; /* waiting */ + } + +#ifdef ET_DEBUG + printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n", + dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); +#endif + + NetSetEther (NetTxPacket, ether, PROT_IP); + NetSetIP (NetTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); + (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); + + return 0; /* transmited */ +} + +#if (CONFIG_COMMANDS & CFG_CMD_PING) +static ushort PingSeqNo; + +int PingSend(void) +{ + static uchar mac[6]; + volatile IP_t *ip; + volatile ushort *s; + + /* XXX always send arp request */ + + memcpy(mac, NetEtherNullAddr, 6); + +#ifdef ET_DEBUG + printf("sending ARP for %08lx\n", NetPingIP); +#endif + + NetArpWaitPacketIP = NetPingIP; + NetArpWaitPacketMAC = mac; + + NetSetEther(NetArpWaitTxPacket, mac, PROT_IP); + + ip = (volatile IP_t *)(NetArpWaitTxPacket + ETHER_HDR_SIZE); + + /* + * Construct an IP and ICMP header. (need to set no fragment bit - XXX) + */ + ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ + ip->ip_tos = 0; + ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); + ip->ip_id = htons(NetIPID++); + ip->ip_off = htons(0x4000); /* No fragmentation */ + ip->ip_ttl = 255; + ip->ip_p = 0x01; /* ICMP */ + ip->ip_sum = 0; + NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ + NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ + ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); + + s = &ip->udp_src; /* XXX ICMP starts here */ + s[0] = htons(0x0800); /* echo-request, code */ + s[1] = 0; /* checksum */ + s[2] = 0; /* identifier */ + s[3] = htons(PingSeqNo++); /* sequence number */ + s[1] = ~NetCksum((uchar *)s, 8/2); + + /* size of the waiting packet */ + NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + 8; + + /* and do the ARP request */ + NetArpWaitTry = 1; + NetArpWaitTimerStart = get_timer(0); + ArpRequest(); + return 1; /* waiting */ +} + +static void +PingTimeout (void) +{ + eth_halt(); + NetState = NETLOOP_FAIL; /* we did not get the reply */ +} + +static void +PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) +{ + IPaddr_t tmp; + volatile IP_t *ip = (volatile IP_t *)pkt; + + tmp = NetReadIP((void *)&ip->ip_src); + if (tmp != NetPingIP) + return; + + NetState = NETLOOP_SUCCESS; +} + +static void PingStart(void) +{ + NetSetTimeout (10 * CFG_HZ, PingTimeout); + NetSetHandler (PingHandler); + + PingSend(); +} + +#endif void NetReceive(volatile uchar * pkt, int len) @@ -387,7 +643,6 @@ IPaddr_t tmp; int x; - NetRxPkt = pkt; NetRxPktLen = len; et = (Ethernet_t *)pkt; @@ -462,14 +717,40 @@ NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]); memcpy (&arp->ar_data[ 0], NetOurEther, 6); NetCopyIP(&arp->ar_data[ 6], &NetOurIP); - NetSendPacket((uchar *)et,((uchar *)arp-pkt)+ARP_HDR_SIZE); + (void) eth_send((uchar *)et, ((uchar *)arp-pkt) + ARP_HDR_SIZE); return; - case ARPOP_REPLY: /* set TFTP server eth addr */ + + case ARPOP_REPLY: /* arp reply */ + /* are we waiting for a reply */ + if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) + break; +#ifdef ET_DEBUG + printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", + arp->ar_data[0], arp->ar_data[1], + arp->ar_data[2], arp->ar_data[3], + arp->ar_data[4], arp->ar_data[5]); +#endif + + tmp = NetReadIP(&arp->ar_data[6]); + + /* matched waiting packet's address */ + if (tmp == NetArpWaitReplyIP) { #ifdef ET_DEBUG - printf("Got ARP REPLY, set server/gtwy eth addr\n"); + printf("Got it\n"); #endif - memcpy (NetServerEther, &arp->ar_data[0], 6); - (*packetHandler)(0,0,0,0); /* start TFTP */ + /* save address for later use */ + memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); + + /* modify header, and transmit it */ + memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); + (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize); + + /* no arp request pending now */ + NetArpWaitPacketIP = 0; + NetArpWaitTxPacketSize = 0; + NetArpWaitPacketMAC = NULL; + + } return; default: #ifdef ET_DEBUG @@ -553,13 +834,26 @@ if (ip->ip_p == IPPROTO_ICMP) { ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); - if (icmph->type != ICMP_REDIRECT) - return; + switch (icmph->type) { + case ICMP_REDIRECT: if (icmph->code != ICMP_REDIR_HOST) return; puts (" ICMP Host Redirect to "); print_IPaddr(icmph->un.gateway); putc(' '); + break; +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case ICMP_ECHO_REPLY: + /* + * IP header OK. Pass the packet to the current handler. + */ + /* XXX point to ip packet */ + (*packetHandler)((uchar *)ip, 0, 0, 0); + break; +#endif + default: + return; + } } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ return; } @@ -582,15 +876,25 @@ static int net_check_prereq (proto_t protocol) { switch (protocol) { - case ARP: /* nothing to do */ - break; - + /* Fall through */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: + if (NetPingIP == 0) { + puts ("*** ERROR: ping address not given\n"); + return (1); + } + goto common; +#endif case TFTP: if (NetServerIP == 0) { puts ("*** ERROR: `serverip' not set\n"); return (1); } +#if (CONFIG_COMMANDS & CFG_CMD_PING) + common: +#endif + if (NetOurIP == 0) { puts ("*** ERROR: `ipaddr' not set\n"); return (1); @@ -626,6 +930,8 @@ #endif } /* Fall through */ + default: + return(0); } return (0); /* OK */ } @@ -723,22 +1029,14 @@ ); } -void print_IPaddr (IPaddr_t x) -{ - char tmp[16]; - - ip_to_string(x, tmp); - - puts(tmp); -} - -IPaddr_t getenv_IPaddr (char *var) +IPaddr_t string_to_ip(char *s) { IPaddr_t addr; - char *s, *e; + char *e; int i; - s = getenv (var); + if (s == NULL) + return(0); for (addr=0, i=0; i<4; ++i) { ulong val = s ? simple_strtoul(s, &e, 10) : 0; @@ -750,4 +1048,18 @@ } return (htonl(addr)); +} + +void print_IPaddr (IPaddr_t x) +{ + char tmp[16]; + + ip_to_string(x, tmp); + + puts(tmp); +} + +IPaddr_t getenv_IPaddr (char *var) +{ + return (string_to_ip(getenv(var))); } diff -brNu u-boot-0.3.0-orig/net/tftp.c u-boot-0.3.0-1/net/tftp.c --- u-boot-0.3.0-orig/net/tftp.c Wed Apr 16 10:56:20 2003 +++ u-boot-0.3.0-1/net/tftp.c Mon Jun 2 11:48:53 2003 @@ -142,10 +142,7 @@ break; } - NetSetEther (NetTxPacket, NetServerEther, PROT_IP); - NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP, - TftpServerPort, TftpOurPort, len); - NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); + NetSendUDPPacket(NetServerEther, NetServerIP, TftpServerPort, TftpOurPort, len); } @@ -257,17 +254,6 @@ void TftpStart (void) { -#ifdef ET_DEBUG - printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", - NetServerEther[0], - NetServerEther[1], - NetServerEther[2], - NetServerEther[3], - NetServerEther[4], - NetServerEther[5] - ); -#endif /* DEBUG */ - if (BootFile[0] == '\0') { IPaddr_t OurIP = ntohl(NetOurIP); @@ -319,6 +305,9 @@ TftpTimeoutCount = 0; TftpState = STATE_RRQ; TftpOurPort = 1024 + (get_timer(0) % 3072); + + /* zero out server ether in case the server ip has changed */ + memset(NetServerEther, 0, 6); TftpSend (); }