2007-07-05 16:01:23 +00:00
|
|
|
#include <common.h>
|
|
|
|
#include <command.h>
|
|
|
|
#include <clock.h>
|
|
|
|
#include <net.h>
|
|
|
|
|
|
|
|
static ushort PingSeqNo;
|
|
|
|
|
2008-03-31 19:52:09 +00:00
|
|
|
static int PingSend(void)
|
2007-07-05 16:01:23 +00:00
|
|
|
{
|
|
|
|
static uchar mac[6];
|
2008-03-31 19:52:09 +00:00
|
|
|
IP_t *ip;
|
|
|
|
ushort *s;
|
2007-07-05 16:01:23 +00:00
|
|
|
uchar *pkt;
|
|
|
|
|
|
|
|
/* XXX always send arp request */
|
|
|
|
|
|
|
|
memcpy(mac, NetEtherNullAddr, 6);
|
|
|
|
|
|
|
|
#ifdef ET_DEBUG
|
|
|
|
printf("sending ARP for %08lx\n", NetPingIP);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NetArpWaitPacketIP = NetPingIP;
|
|
|
|
NetArpWaitPacketMAC = mac;
|
|
|
|
|
|
|
|
pkt = NetArpWaitTxPacket;
|
|
|
|
pkt += NetSetEther(pkt, mac, PROT_IP);
|
|
|
|
|
2008-03-31 19:52:09 +00:00
|
|
|
ip = (IP_t *)pkt;
|
2007-07-05 16:01:23 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE_NO_UDP + 8;
|
|
|
|
|
|
|
|
/* and do the ARP request */
|
|
|
|
NetArpWaitTimerStart = get_time_ns();
|
|
|
|
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;
|
2007-10-11 19:54:33 +00:00
|
|
|
IP_t *ip = (IP_t *)pkt;
|
2007-07-05 16:01:23 +00:00
|
|
|
|
|
|
|
tmp = NetReadIP((void *)&ip->ip_src);
|
|
|
|
if (tmp != NetPingIP)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NetState = NETLOOP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-09-24 10:31:08 +00:00
|
|
|
int do_ping (cmd_tbl_t *cmdtp, int argc, char *argv[])
|
2007-07-05 16:01:23 +00:00
|
|
|
{
|
|
|
|
if (argc < 2)
|
|
|
|
return -1;
|
|
|
|
|
2008-08-20 11:19:15 +00:00
|
|
|
if (string_to_ip(argv[1], &NetPingIP)) {
|
2007-07-05 16:01:23 +00:00
|
|
|
printf ("Usage:\n%s\n", cmdtp->usage);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-08-19 12:20:13 +00:00
|
|
|
if (NetLoopInit(PING) < 0)
|
|
|
|
return 1;
|
|
|
|
|
2009-08-19 13:06:30 +00:00
|
|
|
NetSetTimeout (10 * SECOND, PingTimeout);
|
|
|
|
NetSetHandler (PingHandler);
|
|
|
|
PingSend();
|
2009-08-19 13:00:06 +00:00
|
|
|
|
|
|
|
if (NetLoop() < 0) {
|
2007-07-05 16:01:23 +00:00
|
|
|
printf("ping failed; host %s is not alive\n", argv[1]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("host %s is alive\n", argv[1]);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-05 16:01:52 +00:00
|
|
|
U_BOOT_CMD_START(ping)
|
|
|
|
.maxargs = 2,
|
|
|
|
.cmd = do_ping,
|
2007-07-05 16:02:04 +00:00
|
|
|
.usage = "send icmp echo_request to network host",
|
2007-07-05 16:01:52 +00:00
|
|
|
U_BOOT_CMD_END
|