Blame sysdeps/linux/netload.c

Packit d37888
/* Copyright (C) 1998-99 Martin Baulig
Packit d37888
   This file is part of LibGTop 1.0.
Packit d37888
Packit d37888
   Contributed by Martin Baulig <martin@home-of-linux.org>, October 1998.
Packit d37888
Packit d37888
   LibGTop is free software; you can redistribute it and/or modify it
Packit d37888
   under the terms of the GNU General Public License as published by
Packit d37888
   the Free Software Foundation; either version 2 of the License,
Packit d37888
   or (at your option) any later version.
Packit d37888
Packit d37888
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit d37888
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit d37888
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit d37888
   for more details.
Packit d37888
Packit d37888
   You should have received a copy of the GNU General Public License
Packit d37888
   along with LibGTop; see the file COPYING. If not, write to the
Packit d37888
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d37888
   Boston, MA 02110-1301, USA.
Packit d37888
*/
Packit d37888
Packit d37888
#include <config.h>
Packit d37888
Packit d37888
#include <glibtop.h>
Packit d37888
#include <glibtop/error.h>
Packit d37888
#include <glibtop/netload.h>
Packit d37888
Packit d37888
#include "glibtop_private.h"
Packit d37888
Packit d37888
#include <errno.h>
Packit d37888
#include <string.h>
Packit d37888
Packit d37888
#include <sys/types.h>
Packit d37888
#include <sys/socket.h>
Packit d37888
#include <sys/ioctl.h>
Packit d37888
Packit d37888
#if !defined (__GLIBC__) || __GNU_LIBRARY__ > 1
Packit d37888
/* GNU LibC */
Packit d37888
#include <net/if.h>
Packit d37888
#include <netinet/ip_icmp.h>
Packit d37888
#include <netinet/in.h>
Packit d37888
#include <netinet/ip.h>
Packit d37888
#include <netinet/tcp.h>
Packit d37888
#include <netinet/udp.h>
Packit d37888
#include <net/if.h>
Packit d37888
#elif defined (__GLIBC__) /* Libc 5 */
Packit d37888
#include <linux/if.h>
Packit d37888
#include <linux/in.h>
Packit d37888
#include <linux/ip.h>
Packit d37888
#include <linux/icmp.h>
Packit d37888
#include <linux/tcp.h>
Packit d37888
#include <linux/udp.h>
Packit d37888
#endif
Packit d37888
Packit d37888
Packit d37888
#ifdef HAVE_IFADDRS_H
Packit d37888
/* needed for IPV6 support */
Packit d37888
Packit d37888
#include <ifaddrs.h>
Packit d37888
Packit d37888
#ifndef IN6_IS_ADDR_GLOBAL
Packit d37888
#define IN6_IS_ADDR_GLOBAL(a) \
Packit d37888
   (((((__const uint8_t *) (a))[0] & 0xff) == 0x3f   \
Packit d37888
     || (((__const uint8_t *) (a))[0] & 0xff) == 0x20))
Packit d37888
#endif
Packit d37888
#endif /* HAVE_IFADDRS_H */
Packit d37888
Packit d37888
Packit d37888
#define _GLIBTOP_IP_FW_ACCTIN	0x1000	/* Account incoming packets only. */
Packit d37888
#define _GLIBTOP_IP_FW_ACCTOUT	0x2000	/* Account outgoing packets only. */
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload =
Packit d37888
(1L << GLIBTOP_NETLOAD_ERRORS_IN) +
Packit d37888
(1L << GLIBTOP_NETLOAD_ERRORS_OUT) +
Packit d37888
(1L << GLIBTOP_NETLOAD_COLLISIONS);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_data =
Packit d37888
(1L << GLIBTOP_NETLOAD_ADDRESS) +
Packit d37888
(1L << GLIBTOP_NETLOAD_SUBNET) +
Packit d37888
(1L << GLIBTOP_NETLOAD_MTU);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_bytes =
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_IN) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_OUT) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_TOTAL);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_packets =
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_IN) +
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_OUT) +
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_total =
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_TOTAL);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_in =
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) +
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_IN) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_IN);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_out =
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) +
Packit d37888
(1L << GLIBTOP_NETLOAD_PACKETS_OUT) +
Packit d37888
(1L << GLIBTOP_NETLOAD_BYTES_OUT);
Packit d37888
Packit d37888
static const unsigned long _glibtop_sysdeps_netload_6 =
Packit d37888
(1L << GLIBTOP_NETLOAD_ADDRESS6) +
Packit d37888
(1L << GLIBTOP_NETLOAD_PREFIX6) +
Packit d37888
(1L << GLIBTOP_NETLOAD_SCOPE6);
Packit d37888
Packit d37888
/* Init function. */
Packit d37888
Packit d37888
void
Packit d37888
_glibtop_init_netload_s (glibtop *server)
Packit d37888
{
Packit d37888
    server->sysdeps.netload = _glibtop_sysdeps_netload |
Packit d37888
	_glibtop_sysdeps_netload_data |
Packit d37888
	_glibtop_sysdeps_netload_bytes |
Packit d37888
	_glibtop_sysdeps_netload_packets;
Packit d37888
}
Packit d37888
Packit d37888
Packit d37888
#ifdef HAVE_IFADDRS_H
Packit d37888
Packit d37888
static void get_ipv6(glibtop *server, glibtop_netload *buf,
Packit d37888
		     const char *interface)
Packit d37888
{
Packit d37888
	struct ifaddrs *ifa0, *ifr6;
Packit d37888
Packit d37888
	if(getifaddrs (&ifa0) != 0)
Packit d37888
	{
Packit d37888
		glibtop_warn_r(server, "getifaddrs failed : %s", g_strerror(errno));
Packit d37888
		return;
Packit d37888
	}
Packit d37888
Packit d37888
	for (ifr6 = ifa0; ifr6; ifr6 = ifr6->ifa_next) {
Packit d37888
		if (strcmp (ifr6->ifa_name, interface) == 0
Packit d37888
		    && ifr6->ifa_addr != NULL
Packit d37888
		    && ifr6->ifa_addr->sa_family == AF_INET6)
Packit d37888
			break;
Packit d37888
	}
Packit d37888
Packit d37888
	if(!ifr6) goto free_ipv6;
Packit d37888
Packit d37888
	memcpy(buf->address6,
Packit d37888
	       &((struct sockaddr_in6 *) ifr6->ifa_addr)->sin6_addr,
Packit d37888
	       16);
Packit d37888
Packit d37888
	memcpy(buf->prefix6,
Packit d37888
	       &((struct sockaddr_in6 *) ifr6->ifa_netmask)->sin6_addr,
Packit d37888
	       16);
Packit d37888
Packit d37888
Packit d37888
	if (IN6_IS_ADDR_LINKLOCAL (buf->address6))
Packit d37888
		buf->scope6 = GLIBTOP_IF_IN6_SCOPE_LINK;
Packit d37888
Packit d37888
	else if (IN6_IS_ADDR_SITELOCAL (buf->address6))
Packit d37888
		buf->scope6 = GLIBTOP_IF_IN6_SCOPE_SITE;
Packit d37888
Packit d37888
	else if (IN6_IS_ADDR_GLOBAL (buf->address6)
Packit d37888
		 || IN6_IS_ADDR_MC_ORGLOCAL (buf->address6)
Packit d37888
		 || IN6_IS_ADDR_V4COMPAT (buf->address6)
Packit d37888
		 || IN6_IS_ADDR_MULTICAST (buf->address6)
Packit d37888
		 || IN6_IS_ADDR_UNSPECIFIED (buf->address6)
Packit d37888
		)
Packit d37888
		buf->scope6 = GLIBTOP_IF_IN6_SCOPE_GLOBAL;
Packit d37888
Packit d37888
	else if (IN6_IS_ADDR_LOOPBACK (buf->address6))
Packit d37888
		buf->scope6 = GLIBTOP_IF_IN6_SCOPE_HOST;
Packit d37888
Packit d37888
	else
Packit d37888
		buf->scope6 = GLIBTOP_IF_IN6_SCOPE_UNKNOWN;
Packit d37888
Packit d37888
	buf->flags |= _glibtop_sysdeps_netload_6;
Packit d37888
Packit d37888
 free_ipv6:
Packit d37888
	freeifaddrs(ifa0);
Packit d37888
}
Packit d37888
Packit d37888
#endif /* HAVE_IFADDRS_H */
Packit d37888
Packit d37888
Packit d37888
Packit d37888
Packit d37888
static gboolean
Packit d37888
read_value(glibtop *server,
Packit d37888
	   const char *device,
Packit d37888
	   const char *filename,
Packit d37888
	   guint64 *value)
Packit d37888
{
Packit d37888
    char buffer[BUFSIZ];
Packit d37888
Packit d37888
    if(try_file_to_buffer(buffer,
Packit d37888
    			  sizeof buffer,
Packit d37888
			  "/sys/class/net/%s/statistics/%s",
Packit d37888
			  device,
Packit d37888
			  filename))
Packit d37888
    {
Packit d37888
	glibtop_warn_io_r(server,
Packit d37888
			  "Failed to open \"/sys/class/net/%s/statistics/%s\"",
Packit d37888
			  device,
Packit d37888
			  filename);
Packit d37888
Packit d37888
	return FALSE;
Packit d37888
    }
Packit d37888
Packit d37888
    *value = strtoull(buffer, NULL, 10);
Packit d37888
    return TRUE;
Packit d37888
}
Packit d37888
Packit d37888
Packit d37888
Packit d37888
Packit d37888
static void
Packit d37888
linux_2_6_stats(glibtop *server,
Packit d37888
		   glibtop_netload *buf,
Packit d37888
		   const char *dev)
Packit d37888
{
Packit d37888
    if(read_value(server, dev, "rx_packets", &buf->packets_in))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_PACKETS_IN);
Packit d37888
Packit d37888
    if(read_value(server, dev, "tx_packets", &buf->packets_out))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_PACKETS_OUT);
Packit d37888
Packit d37888
    buf->packets_total = buf->packets_in + buf->packets_out;
Packit d37888
    buf->flags |= (1 << GLIBTOP_NETLOAD_PACKETS_TOTAL);
Packit d37888
Packit d37888
Packit d37888
    if(read_value(server, dev, "rx_bytes", &buf->bytes_in))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_BYTES_IN);
Packit d37888
Packit d37888
    if(read_value(server, dev, "tx_bytes", &buf->bytes_out))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_BYTES_OUT);
Packit d37888
Packit d37888
    buf->bytes_total = buf->bytes_in + buf->bytes_out;
Packit d37888
    buf->flags |= (1 << GLIBTOP_NETLOAD_BYTES_TOTAL);
Packit d37888
Packit d37888
Packit d37888
    if(read_value(server, dev, "rx_errors", &buf->errors_in))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_ERRORS_IN);
Packit d37888
Packit d37888
    if(read_value(server, dev, "tx_errors", &buf->errors_out))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_ERRORS_OUT);
Packit d37888
Packit d37888
    buf->errors_total = buf->errors_in + buf->errors_out;
Packit d37888
    buf->flags |= (1 << GLIBTOP_NETLOAD_ERRORS_TOTAL);
Packit d37888
Packit d37888
Packit d37888
    if(read_value(server, dev, "collisions", &buf->collisions))
Packit d37888
	buf->flags |= (1 << GLIBTOP_NETLOAD_COLLISIONS);
Packit d37888
}
Packit d37888
Packit d37888
Packit d37888
Packit d37888
Packit d37888
static void
Packit d37888
linux_2_0_stats(glibtop *server,
Packit d37888
		glibtop_netload *buf,
Packit d37888
		const char *interface)
Packit d37888
{
Packit d37888
    FILE *f;
Packit d37888
    char buffer[BUFSIZ];
Packit d37888
Packit d37888
    f = fopen ("/proc/net/ip_acct", "r");
Packit d37888
Packit d37888
    if (!f) {
Packit d37888
	glibtop_warn_io_r (server,
Packit d37888
			   "Failed to open \"/proc/net/ip_acct\"");
Packit d37888
	return;
Packit d37888
    }
Packit d37888
Packit d37888
    /* Skip over the header line. */
Packit d37888
    fgets (buffer, BUFSIZ-1, f);
Packit d37888
Packit d37888
    while (fgets (buffer, BUFSIZ-1, f)) {
Packit d37888
	unsigned long long flags, packets, bytes;
Packit d37888
	char *p, *dev;
Packit d37888
Packit d37888
	/* Skip over the network thing. */
Packit d37888
	dev = skip_token (buffer) + 1;
Packit d37888
	p = skip_token (dev);
Packit d37888
	*p++ = 0;
Packit d37888
Packit d37888
	if (strcmp (dev, interface))
Packit d37888
	    continue;
Packit d37888
Packit d37888
	p = skip_token (p);
Packit d37888
Packit d37888
	flags   = strtoull (p, &p, 16);
Packit d37888
Packit d37888
	p = skip_multiple_token (p, 2);
Packit d37888
Packit d37888
	packets = strtoull (p, &p, 0);
Packit d37888
	bytes   = strtoull (p, &p, 0);
Packit d37888
Packit d37888
	if (flags & _GLIBTOP_IP_FW_ACCTIN) {
Packit d37888
	    /* Incoming packets only. */
Packit d37888
Packit d37888
	    buf->packets_total += packets;
Packit d37888
	    buf->packets_in += packets;
Packit d37888
Packit d37888
	    buf->bytes_total += bytes;
Packit d37888
	    buf->bytes_in += bytes;
Packit d37888
Packit d37888
	    buf->flags |= _glibtop_sysdeps_netload_in;
Packit d37888
Packit d37888
	} else if (flags & _GLIBTOP_IP_FW_ACCTOUT) {
Packit d37888
	    /* Outgoing packets only. */
Packit d37888
Packit d37888
	    buf->packets_total += packets;
Packit d37888
	    buf->packets_out += packets;
Packit d37888
Packit d37888
	    buf->bytes_total += bytes;
Packit d37888
	    buf->bytes_out += bytes;
Packit d37888
Packit d37888
	    buf->flags |= _glibtop_sysdeps_netload_out;
Packit d37888
Packit d37888
	} else {
Packit d37888
	    /* Only have total values. */
Packit d37888
Packit d37888
	    buf->packets_total += packets;
Packit d37888
	    buf->bytes_total += bytes;
Packit d37888
Packit d37888
	    buf->flags |= _glibtop_sysdeps_netload_total;
Packit d37888
	}
Packit d37888
    }
Packit d37888
Packit d37888
    fclose (f);
Packit d37888
}
Packit d37888
Packit d37888
Packit d37888
Packit d37888
Packit d37888
static void
Packit d37888
linux_2_4_stats(glibtop *server,
Packit d37888
		glibtop_netload *buf,
Packit d37888
		const char *interface)
Packit d37888
{
Packit d37888
    char buffer [BUFSIZ], *p;
Packit d37888
    int have_bytes, fields;
Packit d37888
    FILE *f;
Packit d37888
Packit d37888
    /* Ok, either IP accounting is not enabled in the kernel or
Packit d37888
     * it was not enabled for the requested interface. */
Packit d37888
Packit d37888
    f = fopen ("/proc/net/dev", "r");
Packit d37888
    if (!f) {
Packit d37888
	glibtop_warn_io_r(server,
Packit d37888
			  "Failed to open \"/proc/net/dev\"");
Packit d37888
	return;
Packit d37888
    }
Packit d37888
Packit d37888
    /* Skip over the header line. */
Packit d37888
    fgets (buffer, BUFSIZ-1, f);
Packit d37888
    fgets (buffer, BUFSIZ-1, f);
Packit d37888
Packit d37888
    /* Starting with 2.1.xx (don't know exactly which version)
Packit d37888
     * /proc/net/dev contains both byte and package counters. */
Packit d37888
Packit d37888
    p = strchr (buffer, '|');
Packit d37888
    if (!p) {
Packit d37888
	fclose (f);
Packit d37888
	return;
Packit d37888
    }
Packit d37888
Packit d37888
    /* Do we already have byte counters ? */
Packit d37888
    have_bytes = strncmp (++p, "bytes", 5) == 0;
Packit d37888
Packit d37888
    /* Count remaining 'Receive' fields so we know where
Packit d37888
     * the first 'Transmit' field starts. */
Packit d37888
Packit d37888
    fields = 0;
Packit d37888
    while (*p != '|') {
Packit d37888
	if (!isspace (*p++)) continue;
Packit d37888
	while (isspace (*p++)) ;
Packit d37888
	fields++;
Packit d37888
    }
Packit d37888
Packit d37888
    /* Should never happen. */
Packit d37888
    if (fields < 2) {
Packit d37888
	fclose (f);
Packit d37888
	return;
Packit d37888
    }
Packit d37888
    fields--;
Packit d37888
Packit d37888
    while (fgets (buffer, BUFSIZ-1, f)) {
Packit d37888
	char *p, *dev;
Packit d37888
Packit d37888
	dev = buffer;
Packit d37888
	while (isspace (*dev)) dev++;
Packit d37888
Packit d37888
	p = strchr (dev, ':');
Packit d37888
	if (!p) continue;
Packit d37888
	*p++ = 0;
Packit d37888
Packit d37888
	/* If it's not a digit, then it's most likely an error
Packit d37888
	 * message like 'No statistics available'. */
Packit d37888
	while (isspace (*p)) p++;
Packit d37888
	if (!isdigit (*p)) continue;
Packit d37888
Packit d37888
	if (strcmp (dev, interface))
Packit d37888
	    continue;
Packit d37888
Packit d37888
	/* Ok, we've found the interface */
Packit d37888
Packit d37888
	/* Only read byte counts if we really have them. */
Packit d37888
Packit d37888
	if (have_bytes) {
Packit d37888
	    buf->bytes_in = strtoull (p, &p, 0);
Packit d37888
	    fields--;
Packit d37888
	}
Packit d37888
Packit d37888
	buf->packets_in = strtoull (p, &p, 0);
Packit d37888
	buf->errors_in  = strtoull (p, &p, 0);
Packit d37888
Packit d37888
	p = skip_multiple_token (p, fields);
Packit d37888
Packit d37888
	if (have_bytes)
Packit d37888
	    buf->bytes_out = strtoull (p, &p, 0);
Packit d37888
Packit d37888
	buf->packets_out = strtoull (p, &p, 0);
Packit d37888
	buf->errors_out  = strtoull (p, &p, 0);
Packit d37888
Packit d37888
	p = skip_multiple_token (p, 2);
Packit d37888
Packit d37888
	buf->collisions  = strtoull (p, &p, 0);
Packit d37888
Packit d37888
	/* Compute total valules. */
Packit d37888
Packit d37888
	buf->bytes_total = buf->bytes_in + buf->bytes_out;
Packit d37888
	buf->packets_total = buf->packets_in + buf->packets_out;
Packit d37888
Packit d37888
	/* And now the flags. */
Packit d37888
Packit d37888
	buf->flags |= _glibtop_sysdeps_netload;
Packit d37888
	buf->flags |= _glibtop_sysdeps_netload_packets;
Packit d37888
Packit d37888
	if (have_bytes)
Packit d37888
	    buf->flags |= _glibtop_sysdeps_netload_bytes;
Packit d37888
Packit d37888
	break; /* finished */
Packit d37888
    }
Packit d37888
Packit d37888
    fclose (f);
Packit d37888
}
Packit d37888
Packit d37888
Packit d37888
Packit d37888
Packit d37888
/* Provides network statistics. */
Packit d37888
Packit d37888
void
Packit d37888
glibtop_get_netload_s (glibtop *server, glibtop_netload *buf,
Packit d37888
		       const char *interface)
Packit d37888
{
Packit d37888
    int skfd;
Packit d37888
    memset (buf, 0, sizeof (glibtop_netload));
Packit d37888
Packit d37888
    skfd = socket (AF_INET, SOCK_DGRAM, 0);
Packit d37888
    if (skfd) {
Packit d37888
	struct ifreq ifr;
Packit d37888
Packit d37888
	g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
Packit d37888
	if (!ioctl (skfd, SIOCGIFFLAGS, &ifr)) {
Packit d37888
	    const unsigned long long flags = ifr.ifr_flags;
Packit d37888
Packit d37888
	    buf->flags |= (1L << GLIBTOP_NETLOAD_IF_FLAGS);
Packit d37888
Packit d37888
	    if (flags & IFF_UP)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP);
Packit d37888
Packit d37888
	    if (flags & IFF_BROADCAST)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST);
Packit d37888
Packit d37888
	    if (flags & IFF_DEBUG)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG);
Packit d37888
Packit d37888
	    if (flags & IFF_LOOPBACK)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK);
Packit d37888
Packit d37888
	    if (flags & IFF_POINTOPOINT)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT);
Packit d37888
Packit d37888
	    if (flags & IFF_RUNNING)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING);
Packit d37888
Packit d37888
	    if (flags & IFF_NOARP)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP);
Packit d37888
Packit d37888
	    if (flags & IFF_PROMISC)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC);
Packit d37888
Packit d37888
	    if (flags & IFF_ALLMULTI)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI);
Packit d37888
Packit d37888
	    if (flags & IFF_MULTICAST)
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST);
Packit d37888
	    }
Packit d37888
Packit d37888
	g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
Packit d37888
	if (!ioctl(skfd, /* SIOCGIWNAME */ 0x8B01, &ifr))
Packit d37888
		buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_WIRELESS);
Packit d37888
Packit d37888
	g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
Packit d37888
	if (!ioctl (skfd, SIOCGIFADDR, &ifr)) {
Packit d37888
	    buf->address = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
Packit d37888
	    buf->flags |= (1L << GLIBTOP_NETLOAD_ADDRESS);
Packit d37888
	}
Packit d37888
Packit d37888
	g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
Packit d37888
	if (!ioctl (skfd, SIOCGIFNETMASK, &ifr)) {
Packit d37888
	    buf->subnet = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
Packit d37888
	    buf->flags |= (1L << GLIBTOP_NETLOAD_SUBNET);
Packit d37888
	}
Packit d37888
Packit d37888
	g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
Packit d37888
	if (!ioctl (skfd, SIOCGIFMTU, &ifr)) {
Packit d37888
	    buf->mtu = ifr.ifr_mtu;
Packit d37888
	    buf->flags |= (1L << GLIBTOP_NETLOAD_MTU);
Packit d37888
	}
Packit d37888
Packit d37888
	g_strlcpy (ifr.ifr_name, interface, sizeof ifr.ifr_name);
Packit d37888
	if (!ioctl (skfd, SIOCGIFHWADDR, &ifr)) {
Packit d37888
	    memcpy(buf->hwaddress, &ifr.ifr_hwaddr.sa_data, 8);
Packit d37888
	    buf->flags |= (1L << GLIBTOP_NETLOAD_HWADDRESS);
Packit d37888
	}
Packit d37888
Packit d37888
	close (skfd);
Packit d37888
    }
Packit d37888
Packit d37888
Packit d37888
    /*
Packit d37888
     * Statistics
Packit d37888
     */
Packit d37888
Packit d37888
    /* Linux 2.1.114 - don't know where exactly this was added, but
Packit d37888
	 * recent kernels have byte count in /proc/net/dev so we don't
Packit d37888
	 * need IP accounting.
Packit d37888
	 */
Packit d37888
Packit d37888
    if (server->os_version_code < LINUX_VERSION_CODE(2, 1, 14)) {
Packit d37888
	linux_2_0_stats(server, buf, interface);
Packit d37888
    }
Packit d37888
    else if (server->os_version_code > LINUX_VERSION_CODE(2, 6, 0)
Packit d37888
	     && has_sysfs()) {
Packit d37888
	linux_2_6_stats(server, buf, interface);
Packit d37888
    }
Packit d37888
    else {
Packit d37888
	/* 2.4 and 2.6 without /sys (?$£Z¥!) */
Packit d37888
	linux_2_4_stats(server, buf, interface);
Packit d37888
    }
Packit d37888
Packit d37888
#ifdef HAVE_IFADDRS_H
Packit d37888
    get_ipv6(server, buf, interface);
Packit d37888
#endif /* HAVE_IFADDRS_H */
Packit d37888
}
Packit d37888
Packit d37888
Packit d37888