--- ioctl_stat.c.orig Tue Feb 1 08:11:24 2000 +++ ioctl_stat.c Mon Oct 18 22:32:49 2004 @@ -30,6 +30,12 @@ #include /* open */ #include /* ioctl */ #include +#ifdef __FreeBSD__ +#include +#include +#include +#include +#endif #ifndef STREAMS /* Linux, FreeBSD, NetBSD, Ultrix */ # include /* socket */ @@ -63,6 +69,16 @@ struct ifreq ifr; struct ifpppstatsreq req; +#ifdef __FreeBSD__ + static int if_ix = -1; + struct ifmibdata ifmd; + size_t ifmd_sz = sizeof(ifmd); + int nr_ifs; + size_t nr_ifs_sz = sizeof(nr_ifs); + int name[6]; + int i; +#endif + if (!ifd->s) getsocket(ifd); memset(&ifr, 0, sizeof(ifr)); @@ -84,18 +100,36 @@ #define ifr_name ifr__name #endif - strncpy(req.ifr_name, ifd->device, sizeof(req.ifr_name)); - if (ioctl(ifd->s, SIOCGPPPSTATS, &req) != 0) - { - /* shouldn't fail if SIOCGIFFLAGS worked... */ - ifd->in_bytes = 0UL; - ifd->out_bytes = 0UL; - return; +#ifdef __FreeBSD__ + name[0] = CTL_NET; + name[1] = PF_LINK; + name[2] = NETLINK_GENERIC; + name[3] = IFMIB_IFDATA; + name[5] = IFDATA_GENERAL; + + if (if_ix < 0) { + if (sysctlbyname("net.link.generic.system.ifcount", (void *) &nr_ifs, &nr_ifs_sz, (void *) 0, 0) < 0) { + return; + } + for (i = 1; i <= nr_ifs; i++) { + name[4] = i; /* row of the ifmib table */ + + if (sysctl(name, 6, (void *) &ifmd, &ifmd_sz, (void *) 0, 0) < 0) { + continue; + } + if (strncmp(ifmd.ifmd_name, ifr.ifr_name, strlen(ifr.ifr_name)) == 0) { + if_ix = i; + break; + } + } } - - ifd->in_bytes = (unsigned long)req.stats.p.ppp_ibytes; - ifd->out_bytes = (unsigned long)req.stats.p.ppp_obytes; - + name[4] = if_ix; + if (sysctl(name, 6, (void *) &ifmd, &ifmd_sz, (void *) 0, 0) >= 0) { + ifd->in_bytes = ifmd.ifmd_data.ifi_ibytes; + ifd->out_bytes = ifmd.ifmd_data.ifi_obytes; + } +#endif + return; }