ping() integrated
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@872 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
4be5ae53a0
commit
63c893a73c
|
@ -270,14 +270,14 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||
uip_ipaddr_t ipaddr;
|
||||
uint32 start;
|
||||
uint32 next;
|
||||
uint32 dsec;
|
||||
uint32 dsec = 10;
|
||||
uint16 id;
|
||||
int sec = 1;
|
||||
int count = 10;
|
||||
int option;
|
||||
int seqno;
|
||||
int replies = 0;
|
||||
int elapsed;
|
||||
int tmp;
|
||||
int i;
|
||||
|
||||
/* Get the ping options */
|
||||
|
@ -296,12 +296,13 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'i':
|
||||
sec = atoi(optarg);
|
||||
if (sec < 1 || sec >= 4294)
|
||||
tmp = atoi(optarg);
|
||||
if (tmp < 1 || tmp >= 4294)
|
||||
{
|
||||
fmt = g_fmtargrange;
|
||||
goto errout;
|
||||
}
|
||||
dsec = 10 * tmp;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
|
@ -334,39 +335,67 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
/* Convert the ping interval to microseconds and deciseconds*/
|
||||
|
||||
dsec = 10 * sec;
|
||||
|
||||
/* Get the ID to use */
|
||||
|
||||
id = ping_newid();
|
||||
|
||||
/* Loop for the specified count */
|
||||
|
||||
nsh_output(vtbl, "PING %s %dbytes of data\n", staddr, DEFAULT_PING_DATALEN);
|
||||
nsh_output(vtbl, "PING %s %d bytes of data\n", staddr, DEFAULT_PING_DATALEN);
|
||||
start = g_system_timer;
|
||||
for (i = 0; i < count; i++)
|
||||
for (i = 1; i <= count; i++)
|
||||
{
|
||||
next = g_system_timer;
|
||||
/* Send the ECHO request and wait for the response */
|
||||
|
||||
next = g_system_timer;
|
||||
seqno = uip_ping(ipaddr, id, i, DEFAULT_PING_DATALEN, dsec);
|
||||
elapsed = TICK2MSEC(g_system_timer - next);
|
||||
if (seqno >= 0)
|
||||
|
||||
/* Was any response returned? We can tell if a non-negative sequence
|
||||
* number was returned.
|
||||
*/
|
||||
|
||||
if (seqno >= 0 && seqno <= i)
|
||||
{
|
||||
/* Get the elpased time from the time that the request was
|
||||
* sent until the response was received. If we got a response
|
||||
* to an earlier request, then fudge the elpased time.
|
||||
*/
|
||||
|
||||
elapsed = TICK2MSEC(g_system_timer - next);
|
||||
if (seqno < i)
|
||||
{
|
||||
elapsed += 100*dsec*(i - seqno);
|
||||
}
|
||||
|
||||
/* Report the receipt of the reply */
|
||||
|
||||
nsh_output(vtbl, "%d bytes from %s: icmp_seq=%d time=%d ms\n",
|
||||
DEFAULT_PING_DATALEN, staddr, seqno, elapsed);
|
||||
replies++;
|
||||
}
|
||||
|
||||
/* Wait for the remainder of the interval. If the last seqno<i,
|
||||
* then this is a bad idea... we will probably lose the response
|
||||
* to the current request!
|
||||
*/
|
||||
|
||||
elapsed = TICK2DSEC(g_system_timer - next);
|
||||
if (elapsed < dsec)
|
||||
{
|
||||
usleep(100000*dsec);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the total elapsed time */
|
||||
|
||||
elapsed = TICK2MSEC(g_system_timer - start);
|
||||
|
||||
nsh_output(vtbl, "%d packets transmitted, %d received, %d%% packet loss, time %dms\n",
|
||||
count, replies, (100*replies + count/2)/count, elapsed);
|
||||
/* Calculate the percentage of lost packets */
|
||||
|
||||
tmp = (100*(count - replies) + (count >> 1)) / count;
|
||||
|
||||
nsh_output(vtbl, "%d packets transmitted, %d received, %d%% packet loss, time %d ms\n",
|
||||
count, replies, tmp, elapsed);
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
|
|
|
@ -91,7 +91,13 @@
|
|||
#define UIP_TS_MASK 15
|
||||
#define UIP_STOPPED 16
|
||||
|
||||
/* Header sizes */
|
||||
/* Flag bits in 16-bit flags+ipoffset IPv4 TCP header field */
|
||||
|
||||
#define UIP_TCPFLAG_RESERVED 0x8000
|
||||
#define UIP_TCPFLAG_DONTFRAG 0x4000
|
||||
#define UIP_TCPFLAG_MOREFRAGS 0x2000
|
||||
|
||||
/* TCP header sizes */
|
||||
|
||||
#define UIP_TCPH_LEN 20 /* Size of TCP header */
|
||||
#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + TCP header */
|
||||
|
|
|
@ -174,13 +174,13 @@ EXTERN FAR struct uip_driver_s *netdev_findbyname(const char *ifname);
|
|||
/* net-findbyaddr.c **********************************************************/
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
EXTERN FAR struct uip_driver_s *netdev_findbyaddr(uip_ipaddr_t *raddr);
|
||||
EXTERN FAR struct uip_driver_s *netdev_findbyaddr(const uip_ipaddr_t *raddr);
|
||||
#endif
|
||||
|
||||
/* net-txnotify.c ************************************************************/
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
EXTERN void netdev_txnotify(uip_ipaddr_t *raddr);
|
||||
EXTERN void netdev_txnotify(const uip_ipaddr_t *raddr);
|
||||
#endif
|
||||
|
||||
/* net-count.c ***************************************************************/
|
||||
|
|
|
@ -105,7 +105,7 @@ static inline boolean netdev_maskcmp(uip_ipaddr_t *ipaddr, uip_ipaddr_t *raddr,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct uip_driver_s *netdev_findbyaddr(uip_ipaddr_t *raddr)
|
||||
FAR struct uip_driver_s *netdev_findbyaddr(const uip_ipaddr_t *raddr)
|
||||
{
|
||||
struct uip_driver_s *dev;
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netdev_txnotify(uip_ipaddr_t *raddr)
|
||||
void netdev_txnotify(const uip_ipaddr_t *raddr)
|
||||
{
|
||||
/* Find the device driver that serves the subnet of the remote address */
|
||||
|
||||
|
|
|
@ -323,10 +323,7 @@ void uip_arp_arpin(struct uip_driver_s *dev)
|
|||
|
||||
uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr);
|
||||
|
||||
/* The reply opcode is 2. */
|
||||
|
||||
ARPBUF->ah_opcode = HTONS(2);
|
||||
|
||||
ARPBUF->ah_opcode = HTONS(ARP_REPLY);
|
||||
memcpy(ARPBUF->ah_dhwaddr, ARPBUF->ah_shwaddr, ETHER_ADDR_LEN);
|
||||
memcpy(ARPBUF->ah_shwaddr, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
memcpy(ETHBUF->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
|
|
|
@ -236,7 +236,7 @@ uint16 uip_callbackexecute(FAR struct uip_driver_s *dev, void *pvconn, uint16 fl
|
|||
* beginning of the list (which will be ignored on this pass)
|
||||
*/
|
||||
|
||||
vdbg("Call event=%p with flags=%04x\n", list->event, flags);
|
||||
nvdbg("Call event=%p with flags=%04x\n", list->event, flags);
|
||||
flags = list->event(dev, pvconn, list->private, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* net/uip/uip-chksum.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
*
|
||||
|
|
|
@ -243,7 +243,23 @@ typeerr:
|
|||
#ifdef CONFIG_NET_ICMP_PING
|
||||
else if (ICMPBUF->type == ICMP6_ECHO_REPLY && g_echocallback)
|
||||
{
|
||||
(void)uip_callbackexecute(dev, ICMPBUF, UIP_ECHOREPLY, g_echocallback);
|
||||
uint16 flags = UIP_ECHOREPLY;
|
||||
|
||||
if (g_echocallback)
|
||||
{
|
||||
/* Dispatch the ECHO reply to the waiting thread */
|
||||
|
||||
flags = uip_callbackexecute(dev, ICMPBUF, flags, g_echocallback);
|
||||
}
|
||||
|
||||
/* If the ECHO reply was not handled, then drop the packet */
|
||||
|
||||
if (flags == UIP_ECHOREPLY)
|
||||
{
|
||||
/* The ECHO reply was not handled */
|
||||
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#define ICMPBUF ((struct uip_icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
#define ICMPDAT &dev->d_buf[UIP_LLH_LEN + sizeof(struct uip_icmpip_hdr)]
|
||||
#define ICMPDAT (&dev->d_buf[UIP_LLH_LEN + sizeof(struct uip_icmpip_hdr)])
|
||||
|
||||
/* Allocate a new ICMP data callback */
|
||||
|
||||
|
@ -149,6 +149,7 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
|
|||
{
|
||||
struct icmp_ping_s *pstate = (struct icmp_ping_s *)pvprivate;
|
||||
int failcode = -ETIMEDOUT;
|
||||
int i;
|
||||
|
||||
nvdbg("flags: %04x\n", flags);
|
||||
if (pstate)
|
||||
|
@ -162,6 +163,7 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
|
|||
* that the destination address is not reachable.
|
||||
*/
|
||||
|
||||
nvdbg("Not reachable\n");
|
||||
failcode = -ENETUNREACH;
|
||||
}
|
||||
else
|
||||
|
@ -175,8 +177,17 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
|
|||
if ((flags & UIP_ECHOREPLY) != 0 && conn != NULL)
|
||||
{
|
||||
struct uip_icmpip_hdr *icmp = (struct uip_icmpip_hdr *)conn;
|
||||
ndbg("ECHO reply: id=%d seqno=%d\n", ntohs(icmp->id), ntohs(icmp->seqno));
|
||||
|
||||
if (ntohs(icmp->id) == pstate->png_id)
|
||||
{
|
||||
/* Consume the ECHOREPLY */
|
||||
|
||||
flags &= ~UIP_ECHOREPLY;
|
||||
dev->d_len = 0;
|
||||
|
||||
/* Return the result to the caller */
|
||||
|
||||
pstate->png_result = OK;
|
||||
pstate->png_seqno = ntohs(icmp->seqno);
|
||||
goto end_wait;
|
||||
|
@ -213,13 +224,19 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
|
|||
#else
|
||||
# error "IPv6 ECHO Request not implemented"
|
||||
#endif
|
||||
memset(ICMPDAT, 0, pstate->png_datlen);
|
||||
/* Add some easily verifiable data */
|
||||
|
||||
for (i = 0; i < pstate->png_datlen; i++)
|
||||
{
|
||||
ICMPDAT[i] = i;
|
||||
}
|
||||
|
||||
/* Send the ICMP echo request. Note that d_sndlen is set to
|
||||
* the size of the ICMP payload and does not include the size
|
||||
* of the ICMP header.
|
||||
*/
|
||||
|
||||
ndbg("Send ECHO request: seqno=%d\n", pstate->png_seqno);
|
||||
dev->d_sndlen= pstate->png_datlen + 4;
|
||||
uip_icmpsend(dev, &pstate->png_addr);
|
||||
pstate->png_sent = TRUE;
|
||||
|
@ -233,7 +250,7 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
|
|||
{
|
||||
/* Yes.. report the timeout */
|
||||
|
||||
nvdbg("Ping timeout\n");
|
||||
ndbg("Ping timeout\n");
|
||||
pstate->png_result = failcode;
|
||||
goto end_wait;
|
||||
}
|
||||
|
@ -243,6 +260,8 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
|
|||
return flags;
|
||||
|
||||
end_wait:
|
||||
nvdbg("Resuming\n");
|
||||
|
||||
/* Do not allow any further callbacks */
|
||||
|
||||
pstate->png_cb->flags = 0;
|
||||
|
@ -313,6 +332,11 @@ int uip_ping(uip_ipaddr_t addr, uint16 id, uint16 seqno, uint16 datalen, int dse
|
|||
state.png_cb->flags = UIP_POLL|UIP_ECHOREPLY;
|
||||
state.png_cb->private = (void*)&state;
|
||||
state.png_cb->event = ping_interrupt;
|
||||
state.png_result = -EINTR; /* Assume sem-wait interrupted by signal */
|
||||
|
||||
/* Notify the device driver of the availaibilty of TX data */
|
||||
|
||||
netdev_txnotify(&state.png_addr);
|
||||
|
||||
/* Wait for either the full round trip transfer to complete or
|
||||
* for timeout to occur. (1) sem_wait will also terminate if a
|
||||
|
@ -321,7 +345,7 @@ int uip_ping(uip_ipaddr_t addr, uint16 id, uint16 seqno, uint16 datalen, int dse
|
|||
* re-enabled when the task restarts.
|
||||
*/
|
||||
|
||||
state.png_result = -EINTR; /* Assume sem-waited interrupt by signal */
|
||||
ndbg("Start time: 0x%08x seqno: %d\n", state.png_time, seqno);
|
||||
sem_wait(&state.png_sem);
|
||||
|
||||
uip_icmpcallbackfree(state.png_cb);
|
||||
|
@ -334,10 +358,12 @@ int uip_ping(uip_ipaddr_t addr, uint16 id, uint16 seqno, uint16 datalen, int dse
|
|||
|
||||
if (!state.png_result)
|
||||
{
|
||||
ndbg("Return seqno=%d\n", state.png_seqno);
|
||||
return (int)state.png_seqno;
|
||||
}
|
||||
else
|
||||
{
|
||||
ndbg("Return error=%d\n", -state.png_result);
|
||||
return state.png_result;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue