You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gu...@apache.org on 2021/12/21 14:01:43 UTC

[incubator-nuttx] branch master updated (2737701 -> cc1a1b5)

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

gustavonihei pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 2737701  cortex-m/hardfault: add secure-fault handler
     new 1cd935f  net: Add lifr_ifindex field to struct lifreq
     new cc1a1b5  net: Implement getifaddrs and freeifaddrs

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 include/{nl_types.h => ifaddrs.h}                  |  33 ++-
 include/net/if.h                                   |   1 +
 libs/libc/net/Make.defs                            |   1 +
 .../net/{lib_freenameindex.c => lib_freeifaddrs.c} |  21 +-
 libs/libc/net/lib_getifaddrs.c                     | 282 +++++++++++++++++++++
 5 files changed, 317 insertions(+), 21 deletions(-)
 copy include/{nl_types.h => ifaddrs.h} (75%)
 copy libs/libc/net/{lib_freenameindex.c => lib_freeifaddrs.c} (80%)
 create mode 100644 libs/libc/net/lib_getifaddrs.c

[incubator-nuttx] 02/02: net: Implement getifaddrs and freeifaddrs

Posted by gu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit cc1a1b5781b73ed3b57e5ec66d697bdf924a2967
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Dec 19 17:41:56 2021 +0800

    net: Implement getifaddrs and freeifaddrs
    
    specify here:
    https://man7.org/linux/man-pages/man3/getifaddrs.3.html
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 include/ifaddrs.h               |  73 +++++++++++
 libs/libc/net/Make.defs         |   1 +
 libs/libc/net/lib_freeifaddrs.c |  56 ++++++++
 libs/libc/net/lib_getifaddrs.c  | 282 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 412 insertions(+)

diff --git a/include/ifaddrs.h b/include/ifaddrs.h
new file mode 100644
index 0000000..286ace2
--- /dev/null
+++ b/include/ifaddrs.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ * include/ifaddrs.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_IFADDRS_H
+#define __INCLUDE_IFADDRS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/socket.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef ifa_broadaddr
+#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
+#endif
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+struct ifaddrs
+{
+  FAR struct ifaddrs  *ifa_next;
+  FAR char            *ifa_name;
+  unsigned int         ifa_flags;
+  FAR struct sockaddr *ifa_addr;
+  FAR struct sockaddr *ifa_netmask;
+  FAR struct sockaddr *ifa_dstaddr;
+  FAR void            *ifa_data;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+extern int getifaddrs(FAR struct ifaddrs **addrs);
+extern void freeifaddrs(FAR struct ifaddrs *addrs);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_IFADDRS_H */
diff --git a/libs/libc/net/Make.defs b/libs/libc/net/Make.defs
index 10aed94..6a51876 100644
--- a/libs/libc/net/Make.defs
+++ b/libs/libc/net/Make.defs
@@ -34,6 +34,7 @@ CSRCS += lib_loopback.c
 endif
 
 ifeq ($(CONFIG_NETDEV_IFINDEX),y)
+CSRCS += lib_getifaddrs.c lib_freeifaddrs.c
 CSRCS += lib_indextoname.c lib_nametoindex.c
 CSRCS += lib_nameindex.c lib_freenameindex.c
 endif
diff --git a/libs/libc/net/lib_freeifaddrs.c b/libs/libc/net/lib_freeifaddrs.c
new file mode 100644
index 0000000..2e68969
--- /dev/null
+++ b/libs/libc/net/lib_freeifaddrs.c
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * libs/libc/net/lib_freeifaddrs.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <ifaddrs.h>
+
+#include "libc.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: freeifaddrs
+ *
+ * Description:
+ *   The freeifaddrs() function frees the data structure returned by
+ *   getifaddrs().
+ *
+ * Input Parameters:
+ *   addrs - The data structure to free
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void freeifaddrs(FAR struct ifaddrs *addrs)
+{
+  while (addrs != NULL)
+    {
+      FAR struct ifaddrs *tmp = addrs;
+      addrs = addrs->ifa_next;
+      lib_free(tmp);
+    }
+}
diff --git a/libs/libc/net/lib_getifaddrs.c b/libs/libc/net/lib_getifaddrs.c
new file mode 100644
index 0000000..0e17cd4
--- /dev/null
+++ b/libs/libc/net/lib_getifaddrs.c
@@ -0,0 +1,282 @@
+/****************************************************************************
+ * libs/libc/net/lib_getifaddrs.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <nuttx/net/netconfig.h>
+
+#include "libc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#undef  broadaddr
+#define broadaddr dstaddr
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+struct myifaddrs
+{
+  struct ifaddrs          addrs;
+  char                    name[IF_NAMESIZE];
+  struct sockaddr_storage addr;
+  struct sockaddr_storage netmask;
+  struct sockaddr_storage dstaddr;
+  struct sockaddr         hwaddr;
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getifaddrs
+ *
+ * Description:
+ *   The getifaddrs() function returns a linked list of ifaddrs structures,
+ *   each containing information about one of the network interfaces on the
+ *   local system. The ifaddrs structure contains at least the following
+ *   entries:
+ *        struct ifaddrs  *ifa_next;
+ *        char            *ifa_name;
+ *        unsigned int     ifa_flags;
+ *        struct sockaddr *ifa_addr;
+ *        struct sockaddr *ifa_netmask;
+ *        struct sockaddr *ifa_dstaddr;
+ *        void            *ifa_data;
+ *  The ifa_next field contains a pointer to the next structure on
+ *  the list, or NULL if this is the last item of the list.
+ *
+ *  The ifa_name points to the null-terminated interface name.
+ *
+ *  The ifa_flags field contains the interface flags, as returned by
+ *  the SIOCGIFFLAGS ioctl(2) operation (see netdevice(7) for a list
+ *  of these flags).
+ *
+ *  The ifa_addr field points to a structure containing the interface
+ *  address.  (The sa_family subfield should be consulted to
+ *  determine the format of the address structure.)  This field may
+ *  contain a null pointer.
+ *
+ *  The ifa_netmask field points to a structure containing the
+ *  netmask associated with ifa_addr, if applicable for the address
+ *  family.  This field may contain a null pointer.
+ *
+ *  Depending on whether the bit IFF_BROADCAST or IFF_POINTOPOINT is
+ *  set in ifa_flags (only one can be set at a time), either
+ *  ifa_broadaddr will contain the broadcast address associated with
+ *  ifa_addr (if applicable for the address family) or ifa_dstaddr
+ *  will contain the destination address of the point-to-point
+ *  interface.
+ *
+ *  The ifa_data field points to a buffer containing address-family-
+ *  specific data; this field may be NULL if there is no such data
+ *  for this interface.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   On success, getifaddrs() returns pointer to the linked list; on error,
+ *   NULL is returned, and errno is set to indicate the error.
+ *
+ ****************************************************************************/
+
+int getifaddrs(FAR struct ifaddrs **addrs)
+{
+  FAR struct myifaddrs *myaddrs = NULL;
+  int sockfd;
+  int i;
+
+  if (addrs == NULL)
+    {
+      set_errno(EINVAL);
+      return ERROR;
+    }
+
+  sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
+  if (sockfd < 0)
+    {
+      return sockfd;
+    }
+
+  for (i = 1, *addrs = NULL; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq req;
+
+      memset(&req, 0, sizeof(req));
+      req.lifr_ifindex = i;
+
+      if (ioctl(sockfd, SIOCGIFNAME, (unsigned long)&req) < 0)
+        {
+          continue; /* Empty slot, try next one */
+        }
+
+      if (ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req) < 0)
+        {
+          goto err;
+        }
+
+      flags = req.lifr_flags;
+
+      if (myaddrs != NULL)
+        {
+          myaddrs->addrs.ifa_next = lib_zalloc(sizeof(*myaddrs));
+          myaddrs = (FAR struct myifaddrs *)myaddrs->addrs.ifa_next;
+        }
+      else
+        {
+          *addrs = lib_zalloc(sizeof(*myaddrs));
+          myaddrs = (FAR struct myifaddrs *)*addrs;
+        }
+
+      if (myaddrs == NULL)
+        {
+          goto err;
+        }
+
+      myaddrs->addrs.ifa_name = myaddrs->name;
+      strncpy(myaddrs->name, req.lifr_name, IF_NAMESIZE);
+
+      myaddrs->addrs.ifa_flags = flags;
+
+#ifdef CONFIG_NET_IPv4
+      if (ioctl(sockfd, SIOCGIFADDR, (unsigned long)&req) >= 0)
+        {
+          myaddrs->addrs.ifa_addr = (FAR struct sockaddr *)&myaddrs->addr;
+          memcpy(&myaddrs->addr, &req.lifr_addr, sizeof(req.lifr_addr));
+
+          if (ioctl(sockfd, SIOCGIFNETMASK, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_netmask =
+                     (FAR struct sockaddr *)&myaddrs->netmask;
+              memcpy(&myaddrs->netmask,
+                     &req.lifr_netmask, sizeof(req.lifr_netmask));
+            }
+
+          if (ioctl(sockfd, SIOCGIFDSTADDR, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_dstaddr =
+                     (FAR struct sockaddr *)&myaddrs->dstaddr;
+              memcpy(&myaddrs->dstaddr,
+                     &req.lifr_dstaddr, sizeof(req.lifr_dstaddr));
+            }
+          else if (ioctl(sockfd, SIOCGIFBRDADDR, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_broadaddr =
+                     (FAR struct sockaddr *)&myaddrs->broadaddr;
+              memcpy(&myaddrs->broadaddr,
+                     &req.lifr_broadaddr, sizeof(req.lifr_broadaddr));
+            }
+
+          if (ioctl(sockfd, SIOCGIFHWADDR, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_data = &myaddrs->hwaddr;
+              memcpy(&myaddrs->hwaddr,
+                     &req.lifr_hwaddr, sizeof(req.lifr_hwaddr));
+            }
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          /* Has IPv4 entry ? */
+
+          if (myaddrs->addrs.ifa_addr)
+            {
+              /* Yes, allocate the new entry for IPv6 */
+
+              myaddrs->addrs.ifa_next = lib_zalloc(sizeof(*myaddrs));
+              myaddrs = (FAR struct myifaddrs *)myaddrs->addrs.ifa_next;
+
+              if (myaddrs == NULL)
+                {
+                  goto err;
+                }
+
+              myaddrs->addrs.ifa_name = myaddrs->name;
+              strncpy(myaddrs->name, req.lifr_name, IF_NAMESIZE);
+
+              myaddrs->addrs.ifa_flags = flags;
+            }
+
+          myaddrs->addrs.ifa_addr = (FAR struct sockaddr *)&myaddrs->addr;
+          memcpy(&myaddrs->addr, &req.lifr_addr, sizeof(req.lifr_addr));
+
+          if (ioctl(sockfd, SIOCGLIFNETMASK, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_netmask =
+                     (FAR struct sockaddr *)&myaddrs->netmask;
+              memcpy(&myaddrs->netmask,
+                     &req.lifr_netmask, sizeof(req.lifr_netmask));
+            }
+
+          if (ioctl(sockfd, SIOCGLIFDSTADDR, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_dstaddr =
+                     (FAR struct sockaddr *)&myaddrs->dstaddr;
+              memcpy(&myaddrs->dstaddr,
+                     &req.lifr_dstaddr, sizeof(req.lifr_dstaddr));
+            }
+          else if (ioctl(sockfd, SIOCGLIFBRDADDR, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_broadaddr =
+                     (FAR struct sockaddr *)&myaddrs->broadaddr;
+              memcpy(&myaddrs->broadaddr,
+                     &req.lifr_broadaddr, sizeof(req.lifr_broadaddr));
+            }
+
+          if (ioctl(sockfd, SIOCGIFHWADDR, (unsigned long)&req) >= 0)
+            {
+              myaddrs->addrs.ifa_data = &myaddrs->hwaddr;
+              memcpy(&myaddrs->hwaddr,
+                     &req.lifr_hwaddr, sizeof(req.lifr_hwaddr));
+            }
+        }
+#endif
+    }
+
+  close(sockfd);
+  return OK;
+
+err:
+  if (*addrs != NULL)
+    {
+      freeifaddrs(*addrs);
+      *addrs = NULL;
+    }
+
+  close(sockfd);
+  return ERROR;
+}

[incubator-nuttx] 01/02: net: Add lifr_ifindex field to struct lifreq

Posted by gu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1cd935fece78cc67e66ade94391f1b638a1b8cc0
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Dec 19 23:03:16 2021 +0800

    net: Add lifr_ifindex field to struct lifreq
    
    to ensure union lifr_ifru start at the same offset of union ifr_ifru
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 include/net/if.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/net/if.h b/include/net/if.h
index 28da8d7..e54c1b8 100644
--- a/include/net/if.h
+++ b/include/net/if.h
@@ -160,6 +160,7 @@ struct can_ioctl_data_s
 struct lifreq
 {
   char                        lifr_name[IFNAMSIZ];      /* Network device name (e.g. "eth0") */
+  int16_t                     lifr_ifindex;             /* Interface index */
   union
   {
     struct sockaddr_storage   lifru_addr;               /* IP Address */