parent
a0405c9463
commit
1407a73ebb
|
@ -0,0 +1,168 @@
|
|||
/* XFce 4 - Netload Plugin
|
||||
* Copyright (c) 2003 Bernhard Walle <bernhard.walle@gmx.de>
|
||||
*
|
||||
* Id: $Id: net.c,v 1.1 2003/08/24 20:02:29 bwalle Exp $
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is just a wrapper between the netload-plugin and the wormulon source.
|
||||
* Wormulon is a small command-line util which displays the netload. You can find it
|
||||
* at http://raisdorf.net/wormulon. Most sourcecode is taken from wormulon.
|
||||
*
|
||||
* Thanks to Hendrik Scholz. Only his work made it possible to support a large
|
||||
* number of operating systems quickly without a library! Without him only
|
||||
* Linux and FreeBSD (with foreign code from IceWM) would be supported.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/* From Wormulon */
|
||||
#include "os.h"
|
||||
#include "wormulon.h"
|
||||
#include "slurm.h" /* slurm structs */
|
||||
|
||||
#ifdef __HPUX__
|
||||
#include "wormulon/hpux.h"
|
||||
#include "wormulon/hpux.c"
|
||||
#elif __FreeBSD__
|
||||
#include "wormulon/freebsd.h"
|
||||
#include "wormulon/freebsd.c"
|
||||
#elif __linux__
|
||||
#include "wormulon/linux.h"
|
||||
#include "wormulon/linux.c"
|
||||
#elif __OpenBSD__ || __MicroBSD__
|
||||
#include "wormulon/openbsd.h"
|
||||
#include "wormulon/openbsd.c"
|
||||
#elif __NetBSD__
|
||||
#include "wormulon/netbsd.h"
|
||||
#include "wormulon/netbsd.c"
|
||||
#elif __Solaris__
|
||||
#include "wormulon/solaris.h"
|
||||
#include "wormulon/solaris.c"
|
||||
#else
|
||||
/* should not get here */
|
||||
#error "OS not supported"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
static double backup_in, backup_out;
|
||||
static double cur_in, cur_out;
|
||||
static char dim_in[4], dim_out[4];
|
||||
static struct timeval prev_time;
|
||||
int correct_interface;
|
||||
|
||||
|
||||
void init_netload(const char* device)
|
||||
{
|
||||
strncpy( ifdata.if_name, device, 9 );
|
||||
ifdata.if_name[9] = '\0';
|
||||
|
||||
if (checkinterface() != TRUE)
|
||||
{
|
||||
correct_interface = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* init in a sane state */
|
||||
get_stat();
|
||||
backup_in = stats.rx_bytes;
|
||||
backup_out = stats.tx_bytes;
|
||||
memset(dim_in, 0, sizeof(dim_in));
|
||||
memset(dim_out, 0, sizeof(dim_out));
|
||||
|
||||
correct_interface = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the current netload.
|
||||
* @param in Will be filled with the "in"-load.
|
||||
* @param out Will be filled with the "out"-load.
|
||||
* @param tot Will be filled with the "total"-load.
|
||||
*/
|
||||
void get_current_netload(unsigned long *in, unsigned long *out, unsigned long *tot)
|
||||
{
|
||||
struct timeval curr_time;
|
||||
double delta_t;
|
||||
|
||||
if( !correct_interface )
|
||||
{
|
||||
if( in != NULL && out != NULL && tot != NULL )
|
||||
{
|
||||
*in = *out = *tot = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&curr_time, NULL);
|
||||
|
||||
delta_t = (double) ((curr_time.tv_sec - prev_time.tv_sec) * 1000000L
|
||||
+ (curr_time.tv_usec - prev_time.tv_usec)) / 1000000.0;
|
||||
|
||||
/* update */
|
||||
get_stat();
|
||||
if (backup_in > stats.rx_bytes)
|
||||
{
|
||||
cur_in = (int) stats.rx_bytes / delta_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_in = (int) (stats.rx_bytes - backup_in) / delta_t;
|
||||
}
|
||||
|
||||
if (backup_out > stats.tx_bytes)
|
||||
{
|
||||
cur_out = (int) stats.tx_bytes / delta_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_out = (int) (stats.tx_bytes - backup_out) / delta_t;
|
||||
}
|
||||
|
||||
if( in != NULL && out != NULL && tot != NULL )
|
||||
{
|
||||
*in = cur_in;
|
||||
*out = cur_out;
|
||||
*tot = *in + *out;
|
||||
}
|
||||
|
||||
/* save 'new old' values */
|
||||
backup_in = stats.rx_bytes;
|
||||
backup_out = stats.tx_bytes;
|
||||
|
||||
/* do the same with time */
|
||||
prev_time.tv_sec = curr_time.tv_sec;
|
||||
prev_time.tv_usec = curr_time.tv_usec;
|
||||
}
|
||||
|
||||
void close_netload()
|
||||
{
|
||||
/* We need not code here */
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
/* XFce 4 - Netload Plugin
|
||||
* Copyright (c) 2003 Bernhard Walle <bernhard.walle@gmx.de>
|
||||
*
|
||||
*
|
||||
* Id: $Id: net.h,v 1.3 2003/08/24 20:02:29 bwalle Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -17,27 +19,27 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef _NET_H_
|
||||
#define _NET_H_
|
||||
#include <gtk/gtk.h>
|
||||
#ifndef NET_H
|
||||
#define NET_H
|
||||
|
||||
/**
|
||||
* Should be called to initialize.
|
||||
* Initializes the netload plugin. Used to set up inital values. This function must
|
||||
* be called after each change of the network interface.
|
||||
* @param device The network device, e.g. <code>ippp0</code> for ISDN on Linux.
|
||||
*/
|
||||
void init_netload();
|
||||
void init_netload(const char* device);
|
||||
|
||||
/**
|
||||
* Gets the current netload. You must call init_netload() once before you use this function!
|
||||
* @param device A device string like "ippp0" or "eth0".
|
||||
* @param in Input load in byte/s.
|
||||
* @param out Output load in byte/s.
|
||||
* @param tot Total load in byte/s.
|
||||
*/
|
||||
void get_current_netload(const gchar* device, gint64 *in, gint64 *out, gint64 *tot);
|
||||
void get_current_netload(unsigned long *in, unsigned long *out, unsigned long *tot);
|
||||
|
||||
/**
|
||||
* Should be called to do cleanup work.
|
||||
*/
|
||||
void close_netload();
|
||||
|
||||
#endif /* _NET_H_ */
|
||||
#endif /* NET_H */
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/* XFce 4 - Netload Plugin
|
||||
* Copyright (c) 2003 Bernhard Walle <bernhard.walle@gmx.de>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_mib.h>
|
||||
|
||||
#include "net.h"
|
||||
|
||||
|
||||
/*
|
||||
* Basic code taken from IceWM
|
||||
* (c) Marko Macek and others, GNU General Public License
|
||||
*
|
||||
* Converted from C++ to C (using glib data types) by Bernhard Walle
|
||||
*/
|
||||
|
||||
|
||||
static guint64 prev_ibytes, cur_ibytes, offset_ibytes;
|
||||
static guint64 prev_obytes, cur_obytes, offset_obytes;
|
||||
static struct timeval prev_time;
|
||||
|
||||
void init_netload()
|
||||
{
|
||||
prev_ibytes = cur_ibytes = offset_ibytes = 0;
|
||||
prev_obytes = cur_obytes = offset_obytes = 0;
|
||||
gettimeofday(&prev_time, NULL);
|
||||
}
|
||||
|
||||
|
||||
void get_current_netload(const gchar* device, gint64 *in, gint64 *out, gint64 *tot)
|
||||
{
|
||||
static gboolean first = TRUE;
|
||||
struct timeval curr_time;
|
||||
gdouble delta_t;
|
||||
gint64 ni, no;
|
||||
struct ifmibdata ifmd;
|
||||
size_t ifmd_size = sizeof(ifmd);
|
||||
gint nr_network_devs;
|
||||
size_t int_size = sizeof(nr_network_devs);
|
||||
gint name[] = {
|
||||
CTL_NET, /* 0 */
|
||||
PF_LINK, /* 1 */
|
||||
NETLINK_GENERIC, /* 2 */
|
||||
IFMIB_IFDATA, /* 3 */
|
||||
0, /* 4 */
|
||||
IFDATA_GENERAL /* 5 */
|
||||
};
|
||||
gint i;
|
||||
|
||||
gettimeofday(&curr_time, NULL);
|
||||
|
||||
delta_t = (gdouble) ((curr_time.tv_sec - prev_time.tv_sec) * 1000000L
|
||||
+ (curr_time.tv_usec - prev_time.tv_usec)) / 1000000.0;
|
||||
|
||||
if(sysctlbyname("net.link.generic.system.ifcount", &nr_network_devs, &int_size, NULL, 0) == -1)
|
||||
{
|
||||
g_printf("%s@%d: %s\n", __FILE__, __LINE__, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 1; i <= nr_network_devs; i++ )
|
||||
{
|
||||
name[4] = i; /* row of the ifmib table */
|
||||
|
||||
if( sysctl(name, 6, &ifmd, &ifmd_size, (void *)0, 0) == -1 )
|
||||
{
|
||||
printf("%s@%d: %s\n" ,__FILE__ ,__LINE__, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if ( strncmp(ifmd.ifmd_name, device, strlen(device)) == 0 )
|
||||
{
|
||||
cur_ibytes = ifmd.ifmd_data.ifi_ibytes;
|
||||
cur_obytes = ifmd.ifmd_data.ifi_obytes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_ibytes += offset_ibytes;
|
||||
cur_obytes += offset_obytes;
|
||||
|
||||
if (cur_ibytes < prev_ibytes)
|
||||
{
|
||||
/* har, har, overflow. Use the recent prev_ibytes value as offset this time */
|
||||
cur_ibytes = offset_ibytes = prev_ibytes;
|
||||
}
|
||||
|
||||
if (cur_obytes < prev_obytes)
|
||||
{
|
||||
/* har, har, overflow. Use the recent prev_obytes value as offset this time */
|
||||
cur_obytes = offset_obytes = prev_obytes;
|
||||
}
|
||||
|
||||
|
||||
ni = (gint64)((cur_ibytes - prev_ibytes) / delta_t);
|
||||
no = (gint64)((cur_obytes - prev_obytes) / delta_t);
|
||||
|
||||
if (in != NULL && out != NULL && tot != NULL && !first)
|
||||
{
|
||||
*in = ni;
|
||||
*out = no;
|
||||
*tot = *in + *out;
|
||||
}
|
||||
else
|
||||
{
|
||||
*in = *out = *tot = 0;
|
||||
first = FALSE;
|
||||
}
|
||||
|
||||
prev_time.tv_sec = curr_time.tv_sec;
|
||||
prev_time.tv_usec = curr_time.tv_usec;
|
||||
|
||||
prev_ibytes = cur_ibytes;
|
||||
prev_obytes = cur_obytes;
|
||||
|
||||
}
|
||||
|
||||
void close_netload()
|
||||
{
|
||||
/* Do nothing here */
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Bernhard Walle <bernhard.walle@gmx.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <glibtop.h>
|
||||
#include <glibtop/close.h>
|
||||
#include <glibtop/netload.h>
|
||||
|
||||
#include "net.h"
|
||||
|
||||
static glibtop_netload netload;
|
||||
static struct timeval prev_time;
|
||||
static guint64 prev_ibytes, cur_ibytes;
|
||||
static guint64 prev_obytes, cur_obytes;
|
||||
static guint64 prev_tbytes, cur_tbytes;
|
||||
|
||||
void init_netload()
|
||||
{
|
||||
glibtop_init();
|
||||
prev_ibytes = cur_ibytes = 0;
|
||||
prev_obytes = cur_obytes = 0;
|
||||
prev_tbytes = cur_tbytes = 0;
|
||||
gettimeofday(&prev_time, NULL);
|
||||
}
|
||||
|
||||
void get_current_netload(const gchar* device, gint64 *in, gint64 *out, gint64 *tot)
|
||||
{
|
||||
static gboolean first = TRUE;
|
||||
struct timeval curr_time;
|
||||
gdouble delta_t;
|
||||
|
||||
if (in != NULL && out != NULL && tot != NULL)
|
||||
{
|
||||
*in = *out = *tot = 0;
|
||||
}
|
||||
|
||||
gettimeofday(&curr_time, NULL);
|
||||
delta_t = (gdouble) ((curr_time.tv_sec - prev_time.tv_sec) * 1000000L
|
||||
+ (curr_time.tv_usec - prev_time.tv_usec)) / 1000000.0;
|
||||
|
||||
glibtop_get_netload (&netload, device);
|
||||
|
||||
cur_ibytes = (gint64) netload.bytes_in;
|
||||
cur_obytes = (gint64) netload.bytes_out;
|
||||
cur_tbytes = (gint64) netload.bytes_total;
|
||||
|
||||
if (in != NULL && out != NULL && tot != NULL && !first)
|
||||
{
|
||||
*in = (gint64)((cur_ibytes - prev_ibytes) / delta_t);
|
||||
*out = (gint64)((cur_obytes - prev_obytes) / delta_t);
|
||||
*tot = (gint64)((cur_tbytes - prev_tbytes) / delta_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
*in = *out = *tot = 0;
|
||||
first = FALSE;
|
||||
}
|
||||
|
||||
prev_time.tv_sec = curr_time.tv_sec;
|
||||
prev_time.tv_usec = curr_time.tv_usec;
|
||||
|
||||
prev_ibytes = cur_ibytes;
|
||||
prev_obytes = cur_obytes;
|
||||
prev_tbytes = cur_tbytes;
|
||||
|
||||
}
|
||||
|
||||
void close_netload()
|
||||
{
|
||||
glibtop_close();
|
||||
}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
/* XFce 4 - Netload Plugin
|
||||
* Copyright (c) 2003 Bernhard Walle <bernhard.walle@gmx.de>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "net.h"
|
||||
|
||||
/*
|
||||
* Basic code taken from IceWM
|
||||
* (c) Marko Macek and others, GNU General Public License
|
||||
*
|
||||
* Converted from C++ to C (using glib data types) by Bernhard Walle
|
||||
*/
|
||||
|
||||
|
||||
static guint64 prev_ibytes, cur_ibytes, offset_ibytes;
|
||||
static guint64 prev_obytes, cur_obytes, offset_obytes;
|
||||
static struct timeval prev_time;
|
||||
|
||||
void init_netload()
|
||||
{
|
||||
prev_ibytes = cur_ibytes = offset_ibytes = 0;
|
||||
prev_obytes = cur_obytes = offset_obytes = 0;
|
||||
gettimeofday(&prev_time, NULL);
|
||||
}
|
||||
|
||||
void get_current_netload(const gchar* device, gint64 *in, gint64 *out, gint64 *tot)
|
||||
{
|
||||
static gboolean first = TRUE;
|
||||
struct timeval curr_time;
|
||||
gdouble delta_t;
|
||||
gint64 ni, no;
|
||||
|
||||
gchar buf[BUFSIZ];
|
||||
gchar *p;
|
||||
gint64 ipackets, opackets, ierrs, oerrs, idrop, odrop, ififo, ofifo,
|
||||
iframe, ocolls, ocarrier, icomp, ocomp, imcast;
|
||||
|
||||
FILE *fp = NULL;
|
||||
|
||||
gettimeofday(&curr_time, NULL);
|
||||
|
||||
delta_t = (gdouble) ((curr_time.tv_sec - prev_time.tv_sec) * 1000000L
|
||||
+ (curr_time.tv_usec - prev_time.tv_usec)) / 1000000.0;
|
||||
|
||||
|
||||
if ( (fp = fopen("/proc/net/dev", "r")) == NULL)
|
||||
{
|
||||
*in = *out = *tot = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while ( fgets(buf, BUFSIZ, fp) != NULL )
|
||||
{
|
||||
p = buf;
|
||||
while (*p == ' ')
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
if (strncmp(p, device, strlen(device)) == 0 && p[strlen(device)] == ':')
|
||||
{
|
||||
p = strchr(p, ':') + 1;
|
||||
|
||||
if (sscanf(
|
||||
p,
|
||||
"%llu %lld %lld %lld %lld %lld %lld %lld" " %llu %lld %lld %lld %lld %lld %lld %lld",
|
||||
&cur_ibytes, &ipackets, &ierrs, &idrop, &ififo, &iframe, &icomp, &imcast,
|
||||
&cur_obytes, &opackets, &oerrs, &odrop, &ofifo, &ocolls, &ocarrier, &ocomp) != 16 )
|
||||
{
|
||||
ipackets = opackets = 0;
|
||||
sscanf(p, "%lld %lld %lld %lld %lld" " %lld %lld %lld %lld %lld %lld",
|
||||
&ipackets, &ierrs, &idrop, &ififo, &iframe,
|
||||
&opackets, &oerrs, &odrop, &ofifo, &ocolls, &ocarrier);
|
||||
/* for linux<2.0 fake packets as bytes (we only need relative values anyway) */
|
||||
cur_ibytes = ipackets;
|
||||
cur_obytes = opackets;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
cur_ibytes += offset_ibytes;
|
||||
cur_obytes += offset_obytes;
|
||||
|
||||
if (cur_ibytes < prev_ibytes)
|
||||
{
|
||||
/* har, har, overflow. Use the recent prev_ibytes value as offset this time */
|
||||
cur_ibytes = offset_ibytes = prev_ibytes;
|
||||
}
|
||||
|
||||
if (cur_obytes < prev_obytes)
|
||||
{
|
||||
/* har, har, overflow. Use the recent prev_obytes value as offset this time */
|
||||
cur_obytes = offset_obytes = prev_obytes;
|
||||
}
|
||||
|
||||
|
||||
ni = (gint64)((cur_ibytes - prev_ibytes) / delta_t);
|
||||
no = (gint64)((cur_obytes - prev_obytes) / delta_t);
|
||||
|
||||
if (in != NULL && out != NULL && tot != NULL && !first)
|
||||
{
|
||||
*in = ni;
|
||||
*out = no;
|
||||
*tot = *in + *out;
|
||||
}
|
||||
else
|
||||
{
|
||||
*in = *out = *tot = 0;
|
||||
first = FALSE;
|
||||
}
|
||||
|
||||
prev_time.tv_sec = curr_time.tv_sec;
|
||||
prev_time.tv_usec = curr_time.tv_usec;
|
||||
|
||||
prev_ibytes = cur_ibytes;
|
||||
prev_obytes = cur_obytes;
|
||||
|
||||
}
|
||||
|
||||
void close_netload()
|
||||
{
|
||||
/* Do nothing here */
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* os.h
|
||||
*
|
||||
* include OS-dependent headers
|
||||
*
|
||||
******************************************************************************
|
||||
* This file is from Wormulon. Id: os.h,v 1.3 2003/08/14 10:58:30 hscholz Exp
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _OS_H
|
||||
#if defined (__sun__)
|
||||
#define __Solaris__ 1
|
||||
#endif
|
||||
|
||||
#ifdef __HPUX__ /* H P U X */
|
||||
#define _XOPEN_SOURCE_EXTENDED
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stdsyms.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/mib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#elif __FreeBSD__ /* F R E E B S D */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_mib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/ppp_defs.h>
|
||||
#include <net/if_ppp.h>
|
||||
#elif __NetBSD__ /* N E T B S D */
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/ppp_defs.h>
|
||||
#include <net/if_ppp.h>
|
||||
#include <net/if.h>
|
||||
#elif __OpenBSD__ || __MicroBSD__ /* O P E N B S D */
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/ppp_defs.h>
|
||||
#include <net/if_ppp.h>
|
||||
#elif __linux__ /* L I N U X */
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/ppp_defs.h>
|
||||
#include <net/if_ppp.h>
|
||||
#elif __Solaris__ /* S O L A R I S */
|
||||
#include <stdio.h>
|
||||
#define _WIDEC_H
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <net/if.h>
|
||||
#include <kstat.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#else
|
||||
#error "OS not supported"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* slurm.h - structs known from slurm and used in src/
|
||||
*
|
||||
******************************************************************************
|
||||
* This file is from Wormulon. Id: slurm.h,v 1.2 2003/07/16 16:52:56 hscholz Exp
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _SLURM_H_
|
||||
|
||||
typedef struct IfData{
|
||||
char if_name[10]; /* The device name given as start parameter*/
|
||||
int if_speed; /* The Interface speed */
|
||||
char if_speedstring[12]; /* the measuring unit like Mbit, kbit */
|
||||
int if_id; /* The ID which the interface inside the OS has */
|
||||
int if_amount; /* The amount of all interfaces available */
|
||||
int if_valid; /* 1 = selected interface exists
|
||||
* 0 = interfaces does not exists */
|
||||
} IfData;
|
||||
IfData ifdata;
|
||||
|
||||
/* This structure stays the INFO variables */
|
||||
typedef struct DataStats {
|
||||
unsigned long rx_packets;
|
||||
unsigned long rx_errors;
|
||||
int rx_over;
|
||||
unsigned long tx_packets;
|
||||
unsigned long tx_errors;
|
||||
int tx_over;
|
||||
double rx_bytes;
|
||||
double tx_bytes;
|
||||
double rx_bytes_comp;
|
||||
double tx_bytes_comp;
|
||||
double rx_packets_led;
|
||||
double tx_packets_led;
|
||||
unsigned long connect_time;
|
||||
unsigned long current_time;
|
||||
float top_speed;
|
||||
int online_days;
|
||||
int online_hour;
|
||||
int online_min;
|
||||
int online_sec;
|
||||
unsigned long rx_packets_off;
|
||||
unsigned long rx_errors_off;
|
||||
int rx_over_off;
|
||||
unsigned long tx_packets_off;
|
||||
unsigned long tx_errors_off;
|
||||
int tx_over_off;
|
||||
double rx_bytes_off;
|
||||
double tx_bytes_off;
|
||||
double rx_bytes_comp_off;
|
||||
double tx_bytes_comp_off;
|
||||
} DataStats;
|
||||
DataStats stats;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* wormulon.h
|
||||
*
|
||||
* application specific defines. You should never need to tune anything here
|
||||
*
|
||||
******************************************************************************
|
||||
* $Id: wormulon.h,v 1.1 2003/08/24 20:02:29 bwalle Exp $
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _WORMULON_H
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define SAMPLE_TIME 1 /* one second default sample time */
|
||||
|
||||
#ifdef __linux__
|
||||
#define PATH_NET_DEV "/proc/net/dev"
|
||||
static FILE *proc_net_dev;
|
||||
#endif
|
||||
|
||||
/* define possible options */
|
||||
#define OPT_NONE 0x0000
|
||||
#define OPT_MRTG 0x0001
|
||||
#define OPT_FULLMRTG 0x0002
|
||||
#ifdef CUSTOM_MODE
|
||||
#define OPT_CUSTOM 0x0004
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,124 @@
|
|||
/* $Id: freebsd.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* checkinterface()
|
||||
*
|
||||
* check if a given interface exists and is up.
|
||||
* return TRUE if it does and FALSE if not
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int checkinterface(void)
|
||||
{
|
||||
int validinterface = FALSE;
|
||||
|
||||
int i, num_iface;
|
||||
size_t len;
|
||||
int name[6];
|
||||
struct ifmibdata ifmd;
|
||||
|
||||
len = sizeof(num_iface);
|
||||
sysctlbyname("net.link.generic.system.ifcount", &num_iface, &len, NULL, 0);
|
||||
for (i=1; i <= num_iface; i++)
|
||||
{
|
||||
name[0] = CTL_NET;
|
||||
name[1] = PF_LINK;
|
||||
name[2] = NETLINK_GENERIC;
|
||||
name[3] = IFMIB_IFDATA;
|
||||
name[4] = i;
|
||||
name[5] = IFDATA_GENERAL;
|
||||
|
||||
len = sizeof(ifmd);
|
||||
sysctl(name, 6, &ifmd, &len, NULL, 0);
|
||||
if (strcmp(ifmd.ifmd_name, (char *)ifdata.if_name) == 0)
|
||||
{
|
||||
/*
|
||||
* now we have an interface and just have to see if it's up
|
||||
* in case we just want to debug media types we disable
|
||||
* IFF_UP flags
|
||||
*/
|
||||
#ifndef MEDIADEBUG
|
||||
if (ifmd.ifmd_flags & IFF_UP)
|
||||
#endif
|
||||
validinterface = TRUE;
|
||||
break; /* in any case we can stop searching here */
|
||||
}
|
||||
}
|
||||
return validinterface;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* use sysctl() to read the statistics and fill statistics struct
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
/*
|
||||
* use sysctl() to get the right interface number if !dev_opened
|
||||
* then read the data directly from the ifmd_data struct
|
||||
*/
|
||||
|
||||
static int watchif = -1;
|
||||
int i, num_iface;
|
||||
size_t len;
|
||||
int name[6];
|
||||
struct ifmibdata ifmd;
|
||||
static int dev_opened = 0;
|
||||
unsigned long rx_o, tx_o;
|
||||
|
||||
if (!dev_opened)
|
||||
{
|
||||
len = sizeof(num_iface);
|
||||
sysctlbyname("net.link.generic.system.ifcount", &num_iface, &len,
|
||||
NULL, 0);
|
||||
for (i=1; i <= num_iface; i++)
|
||||
{
|
||||
name[0] = CTL_NET;
|
||||
name[1] = PF_LINK;
|
||||
name[2] = NETLINK_GENERIC;
|
||||
name[3] = IFMIB_IFDATA;
|
||||
name[4] = i;
|
||||
name[5] = IFDATA_GENERAL;
|
||||
|
||||
len = sizeof(ifmd);
|
||||
sysctl(name, 6, &ifmd, &len, NULL, 0);
|
||||
if (strcmp(ifmd.ifmd_name, (char *)ifdata.if_name) == 0)
|
||||
{
|
||||
/* got the right interface */
|
||||
watchif = i;
|
||||
dev_opened++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* in any case read the struct and record statistics */
|
||||
name[0] = CTL_NET;
|
||||
name[1] = PF_LINK;
|
||||
name[2] = NETLINK_GENERIC;
|
||||
name[3] = IFMIB_IFDATA;
|
||||
name[4] = watchif;
|
||||
name[5] = IFDATA_GENERAL;
|
||||
|
||||
len = sizeof(ifmd);
|
||||
sysctl(name, 6, &ifmd, &len, NULL, 0);
|
||||
|
||||
rx_o = stats.rx_bytes; tx_o = stats.tx_bytes;
|
||||
|
||||
stats.tx_packets = ifmd.ifmd_data.ifi_opackets;
|
||||
stats.rx_packets = ifmd.ifmd_data.ifi_ipackets;
|
||||
stats.rx_bytes = ifmd.ifmd_data.ifi_ibytes;
|
||||
stats.tx_bytes = ifmd.ifmd_data.ifi_obytes;
|
||||
stats.rx_errors = ifmd.ifmd_data.ifi_ierrors;
|
||||
stats.tx_errors = ifmd.ifmd_data.ifi_oerrors;
|
||||
|
||||
if (rx_o > stats.rx_bytes)
|
||||
stats.rx_over++;
|
||||
if (tx_o > stats.tx_bytes)
|
||||
stats.tx_over++;
|
||||
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
int get_stat(void);
|
||||
int checkinterface(void);
|
|
@ -0,0 +1,181 @@
|
|||
#include <netio.h>
|
||||
#define WAIT_PCKS_COUNTER 15
|
||||
|
||||
/* $Id: hpux.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* _countinterfaces()
|
||||
*
|
||||
* count all network interfaces in the system. This function is intended to
|
||||
* use it only in hpux.c
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int _countinterfaces(void)
|
||||
{
|
||||
int val, num_iface=-1, sd;
|
||||
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (ioctl(sd, SIOCGIFNUM, &val) != -1)
|
||||
num_iface = val;
|
||||
close(sd);
|
||||
|
||||
return num_iface;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* _getifdata()
|
||||
*
|
||||
* get the Interface-ID, the Interface-Speed, and over all, check if the
|
||||
* given interface really exists. This function is intended to use it only in
|
||||
* hpux.c
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void _getifdata()
|
||||
{
|
||||
int buffer, fd, val, ret = -1;
|
||||
unsigned int len, i;
|
||||
char tmpinterfacestring[sizeof(ifdata.if_name)+1],*strstrmatch;
|
||||
struct nmparms params;
|
||||
mib_ifEntry * if_buf;
|
||||
|
||||
|
||||
/*
|
||||
* The interface description is more then the pure devicename.
|
||||
* Let's do some formating to allow a propper pattern matching
|
||||
*/
|
||||
strcpy(tmpinterfacestring,ifdata.if_name);
|
||||
strcat(tmpinterfacestring," ");
|
||||
|
||||
for (i=0; i <= ifdata.if_amount; i++)
|
||||
{
|
||||
if ((fd = open_mib("/dev/lan", O_RDWR, i, 0)) >= 0)
|
||||
{
|
||||
if ((if_buf = (mib_ifEntry *) malloc (sizeof(mib_ifEntry))) != 0) {
|
||||
params.objid = ID_ifEntry;
|
||||
params.buffer = if_buf;
|
||||
len = sizeof(mib_ifEntry);
|
||||
params.len = &len;
|
||||
if_buf->ifIndex = i+1;
|
||||
if ((ret = get_mib_info(fd, ¶ms)) == 0) {
|
||||
/*
|
||||
* The interface given by the user must start at the
|
||||
* beginning of if_buf->ifDescr. If that's the case,
|
||||
* strstrmatch is equal to if_buf->ifDescr. If not,
|
||||
* strstrmatch might be a subset of if_buf->ifDescr,
|
||||
* or NULL
|
||||
*/
|
||||
strstrmatch = strstr(if_buf->ifDescr, (char *)tmpinterfacestring);
|
||||
if ( strstrmatch && (strcmp(strstrmatch,if_buf->ifDescr)== 0))
|
||||
{
|
||||
ifdata.if_valid = 1;
|
||||
ifdata.if_id = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(if_buf);
|
||||
close_mib(fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* checkinterface()
|
||||
*
|
||||
* check if a given interface exists, return 1 if it does and 0 if not (This
|
||||
* function is a wrapper function for _countinterfaces && _getifdata.)
|
||||
*
|
||||
****************************************************************************/
|
||||
int checkinterface(void)
|
||||
{
|
||||
/* == 0 no network interfaces, -1 sth. went wrong */
|
||||
if ((ifdata.if_amount =_countinterfaces()) > 0)
|
||||
_getifdata();
|
||||
return ifdata.if_valid;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* stub function for all unsupported operating systems
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
int i,fd, ret=-1;
|
||||
static int wait_pcks_counter=WAIT_PCKS_COUNTER+1;
|
||||
unsigned int len;
|
||||
unsigned long rx_o, tx_o;
|
||||
struct nmparms params, params2;
|
||||
mib_ifEntry *if_buf;
|
||||
|
||||
static nmapi_logstat *if_ptr = (nmapi_logstat *) 0;
|
||||
if (ifdata.if_valid == 1 && (fd = open_mib("/dev/lan", O_RDWR, 0, 0)) >= 0)
|
||||
{
|
||||
if ((if_buf = (mib_ifEntry *) malloc (sizeof(mib_ifEntry))) != 0)
|
||||
{
|
||||
if_buf->ifIndex = ifdata.if_id;
|
||||
params.objid = ID_ifEntry;
|
||||
params.buffer = if_buf;
|
||||
len = (unsigned int) sizeof(mib_ifEntry);
|
||||
params.len = &len;
|
||||
if ((ret = get_mib_info(fd, ¶ms)) == 0)
|
||||
{
|
||||
rx_o = stats.rx_bytes; tx_o = stats.tx_bytes;
|
||||
|
||||
stats.tx_bytes = if_buf->ifOutOctets;
|
||||
stats.rx_bytes = if_buf->ifInOctets;
|
||||
stats.tx_errors = if_buf->ifOutErrors;
|
||||
stats.rx_errors = if_buf->ifInErrors;
|
||||
|
||||
if (rx_o > stats.rx_bytes)
|
||||
stats.rx_over++;
|
||||
if (tx_o > stats.tx_bytes)
|
||||
stats.tx_over++;
|
||||
}
|
||||
}
|
||||
free(if_buf);
|
||||
|
||||
/*
|
||||
* Getting the tx/rx packets every run often hurts to much performance
|
||||
* With WAIT_PCKS_COUNTER=15 i save on my system 43% cpu usage.instead of
|
||||
* WAIT_PCKS_COUNTER=0
|
||||
*/
|
||||
if( wait_pcks_counter > WAIT_PCKS_COUNTER )
|
||||
{
|
||||
if ((if_ptr = (nmapi_logstat *) malloc(sizeof(nmapi_logstat) * ifdata.if_amount)) != 0 )
|
||||
{
|
||||
len = (unsigned int) ifdata.if_amount *sizeof(nmapi_logstat);
|
||||
if ((ret = get_logical_stat(if_ptr, &len)) == 0)
|
||||
{
|
||||
for (i=0; i <= ifdata.if_amount; i++)
|
||||
{
|
||||
if(if_ptr[i].ifindex == ifdata.if_id)
|
||||
{
|
||||
stats.tx_packets = if_ptr[i].out_packets;
|
||||
stats.rx_packets = if_ptr[i].in_packets;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(if_ptr);
|
||||
wait_pcks_counter=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wait_pcks_counter++;
|
||||
}
|
||||
}
|
||||
close_mib(fd);
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _HPUX_H_
|
||||
#define _HPUX_H_
|
||||
extern int checkinterface(void);
|
||||
extern int get_stat(void);
|
||||
#endif
|
|
@ -0,0 +1,322 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* src/if_media.h - part of slurm
|
||||
*
|
||||
* this file handles basic network information functions for all
|
||||
* operating systems.
|
||||
*
|
||||
*****************************************************************************
|
||||
* $Id: if_media.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $
|
||||
*****************************************************************************/
|
||||
|
||||
#if defined (__FreeBSD__) || (__OpenBSD__) || (__NetBSD__) || (__MicroBSD__)
|
||||
#define MEDIA_H_SUPPORTED
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* get_if_speed()
|
||||
*
|
||||
* determine current interface speed, needs interface name as argument
|
||||
* return the interface speed as an integer. unit: kbit/s
|
||||
* in case of error return ERR_IFACE_NO_SPEED
|
||||
*
|
||||
* tested/supported operating systems:
|
||||
*
|
||||
* - FreeBSD
|
||||
* - OpenBSD
|
||||
* - NetBSD
|
||||
* - MicroBSD (99% OpenBSD)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef MEDIA_H_SUPPORTED
|
||||
int get_if_speed (char *ifstring)
|
||||
{
|
||||
int speed=ERR_IFACE_NO_SPEED;
|
||||
int s; /* socket */
|
||||
struct ifmediareq ifmr;
|
||||
int *media_list;
|
||||
int type, physical;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "cannot create socket!\n");
|
||||
return ERR_IFACE_NO_SPEED;
|
||||
}
|
||||
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strncpy(ifmr.ifm_name, (char *)ifstring, sizeof(ifmr.ifm_name));
|
||||
|
||||
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
|
||||
{
|
||||
fprintf(stderr, "interface does not support SIOCGIFMEDIA ioctl()\n");
|
||||
return ERR_IFACE_NO_SPEED;
|
||||
}
|
||||
|
||||
if (ifmr.ifm_count == 0)
|
||||
{
|
||||
fprintf(stderr, "%s: no media types?\n", (char *)ifstring);
|
||||
return ERR_IFACE_NO_SPEED;
|
||||
}
|
||||
|
||||
media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
|
||||
if (media_list == NULL)
|
||||
fprintf(stderr, "malloc() error in if_media.c\n");
|
||||
ifmr.ifm_ulist = media_list;
|
||||
|
||||
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
|
||||
{
|
||||
fprintf(stderr, "ioctl(SIOCGIFMEDIA) failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* define type and physical
|
||||
*
|
||||
* bits:
|
||||
* 0-4 Media variant
|
||||
* 5-7 Media type
|
||||
*
|
||||
*/
|
||||
|
||||
type = ifmr.ifm_active & 0xf0;
|
||||
physical = ifmr.ifm_active & 0x0f;
|
||||
|
||||
#ifdef MEDIADEBUG
|
||||
printf(" all: %6d\n", ifmr.ifm_current);
|
||||
printf(" active: %6d\n", ifmr.ifm_active);
|
||||
printf(" status: %6d\n", ifmr.ifm_status);
|
||||
printf(" type: %6d\n", type);
|
||||
printf(" phys: %6d\n", physical);
|
||||
printf("if active: %6d\n", ifmr.ifm_active & IFM_ACTIVE);
|
||||
#endif
|
||||
|
||||
/* switch type */
|
||||
switch (type)
|
||||
{
|
||||
/* Ethernet */
|
||||
case IFM_ETHER:
|
||||
switch (physical)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
#if __FreeBSD__ <= 4
|
||||
case IFM_1000_FX:
|
||||
case IFM_1000_TX:
|
||||
#endif
|
||||
#endif
|
||||
case IFM_1000_SX:
|
||||
case IFM_1000_LX:
|
||||
case IFM_1000_CX:
|
||||
#ifdef IFM_1000_T
|
||||
case IFM_1000_T:
|
||||
#endif
|
||||
speed = 1000 * 1000;
|
||||
break;
|
||||
case IFM_100_TX:
|
||||
case IFM_100_FX:
|
||||
case IFM_100_T4:
|
||||
case IFM_100_VG:
|
||||
case IFM_100_T2:
|
||||
speed = 100 * 1000;
|
||||
break;
|
||||
case IFM_10_T:
|
||||
case IFM_10_2:
|
||||
case IFM_10_5:
|
||||
case IFM_10_FL:
|
||||
case IFM_10_STP:
|
||||
speed = 10 * 1000;
|
||||
break;
|
||||
#if defined(__OpenBSD__) || (__MicroBSD__) || (__NetBSD__)
|
||||
case IFM_HPNA_1:
|
||||
#else
|
||||
#if __FreeBSD__ <= 4
|
||||
case IFM_homePNA:
|
||||
#endif
|
||||
#endif
|
||||
speed = 1 * 1000;
|
||||
break;
|
||||
default:
|
||||
speed = ERR_IFACE_NO_SPEED;
|
||||
break;
|
||||
} /* end switch physical */
|
||||
break;
|
||||
/* FDDI interfaces */
|
||||
/* fpa doesn't seem to support SIOCGIFMEDIA on FreeBSD
|
||||
* so we won't get here but anyway ...
|
||||
*/
|
||||
case IFM_FDDI:
|
||||
switch (physical)
|
||||
{
|
||||
case IFM_FDDI_SMF:
|
||||
case IFM_FDDI_MMF:
|
||||
case IFM_FDDI_UTP:
|
||||
speed = 100 * 1000;
|
||||
break;
|
||||
default:
|
||||
speed = ERR_IFACE_NO_SPEED;
|
||||
}
|
||||
break;
|
||||
/* IEEE 802.11 wireless interfaces */
|
||||
case IFM_IEEE80211:
|
||||
switch (physical)
|
||||
{
|
||||
case IFM_IEEE80211_FH1:
|
||||
case IFM_IEEE80211_DS1:
|
||||
speed = 1 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_FH2:
|
||||
case IFM_IEEE80211_DS2:
|
||||
speed = 2 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_DS5:
|
||||
speed = (int) 5.5 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_DS11:
|
||||
speed = 11 * 1000;
|
||||
break;
|
||||
#if __FreeBSD_version >= 460102
|
||||
case IFM_IEEE80211_DS22:
|
||||
speed = 22 * 1000;
|
||||
break;
|
||||
#if __FreeBSD_version > 500111
|
||||
case IFM_IEEE80211_OFDM6:
|
||||
speed = 6 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM9:
|
||||
speed = 9 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM12:
|
||||
speed = 12 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM18:
|
||||
speed = 18 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM24:
|
||||
speed = 24 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM36:
|
||||
speed = 36 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM48:
|
||||
speed = 48 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM54:
|
||||
speed = 54 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_OFDM72:
|
||||
speed = 72 * 1000;
|
||||
break;
|
||||
#else
|
||||
/* these are the old common typos */
|
||||
case IFM_IEEE80211_ODFM6:
|
||||
speed = 6 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM9:
|
||||
speed = 9 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM12:
|
||||
speed = 12 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM18:
|
||||
speed = 18 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM24:
|
||||
speed = 24 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM36:
|
||||
speed = 36 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM48:
|
||||
speed = 48 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM54:
|
||||
speed = 54 * 1000;
|
||||
break;
|
||||
case IFM_IEEE80211_ODFM72:
|
||||
speed = 72 * 1000;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
speed = ERR_IFACE_NO_SPEED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
speed = ERR_IFACE_NO_SPEED;
|
||||
} /* end switch type */
|
||||
|
||||
#ifdef MEDIADEBUG
|
||||
printf(" speed: %6d\n", speed);
|
||||
#endif
|
||||
return speed;
|
||||
}
|
||||
#elif __HPUX__
|
||||
int get_if_speed(char *ifstring)
|
||||
{
|
||||
int speed=ERR_IFACE_NO_SPEED, buffer, fd, val, ret = -1;
|
||||
unsigned int len, i;
|
||||
struct nmparms params;
|
||||
mib_ifEntry * if_buf;
|
||||
|
||||
for (i=0; i <= ifdata.if_amount; i++)
|
||||
{
|
||||
if ((fd = open_mib("/dev/lan", O_RDWR, i, 0)) >= 0)
|
||||
{
|
||||
if ((if_buf = (mib_ifEntry *) malloc (sizeof(mib_ifEntry))) != 0)
|
||||
{
|
||||
params.objid = ID_ifEntry;
|
||||
params.buffer = if_buf;
|
||||
len = sizeof(mib_ifEntry);
|
||||
params.len = &len;
|
||||
if_buf->ifIndex = i+1;
|
||||
if ((ret = get_mib_info(fd, ¶ms)) == 0)
|
||||
{
|
||||
if ( i+1 == ifdata.if_id)
|
||||
if (if_buf->ifOper == 1)
|
||||
speed = if_buf->ifSpeed/1000;
|
||||
else
|
||||
speed ERR_IFACE_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(if_buf);
|
||||
close_mib(fd);
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
#elif defined (__Solaris__)
|
||||
/******************************************************************************
|
||||
*
|
||||
* Solaris interface speed detection
|
||||
*
|
||||
*****************************************************************************/
|
||||
int get_if_speed(char *ifstring)
|
||||
{
|
||||
int speed=ERR_IFACE_NO_SPEED;
|
||||
kstat_t *ksp;
|
||||
kstat_named_t *knp;
|
||||
kstat_ctl_t *kc;
|
||||
|
||||
if ((kc = kstat_open()) == NULL)
|
||||
return ERR_IFACE_NO_SPEED;
|
||||
|
||||
ksp = kstat_lookup(kc, NULL, -1, ifstring);
|
||||
if (ksp && kstat_read(kc, ksp, NULL) >= 0)
|
||||
{
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "ifspeed");
|
||||
if (knp)
|
||||
speed = (int) knp->value.ui64 / 1000;
|
||||
}
|
||||
kstat_close(kc);
|
||||
|
||||
return speed;
|
||||
}
|
||||
#else
|
||||
int get_if_speed(char *ifstring)
|
||||
{
|
||||
ifstring++; /* ugly hack to prevent compiler warning on Linux */
|
||||
return ERR_IFACE_NO_SPEED;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
/* interface speed detection errors */
|
||||
#define ERR_IFACE_NO_SPEED -1
|
||||
#define ERR_IFACE_DOWN -2
|
||||
|
||||
int get_if_speed(char *);
|
|
@ -0,0 +1,106 @@
|
|||
/* $Id: linux.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* checkinterface()
|
||||
*
|
||||
* check if a given interface exists and is up.
|
||||
* return TRUE if found, FALSE if not
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int checkinterface(void)
|
||||
{
|
||||
int interfacefound = FALSE;
|
||||
unsigned int i;
|
||||
struct if_nameindex *ifs;
|
||||
|
||||
if ((ifs = if_nameindex()) == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; ifs[i].if_index; i++)
|
||||
{
|
||||
if (strcmp(ifs[i].if_name, ifdata.if_name) == 0)
|
||||
{
|
||||
interfacefound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return interfacefound;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* read the network statistics from /proc/net/dev (PATH_NET_DEV)
|
||||
* if the file is not open open it. fseek() to the beginning and parse
|
||||
* each line until we've found the right interface
|
||||
*
|
||||
* returns 0 if successful, 1 in case of error
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
static int opened = 0;
|
||||
char buffer[BUFSIZE];
|
||||
char *ptr;
|
||||
char *devname;
|
||||
int dump;
|
||||
int interfacefound;
|
||||
unsigned long rx_o, tx_o;
|
||||
|
||||
if (opened != 1)
|
||||
{
|
||||
if ((proc_net_dev = fopen(PATH_NET_DEV, "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "cannot open %s!\nnot running Linux?\n",
|
||||
PATH_NET_DEV);
|
||||
exit(1);
|
||||
}
|
||||
opened++;
|
||||
}
|
||||
|
||||
/* backup old rx/tx values */
|
||||
rx_o = stats.rx_bytes; tx_o = stats.tx_bytes;
|
||||
|
||||
/* do not parse the first two lines as they only contain static garbage */
|
||||
fseek(proc_net_dev, 0, SEEK_SET);
|
||||
fgets(buffer, BUFSIZ-1, proc_net_dev);
|
||||
fgets(buffer, BUFSIZ-1, proc_net_dev);
|
||||
|
||||
interfacefound = 0;
|
||||
while (fgets(buffer, BUFSIZ-1, proc_net_dev) != NULL)
|
||||
{
|
||||
/* find the device name and substitute ':' with '\0' */
|
||||
ptr = buffer;
|
||||
while (*ptr == ' ')
|
||||
ptr++;
|
||||
devname = ptr;
|
||||
while (*ptr != ':')
|
||||
ptr++;
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
if (!strcmp(devname, (char *) ifdata.if_name))
|
||||
{
|
||||
/* read stats and fill struct */
|
||||
sscanf(ptr, "%lg %lu %lu %d %d %d %d %d %lg %lu %lu %d %d %d %d %d",
|
||||
&stats.rx_bytes, &stats.rx_packets, &stats.rx_errors,
|
||||
&dump, &dump, &dump, &dump, &dump,
|
||||
&stats.tx_bytes, &stats.tx_packets, &stats.tx_errors,
|
||||
&dump, &dump, &dump, &dump, &dump);
|
||||
interfacefound = 1;
|
||||
continue; /* break, as we won't get any new information */
|
||||
}
|
||||
}
|
||||
if (interfacefound)
|
||||
{
|
||||
if (rx_o > stats.rx_bytes)
|
||||
stats.rx_over++;
|
||||
if (tx_o > stats.tx_bytes)
|
||||
stats.tx_over++;
|
||||
}
|
||||
return (interfacefound == 1)? 0 : 1;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
int checkinterface(void);
|
||||
int get_stat(void);
|
||||
#ifdef __linux__
|
||||
#define BUFSIZE 256
|
||||
#endif
|
|
@ -0,0 +1,149 @@
|
|||
/* $Id: netbsd.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* checkinterface()
|
||||
*
|
||||
* check if a given interface exists, return TRUE if it does and FALSE if not
|
||||
*
|
||||
****************************************************************************/
|
||||
int checkinterface()
|
||||
{
|
||||
int validinterface = FALSE;
|
||||
static int mib_name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
|
||||
static char *buf;
|
||||
static int alloc;
|
||||
char *lim, *next;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
size_t needed;
|
||||
char s[32];
|
||||
|
||||
if (sysctl(mib_name, 6, NULL, &needed, NULL, 0) < 0)
|
||||
return FALSE;
|
||||
if (alloc < (signed long) needed)
|
||||
{
|
||||
if (buf != NULL)
|
||||
free (buf);
|
||||
buf = malloc(needed);
|
||||
if (buf == NULL)
|
||||
return FALSE;
|
||||
alloc = needed;
|
||||
}
|
||||
|
||||
if (sysctl(mib_name, 6, buf, &needed, NULL, 0) < 0)
|
||||
return FALSE;
|
||||
lim = buf + needed;
|
||||
next = buf;
|
||||
while ((next < lim) && (validinterface == 0))
|
||||
{
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type != RTM_IFINFO)
|
||||
return FALSE;
|
||||
next += ifm->ifm_msglen;
|
||||
|
||||
while (next < lim)
|
||||
{
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (ifm->ifm_flags & IFF_UP)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
|
||||
s[sdl->sdl_nlen] = '\0';
|
||||
/* search for the right network interface */
|
||||
if (sdl->sdl_family != AF_LINK)
|
||||
continue;
|
||||
if (strcmp(s, ifdata.if_name) != 0)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
validinterface = TRUE;
|
||||
break; /* stop searching */
|
||||
}
|
||||
}
|
||||
}
|
||||
return validinterface;
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* this code is based on gkrellm code (thanks guys!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
static int mib_name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
|
||||
static char *buf;
|
||||
static int alloc;
|
||||
char *lim, *next;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
char s[32];
|
||||
size_t needed;
|
||||
unsigned long rx_o, tx_o;
|
||||
|
||||
if (sysctl(mib_name, 6, NULL, &needed, NULL, 0) < 0)
|
||||
return 1;
|
||||
if (alloc < (signed long) needed)
|
||||
{
|
||||
if (buf != NULL)
|
||||
free (buf);
|
||||
buf = malloc(needed);
|
||||
if (buf == NULL)
|
||||
return 1;
|
||||
alloc = needed;
|
||||
}
|
||||
|
||||
if (sysctl(mib_name, 6, buf, &needed, NULL, 0) < 0)
|
||||
return 1;
|
||||
lim = buf + needed;
|
||||
next = buf;
|
||||
while (next < lim)
|
||||
{
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type != RTM_IFINFO)
|
||||
return 1;
|
||||
next += ifm->ifm_msglen;
|
||||
|
||||
while (next < lim)
|
||||
{
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (ifm->ifm_flags & IFF_UP)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
|
||||
s[sdl->sdl_nlen] = '\0';
|
||||
|
||||
/* search for the right network interface */
|
||||
if (strcmp(s, ifdata.if_name) != 0)
|
||||
continue;
|
||||
|
||||
rx_o = stats.rx_bytes; tx_o = stats.tx_bytes;
|
||||
/* write stats */
|
||||
stats.tx_packets = ifm->ifm_data.ifi_opackets;
|
||||
stats.rx_packets = ifm->ifm_data.ifi_ipackets;
|
||||
stats.rx_bytes = ifm->ifm_data.ifi_ibytes;
|
||||
stats.tx_bytes = ifm->ifm_data.ifi_obytes;
|
||||
stats.rx_errors = ifm->ifm_data.ifi_ierrors;
|
||||
stats.tx_errors = ifm->ifm_data.ifi_oerrors;
|
||||
|
||||
if (rx_o > stats.rx_bytes)
|
||||
stats.rx_over++;
|
||||
if (tx_o > stats.tx_bytes)
|
||||
stats.tx_over++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
int get_stat(void);
|
||||
int checkinterface(void);
|
|
@ -0,0 +1,152 @@
|
|||
/* $Id: openbsd.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* checkinterface()
|
||||
*
|
||||
* check if a given interface exists, return TRUE if it does and FALSE if not
|
||||
*
|
||||
****************************************************************************/
|
||||
int checkinterface()
|
||||
{
|
||||
int validinterface = FALSE;
|
||||
static int mib_name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
|
||||
static char *buf;
|
||||
static int alloc;
|
||||
char *lim, *next;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
size_t needed;
|
||||
char s[32];
|
||||
|
||||
if (sysctl(mib_name, 6, NULL, &needed, NULL, 0) < 0)
|
||||
return FALSE;
|
||||
if (alloc < (signed long) needed)
|
||||
{
|
||||
if (buf != NULL)
|
||||
free (buf);
|
||||
buf = malloc(needed);
|
||||
if (buf == NULL)
|
||||
return FALSE;
|
||||
alloc = needed;
|
||||
}
|
||||
|
||||
if (sysctl(mib_name, 6, buf, &needed, NULL, 0) < 0)
|
||||
return FALSE;
|
||||
|
||||
lim = buf + needed;
|
||||
next = buf;
|
||||
while ((next < lim) && (validinterface == 0))
|
||||
{
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type != RTM_IFINFO)
|
||||
return FALSE;
|
||||
next += ifm->ifm_msglen;
|
||||
|
||||
while (next < lim)
|
||||
{
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (ifm->ifm_flags & IFF_UP)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
|
||||
s[sdl->sdl_nlen] = '\0';
|
||||
/* search for the right network interface */
|
||||
if (sdl->sdl_family != AF_LINK)
|
||||
continue;
|
||||
if (strcmp(s, ifdata.if_name) != 0)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
validinterface = TRUE;
|
||||
break; /* stop searching */
|
||||
}
|
||||
}
|
||||
}
|
||||
return validinterface;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* this code is based on gkrellm code (thanks guys!)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
static int mib_name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
|
||||
static char *buf;
|
||||
static int alloc;
|
||||
char *lim, *next;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
char s[32];
|
||||
size_t needed;
|
||||
unsigned long rx_o, tx_o;
|
||||
|
||||
if (sysctl(mib_name, 6, NULL, &needed, NULL, 0) < 0)
|
||||
return 1;
|
||||
if (alloc < (signed long) needed)
|
||||
{
|
||||
if (buf != NULL)
|
||||
free (buf);
|
||||
buf = malloc(needed);
|
||||
if (buf == NULL)
|
||||
return 1;
|
||||
alloc = needed;
|
||||
}
|
||||
|
||||
if (sysctl(mib_name, 6, buf, &needed, NULL, 0) < 0)
|
||||
return 1;
|
||||
lim = buf + needed;
|
||||
next = buf;
|
||||
while (next < lim)
|
||||
{
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type != RTM_IFINFO)
|
||||
return 1;
|
||||
next += ifm->ifm_msglen;
|
||||
|
||||
while (next < lim)
|
||||
{
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (ifm->ifm_flags & IFF_UP)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
/* search for the right network interface */
|
||||
if (sdl->sdl_family != AF_LINK)
|
||||
continue;
|
||||
if (strcmp(sdl->sdl_data, ifdata.if_name) != 0)
|
||||
continue;
|
||||
strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
|
||||
s[sdl->sdl_nlen] = '\0';
|
||||
|
||||
rx_o = stats.rx_bytes; tx_o = stats.tx_bytes;
|
||||
/* write stats */
|
||||
stats.tx_packets = ifm->ifm_data.ifi_opackets;
|
||||
stats.rx_packets = ifm->ifm_data.ifi_ipackets;
|
||||
stats.rx_bytes = ifm->ifm_data.ifi_ibytes;
|
||||
stats.tx_bytes = ifm->ifm_data.ifi_obytes;
|
||||
stats.rx_errors = ifm->ifm_data.ifi_ierrors;
|
||||
stats.tx_errors = ifm->ifm_data.ifi_oerrors;
|
||||
|
||||
if (rx_o > stats.rx_bytes)
|
||||
stats.rx_over++;
|
||||
if (tx_o > stats.tx_bytes)
|
||||
stats.tx_over++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
int get_stat(void);
|
||||
int checkinterface(void);
|
|
@ -0,0 +1,135 @@
|
|||
/* $Id: solaris.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* checkinterface()
|
||||
*
|
||||
* check if a given interface exists, return TRUE if it does and FALSE if not
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int checkinterface()
|
||||
{
|
||||
int validinterface = FALSE;
|
||||
int sockfd, i, numifs, numifreqs;
|
||||
size_t bufsize;
|
||||
char *buf;
|
||||
struct ifreq ifr, *ifrp;
|
||||
struct ifconf ifc;
|
||||
unsigned long rx_o, tx_o;
|
||||
|
||||
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
perror("socket");
|
||||
return FALSE;
|
||||
}
|
||||
if (ioctl(sockfd, SIOCGIFNUM, (char *) &numifs) < 0)
|
||||
{
|
||||
perror("SIOCGIFNUM");
|
||||
close(sockfd);
|
||||
return FALSE;
|
||||
}
|
||||
bufsize = ((size_t) numifs) * sizeof(struct ifreq);
|
||||
buf = (char *) malloc(bufsize);
|
||||
if (!buf)
|
||||
{
|
||||
perror("malloc");
|
||||
close(sockfd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ifc.ifc_len = bufsize;
|
||||
ifc.ifc_buf = buf;
|
||||
|
||||
if (ioctl(sockfd, SIOCGIFCONF, (char *) &ifc) < 0)
|
||||
{
|
||||
perror("SIOCGIFCONF");
|
||||
close(sockfd);
|
||||
free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ifrp = ifc.ifc_req;
|
||||
numifreqs = ifc.ifc_len / sizeof(struct ifreq);
|
||||
|
||||
for (i = 0; i < numifreqs; i++, ifrp++)
|
||||
{
|
||||
memset((char *)&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
|
||||
/* do not check for loopback device as it cannot be monitored */
|
||||
if (!strncmp(ifr.ifr_name, "lo", 2))
|
||||
continue;
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
|
||||
{
|
||||
perror("SIOCGIFFLAGS");
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(ifdata.if_name, ifr.ifr_name) && (ifr.ifr_flags & IFF_UP))
|
||||
{
|
||||
validinterface = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
close(sockfd);
|
||||
|
||||
return validinterface;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* use the Solaris kstat_*() interface to gather statistics
|
||||
* We have to open/close *kc each time :(
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
kstat_t *ksp;
|
||||
kstat_named_t *knp;
|
||||
kstat_ctl_t *kc;
|
||||
unsigned long rx_o, tx_o;
|
||||
|
||||
if ((kc = kstat_open()) == NULL)
|
||||
{
|
||||
perror("kstat_open()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rx_o = stats.rx_bytes; tx_o = stats.tx_bytes;
|
||||
|
||||
ksp = kstat_lookup(kc, NULL, -1, ifdata.if_name);
|
||||
if (ksp && kstat_read(kc, ksp, NULL) >= 0)
|
||||
{
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "opackets");
|
||||
if (knp)
|
||||
stats.tx_packets = knp->value.ui32;
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets");
|
||||
if (knp)
|
||||
stats.rx_packets = knp->value.ui32;
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "obytes");
|
||||
if (knp)
|
||||
stats.tx_bytes = knp->value.ui32;
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes");
|
||||
if (knp)
|
||||
stats.rx_bytes = knp->value.ui32;
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "oerrors");
|
||||
if (knp)
|
||||
stats.tx_errors = knp->value.ui32;
|
||||
knp = (kstat_named_t *)kstat_data_lookup(ksp, "ierrors");
|
||||
if (knp)
|
||||
stats.rx_errors = knp->value.ui32;
|
||||
}
|
||||
|
||||
kstat_close(kc);
|
||||
|
||||
/* check for overflows */
|
||||
if (rx_o > stats.rx_bytes)
|
||||
stats.rx_over++;
|
||||
if (tx_o > stats.tx_bytes)
|
||||
stats.tx_over++;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
int get_stat(void);
|
||||
int checkinterface(void);
|
|
@ -0,0 +1,14 @@
|
|||
/* $Id: unsupported.c,v 1.1 2003/08/24 20:01:48 bwalle Exp $ */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* get_stat()
|
||||
*
|
||||
* stub function for all unsupported operating systems
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int get_stat(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int get_stat(void);
|
Loading…
Reference in New Issue