summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--features.def2
-rw-r--r--include/glibtop/interfaces.h19
-rw-r--r--include/glibtop/netinfo.h8
-rw-r--r--sysdeps/linux/netinfo.c87
4 files changed, 89 insertions, 27 deletions
diff --git a/features.def b/features.def
index cfab348d..d70aa117 100644
--- a/features.def
+++ b/features.def
@@ -19,6 +19,6 @@ array(glibtop_map_entry)|proc_map|array|pid_t(pid)
array(glibtop_mountentry)|@mountlist|array|int(all_fs)
retval|@fsusage|ulong(blocks,bfree,bavail,files,ffree)|string(mount_dir)
array(glibtop_interface)|interface_names|array|ulong(interface,number,instance,strategy)
-retval|netinfo|ulong(if_flags,transport,mtu,subnet[GLIBTOP_IFADDR_LEN],address[GLIBTOP_IFADDR_LEN])|string(interface):ulong(transport)
+array(glibtop_ifaddr)|netinfo|array:ulong(if_flags,transport,mtu,subnet)|string(interface):ulong(transport)
retval|netload|ulong(packets_in,packets_out,packets_total,bytes_in,bytes_out,bytes_total,errors_in,errors_out,errors_total,collisions)|string(interface):unsigned(transport,protocol)
retval|ppp|ulong(state,bytes_in,bytes_out)|ushort(device,use_isdn):string(lockfile)
diff --git a/include/glibtop/interfaces.h b/include/glibtop/interfaces.h
index adf6b995..e04fcbbd 100644
--- a/include/glibtop/interfaces.h
+++ b/include/glibtop/interfaces.h
@@ -44,7 +44,16 @@ BEGIN_LIBGTOP_DECLS
#define GLIBTOP_MAX_INTERFACE 7
+#define GLIBTOP_IFADDR_TRANSPORT 0
+#define GLIBTOP_IFADDR_ADDR_LEN 1
+#define GLIBTOP_IFADDR_ADDRESS 2
+#define GLIBTOP_IFADDR_SUBNET 3
+#define GLIBTOP_IFADDR_SCOPE 4
+
+#define GLIBTOP_MAX_IFADDR 5
+
typedef struct _glibtop_interface glibtop_interface;
+typedef struct _glibtop_ifaddr glibtop_ifaddr;
typedef enum _glibtop_interface_type glibtop_interface_type;
typedef enum _glibtop_transport glibtop_transport;
@@ -127,6 +136,16 @@ enum _glibtop_interface_flags {
GLIBTOP_IF_FLAGS_MULTICAST
};
+struct _glibtop_ifaddr
+{
+ u_int64_t flags,
+ transport; /* GLIBTOP_IFADDR_TRANSPORT */
+ u_int8_t addr_len, /* GLIBTOP_IFADDR_ADDR_LEN */
+ address [GLIBTOP_IFADDR_LEN]; /* GLIBTOP_IFADDR_ADDRESS */
+ u_int64_t subnet, /* GLIBTOP_IFADDR_SUBNET */
+ scope; /* GLIBTOP_IFADDR_SCOPE */
+};
+
struct _glibtop_interface
{
u_int64_t flags,
diff --git a/include/glibtop/netinfo.h b/include/glibtop/netinfo.h
index 2ca45913..e27d770b 100644
--- a/include/glibtop/netinfo.h
+++ b/include/glibtop/netinfo.h
@@ -49,8 +49,6 @@ struct _glibtop_netinfo
if_flags, /* GLIBTOP_NETINFO_IF_FLAGS */
transport, /* GLIBTOP_NETINFO_TRANSPORT */
mtu; /* GLIBTOP_NETINFO_MTU */
- u_int8_t subnet [GLIBTOP_IFADDR_LEN],/* GLIBTOP_NETINFO_SUBNET */
- address [GLIBTOP_IFADDR_LEN]; /* GLIBTOP_NETINFO_ADDRESS */
};
#define glibtop_get_netinfo(netinfo,interface,transport) glibtop_get_netinfo_l(glibtop_global_server, netinfo, interface, transport)
@@ -61,14 +59,14 @@ struct _glibtop_netinfo
#define glibtop_get_netinfo_r glibtop_get_netinfo_s
#endif
-int glibtop_get_netinfo_l (glibtop *server, glibtop_netinfo *buf, const char *interface, u_int64_t transport);
+glibtop_ifaddr *glibtop_get_netinfo_l (glibtop *server, glibtop_array *array, glibtop_netinfo *buf, const char *interface, u_int64_t transport);
#if GLIBTOP_SUID_NETINFO
int glibtop_init_netinfo_p (glibtop *server);
-int glibtop_get_netinfo_p (glibtop *server, glibtop_netinfo *buf, const char *interface, u_int64_t transport);
+glibtop_ifaddr *glibtop_get_netinfo_p (glibtop *server, glibtop_array *array, glibtop_netinfo *buf, const char *interface, u_int64_t transport);
#else
int glibtop_init_netinfo_s (glibtop *server);
-int glibtop_get_netinfo_s (glibtop *server, glibtop_netinfo *buf, const char *interface, u_int64_t transport);
+glibtop_ifaddr *glibtop_get_netinfo_s (glibtop *server, glibtop_array *array, glibtop_netinfo *buf, const char *interface, u_int64_t transport);
#endif
#ifdef GLIBTOP_NAMES
diff --git a/sysdeps/linux/netinfo.c b/sysdeps/linux/netinfo.c
index 717f9bac..21e3e286 100644
--- a/sysdeps/linux/netinfo.c
+++ b/sysdeps/linux/netinfo.c
@@ -25,6 +25,7 @@
#include <glibtop.h>
#include <glibtop/error.h>
+#include <glibtop/xmalloc.h>
#include <glibtop/netinfo.h>
#include <sys/types.h>
@@ -82,7 +83,7 @@ glibtop_init_netinfo_s (glibtop *server)
static int
_netinfo_ipv4 (glibtop *server, glibtop_netinfo *buf,
- const char *interface, int only_common)
+ const char *interface, glibtop_ifaddr *address)
{
int skfd;
@@ -91,7 +92,10 @@ _netinfo_ipv4 (glibtop *server, glibtop_netinfo *buf,
struct ifreq ifr;
unsigned flags;
- if (!only_common) {
+ if (address) {
+ address->transport = GLIBTOP_TRANSPORT_IPV4;
+ address->flags |= (1L << GLIBTOP_IFADDR_TRANSPORT);
+
buf->transport = GLIBTOP_TRANSPORT_IPV4;
buf->flags |= (1L << GLIBTOP_NETINFO_TRANSPORT);
}
@@ -133,21 +137,26 @@ _netinfo_ipv4 (glibtop *server, glibtop_netinfo *buf,
if (flags & IFF_MULTICAST)
buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST);
- if (!only_common) {
+ if (address) {
strcpy (ifr.ifr_name, interface);
if (!ioctl (skfd, SIOCGIFADDR, &ifr)) {
struct sockaddr_in addr =
*(struct sockaddr_in *) &ifr.ifr_addr;
- memcpy (&buf->address, &addr.sin_addr.s_addr, 4);
- buf->flags |= (1L << GLIBTOP_NETINFO_ADDRESS);
+
+ address->addr_len = 4;
+ memcpy (&address->address, &addr.sin_addr.s_addr, 4);
+
+ address->flags |= (1L << GLIBTOP_IFADDR_ADDRESS);
+ address->flags |= (1L << GLIBTOP_IFADDR_ADDR_LEN);
}
strcpy (ifr.ifr_name, interface);
if (!ioctl (skfd, SIOCGIFNETMASK, &ifr)) {
struct sockaddr_in addr =
*(struct sockaddr_in *) &ifr.ifr_addr;
- memcpy (&buf->subnet, &addr.sin_addr.s_addr, 4);
- buf->flags |= (1L << GLIBTOP_NETINFO_SUBNET);
+
+ memcpy (&address->subnet, &addr.sin_addr.s_addr, 4);
+ address->flags |= (1L << GLIBTOP_IFADDR_SUBNET);
}
}
@@ -204,7 +213,7 @@ _parse_ipv6_address (const char *addr_string, u_int8_t *dest)
static int
_netinfo_ipv6 (glibtop *server, glibtop_netinfo *buf,
- const char *interface)
+ const char *interface, glibtop_ifaddr *address)
{
FILE *f;
char addr6[40], devname[20];
@@ -212,7 +221,7 @@ _netinfo_ipv6 (glibtop *server, glibtop_netinfo *buf,
#ifdef HAVE_AFINET6
/* get common things such as mtu and if_flags */
- _netinfo_ipv4 (server, buf, interface, 1);
+ _netinfo_ipv4 (server, buf, interface, NULL);
#endif
buf->transport = GLIBTOP_TRANSPORT_IPV6;
@@ -225,8 +234,14 @@ _netinfo_ipv6 (glibtop *server, glibtop_netinfo *buf,
if (strcmp (devname, interface))
continue;
- if (!_parse_ipv6_address (addr6, buf->address))
- buf->flags |= (1L << GLIBTOP_NETINFO_ADDRESS);
+ if (!_parse_ipv6_address (addr6, address->address))
+ address->flags |= (1L << GLIBTOP_IFADDR_ADDRESS);
+
+ address->addr_len = 8;
+ address->scope = scope;
+
+ address->flags |= (1L << GLIBTOP_IFADDR_ADDR_LEN) |
+ (1L << GLIBTOP_IFADDR_SCOPE);
break;
}
@@ -241,14 +256,19 @@ _netinfo_ipv6 (glibtop *server, glibtop_netinfo *buf,
/* Provides network statistics. */
-int
-glibtop_get_netinfo_s (glibtop *server, glibtop_netinfo *buf,
- const char *interface, u_int64_t transport)
+glibtop_ifaddr *
+glibtop_get_netinfo_s (glibtop *server, glibtop_array *array,
+ glibtop_netinfo *buf, const char *interface,
+ u_int64_t transport)
{
+ GPtrArray *parray;
+ glibtop_ifaddr *retval = NULL;
+ int i;
+
memset (buf, 0, sizeof (glibtop_netinfo));
if (strlen (interface) >= GLIBTOP_INTERFACE_LEN)
- return -1;
+ return NULL;
/* Assume IPv4 is the standard until IPv6 becomes more popular. */
if (transport == GLIBTOP_TRANSPORT_DEFAULT)
@@ -283,16 +303,41 @@ glibtop_get_netinfo_s (glibtop *server, glibtop_netinfo *buf,
}
}
- switch (transport) {
+ parray = g_ptr_array_new ();
+
#ifdef HAVE_AFINET
- case GLIBTOP_TRANSPORT_IPV4:
- return _netinfo_ipv4 (server, buf, interface, 0);
+ if (transport & GLIBTOP_TRANSPORT_IPV4) {
+ glibtop_ifaddr address;
+
+ if (!_netinfo_ipv4 (server, buf, interface, &address))
+ g_ptr_array_add (parray, g_memdup (&parray, sizeof (array)));
+ }
#endif /* HAVE_AFINET */
+
#ifdef HAVE_AFINET6
- case GLIBTOP_TRANSPORT_IPV6:
- return _netinfo_ipv6 (server, buf, interface);
+ if (transport & GLIBTOP_TRANSPORT_IPV6) {
+ glibtop_ifaddr address;
+
+ if (!_netinfo_ipv6 (server, buf, interface, &address))
+ g_ptr_array_add (parray, g_memdup (&parray, sizeof (array)));
+ }
#endif /* HAVE_AFINET6 */
+
+ if (!parray->len) {
+ g_ptr_array_free (parray, TRUE);
+ return NULL;
}
- return 0;
+ retval = glibtop_calloc_r (server, parray->len, sizeof (glibtop_ifaddr));
+
+ for (i = 0; i < parray->len; i++)
+ retval [i] = *(glibtop_ifaddr *) parray->pdata [i];
+
+ array->number = parray->len;
+ array->size = sizeof (glibtop_ifaddr);
+ array->total = array->number * array->size;
+
+ g_ptr_array_free (parray, TRUE);
+
+ return retval;
}