9
0
Fork 0

ping() integrated

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@872 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2008-09-03 16:14:00 +00:00
parent 4be5ae53a0
commit 63c893a73c
10 changed files with 105 additions and 31 deletions

View File

@ -270,14 +270,14 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
uip_ipaddr_t ipaddr; uip_ipaddr_t ipaddr;
uint32 start; uint32 start;
uint32 next; uint32 next;
uint32 dsec; uint32 dsec = 10;
uint16 id; uint16 id;
int sec = 1;
int count = 10; int count = 10;
int option; int option;
int seqno; int seqno;
int replies = 0; int replies = 0;
int elapsed; int elapsed;
int tmp;
int i; int i;
/* Get the ping options */ /* Get the ping options */
@ -296,12 +296,13 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
break; break;
case 'i': case 'i':
sec = atoi(optarg); tmp = atoi(optarg);
if (sec < 1 || sec >= 4294) if (tmp < 1 || tmp >= 4294)
{ {
fmt = g_fmtargrange; fmt = g_fmtargrange;
goto errout; goto errout;
} }
dsec = 10 * tmp;
break; break;
case ':': case ':':
@ -334,39 +335,67 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
goto errout; goto errout;
} }
/* Convert the ping interval to microseconds and deciseconds*/
dsec = 10 * sec;
/* Get the ID to use */ /* Get the ID to use */
id = ping_newid(); id = ping_newid();
/* Loop for the specified count */ /* 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; 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); 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", nsh_output(vtbl, "%d bytes from %s: icmp_seq=%d time=%d ms\n",
DEFAULT_PING_DATALEN, staddr, seqno, elapsed); DEFAULT_PING_DATALEN, staddr, seqno, elapsed);
replies++; 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); elapsed = TICK2DSEC(g_system_timer - next);
if (elapsed < dsec) if (elapsed < dsec)
{ {
usleep(100000*dsec); usleep(100000*dsec);
} }
} }
/* Get the total elapsed time */
elapsed = TICK2MSEC(g_system_timer - start); elapsed = TICK2MSEC(g_system_timer - start);
nsh_output(vtbl, "%d packets transmitted, %d received, %d%% packet loss, time %dms\n", /* Calculate the percentage of lost packets */
count, replies, (100*replies + count/2)/count, elapsed);
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; return OK;
errout: errout:

View File

@ -91,7 +91,13 @@
#define UIP_TS_MASK 15 #define UIP_TS_MASK 15
#define UIP_STOPPED 16 #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_TCPH_LEN 20 /* Size of TCP header */
#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + TCP header */ #define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + TCP header */

View File

@ -174,13 +174,13 @@ EXTERN FAR struct uip_driver_s *netdev_findbyname(const char *ifname);
/* net-findbyaddr.c **********************************************************/ /* net-findbyaddr.c **********************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0 #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 #endif
/* net-txnotify.c ************************************************************/ /* net-txnotify.c ************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0 #if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN void netdev_txnotify(uip_ipaddr_t *raddr); EXTERN void netdev_txnotify(const uip_ipaddr_t *raddr);
#endif #endif
/* net-count.c ***************************************************************/ /* net-count.c ***************************************************************/

View File

@ -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; struct uip_driver_s *dev;

View File

@ -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 */ /* Find the device driver that serves the subnet of the remote address */

View File

@ -323,10 +323,7 @@ void uip_arp_arpin(struct uip_driver_s *dev)
uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr); uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr);
/* The reply opcode is 2. */ ARPBUF->ah_opcode = HTONS(ARP_REPLY);
ARPBUF->ah_opcode = HTONS(2);
memcpy(ARPBUF->ah_dhwaddr, ARPBUF->ah_shwaddr, ETHER_ADDR_LEN); memcpy(ARPBUF->ah_dhwaddr, ARPBUF->ah_shwaddr, ETHER_ADDR_LEN);
memcpy(ARPBUF->ah_shwaddr, dev->d_mac.ether_addr_octet, 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); memcpy(ETHBUF->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);

View File

@ -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) * 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); flags = list->event(dev, pvconn, list->private, flags);
} }

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* net/uip/uip-chksum.c * 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> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* *

View File

@ -243,7 +243,23 @@ typeerr:
#ifdef CONFIG_NET_ICMP_PING #ifdef CONFIG_NET_ICMP_PING
else if (ICMPBUF->type == ICMP6_ECHO_REPLY && g_echocallback) 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 #endif

View File

@ -58,7 +58,7 @@
****************************************************************************/ ****************************************************************************/
#define ICMPBUF ((struct uip_icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN]) #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 */ /* 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; struct icmp_ping_s *pstate = (struct icmp_ping_s *)pvprivate;
int failcode = -ETIMEDOUT; int failcode = -ETIMEDOUT;
int i;
nvdbg("flags: %04x\n", flags); nvdbg("flags: %04x\n", flags);
if (pstate) if (pstate)
@ -162,6 +163,7 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
* that the destination address is not reachable. * that the destination address is not reachable.
*/ */
nvdbg("Not reachable\n");
failcode = -ENETUNREACH; failcode = -ENETUNREACH;
} }
else else
@ -175,8 +177,17 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
if ((flags & UIP_ECHOREPLY) != 0 && conn != NULL) if ((flags & UIP_ECHOREPLY) != 0 && conn != NULL)
{ {
struct uip_icmpip_hdr *icmp = (struct uip_icmpip_hdr *)conn; 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) 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_result = OK;
pstate->png_seqno = ntohs(icmp->seqno); pstate->png_seqno = ntohs(icmp->seqno);
goto end_wait; goto end_wait;
@ -213,13 +224,19 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
#else #else
# error "IPv6 ECHO Request not implemented" # error "IPv6 ECHO Request not implemented"
#endif #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 /* Send the ICMP echo request. Note that d_sndlen is set to
* the size of the ICMP payload and does not include the size * the size of the ICMP payload and does not include the size
* of the ICMP header. * of the ICMP header.
*/ */
ndbg("Send ECHO request: seqno=%d\n", pstate->png_seqno);
dev->d_sndlen= pstate->png_datlen + 4; dev->d_sndlen= pstate->png_datlen + 4;
uip_icmpsend(dev, &pstate->png_addr); uip_icmpsend(dev, &pstate->png_addr);
pstate->png_sent = TRUE; pstate->png_sent = TRUE;
@ -233,7 +250,7 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
{ {
/* Yes.. report the timeout */ /* Yes.. report the timeout */
nvdbg("Ping timeout\n"); ndbg("Ping timeout\n");
pstate->png_result = failcode; pstate->png_result = failcode;
goto end_wait; goto end_wait;
} }
@ -243,6 +260,8 @@ static uint16 ping_interrupt(struct uip_driver_s *dev, void *conn,
return flags; return flags;
end_wait: end_wait:
nvdbg("Resuming\n");
/* Do not allow any further callbacks */ /* Do not allow any further callbacks */
pstate->png_cb->flags = 0; 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->flags = UIP_POLL|UIP_ECHOREPLY;
state.png_cb->private = (void*)&state; state.png_cb->private = (void*)&state;
state.png_cb->event = ping_interrupt; 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 /* Wait for either the full round trip transfer to complete or
* for timeout to occur. (1) sem_wait will also terminate if a * 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. * 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); sem_wait(&state.png_sem);
uip_icmpcallbackfree(state.png_cb); 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) if (!state.png_result)
{ {
ndbg("Return seqno=%d\n", state.png_seqno);
return (int)state.png_seqno; return (int)state.png_seqno;
} }
else else
{ {
ndbg("Return error=%d\n", -state.png_result);
return state.png_result; return state.png_result;
} }
} }