diff --git a/panel-plugin/net.c b/panel-plugin/net.c new file mode 100644 index 0000000..04830b3 --- /dev/null +++ b/panel-plugin/net.c @@ -0,0 +1,168 @@ +/* XFce 4 - Netload Plugin + * Copyright (c) 2003 Bernhard Walle + * + * 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 +#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 */ +} + diff --git a/panel-plugin/net.h b/panel-plugin/net.h index c8f13ff..7d384b8 100644 --- a/panel-plugin/net.h +++ b/panel-plugin/net.h @@ -1,6 +1,8 @@ /* XFce 4 - Netload Plugin * Copyright (c) 2003 Bernhard Walle - * + * + * 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 +#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. ippp0 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 */ diff --git a/panel-plugin/net_freebsd.c b/panel-plugin/net_freebsd.c deleted file mode 100644 index 6fe7e18..0000000 --- a/panel-plugin/net_freebsd.c +++ /dev/null @@ -1,152 +0,0 @@ -/* XFce 4 - Netload Plugin - * Copyright (c) 2003 Bernhard Walle - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#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 */ -} - diff --git a/panel-plugin/net_libgtop2.c b/panel-plugin/net_libgtop2.c deleted file mode 100644 index 336a0ef..0000000 --- a/panel-plugin/net_libgtop2.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2003 Bernhard Walle - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#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(); -} - diff --git a/panel-plugin/net_linux.c b/panel-plugin/net_linux.c deleted file mode 100644 index 8eb852e..0000000 --- a/panel-plugin/net_linux.c +++ /dev/null @@ -1,152 +0,0 @@ -/* XFce 4 - Netload Plugin - * Copyright (c) 2003 Bernhard Walle - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#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 */ -} - diff --git a/panel-plugin/os.h b/panel-plugin/os.h new file mode 100644 index 0000000..2b5b6f7 --- /dev/null +++ b/panel-plugin/os.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#elif __FreeBSD__ /* F R E E B S D */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#elif __NetBSD__ /* N E T B S D */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#elif __OpenBSD__ || __MicroBSD__ /* O P E N B S D */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#elif __linux__ /* L I N U X */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#elif __Solaris__ /* S O L A R I S */ +#include +#define _WIDEC_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +#error "OS not supported" +#endif + +#endif diff --git a/panel-plugin/slurm.h b/panel-plugin/slurm.h new file mode 100644 index 0000000..4ae0b02 --- /dev/null +++ b/panel-plugin/slurm.h @@ -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 diff --git a/panel-plugin/wormulon.h b/panel-plugin/wormulon.h new file mode 100644 index 0000000..afe5c38 --- /dev/null +++ b/panel-plugin/wormulon.h @@ -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 diff --git a/panel-plugin/wormulon/freebsd.c b/panel-plugin/wormulon/freebsd.c new file mode 100644 index 0000000..cc1a598 --- /dev/null +++ b/panel-plugin/wormulon/freebsd.c @@ -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); +} diff --git a/panel-plugin/wormulon/freebsd.h b/panel-plugin/wormulon/freebsd.h new file mode 100644 index 0000000..42aee76 --- /dev/null +++ b/panel-plugin/wormulon/freebsd.h @@ -0,0 +1,2 @@ +int get_stat(void); +int checkinterface(void); diff --git a/panel-plugin/wormulon/hpux.c b/panel-plugin/wormulon/hpux.c new file mode 100644 index 0000000..c78b24c --- /dev/null +++ b/panel-plugin/wormulon/hpux.c @@ -0,0 +1,181 @@ +#include +#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); +} diff --git a/panel-plugin/wormulon/hpux.h b/panel-plugin/wormulon/hpux.h new file mode 100644 index 0000000..4947ad1 --- /dev/null +++ b/panel-plugin/wormulon/hpux.h @@ -0,0 +1,5 @@ +#ifndef _HPUX_H_ +#define _HPUX_H_ +extern int checkinterface(void); +extern int get_stat(void); +#endif diff --git a/panel-plugin/wormulon/if_media.c b/panel-plugin/wormulon/if_media.c new file mode 100644 index 0000000..f3a1933 --- /dev/null +++ b/panel-plugin/wormulon/if_media.c @@ -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 diff --git a/panel-plugin/wormulon/if_media.h b/panel-plugin/wormulon/if_media.h new file mode 100644 index 0000000..8433dbf --- /dev/null +++ b/panel-plugin/wormulon/if_media.h @@ -0,0 +1,5 @@ +/* interface speed detection errors */ +#define ERR_IFACE_NO_SPEED -1 +#define ERR_IFACE_DOWN -2 + +int get_if_speed(char *); diff --git a/panel-plugin/wormulon/linux.c b/panel-plugin/wormulon/linux.c new file mode 100644 index 0000000..6b39445 --- /dev/null +++ b/panel-plugin/wormulon/linux.c @@ -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; +} diff --git a/panel-plugin/wormulon/linux.h b/panel-plugin/wormulon/linux.h new file mode 100644 index 0000000..f40045a --- /dev/null +++ b/panel-plugin/wormulon/linux.h @@ -0,0 +1,5 @@ +int checkinterface(void); +int get_stat(void); +#ifdef __linux__ +#define BUFSIZE 256 +#endif diff --git a/panel-plugin/wormulon/netbsd.c b/panel-plugin/wormulon/netbsd.c new file mode 100644 index 0000000..29936ea --- /dev/null +++ b/panel-plugin/wormulon/netbsd.c @@ -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; +} diff --git a/panel-plugin/wormulon/netbsd.h b/panel-plugin/wormulon/netbsd.h new file mode 100644 index 0000000..42aee76 --- /dev/null +++ b/panel-plugin/wormulon/netbsd.h @@ -0,0 +1,2 @@ +int get_stat(void); +int checkinterface(void); diff --git a/panel-plugin/wormulon/openbsd.c b/panel-plugin/wormulon/openbsd.c new file mode 100644 index 0000000..42781c7 --- /dev/null +++ b/panel-plugin/wormulon/openbsd.c @@ -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; +} diff --git a/panel-plugin/wormulon/openbsd.h b/panel-plugin/wormulon/openbsd.h new file mode 100644 index 0000000..42aee76 --- /dev/null +++ b/panel-plugin/wormulon/openbsd.h @@ -0,0 +1,2 @@ +int get_stat(void); +int checkinterface(void); diff --git a/panel-plugin/wormulon/solaris.c b/panel-plugin/wormulon/solaris.c new file mode 100644 index 0000000..b53c8b2 --- /dev/null +++ b/panel-plugin/wormulon/solaris.c @@ -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; +} diff --git a/panel-plugin/wormulon/solaris.h b/panel-plugin/wormulon/solaris.h new file mode 100644 index 0000000..42aee76 --- /dev/null +++ b/panel-plugin/wormulon/solaris.h @@ -0,0 +1,2 @@ +int get_stat(void); +int checkinterface(void); diff --git a/panel-plugin/wormulon/unsupported.c b/panel-plugin/wormulon/unsupported.c new file mode 100644 index 0000000..ff220d9 --- /dev/null +++ b/panel-plugin/wormulon/unsupported.c @@ -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; +} diff --git a/panel-plugin/wormulon/unsupported.h b/panel-plugin/wormulon/unsupported.h new file mode 100644 index 0000000..20f3547 --- /dev/null +++ b/panel-plugin/wormulon/unsupported.h @@ -0,0 +1 @@ +int get_stat(void);