浏览代码

ping cmd with specified netif in lwip-2.1.2

using LWIP_HOOK_IP4_ROUTE_SRC hook find specified netif route, using
cmd `ping 192.168.xx.xx e0`, ping dest using e0 netif. if not found
netif, using default netif, the effect is same as the cmd `ping 192.168.xx.xx` that only ping with default netif.
yukelab 3 年之前
父节点
当前提交
cda78884aa

+ 24 - 0
components/net/lwip-2.1.2/src/arch/sys_arch.c

@@ -779,6 +779,30 @@ void ppp_trace(int level, const char *format, ...)
 }
 #endif
 
+struct netif *lwip_ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
+{
+    struct netif *netif;
+
+    /* iterate through netifs */
+    for (netif = netif_list; netif != NULL; netif = netif->next)
+    {
+    /* is the netif up, does it have a link and a valid address? */
+    if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif)))
+    {
+    /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
+    if (src != NULL)
+    {
+        if (ip4_addr_cmp(src, netif_ip4_addr(netif)))
+        {
+            return netif;
+        }
+    }
+    }
+  }
+  netif = netif_default;
+  return netif;
+}
+
 /*
  * export bsd socket symbol for RT-Thread Application Module
  */

+ 1 - 0
components/net/lwip-2.1.2/src/lwipopts.h

@@ -648,4 +648,5 @@
 #endif
 
 
+#define LWIP_HOOK_IP4_ROUTE_SRC(dest, src)  lwip_ip4_route_src(dest, src)
 #endif /* __LWIPOPTS_H__ */

+ 7 - 0
components/net/lwip-2.1.2/src/netif/ethernetif.c

@@ -201,6 +201,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len,
     struct addrinfo hint, *res = RT_NULL;
     struct sockaddr_in *h = RT_NULL;
     struct in_addr ina;
+    struct sockaddr_in local;
     
     RT_ASSERT(netif);
     RT_ASSERT(host);
@@ -227,6 +228,12 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len,
         return -RT_ERROR;
     }
 
+    local.sin_len = sizeof(local);
+    local.sin_family = AF_INET;
+    local.sin_port = 0;
+    local.sin_addr.s_addr = (netif->ip_addr.addr);
+    lwip_bind(s, (struct sockaddr *)&local, sizeof(struct sockaddr_in));
+
     lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
 
     if (lwip_ping_send(s, &target_addr, data_len) == ERR_OK)

+ 17 - 3
components/net/netdev/src/netdev.c

@@ -1052,7 +1052,7 @@ MSH_CMD_EXPORT_ALIAS(netdev_ifconfig, ifconfig, list the information of all netw
 #endif /* NETDEV_USING_IFCONFIG */
 
 #ifdef NETDEV_USING_PING
-int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
+int netdev_cmd_ping(char* target_name, char *netdev_name, rt_uint32_t times, rt_size_t size)
 {
 #define NETDEV_PING_DATA_SIZE       32
 /** ping receive timeout - in milliseconds */
@@ -1073,6 +1073,16 @@ int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
         size = NETDEV_PING_DATA_SIZE;
     }
 
+    if (netdev_name != RT_NULL)
+    {
+        netdev = netdev_get_by_name(netdev_name);
+        if (netdev == RT_NULL)
+        {
+            netdev = netdev_default;
+            rt_kprintf("ping: not found specified netif, using default netdev %s.\n", netdev->name);
+        }
+    }
+
     if (NETDEV_PING_IS_COMMONICABLE(netdev_default))
     {
         /* using default network interface device for ping */
@@ -1146,9 +1156,13 @@ int netdev_ping(int argc, char **argv)
     {
         rt_kprintf("Please input: ping <host address>\n");
     }
-    else
+    else if (argc == 2)
+    {
+        netdev_cmd_ping(argv[1], RT_NULL, 4, 0);
+    }
+    else if (argc == 3)
     {
-        netdev_cmd_ping(argv[1], 4, 0);
+        netdev_cmd_ping(argv[1], argv[2], 4, 0);
     }
 
     return 0;