This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit df3121213e563345212064d514ae5103f176e561
Author: zhanghongyu <zhanghon...@xiaomi.com>
AuthorDate: Tue Dec 6 13:42:15 2022 +0800

    cmd_arp: add device input for arp interface
    
    Signed-off-by: zhanghongyu <zhanghon...@xiaomi.com>
---
 include/netutils/netlib.h       |  8 ++--
 netutils/dhcpd/dhcpd.c          |  2 +-
 netutils/netlib/netlib_delarp.c | 13 +++++-
 netutils/netlib/netlib_getarp.c | 13 +++++-
 netutils/netlib/netlib_setarp.c | 12 +++++-
 nshlib/nsh_command.c            |  9 +---
 nshlib/nsh_netcmds.c            | 92 +++++++++++++++++++++++++++--------------
 7 files changed, 105 insertions(+), 44 deletions(-)

diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h
index b3d0e95d3..52d311d27 100644
--- a/include/netutils/netlib.h
+++ b/include/netutils/netlib.h
@@ -268,11 +268,13 @@ int netlib_setessid(FAR const char *ifname, FAR const 
char *essid);
 #ifdef CONFIG_NET_ARP
 /* ARP Table Support */
 
-int netlib_del_arpmapping(FAR const struct sockaddr_in *inaddr);
+int netlib_del_arpmapping(FAR const struct sockaddr_in *inaddr,
+                          FAR const char *ifname);
 int netlib_get_arpmapping(FAR const struct sockaddr_in *inaddr,
-                          FAR uint8_t *macaddr);
+                          FAR uint8_t *macaddr, FAR const char *ifname);
 int netlib_set_arpmapping(FAR const struct sockaddr_in *inaddr,
-                          FAR const uint8_t *macaddr);
+                          FAR const uint8_t *macaddr,
+                          FAR const char *ifname);
 #ifdef CONFIG_NETLINK_ROUTE
 struct arp_entry_s;
 ssize_t netlib_get_arptable(FAR struct arp_entry_s *arptab,
diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c
index 667e8290f..4e39119d6 100644
--- a/netutils/dhcpd/dhcpd.c
+++ b/netutils/dhcpd/dhcpd.c
@@ -323,7 +323,7 @@ static inline void dhcpd_arpupdate(FAR uint8_t *ipaddr, FAR 
uint8_t *hwaddr)
 
   /* Update the ARP table */
 
-  netlib_set_arpmapping(&inaddr, hwaddr);
+  netlib_set_arpmapping(&inaddr, hwaddr, NULL);
 }
 #else
 #  define dhcpd_arpupdate(ipaddr,hwaddr)
diff --git a/netutils/netlib/netlib_delarp.c b/netutils/netlib/netlib_delarp.c
index 96c431373..b0275545c 100644
--- a/netutils/netlib/netlib_delarp.c
+++ b/netutils/netlib/netlib_delarp.c
@@ -51,13 +51,15 @@
  *
  * Parameters:
  *   inaddr   The IPv4 address to use in the query
+ *   ifname   The Network device name
  *
  * Return:
  *   0 on success; a negated errno value on failure.
  *
  ****************************************************************************/
 
-int netlib_del_arpmapping(FAR const struct sockaddr_in *inaddr)
+int netlib_del_arpmapping(FAR const struct sockaddr_in *inaddr,
+                          FAR const char *ifname)
 {
   int ret = -EINVAL;
 
@@ -70,6 +72,15 @@ int netlib_del_arpmapping(FAR const struct sockaddr_in 
*inaddr)
 
           memcpy(&req.arp_pa, inaddr, sizeof(struct sockaddr_in));
           memset(&req.arp_ha, 0, sizeof(struct sockaddr_in));
+          if (ifname != NULL)
+            {
+               strlcpy((FAR char *)&req.arp_dev, ifname,
+                       sizeof(req.arp_dev));
+            }
+          else
+            {
+              req.arp_dev[0] = '\0';
+            }
 
           ret = ioctl(sockfd, SIOCDARP, (unsigned long)((uintptr_t)&req));
           if (ret < 0)
diff --git a/netutils/netlib/netlib_getarp.c b/netutils/netlib/netlib_getarp.c
index 5507030a0..c54accb0f 100644
--- a/netutils/netlib/netlib_getarp.c
+++ b/netutils/netlib/netlib_getarp.c
@@ -53,6 +53,7 @@
  * Parameters:
  *   inaddr   The IPv4 address to use in the query
  *   macaddr  The location to return the mapped Ethernet MAC address
+ *   ifname   The Network device name
  *
  * Return:
  *   0 on success; a negated errno value on failure.
@@ -60,7 +61,7 @@
  ****************************************************************************/
 
 int netlib_get_arpmapping(FAR const struct sockaddr_in *inaddr,
-                          FAR uint8_t *macaddr)
+                          FAR uint8_t *macaddr, FAR const char *ifname)
 {
   int ret = -EINVAL;
 
@@ -72,6 +73,16 @@ int netlib_get_arpmapping(FAR const struct sockaddr_in 
*inaddr,
           struct arpreq req;
 
           memcpy(&req.arp_pa, inaddr, sizeof(struct sockaddr_in));
+          if (ifname != NULL)
+            {
+               strlcpy((FAR char *)&req.arp_dev, ifname,
+                       sizeof(req.arp_dev));
+            }
+          else
+            {
+              req.arp_dev[0] = '\0';
+            }
+
           ret = ioctl(sockfd, SIOCGARP, (unsigned long)((uintptr_t)&req));
           if (ret < 0)
             {
diff --git a/netutils/netlib/netlib_setarp.c b/netutils/netlib/netlib_setarp.c
index ed21a6968..2e0644164 100644
--- a/netutils/netlib/netlib_setarp.c
+++ b/netutils/netlib/netlib_setarp.c
@@ -53,6 +53,7 @@
  * Parameters:
  *   inaddr   The IPv4 address to use in the mapping
  *   macaddr  The Ethernet MAC address to use in the mapping
+ *   ifname   The Network device name
  *
  * Return:
  *   0 on success; a negated errno value on failure.
@@ -60,7 +61,7 @@
  ****************************************************************************/
 
 int netlib_set_arpmapping(FAR const struct sockaddr_in *inaddr,
-                          FAR const uint8_t *macaddr)
+                          FAR const uint8_t *macaddr, FAR const char *ifname)
 {
   int ret = -EINVAL;
 
@@ -75,6 +76,15 @@ int netlib_set_arpmapping(FAR const struct sockaddr_in 
*inaddr,
 
           req.arp_ha.sa_family = ARPHRD_ETHER;
           memcpy(&req.arp_ha.sa_data, macaddr, ETHER_ADDR_LEN);
+          if (ifname != NULL)
+            {
+               strlcpy((FAR char *)&req.arp_dev, ifname,
+                       sizeof(req.arp_dev));
+            }
+          else
+            {
+              req.arp_dev[0] = '\0';
+            }
 
           ret = ioctl(sockfd, SIOCSARP, (unsigned long)((uintptr_t)&req));
           if (ret < 0)
diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c
index 9adf0d058..ba8bf74f0 100644
--- a/nshlib/nsh_command.c
+++ b/nshlib/nsh_command.c
@@ -106,13 +106,8 @@ static const struct cmdmap_s g_cmdmap[] =
 #endif
 
 #if defined(CONFIG_NET) && defined(CONFIG_NET_ARP) && 
!defined(CONFIG_NSH_DISABLE_ARP)
-#ifdef CONFIG_NETLINK_ROUTE
-  { "arp",      cmd_arp,      2, 4,
-    "[-t|-a <ipaddr>|-d <ipaddr>|-s <ipaddr> <hwaddr>]" },
-#else
-  { "arp",      cmd_arp,      3, 4,
-    "[-a <ipaddr>|-d <ipaddr>|-s <ipaddr> <hwaddr>]" },
-#endif
+  { "arp",      cmd_arp,      1, 6,
+    "[-i <ifname>] [-a <ipaddr>|-d <ipaddr>|-s <ipaddr> <hwaddr>]" },
 #endif
 
 #if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_BASE64)
diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c
index 77d33c2e3..203cf2580 100644
--- a/nshlib/nsh_netcmds.c
+++ b/nshlib/nsh_netcmds.c
@@ -43,6 +43,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <debug.h>
+#include <getopt.h>
 
 #if defined(CONFIG_LIBC_NETDB) && !defined(CONFIG_NSH_DISABLE_NSLOOKUP)
 #  include <netdb.h>
@@ -1038,21 +1039,61 @@ int cmd_nslookup(FAR struct nsh_vtbl_s *vtbl, int argc, 
FAR char **argv)
 #if defined(CONFIG_NET_ARP) && !defined(CONFIG_NSH_DISABLE_ARP)
 int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
 {
+  enum opt_type_e
+  {
+    OPT_TYPE_ARP_LIST,
+    OPT_TYPE_ARP_GET,
+    OPT_TYPE_ARP_DELETE,
+    OPT_TYPE_ARP_SET
+  } opt_type = OPT_TYPE_ARP_LIST;
+
   struct sockaddr_in inaddr;
   struct ether_addr mac;
+  FAR const char *ifname = NULL;
+  int option;
   int ret;
 
   /* Forms:
    *
-   * arp -t
-   * arp -a <ipaddr>
-   * arp -d <ipdaddr>
-   * arp -s <ipaddr> <hwaddr>
+   * arp [-i <ifname>]
+   * arp [-i <ifname>] -a <ipaddr>
+   * arp [-i <ifname>] -d <ipdaddr>
+   * arp [-i <ifname>] -s <ipaddr> <hwaddr>
    */
 
   memset(&inaddr, 0, sizeof(inaddr));
+
+  while ((option = getopt(argc, argv, "adsi:")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'a':
+            opt_type = OPT_TYPE_ARP_GET;
+            break;
+
+          case 'd':
+            opt_type = OPT_TYPE_ARP_DELETE;
+            break;
+
+          case 's':
+            opt_type = OPT_TYPE_ARP_SET;
+            break;
+
+          case 'i':
+            ifname = optarg;
+            break;
+
+          case ':':
+            goto errout_missing;
+
+          case '?':
+          default:
+            goto errout_invalid;
+        }
+    }
+
 #ifdef CONFIG_NETLINK_ROUTE
-  if (strcmp(argv[1], "-t") == 0)
+  if (opt_type == OPT_TYPE_ARP_LIST)
     {
       FAR struct arp_entry_s *arptab;
       size_t arpsize;
@@ -1061,11 +1102,6 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
       char ethaddr[24];
       int i;
 
-      if (argc != 2)
-        {
-          goto errout_toomany;
-        }
-
       /* Allocate a buffer to hold the ARP table */
 
       arpsize = CONFIG_NET_ARPTAB_SIZE * sizeof(struct arp_entry_s);
@@ -1129,22 +1165,22 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
     }
   else
 #endif
-  if (strcmp(argv[1], "-a") == 0)
+  if (opt_type == OPT_TYPE_ARP_GET)
     {
       char hwaddr[20];
 
-      if (argc != 3)
+      if (argc - optind < 1)
         {
-          goto errout_toomany;
+          goto errout_missing;
         }
 
       /* Show the corresponding hardware address */
 
       inaddr.sin_family      = AF_INET;
       inaddr.sin_port        = 0;
-      inaddr.sin_addr.s_addr = inet_addr(argv[2]);
+      inaddr.sin_addr.s_addr = inet_addr(argv[optind]);
 
-      ret = netlib_get_arpmapping(&inaddr, mac.ether_addr_octet);
+      ret = netlib_get_arpmapping(&inaddr, mac.ether_addr_octet, ifname);
       if (ret < 0)
         {
           goto errout_cmdfaild;
@@ -1152,35 +1188,35 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
 
       nsh_output(vtbl, "HWaddr: %s\n", ether_ntoa_r(&mac, hwaddr));
     }
-  else if (strcmp(argv[1], "-d") == 0)
+  else if (opt_type == OPT_TYPE_ARP_DELETE)
     {
-      if (argc != 3)
+      if (argc - optind < 1)
         {
-          goto errout_toomany;
+          goto errout_missing;
         }
 
       /* Delete the corresponding address mapping from the arp table */
 
       inaddr.sin_family      = AF_INET;
       inaddr.sin_port        = 0;
-      inaddr.sin_addr.s_addr = inet_addr(argv[2]);
+      inaddr.sin_addr.s_addr = inet_addr(argv[optind]);
 
-      ret = netlib_del_arpmapping(&inaddr);
+      ret = netlib_del_arpmapping(&inaddr, ifname);
       if (ret < 0)
         {
           goto errout_cmdfaild;
         }
     }
-  else if (strcmp(argv[1], "-s") == 0)
+  else if (opt_type == OPT_TYPE_ARP_SET)
     {
-      if (argc != 4)
+      if (argc - optind < 2)
         {
           goto errout_missing;
         }
 
       /* Convert the MAC address string to a binary */
 
-      if (!netlib_ethaddrconv(argv[3], mac.ether_addr_octet))
+      if (!netlib_ethaddrconv(argv[optind + 1], mac.ether_addr_octet))
         {
           goto errout_invalid;
         }
@@ -1189,9 +1225,9 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
 
       inaddr.sin_family      = AF_INET;
       inaddr.sin_port        = 0;
-      inaddr.sin_addr.s_addr = inet_addr(argv[2]);
+      inaddr.sin_addr.s_addr = inet_addr(argv[optind]);
 
-      ret = netlib_set_arpmapping(&inaddr, mac.ether_addr_octet);
+      ret = netlib_set_arpmapping(&inaddr, mac.ether_addr_octet, ifname);
       if (ret < 0)
         {
           goto errout_cmdfaild;
@@ -1209,7 +1245,7 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
 errout_cmdfaild:
   if (ret == -ENOENT)
     {
-      nsh_error(vtbl, g_fmtnosuch, argv[0], "ARP entry", argv[2]);
+      nsh_error(vtbl, g_fmtnosuch, argv[0], "ARP entry", argv[optind]);
     }
   else
     {
@@ -1219,10 +1255,6 @@ errout_cmdfaild:
   return ERROR;
 
 errout_missing:
-  nsh_error(vtbl, g_fmttoomanyargs, argv[0]);
-  return ERROR;
-
-errout_toomany:
   nsh_error(vtbl, g_fmtargrequired, argv[0]);
   return ERROR;
 

Reply via email to