aboutsummaryrefslogtreecommitdiff
path: root/net/wmnet
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2014-10-02 17:55:32 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2014-10-02 17:55:32 +0000
commit19ba1cd55e3de5d092d06409259cac4f8b92ea28 (patch)
treea72b9a165f2f8ea9992d97cba5c848aa843c19ce /net/wmnet
parenta81b1d902845b1234d6f19a056e21dc879f758ec (diff)
downloadports-19ba1cd55e3de5d092d06409259cac4f8b92ea28.tar.gz
ports-19ba1cd55e3de5d092d06409259cac4f8b92ea28.zip
Rewrite if.c so that it uses getifaddrs(3) instead of nosing in
kernel memory via kvm(3). Approved by: bapt (blanket)
Notes
Notes: svn path=/head/; revision=369841
Diffstat (limited to 'net/wmnet')
-rw-r--r--net/wmnet/Makefile2
-rw-r--r--net/wmnet/files/patch-if.c497
2 files changed, 420 insertions, 79 deletions
diff --git a/net/wmnet/Makefile b/net/wmnet/Makefile
index 4b735de87c08..7a855397df31 100644
--- a/net/wmnet/Makefile
+++ b/net/wmnet/Makefile
@@ -3,7 +3,7 @@
PORTNAME= wmnet
PORTVERSION= 1.2
-PORTREVISION= 2
+PORTREVISION= 3
CATEGORIES= net windowmaker
MASTER_SITES= ftp://ftp.enteract.com/users/rneswold/ \
${MASTER_SITE_LOCAL}
diff --git a/net/wmnet/files/patch-if.c b/net/wmnet/files/patch-if.c
index 0a27e6bd7c9d..4fdd7e4e9360 100644
--- a/net/wmnet/files/patch-if.c
+++ b/net/wmnet/files/patch-if.c
@@ -1,89 +1,430 @@
---- if.c.orig Sun Oct 11 19:13:16 1998
-+++ if.c Fri May 21 01:11:19 2004
-@@ -88,8 +88,13 @@
-
- if (!newData) {
- size -= IF_STEP;
-+#if defined(__FreeBSD__) && __FreeBSD_version < 501113
- fprintf(stderr, "wmnet: Warning -- low memory; "
- "ignoring %s interface\n", theData->if_name);
-+#else
-+ fprintf(stderr, "wmnet: Warning -- low memory; "
-+ "ignoring %s interface\n", theData->if_xname);
-+#endif
- return 0;
- }
-
-@@ -118,10 +123,13 @@
- ptr->flags = 0;
-
- #ifndef NDEBUG
-+#if defined(__FreeBSD__) && __FreeBSD_version < 501113
- printf("Added '%.*s%d' to list.\n", IFNAMSIZ, theData->if_name,
- theData->if_unit);
-+#else
-+ printf("Added '%.*s' to list.\n", IFNAMSIZ, theData->if_xname);
-+#endif
- #endif
+--- if.c.orig 1998-10-12 06:13:16.000000000 +0400
++++ if.c 2014-10-02 21:48:19.000000000 +0400
+@@ -11,32 +11,28 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <limits.h>
++#include <errno.h>
+ #include <err.h>
+ #include <sys/param.h>
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
+-#if (__FreeBSD_version >= 300003)
+-#include <net/if_var.h>
+ #include <net/if_types.h>
+-#endif
+ #include <fcntl.h>
+-#include <kvm.h>
+-#include <nlist.h>
+ #include <assert.h>
++#include <ifaddrs.h>
+ #include "wmnet.h"
+
+ #define IF_STEP 10
++#define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
+
+ /*
+ Local data types...
+ */
+ typedef struct {
+- unsigned long ifNetAddr;
+-
++ char name[IFNAMSIZ];
+ unsigned long flags;
+-
+ unsigned current;
+ unsigned long xmt[G_WIDTH], xmtLast;
+ unsigned long rcv[G_WIDTH], rcvLast;
+@@ -45,19 +41,15 @@
+ /*
+ Local prototypes...
+ */
+-static int addIfData(unsigned long);
+-static struct ifnet const* dereference(unsigned long);
+-static void ifTerm(void);
++static int addIfData(struct ifaddrs *);
+
+ /*
+ Local data...
+ */
+-static kvm_t* kd = 0;
+-static unsigned long root = 0;
-
- // Bump the total.
+ static int total = 0;
+ static int size = 0;
+ static IfData* ifData = 0;
++static int sock;
- ++total;
-@@ -144,7 +152,9 @@
+ /*------------------------------------------------------------------------------
+ addIfData
+@@ -66,134 +58,57 @@
+ out of space, more space is allocated. If the interface already
+ exists in the list, we don't do anything.
+ ------------------------------------------------------------------------------*/
+-static int addIfData(unsigned long theAddr)
++static int addIfData(struct ifaddrs *ifa)
{
- static unsigned long c = 0;
- static struct ifnet d;
-+#if defined(__FreeBSD__) && __FreeBSD_version < 501113
- static char name[IFNAMSIZ];
-+#endif
-
- /* If we are passed a NULL, the caller wants us to stop caching
- the current interface. */
-@@ -161,6 +171,7 @@
- return &d;
- else if (sizeof(d) == kvm_read(kd, a, &d, sizeof(d))) {
-
-+#if defined(__FreeBSD__) && __FreeBSD_version < 501113
- /* We've read the structure's data, but the 'name' field still
- points to kernel memory. We transfer the name to a local
- buffer, and then modify the pointer to point to our
-@@ -172,6 +183,7 @@
- if (sizeof(name) == n) {
- name[IFNAMSIZ - 1] = '\0';
- d.if_name = name;
-+#endif
- #ifndef NDEBUG
-
- /* These are other pointer fields that we shouldn't need
-@@ -186,12 +198,13 @@
- #endif
- d.if_bpf = 0;
- d.if_linkmib = 0;
+- struct ifnet const* const theData = dereference(theAddr);
++ IfData* ptr = 0;
++ int ii;
+
+ assert(total <= size);
+
+- /* Now read in the data so we can get to some of its goodies. */
+-
+- if (0 != theData) {
+- IfData* ptr = 0;
+- int ii;
+-
+- /* First check to see if we have enough space in the list. If
+- we don't, we'll have to add more space. */
+-
+- if (total == size) {
+- IfData* const newData =
+- (IfData*) realloc(ifData,
+- (size += IF_STEP) * sizeof(IfData));
+-
+- if (!newData) {
+- size -= IF_STEP;
+- fprintf(stderr, "wmnet: Warning -- low memory; "
+- "ignoring %s interface\n", theData->if_name);
+- return 0;
+- }
+-
+- /* Good. we got more space. */
+-
+- ifData = newData;
++ /* First check to see if we have enough space in the list. If
++ we don't, we'll have to add more space. */
++ if (total == size) {
++ IfData *newData;
++
++ newData = realloc(ifData, (size += IF_STEP) * sizeof(IfData));
++
++ if (!newData) {
++ size -= IF_STEP;
++ fprintf(stderr, "wmnet: Warning -- low memory; "
++ "ignoring %s interface\n", ifa->ifa_name);
++ return ENOMEM;
+ }
+
+- assert(0 != ifData);
+- assert(total < size);
+-
+- /* If we reached here, then 'total' points to the next
+- bucket. Initialize the new bucket. XXX: This would be a
+- good spot to insert-sort the new record. As it stands, the
+- list builds up by the order that the interfaces were
+- bootstrapped. */
+-
+- ptr = ifData + total;
+-
+- ptr->ifNetAddr = theAddr;
+- for (ii = 0; ii < G_WIDTH; ++ii)
+- ptr->rcv[ii] = ptr->xmt[ii] = 0;
+- ptr->rcvLast = theData->if_ibytes;
+- ptr->xmtLast = theData->if_obytes;
+- ptr->current = 0;
+- ptr->flags = 0;
+-
+-#ifndef NDEBUG
+- printf("Added '%.*s%d' to list.\n", IFNAMSIZ, theData->if_name,
+- theData->if_unit);
+-#endif
+-
+- // Bump the total.
+-
+- ++total;
+- } else
+- fprintf(stderr, "Couldn't read interface information\n");
+- return 1;
+-}
+-
+-/*------------------------------------------------------------------------------
+- dereference
+-
+- Takes the kernel memory "pointer" and copies its pointed-to data
+- into a local buffer. The only type of "pointer" we're using is a
+- struct ifnet*, so this function only returns this type of data.
+-
+- Passing in 0 will reset the address cache and force the function
+- to reload the data.
+-------------------------------------------------------------------------------*/
+-static struct ifnet const* dereference(unsigned long a)
+-{
+- static unsigned long c = 0;
+- static struct ifnet d;
+- static char name[IFNAMSIZ];
+-
+- /* If we are passed a NULL, the caller wants us to stop caching
+- the current interface. */
+-
+- if (!a) {
+- c = 0;
+- return 0;
++ /* Good. we got more space. */
++ ifData = newData;
+ }
+
+- /* If the requested address is the same that has been cached, just
+- return the data. */
++ assert(0 != ifData);
++ assert(total < size);
+
+- else if (a == c)
+- return &d;
+- else if (sizeof(d) == kvm_read(kd, a, &d, sizeof(d))) {
+-
+- /* We've read the structure's data, but the 'name' field still
+- points to kernel memory. We transfer the name to a local
+- buffer, and then modify the pointer to point to our
+- buffer. */
+-
+- ssize_t const n = kvm_read(kd, (unsigned long) d.if_name, name,
+- sizeof(name));
+-
+- if (sizeof(name) == n) {
+- name[IFNAMSIZ - 1] = '\0';
+- d.if_name = name;
+-#ifndef NDEBUG
++ /* If we reached here, then 'total' points to the next
++ bucket. Initialize the new bucket. XXX: This would be a
++ good spot to insert-sort the new record. As it stands, the
++ list builds up by the order that the interfaces were
++ bootstrapped. */
++
++ ptr = ifData + total;
++
++ strncpy(ptr->name, ifa->ifa_name, IFNAMSIZ);
++ for (ii = 0; ii < G_WIDTH; ++ii)
++ ptr->rcv[ii] = ptr->xmt[ii] = 0;
++ ptr->rcvLast = IFA_STAT(ibytes);
++ ptr->xmtLast = IFA_STAT(obytes);
++ ptr->current = 0;
++ ptr->flags = 0;
+
+- /* These are other pointer fields that we shouldn't need
+- to look at. While debugging, set these to NULL to trap
+- any attempts. */
+-
+- d.if_softc = 0;
+-#if (__FreeBSD_version >= 300003)
+- d.if_addrhead.tqh_first = 0;
+-#else
+- d.if_addrlist = 0;
+-#endif
+- d.if_bpf = 0;
+- d.if_linkmib = 0;
- d.if_poll_slowq = 0;
++#ifndef NDEBUG
++ printf("Added '%.*s' to list.\n", IFNAMSIZ, ifa->ifa_name);
#endif
- c = a;
- return &d;
-+#if defined(__FreeBSD__) && __FreeBSD_version < 501113
- } else
- return 0;
-+#endif
- } else
- return 0;
+- c = a;
+- return &d;
+- } else
+- return 0;
+- } else
+- return 0;
++ // Bump the total.
++ ++total;
++
++ return 0;
}
-@@ -306,12 +319,16 @@
- if (idx < total) {
- struct ifnet const* const ptr = dereference(ifData[idx].ifNetAddr);
-+#if defined(__FreeBSD__) && __FreeBSD_version < 501113
- if (ptr) {
- static char buffer[IFNAMSIZ + 1];
+ /*------------------------------------------------------------------------------
+@@ -222,56 +137,30 @@
+ ------------------------------------------------------------------------------*/
+ int ifInit(void)
+ {
+- char errBuf[_POSIX2_LINE_MAX];
++ struct ifaddrs *ifap, *ifa;
+
+- /* First try to open the kernel image. If we can't, the rest of
+- the program is essentially useless. */
++ sock = socket(AF_INET, SOCK_DGRAM, 0);
++ if (sock < 0)
++ fprintf(stderr, "socket(): %d\n", errno);
++
++ if (getifaddrs(&ifap) != 0) {
++ fprintf(stderr, "getifaddrs(): %d\n", errno);
++ return (errno);
++ }
+
+- if (0 != (kd = kvm_openfiles(0, 0, 0, O_RDONLY, errBuf))) {
+- static struct nlist nl[] = {
+- { "_ifnet" },
+- { "" }
+- };
+-
+- /* Try to pull the address for the global kernel variable,
+- ifnet. This variable is the root of the singly-linked list
+- of network interfaces. */
+-
+- if (0 == kvm_nlist(kd, nl)) {
+- ssize_t const n = kvm_read(kd, nl[0].n_value, &root, sizeof(root));
+-
+- /* We'll go ahead and make one dereference. We never
+- really want this variable. We want what it points to. */
+-
+- if (sizeof(root) == n) {
+- unsigned long current = root;
+-
+- while (current) {
+- addIfData(current);
+-#if (__FreeBSD_version >= 300003)
+- current = (unsigned long) dereference(current)->if_link.tqe_next;
+-#else
+- current = (unsigned long) dereference(current)->if_next;
+-#endif
+- }
++ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
++ int error;
- sprintf(buffer, "%.*s%d", IFNAMSIZ - 1, ptr->if_name, ptr->if_unit);
- return buffer;
+- /* Try to register our termination function. If it
+- returns an error, we essentially ignore it because
+- the OS will clean up our resources. */
+-
+- (void) atexit(ifTerm);
+- return 1;
+- }
++ if (ifa->ifa_addr->sa_family != AF_LINK)
++ continue;
++ if ((error = addIfData(ifa)) != 0) {
++ freeifaddrs(ifap);
++ return (error);
}
-+#else
-+ return ptr->if_xname;
-+#endif
++ }
+
+- /* If we can't get a symbol list, close the kernel image and
+- return an error. */
+-
+- kvm_close(kd);
+- kd = 0;
+- } else
+- fprintf(stderr, "kvm_open: %s\n", errBuf);
+- return 0;
++ freeifaddrs(ifap);
++ return (0);
+ }
+
+ /*------------------------------------------------------------------------------
+@@ -303,17 +192,7 @@
+ ------------------------------------------------------------------------------*/
+ char const* ifName(unsigned idx)
+ {
+- if (idx < total) {
+- struct ifnet const* const ptr = dereference(ifData[idx].ifNetAddr);
+-
+- if (ptr) {
+- static char buffer[IFNAMSIZ + 1];
+-
+- sprintf(buffer, "%.*s%d", IFNAMSIZ - 1, ptr->if_name, ptr->if_unit);
+- return buffer;
+- }
+- }
+- return 0;
++ return ifData[idx].name;
+ }
+
+ /*------------------------------------------------------------------------------
+@@ -324,68 +203,53 @@
+ ------------------------------------------------------------------------------*/
+ int ifSample(void)
+ {
++ struct ifaddrs *ifap;
+ int ii;
+
+- /* Flush the kernel memory cache so that we're guaranteed to get
+- new data during the next dereference(). */
+-
+- dereference(0);
++ if (getifaddrs(&ifap) != 0) {
++ fprintf(stderr, "getifaddrs(): %d\n", errno);
++ return (errno);
++ }
+
+ /* Loop through all the network interfaces. Even though we display
+ one interface's statistics, we keep track of all of them. */
+-
+ for (ii = 0; ii < total; ++ii) {
+- IfData* const d = ifData + ii;
+- struct ifnet const* const ptr = dereference(d->ifNetAddr);
+-
+- if (!ptr) {
+- fprintf(stderr, "couldn't sample interface.\n");
+- return 0;
+- }
+-
+- d->flags = ptr->if_flags;
++ struct ifreq ifr;
++ struct ifaddrs *ifa;
++ IfData *d;
++
++ d = ifData + ii;
++
++ for (ifa = ifap; ifa; ifa = ifa->ifa_next)
++ if (ifa->ifa_addr->sa_family == AF_LINK &&
++ strcmp(ifa->ifa_name, d->name) == 0)
++ break;
++
++ if (ifa == NULL)
++ /* Interface disappeared? */
++ continue;
+
+ /* Save the new delta for the transmit channel. */
+-
+- d->xmt[d->current] = ptr->if_obytes - d->xmtLast;
+- d->xmtLast = ptr->if_obytes;
++ d->xmt[d->current] = IFA_STAT(obytes) - d->xmtLast;
++ d->xmtLast = IFA_STAT(obytes);
+
+ /* Save the new delta for the receive channel. */
+-
+- d->rcv[d->current] = ptr->if_ibytes - d->rcvLast;
+- d->rcvLast = ptr->if_ibytes;
++ d->rcv[d->current] = IFA_STAT(ibytes) - d->rcvLast;
++ d->rcvLast = IFA_STAT(ibytes);
+
+ /* Prep the index for the next location to be written. */
+-
+ d->current = (d->current + 1) % G_WIDTH;
+- }
+- return 1;
+-}
+-
+-/*------------------------------------------------------------------------------
+- ifTerm
+
+- This function will be called once when the application is ready to exit
+-------------------------------------------------------------------------------*/
+-static void ifTerm(void)
+-{
+-#ifndef NDEBUG
+- printf("Cleaning up resources.\n");
+-#endif
+-
+- /* If the kernel image is open, close it. */
+-
+- if (0 != kd) {
+- kvm_close(kd);
+- kd = 0;
++ memset(&ifr, 0, sizeof(ifr));
++ strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
++ if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
++ continue;
++ d->flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
}
- return 0;
+
+- /* Now free up any memory we're using. */
++ freeifaddrs(ifap);
+
+- if (ifData) {
+- free(ifData);
+- ifData = 0;
+- }
++ return (0);
}
+
+ /*------------------------------------------------------------------------------