/*
* Copyright (c) 2003 Peter Memishian (meem) <meem@gnu.org> and
* Hendrik Scholz <hscholz at raisdorf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* wmnetload - A dockapp to monitor network interface usage.
* Inspired by Seiichi SATO's nifty CPU usage monitor.
*
* FreeBSD-specific interface statistics gathering routines.
*/
#pragma ident "%Z%%M% %I% %E% meem"
#include <config.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_mib.h>
#include "ifstat.h"
#include "utils.h"
struct ifstatstate {
int ifindex; /* cached row index of the interface */
};
/*
* Do one-time setup stuff for accessing the interface statistics and store
* the gathered information in an interface statistics state structure.
* Return the state structure.
*/
ifstatstate_t *
if_statinit(void)
{
ifstatstate_t *statep;
statep = malloc(sizeof (ifstatstate_t));
if (statep == NULL) {
warn("cannot allocate interface statistics state");
return (NULL);
}
statep->ifindex = 1; /* just a guess */
return (statep);
}
/*
* Optionally using state stored in `statep', retrieve stats on interface
* `ifname', and store the statistics in `ifstatsp'.
*/
int
if_stats(const char *ifname, ifstatstate_t *statep, ifstats_t *ifstatsp)
{
int row;
int name[6] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA };
size_t len;
struct ifmibdata ifmd;
name[4] = statep->ifindex;
name[5] = IFDATA_GENERAL;
len = sizeof (ifmd);
if ((sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) ||
(strcmp(ifmd.ifmd_name, ifname) != 0)) {
/*
* Interface index has changed; find it again.
*/
len = sizeof (name[4]);
if (sysctlbyname("net.link.generic.system.ifcount", &name[4],
&len, NULL, 0) == -1) {
warn("cannot retrieve the interface count");
return (0);
}
len = sizeof (ifmd);
for (; name[4] > 0; name[4]--) {
if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1)
break;
if (strcmp(ifmd.ifmd_name, ifname) == 0) {
statep->ifindex = name[4];
goto done;
}
}
warn("cannot retrieve interface statistics");
return (0);
}
done:
ifstatsp->rxbytes = ifmd.ifmd_data.ifi_ibytes;
ifstatsp->txbytes = ifmd.ifmd_data.ifi_obytes;
return (1);
}
/*
* Clean up the interface state structure pointed to by `statep'.
*/
void
if_statfini(ifstatstate_t *statep)
{
free(statep);
}
syntax highlighted by Code2HTML, v. 0.9.1