Ver Fonte

Fix `ping` cmd can supported ping domain name, like 'ping rtthread.com'.

armink há 8 anos atrás
pai
commit
dad98f0c06
1 ficheiros alterados com 52 adições e 39 exclusões
  1. 52 39
      ping/ping.c

+ 52 - 39
ping/ping.c

@@ -2,16 +2,16 @@
  * netutils: ping implementation
  */
 
-#include "lwip/opt.h"
-
-#include "lwip/mem.h"
-#include "lwip/icmp.h"
-#include "lwip/netif.h"
-#include "lwip/sys.h"
-#include "lwip/sockets.h"
-#include "lwip/inet.h"
-#include "lwip/inet_chksum.h"
-#include "lwip/ip.h"
+#include <lwip/opt.h>
+#include <lwip/mem.h>
+#include <lwip/icmp.h>
+#include <lwip/netif.h>
+#include <lwip/sys.h>
+#include <lwip/inet.h>
+#include <lwip/inet_chksum.h>
+#include <lwip/ip.h>
+#include <lwip/netdb.h>
+#include <lwip/sockets.h>
 
 /**
  * PING_DEBUG: Enable debugging for PING.
@@ -55,9 +55,9 @@ static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
     iecho->seqno  = htons(++ping_seq_num);
 
     /* fill the additional data buffer with some data */
-    for(i = 0; i < data_len; i++)
+    for (i = 0; i < data_len; i++)
     {
-        ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
+        ((char*) iecho)[sizeof(struct icmp_echo_hdr) + i] = (char) i;
     }
 
     iecho->chksum = inet_chksum(iecho, len);
@@ -69,7 +69,7 @@ static err_t ping_send(int s, ip_addr_t *addr, int size)
     int err;
     struct icmp_echo_hdr *iecho;
     struct sockaddr_in to;
-    size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
+    int ping_size = sizeof(struct icmp_echo_hdr) + size;
     LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
 
     iecho = rt_malloc(ping_size);
@@ -78,13 +78,13 @@ static err_t ping_send(int s, ip_addr_t *addr, int size)
         return ERR_MEM;
     }
 
-    ping_prepare_echo(iecho, (u16_t)ping_size);
+    ping_prepare_echo(iecho, (u16_t) ping_size);
 
     to.sin_len = sizeof(to);
     to.sin_family = AF_INET;
     to.sin_addr.s_addr = addr->addr;
 
-    err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
+    err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*) &to, sizeof(to));
     rt_free(iecho);
 
     return (err == ping_size ? ERR_OK : ERR_VAL);
@@ -98,12 +98,12 @@ static int ping_recv(int s, int *ttl)
     struct ip_hdr *iphdr;
     struct icmp_echo_hdr *iecho;
 
-    while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0)
+    while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*) &from, (socklen_t*) &fromlen)) > 0)
     {
-        if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr)))
+        if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)))
         {
-            iphdr = (struct ip_hdr *)buf;
-            iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4));
+            iphdr = (struct ip_hdr *) buf;
+            iecho = (struct icmp_echo_hdr *) (buf + (IPH_HL(iphdr) * 4));
             if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)))
             {
                 *ttl = iphdr->_ttl;
@@ -115,34 +115,44 @@ static int ping_recv(int s, int *ttl)
     return len;
 }
 
-rt_err_t ping(char* target, rt_uint32_t times, rt_size_t size)
+rt_err_t ping(char* target_name, rt_uint32_t times, rt_size_t size)
 {
     int s, ttl, recv_len;
     struct timeval timeout = { PING_RCV_TIMEO / RT_TICK_PER_SECOND, PING_RCV_TIMEO % RT_TICK_PER_SECOND };
-    ip_addr_t ping_target;
+    ip_addr_t target_addr;
     rt_uint32_t send_times;
     rt_tick_t recv_start_tick;
-    struct _ip_addr
-    {
-        rt_uint8_t addr0, addr1, addr2, addr3;
-    } *addr;
+    struct addrinfo hint, *res = NULL;
+    struct sockaddr_in *h = NULL;
+    struct in_addr ina;
 
     send_times = 0;
     ping_seq_num = 0;
 
-    if(size == 0)
+    if (size == 0)
+    {
         size = PING_DATA_SIZE;
+    }
 
-    if (inet_aton(target, &ping_target) == 0)
+    memset(&hint, 0, sizeof(hint));
+    /* convert URL to IP */
+    if (lwip_getaddrinfo(target_name, NULL, &hint, &res) != 0)
     {
-        rt_kprintf("ping: unknown host %s\n", target);
+        rt_kprintf("ping: unknown host %s\n", target_name);
         return -RT_ERROR;
     }
-    addr = (struct _ip_addr*)&ping_target;
-
+    memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
+    memcpy(&ina, &h->sin_addr, sizeof(ina));
+    lwip_freeaddrinfo(res);
+    if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
+    {
+        rt_kprintf("ping: unknown host %s\n", target_name);
+        return -RT_ERROR;
+    }
+    /* new a socket */
     if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
     {
-        rt_kprintf("ping: create socket failled\n");
+        rt_kprintf("ping: create socket failed\n");
         return -RT_ERROR;
     }
 
@@ -150,27 +160,30 @@ rt_err_t ping(char* target, rt_uint32_t times, rt_size_t size)
 
     while (1)
     {
-        if (ping_send(s, &ping_target, size) == ERR_OK)
+        if (ping_send(s, &target_addr, size) == ERR_OK)
         {
             recv_start_tick = rt_tick_get();
             if ((recv_len = ping_recv(s, &ttl)) >= 0)
             {
-                rt_kprintf("%d bytes from %d.%d.%d.%d icmp_seq=%d ttl=%d time=%d ticks\n", recv_len, addr->addr0,
-                        addr->addr1, addr->addr2, addr->addr3, send_times, ttl, rt_tick_get() - recv_start_tick);
+                rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ticks\n", recv_len, inet_ntoa(ina), send_times,
+                        ttl, rt_tick_get() - recv_start_tick);
             }
             else
             {
-                rt_kprintf("From %d.%d.%d.%d icmp_seq=%d timeout\n", addr->addr0, addr->addr1, addr->addr2,
-                        addr->addr3, send_times);
+                rt_kprintf("From %s icmp_seq=%d timeout\n", inet_ntoa(ina), send_times);
             }
         }
         else
         {
-            rt_kprintf("Send %d.%d.%d.%d - error\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
+            rt_kprintf("Send %s - error\n", inet_ntoa(ina));
         }
 
-        send_times ++;
-        if (send_times >= times) break; /* send ping times reached, stop */
+        send_times++;
+        if (send_times >= times)
+        {
+            /* send ping times reached, stop */
+            break;
+        }
 
         rt_thread_delay(PING_DELAY); /* take a delay */
     }