[Top][All Lists]
[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
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces,
Giuseppe Scrivano <=
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Alfred M. Szmidt, 2010/08/01
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Sergey Poznyakoff, 2010/08/01
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Giuseppe Scrivano, 2010/08/01
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Giuseppe Scrivano, 2010/08/01
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Alfred M. Szmidt, 2010/08/02
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Giuseppe Scrivano, 2010/08/08
- Re: [bug-inetutils] ifconfig -a doesn't show all interfaces, Alfred M. Szmidt, 2010/08/16