diff options
author | Jasper Lievisse Adriaanse <jasper@humppa.nl> | 2011-06-22 17:26:38 +0200 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@humppa.nl> | 2011-06-22 17:26:38 +0200 |
commit | 537dc1bff1cee909d25d5ee8d9360293137247c0 (patch) | |
tree | 04bc62a3ccad665f91671c7fd2858f1f9c363528 /sysdeps/openbsd | |
parent | 93829c8cbb6c719266dd522f7d1cf76afff0f4a8 (diff) | |
download | libgtop-537dc1bff1cee909d25d5ee8d9360293137247c0.tar.gz |
Fix scope6 and prefix6 retrieval on OpenBSD.
https://bugzilla.gnome.org/show_bug.cgi?id=652997
Diffstat (limited to 'sysdeps/openbsd')
-rw-r--r-- | sysdeps/openbsd/netload.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/sysdeps/openbsd/netload.c b/sysdeps/openbsd/netload.c index 579f951a..88a6110f 100644 --- a/sysdeps/openbsd/netload.c +++ b/sysdeps/openbsd/netload.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netload.c,v 1.3 2011/05/23 19:35:54 jasper Exp $ */ +/* $OpenBSD: netload.c,v 1.5 2011/06/20 11:48:39 jasper Exp $ */ /* Copyright (C) 1998-99 Martin Baulig This file is part of LibGTop 1.0. @@ -34,6 +34,8 @@ #include <net/if_dl.h> #include <net/if_types.h> +#include <sys/ioctl.h> + #ifdef HAVE_NET_IF_VAR_H #include <net/if_var.h> #endif @@ -198,11 +200,37 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, buf->flags |= _glibtop_sysdeps_netload_data; } else if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; - - memcpy (buf->address6, &sin6->sin6_addr, sizeof (buf->address6)); - buf->flags |= GLIBTOP_NETLOAD_ADDRESS6; + int in6fd; + + memcpy (buf->address6, &sin6->sin6_addr, + sizeof (buf->address6)); + buf->flags |= (1L << GLIBTOP_NETLOAD_ADDRESS6); + + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + sin6->sin6_scope_id = + ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); + sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; + } + + buf->scope6 = (guint8) sin6->sin6_scope_id; + buf->flags |= (1L << GLIBTOP_NETLOAD_SCOPE6); + + in6fd = socket (AF_INET6, SOCK_DGRAM, 0); + if (in6fd >= 0) { + struct in6_ifreq ifr; + + memset (&ifr, 0, sizeof (ifr)); + ifr.ifr_addr = *sin6; + g_strlcpy (ifr.ifr_name, interface, + sizeof (ifr.ifr_name)); + if (ioctl (in6fd, SIOCGIFNETMASK_IN6, (char *) &ifr) >= 0) { + memcpy (buf->prefix6, &ifr.ifr_addr.sin6_addr, + sizeof (buf->prefix6)); + buf->flags |= (1L << GLIBTOP_NETLOAD_PREFIX6); + } + close (in6fd); + } } - /* FIXME prefix6, scope6 */ ifaddraddr = (u_long) ifaddr.ifa.ifa_list.tqe_next; } return; |