bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-inetutils] ifconfig -a doesn't show all interfaces


From: Giuseppe Scrivano
Subject: Re: [bug-inetutils] ifconfig -a doesn't show all interfaces
Date: Sun, 01 Aug 2010 15:20:09 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Giuseppe Scrivano <address@hidden> writes:

> It seems that SIOCGIFCONF, used by ifconfig, doesn't return all
> interfaces as we expect.


What do you think about this patch?  Any comment?

Cheers,
Giuseppe



>From 1f4f0273c5dbb14706055639e932554dce8d0353 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <address@hidden>
Date: Sun, 1 Aug 2010 14:52:28 +0200
Subject: [PATCH] Now ifconfig -a includes interfaces without an address

* NEWS: Mention the change.

* ifconfig/if_index.c (if_nameindex): Remove local variables
`ifc', `i', `rq_len', `last_len', `ifr', `end', `cur'.
Add local variables `content', `it', `length', `index'.
Remove code that uses the SIOCGIFCONF ioctl to get the interfaces
list.  Parse the PATH_PROCNET_DEV file to fetch the list of
interfaces.

* bootstrap.conf (gnulib_modules): Add `read-file' module.
---
 ChangeLog           |   14 +++++
 NEWS                |    8 +++
 bootstrap.conf      |    1 +
 ifconfig/if_index.c |  138 +++++++++++++++++++++------------------------------
 4 files changed, 79 insertions(+), 82 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 052daee..c5fcddd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,18 @@
+2010-08-01  Giuseppe Scrivano  <address@hidden>
+
+       * NEWS: Mention the change.
+
+       * ifconfig/if_index.c (if_nameindex): Remove local variables
+       `ifc', `i', `rq_len', `last_len', `ifr', `end', `cur'.
+       Add local variables `content', `it', `length', `index'.
+       Remove code that uses the SIOCGIFCONF ioctl to get the interfaces
+       list.  Parse the PATH_PROCNET_DEV file to fetch the list of
+       interfaces.
+
+       * bootstrap.conf (gnulib_modules): Add `read-file' module.
+
 2010-07-30  Giuseppe Scrivano  <address@hidden>
+       Suggested by Chris Webb <address@hidden>
 
        * ifconfig/if_index.c (if_nameindex): Remove local variable `len'.
        Remove code that compute the sizeof of the struct `ifreq'.
diff --git a/NEWS b/NEWS
index 4583586..2dba114 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,14 @@ See the end of this file for for license conditions.
 
 Please send inetutils bug reports to <address@hidden>.
 
+XXX YY, ZZ
+Version A.B:
+
+* ifconfig
+
+ifconfig -a includes interfaces without an address.
+
+
 May 15, 2010
 Version 1.8:
 
diff --git a/bootstrap.conf b/bootstrap.conf
index bbb5c2e..facab0a 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -53,6 +53,7 @@ minmax
 obstack
 poll
 progname
+read-file
 readline
 readutmp
 realloc
diff --git a/ifconfig/if_index.c b/ifconfig/if_index.c
index 3062bf7..3eafb3a 100644
--- a/ifconfig/if_index.c
+++ b/ifconfig/if_index.c
@@ -29,6 +29,8 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
+#include <read-file.h>
+
 /* Solaris at least earlier 2.6 and before does not include
    the ioctl definitions if BSD_COMP is not set.  */
 #if defined(__svr4__)
@@ -97,104 +99,76 @@ if_freenameindex (struct if_nameindex *ifn)
 struct if_nameindex *
 if_nameindex (void)
 {
-#if defined(SIOCGIFCONF)
-  int fd = socket (AF_INET, SOCK_DGRAM, 0);
-  struct ifconf ifc;
-  unsigned int i = 0;
-  int rq_len, last_len;
+  char *content, *it;
+  size_t length, index;
   struct if_nameindex *idx = NULL;
-  struct ifreq *ifr, *end, *cur;
+  int fd;
 
+  fd = socket (AF_INET, SOCK_DGRAM, 0);
   if (fd < 0)
     return NULL;
 
-  /* A first estimate.  */
-  rq_len = 4 * sizeof (struct ifreq);
-
-  ifc.ifc_buf = NULL;
-  ifc.ifc_len = 0;
-  /* Read all the interfaces out of the kernel.  */
-  do
-    {
-      last_len = ifc.ifc_len;
-      ifc.ifc_buf = alloca (ifc.ifc_len = rq_len);
-      if (ifc.ifc_buf == NULL || ioctl (fd, SIOCGIFCONF, &ifc) < 0)
-       {
-         close (fd);
-         return NULL;
-       }
-      rq_len *= 2;
-    }
-  while (ifc.ifc_len != last_len);
-
-  i = 0;
-  ifr = (struct ifreq *) ifc.ifc_req;
-  end = (struct ifreq *) ((caddr_t) ifr + ifc.ifc_len);
-  while (ifr < end)
-    {
-      cur = ifr;
-
-      ++ifr;
+  content = read_file (PATH_PROCNET_DEV, &length);
+  if (content == NULL)
+    return NULL;
 
-      /* We ignore the other families .. OK ?  */
-      if (cur->ifr_addr.sa_family != AF_INET)
-       continue;
+  /* Count how many interfaces we have.  */
+  {
+    size_t n = 0;
+    it = content;
+    do
+      {
+        it = memchr (it + 1, ':', length - (it - content));
+        n++;
+      }
+    while (it);
 
-      /* Make Room safely.  */
+    idx = malloc (n * sizeof (*idx));
+    if (idx == NULL)
       {
-       struct if_nameindex *tidx = NULL;
-       tidx = realloc (idx, (i + 1) * sizeof (*idx));
-       if (tidx == NULL)
-         {
-           if_freenameindex (idx);
-           close (fd);
-           errno = ENOBUFS;
-           return NULL;
-         }
-       idx = tidx;
+        int saved_errno = errno;
+        close (fd);
+        free (content);
+        errno = saved_errno;
+        return NULL;
       }
+  }
 
-      /* FIXME: We did not deal with duplicates or interface aliases.  */
+  for (it = memchr (content, ':', length), index = 0; it;
+       it = memchr (it, ':', it - content), index++)
+    {
+      char *start = it - 1;
+      *it = '\0';
+
+      while (*start != ' ' && *start != '\n')
+        start--;
 
-      idx[i].if_name = strdup (cur->ifr_name);
-      if (idx[i].if_name == NULL)
-       {
-         if_freenameindex (idx);
-         close (fd);
-         errno = ENOBUFS;
-         return NULL;
-       }
+      idx[index].if_name = strdup (start + 1);
+      idx[index].if_index = index + 1;
 
 # if defined(SIOCGIFINDEX)
-      if (ioctl (fd, SIOCGIFINDEX, cur) >= 0)
-       idx[i].if_index = cur->ifr_index;
-      else
+      {
+        struct ifreq cur;
+        strcpy (cur.ifr_name, idx[index].if_name);
+        cur.ifr_index = -1;
+        if (ioctl (fd, SIOCGIFINDEX, &cur) >= 0)
+          idx[index].if_index = cur.ifr_index;
+      }
 # endif
-       idx[i].if_index = i + 1;
-      i++;
+
+      if (idx[index].if_name == NULL)
+        {
+          int saved_errno = errno;
+          close (fd);
+          free (content);
+          errno = saved_errno;
+          return NULL;
+        }
     }
 
-  /* Terminate the array with an empty solt.  */
-  {
-    struct if_nameindex *tidx = NULL;
-    tidx = realloc (idx, (i + 1) * sizeof (*idx));
-    if (tidx == NULL)
-      {
-       if_freenameindex (idx);
-       close (fd);
-       errno = ENOBUFS;
-       return NULL;
-      }
-    idx = tidx;
-  }
-  idx[i].if_index = 0;
-  idx[i].if_name = NULL;
+  idx[index].if_index = 0;
+  idx[index].if_name = NULL;
 
-  close (fd);
+  free (content);
   return idx;
-
-#else
-  errno = ENOSYS;
-  return NULL;
-#endif
 }
-- 
1.7.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]