Added a check for NULL pointer when wlaking though interfaces (though i

* netload.c: (get_ipv6), (glibtop_get_netload_s): Added a check for NULL
	pointer when wlaking though interfaces (though i don't understand why some
	interface don't have an ifa_addr).
	Move all ipv6 code into a separate function. Added a paranoid check on
	getifaddrs.
This commit is contained in:
Benoît Dejean
2004-11-15 14:58:06 +00:00
parent bbb6cbaa87
commit 1d6debfa56
2 changed files with 78 additions and 48 deletions

View File

@@ -1,3 +1,11 @@
2004-11-15 Benoît Dejean <tazforever@dlfp.org>
* netload.c: (get_ipv6), (glibtop_get_netload_s): Added a check for NULL
pointer when wlaking though interfaces (though i don't understand why some
interface don't have an ifa_addr).
Move all ipv6 code into a separate function. Added a paranoid check on
getifaddrs.
2004-11-13 Benoît Dejean <tazforever@dlfp.org>
* netlist.c: (glibtop_get_netlist_s): Killed warning.

View File

@@ -25,6 +25,9 @@
#include <glibtop/error.h>
#include <glibtop/netload.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -116,6 +119,69 @@ glibtop_init_netload_s (glibtop *server)
_glibtop_sysdeps_netload_packets;
}
#ifdef HAVE_IFADDRS_H
static void get_ipv6(glibtop *server, glibtop_netload *buf,
const char *interface)
{
struct ifaddrs *ifa0, *ifr6;
if(getifaddrs (&ifa0) != 0)
{
glibtop_warn_r(server, "getifaddrs failed : %s", strerror(errno));
return;
}
for (ifr6 = ifa0; ifr6; ifr6 = ifr6->ifa_next) {
if (strcmp (ifr6->ifa_name, interface) == 0
&& ifr6->ifa_addr != NULL
&& ifr6->ifa_addr->sa_family == AF_INET6)
break;
}
if(!ifr6) goto free_ipv6;
memcpy(buf->address6,
&((struct sockaddr_in6 *) ifr6->ifa_addr)->sin6_addr,
16);
memcpy(buf->prefix6,
&((struct sockaddr_in6 *) ifr6->ifa_netmask)->sin6_addr,
16);
if (IN6_IS_ADDR_LINKLOCAL (buf->address6))
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_LINK;
else if (IN6_IS_ADDR_SITELOCAL (buf->address6))
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_SITE;
else if (IN6_IS_ADDR_GLOBAL (buf->address6)
|| IN6_IS_ADDR_MC_ORGLOCAL (buf->address6)
|| IN6_IS_ADDR_V4COMPAT (buf->address6)
|| IN6_IS_ADDR_MULTICAST (buf->address6)
|| IN6_IS_ADDR_UNSPECIFIED (buf->address6)
)
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_GLOBAL;
else if (IN6_IS_ADDR_LOOPBACK (buf->address6))
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_HOST;
else
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_UNKNOWN;
buf->flags |= _glibtop_sysdeps_netload_6;
free_ipv6:
freeifaddrs(ifa0);
}
#endif /* HAVE_IFADDRS_H */
/* Provides network statistics. */
void
@@ -376,54 +442,10 @@ glibtop_get_netload_s (glibtop *server, glibtop_netload *buf,
fclose (f);
#ifdef HAVE_IFADDRS_H
/* IPv6 */
{
struct ifaddrs *ifa0, *ifr6;
getifaddrs (&ifa0);
for (ifr6 = ifa0; ifr6; ifr6 = ifr6->ifa_next) {
if (strcmp (ifr6->ifa_name, interface) == 0
&& ifr6->ifa_addr->sa_family == AF_INET6)
break;
}
if(!ifr6) goto free_ipv6;
memcpy(buf->address6,
&((struct sockaddr_in6 *) ifr6->ifa_addr)->sin6_addr,
16);
memcpy(buf->prefix6,
&((struct sockaddr_in6 *) ifr6->ifa_netmask)->sin6_addr,
16);
if (IN6_IS_ADDR_LINKLOCAL (buf->address6))
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_LINK;
else if (IN6_IS_ADDR_SITELOCAL (buf->address6))
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_SITE;
else if (IN6_IS_ADDR_GLOBAL (buf->address6)
|| IN6_IS_ADDR_MC_ORGLOCAL (buf->address6)
|| IN6_IS_ADDR_V4COMPAT (buf->address6)
|| IN6_IS_ADDR_MULTICAST (buf->address6)
|| IN6_IS_ADDR_UNSPECIFIED (buf->address6)
)
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_GLOBAL;
else if (IN6_IS_ADDR_LOOPBACK (buf->address6))
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_HOST;
else
buf->scope6 = GLIBTOP_IF_IN6_SCOPE_UNKNOWN;
buf->flags |= _glibtop_sysdeps_netload_6;
free_ipv6:
freeifaddrs(ifa0);
} /* IPV6 */
get_ipv6(server, buf, interface);
#endif /* HAVE_IFADDRS_H */
}