summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorwdenk <wdenk>2003-06-05 19:27:42 +0000
committerwdenk <wdenk>2003-06-05 19:27:42 +0000
commit73a8b27c574f5ec1c8fdd9d8d065bb845d8743d3 (patch)
treef409359364776e565b9484337a0620388041b456 /net
parent08eaea9c9fa4e8ea25325610c512cb90b6bea1dd (diff)
downloadu-boot-73a8b27c574f5ec1c8fdd9d8d065bb845d8743d3.tar.gz
u-boot-73a8b27c574f5ec1c8fdd9d8d065bb845d8743d3.tar.xz
u-boot-73a8b27c574f5ec1c8fdd9d8d065bb845d8743d3.zip
* Add support for RMU board
* Add support for TQM862L at 100/50 MHz * Patch by Pantelis Antoniou, 02 Jun 2003: major reconstruction of networking code; add "ping" support (outgoing only!)
Diffstat (limited to 'net')
-rw-r--r--net/Makefile2
-rw-r--r--net/arp.c120
-rw-r--r--net/arp.h40
-rw-r--r--net/bootp.c11
-rw-r--r--net/net.c368
-rw-r--r--net/tftp.c19
6 files changed, 347 insertions, 213 deletions
diff --git a/net/Makefile b/net/Makefile
index db0a69fae0..b899d7b2f2 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
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 --git a/net/arp.c b/net/arp.c
deleted file mode 100644
index c09dc1aac8..0000000000
--- a/net/arp.c
+++ /dev/null
@@ -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 <common.h>
-#include <command.h>
-#include <net.h>
-#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 --git a/net/arp.h b/net/arp.h
deleted file mode 100644
index b83533495e..0000000000
--- a/net/arp.h
+++ /dev/null
@@ -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 --git a/net/bootp.c b/net/bootp.c
index 4be0ad586a..8e0f332466 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -24,7 +24,6 @@
#include <net.h>
#include "bootp.h"
#include "tftp.h"
-#include "arp.h"
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
@@ -336,10 +335,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
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 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
NetState = NETLOOP_SUCCESS;
return;
}
- /* Send ARP request to get TFTP server ethernet address.
- * This automagically starts TFTP, too.
- */
- ArpRequest();
+ TftpStart();
return;
}
break;
diff --git a/net/net.c b/net/net.c
index b9cb67b25c..4758595d1c 100644
--- a/net/net.c
+++ b/net/net.c
@@ -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 @@ ushort NetBootFileSize=0; /* Our bootfile size in blocks */
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 @@ int NetRxPktLen; /* Current rx packet length */
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 @@ static int NetDevExists = 0; /* At least one device configured */
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 @@ volatile uchar *NetTxPacket = 0; /* THE transmit packet */
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 @@ NetLoop(proto_t protocol)
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 @@ NetLoop(proto_t protocol)
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 @@ restart:
*/
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 @@ restart:
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 @@ restart:
RarpTry = 0;
RarpRequest ();
break;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+ case PING:
+ PingStart();
+ break;
+#endif
default:
break;
}
@@ -260,6 +384,7 @@ restart:
return (-1);
}
+ ArpTimeoutCheck();
/*
* Check for a timeout, and run the timeout handler
@@ -376,7 +501,138 @@ NetSendPacket(volatile uchar * pkt, int len)
(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 @@ NetReceive(volatile uchar * pkt, int len)
IPaddr_t tmp;
int x;
-
NetRxPkt = pkt;
NetRxPktLen = len;
et = (Ethernet_t *)pkt;
@@ -462,14 +717,40 @@ NetReceive(volatile uchar * pkt, int len)
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\n");
+ 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
- memcpy (NetServerEther, &arp->ar_data[0], 6);
- (*packetHandler)(0,0,0,0); /* start TFTP */
+
+ tmp = NetReadIP(&arp->ar_data[6]);
+
+ /* matched waiting packet's address */
+ if (tmp == NetArpWaitReplyIP) {
+#ifdef ET_DEBUG
+ printf("Got it\n");
+#endif
+ /* 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 @@ NetReceive(volatile uchar * pkt, int len)
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 @@ NetReceive(volatile uchar * pkt, int len)
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 @@ static int net_check_prereq (proto_t protocol)
#endif
}
/* Fall through */
+ default:
+ return(0);
}
return (0); /* OK */
}
@@ -723,22 +1029,14 @@ void ip_to_string (IPaddr_t x, char *s)
);
}
-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;
@@ -751,3 +1049,17 @@ IPaddr_t getenv_IPaddr (char *var)
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 --git a/net/tftp.c b/net/tftp.c
index 0ad244fd97..5598be32f1 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -142,10 +142,7 @@ TftpSend (void)
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 @@ TftpTimeout (void)
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);
@@ -320,6 +306,9 @@ TftpStart (void)
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 ();
}