From e4303ee6128123820d2ae08f1d7c59c6b445bbc9 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Tue, 4 Jul 2006 16:35:27 +0000 Subject: [PATCH] store net_connection addresses in binary rather than string --- bindings/java/src/jni/generate.pl | 8 +++--- bindings/java/src/jni/javasigar.c | 9 +++++++ include/sigar.h | 20 +++++++++++++-- include/sigar_private.h | 8 ++++++ src/os/linux/linux_sigar.c | 42 +++++++++++-------------------- src/os/solaris/solaris_sigar.c | 15 ++++------- src/sigar.c | 26 +++++++++++++++++++ 7 files changed, 84 insertions(+), 44 deletions(-) diff --git a/bindings/java/src/jni/generate.pl b/bindings/java/src/jni/generate.pl index 59b983ea..df7eae9e 100644 --- a/bindings/java/src/jni/generate.pl +++ b/bindings/java/src/jni/generate.pl @@ -783,7 +783,7 @@ my %classes = ( plat => 'LFSW' }, { - name => 'local_address', type => 'String', + name => 'local_address', type => 'NetAddress', desc => '', plat => 'LFSW' }, @@ -793,7 +793,7 @@ my %classes = ( plat => 'LFSW' }, { - name => 'remote_address', type => 'String', + name => 'remote_address', type => 'NetAddress', desc => '', plat => 'LFSW' }, @@ -1070,7 +1070,7 @@ my %pfields = ( NetAddr => "Sigar::NetAddr", ); -$jfields{'NetAddr'} = $jfields{'String'}; +$jfields{'NetAddress'} = $jfields{'NetAddr'} = $jfields{'String'}; my %jinit = ( String => 'null', @@ -1082,7 +1082,7 @@ my %jtype = ( #alias for my $j (\%jfields, \%jinit, \%jtype) { - $j->{'NetAddr'} = $j->{'String'}; + $j->{'NetAddress'} = $j->{'NetAddr'} = $j->{'String'}; } my %func_alias = ( diff --git a/bindings/java/src/jni/javasigar.c b/bindings/java/src/jni/javasigar.c index 18e8501b..2624479c 100644 --- a/bindings/java/src/jni/javasigar.c +++ b/bindings/java/src/jni/javasigar.c @@ -309,6 +309,15 @@ static jstring jinet_ntoa(JNIEnv *env, sigar_t *sigar, sigar_uint64_t val) { #define SetNetAddrField(env, obj, fieldID, val) \ SetObjectField(env, obj, fieldID, jinet_ntoa(env, sigar, val)) +static jstring jnet_address_to_string(JNIEnv *env, sigar_t *sigar, sigar_net_address_t *val) { + char addr_str[INET6_ADDRSTRLEN]; + sigar_net_address_to_string(sigar, val, addr_str); + return JENV->NewStringUTF(env, addr_str); +} + +#define SetNetAddressField(env, obj, fieldID, val) \ + SetObjectField(env, obj, fieldID, jnet_address_to_string(env, sigar, &val)) + #include "javasigar_generated.c" #define SIGAR_ALLOC_OBJECT(name) \ diff --git a/include/sigar.h b/include/sigar.h index 22cea9b1..e7c6baf4 100644 --- a/include/sigar.h +++ b/include/sigar.h @@ -391,6 +391,22 @@ sigar_file_system_usage_get(sigar_t *sigar, const char *dirname, sigar_file_system_usage_t *fsusage); +typedef struct { + enum { + SIGAR_AF_UNSPEC, + SIGAR_AF_INET, + SIGAR_AF_INET6 + } family; + union { + sigar_uint32_t in; + sigar_uint32_t in6[4]; + } addr; +} sigar_net_address_t; + +SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar, + sigar_net_address_t *address, + char *addr_str); + #ifndef INET6_ADDRSTRLEN # define INET6_ADDRSTRLEN 46 #endif @@ -546,9 +562,9 @@ enum { typedef struct { unsigned long local_port; - char local_address[INET6_ADDRSTRLEN]; + sigar_net_address_t local_address; unsigned long remote_port; - char remote_address[INET6_ADDRSTRLEN]; + sigar_net_address_t remote_address; sigar_uid_t uid; unsigned long inode; int type; diff --git a/include/sigar_private.h b/include/sigar_private.h index ff35a794..a90417ef 100644 --- a/include/sigar_private.h +++ b/include/sigar_private.h @@ -192,6 +192,14 @@ int sigar_net_connection_list_grow(sigar_net_connection_list_t *connlist); sigar_net_connection_list_grow(connlist); \ } +#define sigar_net_address_set(a, val) \ + (a).addr.in = val; \ + (a).family = SIGAR_AF_INET + +#define sigar_net_address6_set(addr, val) \ + memcpy(&((a).addr.in6), val, sizeof((a).addr.in6)); \ + (a).family = SIGAR_AF_INET6 + int sigar_who_list_create(sigar_who_list_t *wholist); int sigar_who_list_grow(sigar_who_list_t *wholist); diff --git a/src/os/linux/linux_sigar.c b/src/os/linux/linux_sigar.c index cb84a811..ae92ccd2 100644 --- a/src/os/linux/linux_sigar.c +++ b/src/os/linux/linux_sigar.c @@ -1685,27 +1685,23 @@ int sigar_net_interface_stat_get(sigar_t *sigar, const char *name, return found ? SIGAR_OK : ENXIO; } -static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr, int len) +static SIGAR_INLINE void convert_hex_address(sigar_net_address_t *address, + char *ptr, int len) { if (len > HEX_ENT_LEN) { - struct in6_addr addr; int i; for (i=0; i<=3; i++, ptr+=HEX_ENT_LEN) { - addr.s6_addr32[i] = hex2int(ptr, HEX_ENT_LEN); - } - if (!inet_ntop(AF_INET6, &addr, buffer, buflen)) { - return errno; + address->addr.in6[i] = hex2int(ptr, HEX_ENT_LEN); } + + address->family = SIGAR_AF_INET6; } else { - struct in_addr addr; - addr.s_addr = (len == HEX_ENT_LEN) ? hex2int(ptr, HEX_ENT_LEN) : 0; - if (!inet_ntop(AF_INET, &addr, buffer, buflen)) { - return errno; - } - } + address->addr.in = + (len == HEX_ENT_LEN) ? hex2int(ptr, HEX_ENT_LEN) : 0; - return SIGAR_OK; + address->family = SIGAR_AF_INET; + } } typedef struct { @@ -1761,7 +1757,7 @@ static int proc_net_read(sigar_net_connection_walker_t *walker, sigar_net_connection_t conn; char *laddr, *raddr; int laddr_len=0, raddr_len=0; - int status, more; + int more; /* skip leading space */ SKIP_WHILE(ptr, ' '); @@ -1799,21 +1795,11 @@ static int proc_net_read(sigar_net_connection_walker_t *walker, conn.type = type; - status = ip_format(conn.local_address, - sizeof(conn.local_address), - laddr, laddr_len); + convert_hex_address(&conn.local_address, + laddr, laddr_len); - if (status != SIGAR_OK) { - return status; - } - - status = ip_format(conn.remote_address, - sizeof(conn.remote_address), - raddr, raddr_len); - - if (status != SIGAR_OK) { - return status; - } + convert_hex_address(&conn.remote_address, + raddr, raddr_len); /* SIGAR_TCP_* currently matches TCP_* in linux/tcp.h */ conn.state = hex2int(ptr, 2); diff --git a/src/os/solaris/solaris_sigar.c b/src/os/solaris/solaris_sigar.c index 4c634a62..bcf09e06 100644 --- a/src/os/solaris/solaris_sigar.c +++ b/src/os/solaris/solaris_sigar.c @@ -2032,7 +2032,6 @@ static int tcp_connection_get(sigar_net_connection_walker_t *walker, struct mib2_tcpConnEntry *entry, int len) { - sigar_t *sigar = walker->sigar; int flags = walker->flags; int status; char *end = (char *)entry + len; @@ -2047,11 +2046,8 @@ static int tcp_connection_get(sigar_net_connection_walker_t *walker, SIGAR_ZERO(&conn); - sigar_inet_ntoa(sigar, entry->tcpConnLocalAddress, - conn.local_address); - - sigar_inet_ntoa(sigar, entry->tcpConnRemAddress, - conn.remote_address); + sigar_net_address_set(conn.local_address, entry->tcpConnLocalAddress); + sigar_net_address_set(conn.remote_address, entry->tcpConnRemAddress); conn.local_port = entry->tcpConnLocalPort; conn.remote_port = entry->tcpConnRemPort; @@ -2124,7 +2120,6 @@ static int udp_connection_get(sigar_net_connection_walker_t *walker, struct mib2_udpEntry *entry, int len) { - sigar_t *sigar = walker->sigar; int flags = walker->flags; int status; char *end = (char *)entry + len; @@ -2140,9 +2135,9 @@ static int udp_connection_get(sigar_net_connection_walker_t *walker, SIGAR_ZERO(&conn); - sigar_inet_ntoa(sigar, entry->udpLocalAddress, - conn.local_address); - SIGAR_SSTRCPY(conn.remote_address, "0.0.0.0"); + sigar_net_address_set(conn.local_address, entry->udpLocalAddress); + sigar_net_address_set(conn.remote_address, 0); + conn.local_port = entry->udpLocalPort; conn.remote_port = 0; conn.type = SIGAR_NETCONN_UDP; diff --git a/src/sigar.c b/src/sigar.c index 4fb2ee6c..fb02a11c 100644 --- a/src/sigar.c +++ b/src/sigar.c @@ -1634,6 +1634,32 @@ SIGAR_DECLARE(int) sigar_inet_ntoa(sigar_t *sigar, return SIGAR_OK; } +SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar, + sigar_net_address_t *address, + char *addr_str) +{ + switch (address->family) { + case SIGAR_AF_INET6: +#if defined(__linux__) /*XXX*/ + if (inet_ntop(AF_INET6, (const void *)&address->addr.in6, + addr_str, INET6_ADDRSTRLEN)) + { + return SIGAR_OK; + } + else { + return errno; + } +#endif + case SIGAR_AF_INET: + return sigar_inet_ntoa(sigar, address->addr.in, addr_str); + case SIGAR_AF_UNSPEC: + default: + return EINVAL; + } + + return SIGAR_OK; +} + static int fqdn_ip_get(sigar_t *sigar, char *name) { int i, status;