diff --git a/examples/nsh/nsh_netcmds.c b/examples/nsh/nsh_netcmds.c
index c5eebe425e6fbec450f890ffb24627d1e8daad20..01f472a319b78dbfe9ef30a9bec019e3a8994c86 100644
--- a/examples/nsh/nsh_netcmds.c
+++ b/examples/nsh/nsh_netcmds.c
@@ -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:
diff --git a/include/net/uip/uip-tcp.h b/include/net/uip/uip-tcp.h
index e0d696981704acbc1a83dea0bce7f5898b2f4505..e625e88656afe678ebdc0bb3aa1763d0956a5490 100644
--- a/include/net/uip/uip-tcp.h
+++ b/include/net/uip/uip-tcp.h
@@ -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 */
diff --git a/net/net-internal.h b/net/net-internal.h
index 6573850c442c60f012195cac44d78dae97a0bf8c..43d8d81df1eeeddb2599af18201e101d469d611d 100644
--- a/net/net-internal.h
+++ b/net/net-internal.h
@@ -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 ***************************************************************/
diff --git a/net/netdev-findbyaddr.c b/net/netdev-findbyaddr.c
index c751960bf2cceb82833d8aa2c5f360abd6e05a0f..0167f6312a76eadd324493d71a51aaafb8b9743b 100644
--- a/net/netdev-findbyaddr.c
+++ b/net/netdev-findbyaddr.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;
 
diff --git a/net/netdev-txnotify.c b/net/netdev-txnotify.c
index 91a225effecbd48554994187e2e47a19b5bb5776..c600e34d38a22039197508fad243ac7bfd5235cc 100644
--- a/net/netdev-txnotify.c
+++ b/net/netdev-txnotify.c
@@ -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 */
 
diff --git a/net/uip/uip-arp.c b/net/uip/uip-arp.c
index 0c33eabfecd1adb4adaf3e5f0c5a4a9a96e74287..6c48ec1b0121d9ae0de3b605320e1475f5ba3f2a 100644
--- a/net/uip/uip-arp.c
+++ b/net/uip/uip-arp.c
@@ -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);
diff --git a/net/uip/uip-callback.c b/net/uip/uip-callback.c
index 22755a43a9ac0490fd6b9422f531cf14bcdd4256..9a2ad781610bafa830808bffdc3098897eccc4a5 100644
--- a/net/uip/uip-callback.c
+++ b/net/uip/uip-callback.c
@@ -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);
         }
 
diff --git a/net/uip/uip-chksum.c b/net/uip/uip-chksum.c
index 479ebc79778e0e1f3972a467aa780a3e8b51cc36..0bfa82861d581454f230a3c393338aee8de4dd86 100644
--- a/net/uip/uip-chksum.c
+++ b/net/uip/uip-chksum.c
@@ -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>
  *
  *
diff --git a/net/uip/uip-icmpinput.c b/net/uip/uip-icmpinput.c
index b6cad0118783e642a968db732ca1e77ad1613445..32bfe2db915da13b5b13766809c5810c0211cf6c 100644
--- a/net/uip/uip-icmpinput.c
+++ b/net/uip/uip-icmpinput.c
@@ -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
 
diff --git a/net/uip/uip-icmpping.c b/net/uip/uip-icmpping.c
index 5bc9b68b04bf8b6092ef682895511a999d35db72..3029e2fc2768c29746d124d2b394156c358ae2b5 100644
--- a/net/uip/uip-icmpping.c
+++ b/net/uip/uip-icmpping.c
@@ -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;
     }
 }