You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/12/19 16:11:07 UTC

[GitHub] [incubator-nuttx] xiaoxiang781216 opened a new pull request #5036: net: Implement getifaddrs and freeifaddrs

xiaoxiang781216 opened a new pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036


   ## Summary
   specify here:
   https://man7.org/linux/man-pages/man3/getifaddrs.3.html
   
   ## Impact
   New API
   
   ## Testing
   Pass CI
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772133349



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       If we set `myaddrs` to `NULL` and `CONFIG_NET_IPv6` is not defined, then with the next loop we will go on `*addrs = lib_zalloc(sizeof(*myaddrs));` path and get memory leak, or I'm missing something?

##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              myaddrs->addrs.ifa_next = lib_zalloc(sizeof(*myaddrs));
+              myaddrs = (FAR struct myifaddrs *)myaddrs->addrs.ifa_next;

Review comment:
       This does not make sense to me: `if (myaddrs == NULL)` -> `myaddrs->addrs.ifa_next`. I mean dereferencing a NULL pointer.

##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              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)
+    {

Review comment:
       really agree that this is not needed




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772151355



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              myaddrs->addrs.ifa_next = lib_zalloc(sizeof(*myaddrs));
+              myaddrs = (FAR struct myifaddrs *)myaddrs->addrs.ifa_next;

Review comment:
       Done.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r771998760



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq 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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              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:
+  freeifaddrs(*addrs);

Review comment:
       This is because
   ```
         if (ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req) < 0)
           {
             goto err;
           }
   ```
   may happen while `*addrs` not allocated.

##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)

Review comment:
       ```suggestion
     for (i = 1, *addrs = NULL; i <= MAX_IFINDEX; i++)
   ```
   Just to prevent if some garbage is pointed by `addrs`

##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq 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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              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:
+  freeifaddrs(*addrs);

Review comment:
       ```suggestion
     if (*addrs)
     {
       freeifaddrs(*addrs);
     }
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r773115595



##########
File path: 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 link list of ifaddrs structures,

Review comment:
       Done.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei merged pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
gustavonihei merged pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772147370



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       No, myaddrs is added to the list at line 154 or 159.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772180747



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       I check ifa_addr field instead adding a new flag, please take a look @pkarashchenko 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772959170



##########
File path: 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 free the data structure returned by

Review comment:
       Done.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772147370



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       No, myaddrs is added to the list at line 154 or 159. So here is four cases:
   
   1. netcard without any ip address(e.g. in the off state)
   2. netcard has only ipv4 address
   3. netcard has only ipv6 address
   4. netcard has both ipv4 and ipv6 address
   
   The first three case generate one entry, the last one generate two entries.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] Ouss4 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
Ouss4 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r773103954



##########
File path: 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 link list of ifaddrs structures,

Review comment:
       ```suggestion
    *   The getifaddrs() function returns a linked list of ifaddrs structures,
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772147663



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              myaddrs->addrs.ifa_next = lib_zalloc(sizeof(*myaddrs));
+              myaddrs = (FAR struct myifaddrs *)myaddrs->addrs.ifa_next;

Review comment:
       You are right I need a flags to indicate this case.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772089618



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq 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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              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:
+  freeifaddrs(*addrs);

Review comment:
       Don't need since freeifaddrs check null before doing the real action:
   ```
   void freeifaddrs(FAR struct ifaddrs *addrs)
   {
     while (addrs != NULL)
       {
         FAR struct ifaddrs *tmp = addrs;
         addrs = addrs->ifa_next;
         lib_free(tmp);
       }
   }
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772180747



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       I check ifa_next field instead adding a new flag, please take a look @pkarashchenko 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772150222



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       Yeah, but that is done due to `FAR struct myifaddrs *myaddrs = NULL;` at line 116 and code
   ```
         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;
           }
   ```
   that goes `else` path for the first time. But if we reset `myaddrs` to `NULL` here, then it will always follow `else` path.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772089058



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq req =
+      {
+      };
+
+      req.lifr_ifindex = i;

Review comment:
       can't use the designated initializers(https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html) here since it doesn't support on C89.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772106246



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq req =
+      {
+      };
+
+      req.lifr_ifindex = i;

Review comment:
       Ok




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r771997906



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq req =
+      {
+      };
+
+      req.lifr_ifindex = i;

Review comment:
       ```suggestion
         struct lifreq req =
         {
           req.lifr_ifindex = i
         };
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772197312



##########
File path: 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 link 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 link 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 =
+      {
+      };

Review comment:
       Done.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772130387



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq 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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              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:
+  freeifaddrs(*addrs);

Review comment:
       Yes. I missed that `addrs` is checked inside the `freeifaddrs`. The fix is actually to init `*addrs` to `NULL` before the loop.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772167516



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * 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 link 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 link 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 =
+      {
+      };
+
+      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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */

Review comment:
       Anyway it is fixed by adding a flag.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] pkarashchenko commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772187430



##########
File path: 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 link 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 link 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 =
+      {
+      };

Review comment:
       Empty braces for initialization seems to be a GNU extension. Can we switch to `struct lifreq req;` -> `memset(&req, 0, sizeof(req));`?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772091680



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)
+    {
+      unsigned int flags;
+      struct lifreq 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));
+            }
+
+          myaddrs = NULL; /* Zero out to handle the dual stack */
+        }
+#endif
+
+#ifdef CONFIG_NET_IPv6
+      if (ioctl(sockfd, SIOCGLIFADDR, (unsigned long)&req) >= 0)
+        {
+          if (myaddrs == NULL)
+            {
+              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:
+  freeifaddrs(*addrs);

Review comment:
       Anyway, I add the check and reset to NULL in case of fail.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772091448



##########
File path: libs/libc/net/lib_getifaddrs.c
##########
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * 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 link 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 link 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; i <= MAX_IFINDEX; i++)

Review comment:
       Done.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #5036: net: Implement getifaddrs and freeifaddrs

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #5036:
URL: https://github.com/apache/incubator-nuttx/pull/5036#discussion_r772680008



##########
File path: 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 free the data structure returned by

Review comment:
       ```suggestion
    *   The freeifaddrs() function frees the data structure returned by
   ```
   nit: minor typo




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org