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.git

commit 884a6803d659b93b9e7291009c0d9645284a9059
Author: meijian <[email protected]>
AuthorDate: Fri Oct 18 14:11:47 2024 +0800

    net/getifaddrs: Support multiple IPv6 addresses for getifaddrs
    
    Signed-off-by: meijian <[email protected]>
---
 libs/libc/net/lib_getifaddrs.c | 78 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/libs/libc/net/lib_getifaddrs.c b/libs/libc/net/lib_getifaddrs.c
index 7a722e9a0d..2bb67dc806 100644
--- a/libs/libc/net/lib_getifaddrs.c
+++ b/libs/libc/net/lib_getifaddrs.c
@@ -24,6 +24,7 @@
  * Included Files
  ****************************************************************************/
 
+#include <debug.h>
 #include <errno.h>
 #include <ifaddrs.h>
 #include <net/if.h>
@@ -57,6 +58,76 @@ struct myifaddrs
   struct sockaddr         hwaddr;
 };
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getmutil_ipv6addr
+ *
+ * Input Parameters:
+ *   fd     - socket fd of ioctl.
+ *   req    - lifreq struct for ioctl request.
+ *   ifaddr - the ifaddrs struct to be filled.
+ *
+ * Returned Value:
+ *   On success, getmutil_ipv6addr() returns newest pointer of the linked
+ *   list; on error, NULL is returned.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_MAX_IPv6_ADDR
+static FAR struct myifaddrs *getmutil_ipv6addr(int fd, struct lifreq *req,
+                                               FAR struct myifaddrs *ifaddr)
+{
+  FAR struct sockaddr_in6 *ipv6addr;
+  int index;
+
+  /* eth0:0 is the second ipaddr */
+
+  for (index = 0; index < CONFIG_NETDEV_MAX_IPv6_ADDR - 1; index++)
+    {
+      int len = snprintf(req->lifr_name, sizeof(req->lifr_name),
+                         "%s:%d", ifaddr->name, index);
+
+      if (len < 0 || len >= sizeof(req->lifr_name))
+        {
+          nwarn("ifname %s:%2d error or too long\n", ifaddr->name, index);
+          return ifaddr;
+        }
+
+      if (ioctl(fd, SIOCGLIFADDR, (unsigned long)req) < 0)
+        {
+          continue;
+        }
+
+      ipv6addr = (FAR struct sockaddr_in6 *)&(req->lifr_addr);
+      if (IN6_IS_ADDR_UNSPECIFIED(&ipv6addr->sin6_addr))
+        {
+          continue;
+        }
+
+      ifaddr->addrs.ifa_next = lib_zalloc(sizeof(*ifaddr));
+      if (ifaddr == NULL)
+        {
+          return NULL;
+        }
+
+      memcpy(ifaddr->addrs.ifa_next, ifaddr, sizeof(struct myifaddrs));
+      ifaddr = (FAR struct myifaddrs *)ifaddr->addrs.ifa_next;
+      memcpy(&ifaddr->addr, &(req->lifr_addr), sizeof(req->lifr_addr));
+      ifaddr->addrs.ifa_addr = (FAR struct sockaddr *)&ifaddr->addr;
+      ifaddr->addrs.ifa_netmask = (FAR struct sockaddr *)&ifaddr->netmask;
+      ifaddr->addrs.ifa_dstaddr = (FAR struct sockaddr *)&ifaddr->dstaddr;
+      ifaddr->addrs.ifa_broadaddr =
+            (FAR struct sockaddr *)&ifaddr->broadaddr;
+      ifaddr->addrs.ifa_data = (FAR struct sockaddr *)&ifaddr->hwaddr;
+    }
+
+  return ifaddr;
+}
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -267,6 +338,13 @@ int getifaddrs(FAR struct ifaddrs **addrs)
               memcpy(&myaddrs->hwaddr,
                      &req.lifr_hwaddr, sizeof(req.lifr_hwaddr));
             }
+
+#  ifdef CONFIG_NETDEV_MAX_IPv6_ADDR
+          if (getmutil_ipv6addr(sockfd, &req, myaddrs) == NULL)
+            {
+              goto err;
+            }
+#  endif
         }
 #endif
     }

Reply via email to