summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>2001-10-17 04:12:29 +0000
committerfenner <fenner@FreeBSD.org>2001-10-17 04:12:29 +0000
commit1e7fe9f955a3d9d24a8f7545a033f8b90126e3bf (patch)
tree3a092a48e9ca517c0577423fc3e3894299750bb4
parentb69c7c0b789e7ca4de555baab2ee087e1bb5d231 (diff)
downloadFreeBSD-src-1e7fe9f955a3d9d24a8f7545a033f8b90126e3bf.zip
FreeBSD-src-1e7fe9f955a3d9d24a8f7545a033f8b90126e3bf.tar.gz
The interface index space may be sparsely populated (e.g. when an
interface in the middle is if_detach()'d). Return (and handle) ENOENT when the ifmib(4) is accessed for a nonexistent interface. MFC after: 14 days
-rw-r--r--libexec/rpc.rstatd/rstat_proc.c4
-rw-r--r--share/man/man4/ifmib.46
-rw-r--r--sys/net/if_mib.c3
-rw-r--r--tools/tools/ifinfo/ifinfo.c7
-rw-r--r--usr.sbin/slstat/slstat.c6
5 files changed, 22 insertions, 4 deletions
diff --git a/libexec/rpc.rstatd/rstat_proc.c b/libexec/rpc.rstatd/rstat_proc.c
index 1014326..2b63394 100644
--- a/libexec/rpc.rstatd/rstat_proc.c
+++ b/libexec/rpc.rstatd/rstat_proc.c
@@ -51,6 +51,7 @@ static const char rcsid[] =
#include <sys/param.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
@@ -294,6 +295,9 @@ updatestat()
mib[4] = i;
mib[5] = IFDATA_GENERAL;
if (sysctl(mib, 6, &ifmd, &len, 0, 0) < 0) {
+ if (errno == ENOENT)
+ continue;
+
syslog(LOG_ERR, "sysctl(net.link.ifdata.%d.general)"
": %m", i);
exit(1);
diff --git a/share/man/man4/ifmib.4 b/share/man/man4/ifmib.4
index 9fd6bc8..dc9b28d 100644
--- a/share/man/man4/ifmib.4
+++ b/share/man/man4/ifmib.4
@@ -76,7 +76,7 @@ MIB. The manifest constants for each level in the
.Ar name
are defined in
.Aq Pa net/if_mib.h .
-A count of interfaces (and thus rows in the table) is given by
+The index of the last row in the table is given by
.Dq Li net.link.generic.system.ifcount
(or, using the manifest constants,
.Dv CTL_NET ,
@@ -87,6 +87,10 @@ A count of interfaces (and thus rows in the table) is given by
A management application searching for a particular interface should
start with row 1 and continue through the table row-by-row until the
desired interface is found, or the interface count is reached.
+Note that the table may be sparse, i.e. a given row may not exist,
+indicated by an errno of
+.Er ENOENT .
+Such an error should be ignored, and the next row should be checked.
.Pp
The generic interface information, common to all interfaces,
can be accessed via the following procedure:
diff --git a/sys/net/if_mib.c b/sys/net/if_mib.c
index 5b04cbb..b8e7ed6 100644
--- a/sys/net/if_mib.c
+++ b/sys/net/if_mib.c
@@ -80,7 +80,8 @@ sysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XXX bad syntax! */
if (namelen != 2)
return EINVAL;
- if (name[0] <= 0 || name[0] > if_index)
+ if (name[0] <= 0 || name[0] > if_index ||
+ ifaddr_byindex(name[0]) == NULL)
return ENOENT;
ifp = ifaddr_byindex(name[0])->ifa_ifp;
diff --git a/tools/tools/ifinfo/ifinfo.c b/tools/tools/ifinfo/ifinfo.c
index 8e462dd..54ca164 100644
--- a/tools/tools/ifinfo/ifinfo.c
+++ b/tools/tools/ifinfo/ifinfo.c
@@ -34,6 +34,7 @@
#include <sys/time.h>
#include <err.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -99,9 +100,13 @@ main(int argc, char **argv)
name[3] = IFMIB_IFDATA;
name[4] = i;
name[5] = IFDATA_GENERAL;
- if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0)
+ if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) {
+ if (errno == ENOENT)
+ continue;
+
err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)",
i);
+ }
if (!isit(argc - optind, argv + optind, ifmd.ifmd_name))
continue;
diff --git a/usr.sbin/slstat/slstat.c b/usr.sbin/slstat/slstat.c
index 27c27ed..ac1fa83 100644
--- a/usr.sbin/slstat/slstat.c
+++ b/usr.sbin/slstat/slstat.c
@@ -120,8 +120,12 @@ main(argc, argv)
for (i = 1; ; i++) {
name[4] = i;
- if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0)
+ if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) {
+ if (errno == ENOENT)
+ continue;
+
err(1, "sysctl");
+ }
if (strncmp(interface, ifmd.ifmd_name, IFNAMSIZ) == 0
&& ifmd.ifmd_data.ifi_type == IFT_SLIP) {
indx = i;
OpenPOWER on IntegriCloud