summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoît Dejean <bdejean@src.gnome.org>2007-10-10 08:13:49 +0000
committerBenoît Dejean <bdejean@src.gnome.org>2007-10-10 08:13:49 +0000
commit9618fe795fc2aa9bc3540f27bfe0c137f7321a8b (patch)
treee0626610fa82d8818e5cf13c01466be5b36c3729
parent2e3231b051cb6a053109479e8eb7ae6e1dd42321 (diff)
downloadlibgtop-9618fe795fc2aa9bc3540f27bfe0c137f7321a8b.tar.gz
Fixed netload build.
Patch by Henry Zhang <hua.zhang@sun.com>. Closes #346021. svn path=/trunk/; revision=2675
-rw-r--r--sysdeps/solaris/netload.c225
1 files changed, 219 insertions, 6 deletions
diff --git a/sysdeps/solaris/netload.c b/sysdeps/solaris/netload.c
index 0bdf7ade..595b9edd 100644
--- a/sysdeps/solaris/netload.c
+++ b/sysdeps/solaris/netload.c
@@ -1,7 +1,7 @@
-/* Copyright (C) 1998-99 Martin Baulig
- This file is part of LibGTop 1.0.
+/* Copyright (C) 2007 Henry Zhang
+ This file is part of LibGTop 2.20.
- Contributed by Martin Baulig <martin@home-of-linux.org>, October 1998.
+ Contributed by Henry Zhang <hua.zhang@sun.com>, October 2007.
LibGTop is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@@ -24,14 +24,163 @@
#include <glibtop/error.h>
#include <glibtop/netload.h>
-static const unsigned long _glibtop_sysdeps_netload = 0;
+#include "glibtop_private.h"
+
+#include <errno.h>
+#include <string.h>
+#include <kstat.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+
+static const unsigned long _glibtop_sysdeps_netload =
+(1L << GLIBTOP_NETLOAD_ERRORS_IN) +
+(1L << GLIBTOP_NETLOAD_ERRORS_OUT) +
+(1L << GLIBTOP_NETLOAD_COLLISIONS);
+
+static const unsigned long _glibtop_sysdeps_netload_data =
+(1L << GLIBTOP_NETLOAD_ADDRESS) +
+(1L << GLIBTOP_NETLOAD_SUBNET) +
+(1L << GLIBTOP_NETLOAD_MTU);
+
+static const unsigned long _glibtop_sysdeps_netload_bytes =
+(1L << GLIBTOP_NETLOAD_BYTES_IN) +
+(1L << GLIBTOP_NETLOAD_BYTES_OUT) +
+(1L << GLIBTOP_NETLOAD_BYTES_TOTAL);
+
+static const unsigned long _glibtop_sysdeps_netload_packets =
+(1L << GLIBTOP_NETLOAD_PACKETS_IN) +
+(1L << GLIBTOP_NETLOAD_PACKETS_OUT) +
+(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL);
+
+static const unsigned long _glibtop_sysdeps_netload_total =
+(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
+(1L << GLIBTOP_NETLOAD_BYTES_TOTAL);
+
+static const unsigned long _glibtop_sysdeps_netload_in =
+(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
+(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) +
+(1L << GLIBTOP_NETLOAD_PACKETS_IN) +
+(1L << GLIBTOP_NETLOAD_BYTES_IN);
+
+static const unsigned long _glibtop_sysdeps_netload_out =
+(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
+(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) +
+(1L << GLIBTOP_NETLOAD_PACKETS_OUT) +
+(1L << GLIBTOP_NETLOAD_BYTES_OUT);
+
+static const unsigned long _glibtop_sysdeps_netload_6 =
+(1L << GLIBTOP_NETLOAD_ADDRESS6) +
+(1L << GLIBTOP_NETLOAD_PREFIX6) +
+(1L << GLIBTOP_NETLOAD_SCOPE6);
/* Init function. */
void
_glibtop_init_netload_s (glibtop *server)
{
- server->sysdeps.netload = _glibtop_sysdeps_netload;
+ server->sysdeps.netload = _glibtop_sysdeps_netload |
+ _glibtop_sysdeps_netload_bytes |
+ _glibtop_sysdeps_netload_packets;
+}
+
+static int
+solaris_stats(glibtop *server,
+ glibtop_netload *buf,
+ const char *interface)
+{
+ char *name = interface;
+ char *module;
+ char *ptr;
+ kstat_ctl_t * const kctl = server->machine.kc;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+ int have_bytes = 1;
+
+ /*
+ * chop off the trailing interface
+ */
+ module = strdup( name );
+ ptr = module + strlen( module ) - 1;
+ while( (ptr > module) && isdigit( (int) *ptr ) ) {
+ *ptr = '\0';
+ ptr--;
+ }
+
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( kctl == NULL ){
+ glibtop_warn_io_r (server, "kstat_open ()");
+ free( module );
+ return( 0 );
+ }
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ /*
+ * traverse the kstat chain
+ * to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl,
+ module, 0, name )) == NULL ) {
+ free( module );
+ return( 0 );
+ }
+ if( kstat_read( kctl, ksp, NULL ) == -1 ) {
+ free( module );
+ return( 0 );
+ }
+ free( module );
+
+ /*
+ * lookup & store the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ipackets" );
+ if( kdata != NULL ) {
+ buf->packets_in= kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "opackets" );
+ if( kdata != NULL ) {
+ buf->packets_out = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "rbytes" );
+ if( kdata != NULL ) {
+ buf->bytes_in =kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "obytes" );
+ if( kdata != NULL ) {
+ buf->bytes_out =kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ierrors" );
+ if( kdata != NULL ) {
+ buf->errors_in = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "oerrors" );
+ if( kdata != NULL ) {
+ buf->errors_out = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "collisions" );
+ if( kdata != NULL ) {
+ buf->collisions = kdata->value.ul;
+ }
+
+ /* Compute total valules. */
+
+ buf->bytes_total = buf->bytes_in + buf->bytes_out;
+ buf->packets_total = buf->packets_in + buf->packets_out;
+ buf->errors_total = buf->errors_in + buf->errors_out;
+ /* And now the flags. */
+ buf->flags |= _glibtop_sysdeps_netload;
+ buf->flags |= _glibtop_sysdeps_netload_bytes;
+ buf->flags |= _glibtop_sysdeps_netload_packets;
+
+ /* finished */
}
/* Provides network statistics. */
@@ -40,5 +189,69 @@ void
glibtop_get_netload_s (glibtop *server, glibtop_netload *buf,
const char *interface)
{
- memset (buf, 0, sizeof (glibtop_netload));
+ int skfd;
+ memset (buf, 0, sizeof (glibtop_netload));
+
+ /* set flag */
+ skfd = socket (PF_INET, SOCK_DGRAM, 0);
+ if (skfd) {
+ struct ifreq ifr;
+
+ g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
+ if (ioctl (skfd, SIOCGIFFLAGS, &ifr) >= 0) {
+ const unsigned long long flags = ifr.ifr_flags;
+
+ buf->flags |= (1L << GLIBTOP_NETLOAD_IF_FLAGS);
+
+ if (flags & IFF_UP)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP);
+
+ if (flags & IFF_BROADCAST)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST);
+
+ if (flags & IFF_DEBUG)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG);
+
+ if (flags & IFF_LOOPBACK)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK);
+
+ if (flags & IFF_POINTOPOINT)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT);
+
+ if (flags & IFF_RUNNING)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING);
+
+ if (flags & IFF_NOARP)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP);
+
+ if (flags & IFF_PROMISC)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC);
+
+ if (flags & IFF_ALLMULTI)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI);
+
+ if (flags & IFF_MULTICAST)
+ buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST);
+ }
+
+ g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
+ if (!ioctl (skfd, SIOCGIFADDR, &ifr)) {
+ buf->address = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
+ buf->flags |= (1L << GLIBTOP_NETLOAD_ADDRESS);
+ }
+
+ g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
+ if (!ioctl (skfd, SIOCGIFNETMASK, &ifr)) {
+ buf->subnet = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
+ buf->flags |= (1L << GLIBTOP_NETLOAD_SUBNET);
+ }
+ close (skfd);
+ }
+
+ /*
+ * Statistics
+ */
+
+ solaris_stats(server, buf, interface);
+
}