Add net_stat_port function to provide metrics on specific port+address

This commit is contained in:
Doug MacEachern 2007-04-06 05:05:37 +00:00
parent 808a7deeba
commit 86deb1a2d9
9 changed files with 263 additions and 8 deletions

View File

@ -1,5 +1,7 @@
2007-04-05 Doug MacEachern <dougm@hyperic.com> 2007-04-05 Doug MacEachern <dougm@hyperic.com>
* Add net_stat_port function to provide metrics on specific port+address
* [SIGAR-46] Fix cpu_info.{mhz,cache_size} fields in UML vms * [SIGAR-46] Fix cpu_info.{mhz,cache_size} fields in UML vms
2007-03-29 Doug MacEachern <dougm@hyperic.com> 2007-03-29 Doug MacEachern <dougm@hyperic.com>

View File

@ -847,6 +847,12 @@ my %classes = (
{ {
name => 'tcp_outbound_total', type => 'Int', name => 'tcp_outbound_total', type => 'Int',
}, },
{
name => 'all_inbound_total', type => 'Int',
},
{
name => 'all_outbound_total', type => 'Int',
},
], ],
ResourceLimit => [ ResourceLimit => [
{ {

View File

@ -851,8 +851,31 @@ JNIEXPORT jobjectArray SIGAR_JNIx(getNetConnectionList)
return connarray; return connarray;
} }
static int jbyteArray_to_sigar_net_address(JNIEnv *env, jbyteArray jaddress,
sigar_net_address_t *address)
{
jsize len = JENV->GetArrayLength(env, jaddress);
JENV->GetByteArrayRegion(env, jaddress, 0, len,
(jbyte *)&address->addr.in6);
switch (len) {
case 4:
address->family = SIGAR_AF_INET;
break;
case 4*4:
address->family = SIGAR_AF_INET6;
break;
default:
return EINVAL;
}
return SIGAR_OK;
}
JNIEXPORT void SIGAR_JNI(NetStat_stat) JNIEXPORT void SIGAR_JNI(NetStat_stat)
(JNIEnv *env, jobject obj, jobject sigar_obj, jint flags) (JNIEnv *env, jobject obj, jobject sigar_obj, jint flags,
jbyteArray jaddress, jlong port)
{ {
int status; int status;
sigar_net_stat_t netstat; sigar_net_stat_t netstat;
@ -860,9 +883,21 @@ JNIEXPORT void SIGAR_JNI(NetStat_stat)
jfieldID id; jfieldID id;
jintArray states; jintArray states;
jint tcp_states[SIGAR_TCP_UNKNOWN]; jint tcp_states[SIGAR_TCP_UNKNOWN];
sigar_net_address_t address;
jboolean has_port = (port != -1);
dSIGAR_VOID; dSIGAR_VOID;
status = sigar_net_stat_get(sigar, &netstat, flags); if (has_port) {
status = jbyteArray_to_sigar_net_address(env, jaddress, &address);
if (status == SIGAR_OK) {
status = sigar_net_stat_port_get(sigar, &netstat, flags,
&address, port);
}
}
else {
status = sigar_net_stat_get(sigar, &netstat, flags);
}
if (status != SIGAR_OK) { if (status != SIGAR_OK) {
sigar_throw_error(env, jsigar, status); sigar_throw_error(env, jsigar, status);
return; return;
@ -891,8 +926,6 @@ JNIEXPORT void SIGAR_JNI(NetStat_stat)
id = JENV->GetFieldID(env, cls, "tcpStates", "[I"); id = JENV->GetFieldID(env, cls, "tcpStates", "[I");
JENV->SetObjectField(env, obj, id, states); JENV->SetObjectField(env, obj, id, states);
return;
} }
JNIEXPORT jstring SIGAR_JNI(NetConnection_getTypeString) JNIEXPORT jstring SIGAR_JNI(NetConnection_getTypeString)

View File

@ -20,12 +20,14 @@ package org.hyperic.sigar;
public class NetStat implements java.io.Serializable { public class NetStat implements java.io.Serializable {
private static final long serialVersionUID = 02242007L; private static final long serialVersionUID = 04052007L;
protected int[] tcpStates; protected int[] tcpStates;
protected int tcpInboundTotal, tcpOutboundTotal; protected int tcpInboundTotal, tcpOutboundTotal;
protected int allInboundTotal, allOutboundTotal;
public native void stat(Sigar sigar, int flags) throws SigarException; native void stat(Sigar sigar, int flags,
byte[] address, long port) throws SigarException;
public NetStat() { } public NetStat() { }
@ -34,7 +36,17 @@ public class NetStat implements java.io.Serializable {
NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT | NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT |
NetFlags.CONN_TCP; NetFlags.CONN_TCP;
stat(sigar, flags); stat(sigar, flags, null, -1);
}
public void stat(Sigar sigar,
byte[] address, long port)
throws SigarException {
int flags =
NetFlags.CONN_CLIENT | NetFlags.CONN_TCP;
stat(sigar, flags, address, port);
} }
public int getTcpInboundTotal() { public int getTcpInboundTotal() {
@ -45,6 +57,14 @@ public class NetStat implements java.io.Serializable {
return this.tcpOutboundTotal; return this.tcpOutboundTotal;
} }
public int getAllInboundTotal() {
return this.allInboundTotal;
}
public int getAllOutboundTotal() {
return this.allOutboundTotal;
}
public int[] getTcpStates() { public int[] getTcpStates() {
return this.tcpStates; return this.tcpStates;
} }

View File

@ -800,6 +800,13 @@ public class Sigar implements SigarProxy {
return netstat; return netstat;
} }
public NetStat getNetStat(byte[] address, long port)
throws SigarException {
NetStat netstat = new NetStat();
netstat.stat(this, address, port);
return netstat;
}
public native Who[] getWhoList() public native Who[] getWhoList()
throws SigarException; throws SigarException;

View File

@ -55,6 +55,7 @@ public class SigarTestRunner extends SigarCommandBase {
TestNetInfo.class, TestNetInfo.class,
TestNetRoute.class, TestNetRoute.class,
TestNetStat.class, TestNetStat.class,
TestNetStatPort.class,
TestProcArgs.class, TestProcArgs.class,
TestProcEnv.class, TestProcEnv.class,
TestProcExe.class, TestProcExe.class,

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
* This file is part of SIGAR.
*
* SIGAR is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License as
* published by the Free Software Foundation. This program is distributed
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package org.hyperic.sigar.test;
import java.net.InetAddress;
import org.hyperic.sigar.NetConnection;
import org.hyperic.sigar.NetFlags;
import org.hyperic.sigar.NetInterfaceConfig;
import org.hyperic.sigar.NetStat;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarNotImplementedException;
public class TestNetStatPort extends SigarTestCase {
public TestNetStatPort(String name) {
super(name);
}
private void netstat(Sigar sigar, String addr, long port) throws Exception {
InetAddress address = InetAddress.getByName(addr);
traceln("");
traceln("using address=" + address + ":" + port);
NetStat netstat;
try {
netstat = sigar.getNetStat(address.getAddress(), port);
} catch (SigarNotImplementedException e) {
return;
}
assertGtEqZeroTrace("AllOutbound", netstat.getAllOutboundTotal());
assertGtEqZeroTrace("Outbound", netstat.getTcpOutboundTotal());
assertGtEqZeroTrace("Inbound", netstat.getTcpInboundTotal());
assertGtEqZeroTrace("AllInbound", netstat.getAllInboundTotal());
int[] states = netstat.getTcpStates();
for (int i=0; i<NetFlags.TCP_UNKNOWN; i++) {
assertGtEqZeroTrace(NetConnection.getStateString(i), states[i]);
}
}
public void testCreate() throws Exception {
Sigar sigar = getSigar();
NetInterfaceConfig ifconfig =
sigar.getNetInterfaceConfig(null);
String[] addrs = {
ifconfig.getAddress(),
"0:0:0:0:0:0:0:1",
};
for (int i=0; i<addrs.length; i++) {
netstat(sigar, addrs[i], 22);
}
}
}

View File

@ -461,6 +461,9 @@ typedef struct {
} addr; } addr;
} sigar_net_address_t; } sigar_net_address_t;
SIGAR_DECLARE(int) sigar_net_address_equals(sigar_net_address_t *addr1,
sigar_net_address_t *addr2);
SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar, SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar,
sigar_net_address_t *address, sigar_net_address_t *address,
char *addr_str); char *addr_str);
@ -666,6 +669,8 @@ typedef struct {
int tcp_states[SIGAR_TCP_UNKNOWN]; int tcp_states[SIGAR_TCP_UNKNOWN];
sigar_uint32_t tcp_inbound_total; sigar_uint32_t tcp_inbound_total;
sigar_uint32_t tcp_outbound_total; sigar_uint32_t tcp_outbound_total;
sigar_uint32_t all_inbound_total;
sigar_uint32_t all_outbound_total;
} sigar_net_stat_t; } sigar_net_stat_t;
SIGAR_DECLARE(int) SIGAR_DECLARE(int)
@ -673,6 +678,14 @@ sigar_net_stat_get(sigar_t *sigar,
sigar_net_stat_t *netstat, sigar_net_stat_t *netstat,
int flags); int flags);
SIGAR_DECLARE(int)
sigar_net_stat_port_get(sigar_t *sigar,
sigar_net_stat_t *netstat,
int flags,
sigar_net_address_t *address,
unsigned long port);
SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type); SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type);
SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state); SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state);

View File

@ -989,6 +989,85 @@ sigar_net_stat_get(sigar_t *sigar,
} }
} }
typedef struct {
sigar_net_stat_t *netstat;
sigar_net_address_t *address;
unsigned long port;
} net_stat_port_getter_t;
static int net_stat_port_walker(sigar_net_connection_walker_t *walker,
sigar_net_connection_t *conn)
{
net_stat_port_getter_t *getter =
(net_stat_port_getter_t *)walker->data;
sigar_net_stat_t *netstat = getter->netstat;
if (conn->type == SIGAR_NETCONN_TCP) {
if (conn->local_port == getter->port) {
netstat->all_inbound_total++;
if (sigar_net_address_equals(getter->address,
&conn->local_address) == SIGAR_OK)
{
netstat->tcp_inbound_total++;
}
}
else if (conn->remote_port == getter->port) {
netstat->all_outbound_total++;
if (sigar_net_address_equals(getter->address,
&conn->remote_address) == SIGAR_OK)
{
netstat->tcp_outbound_total++;
}
}
else {
return SIGAR_OK;
}
netstat->tcp_states[conn->state]++;
}
else if (conn->type == SIGAR_NETCONN_UDP) {
/*XXX*/
}
return SIGAR_OK;
}
SIGAR_DECLARE(int)
sigar_net_stat_port_get(sigar_t *sigar,
sigar_net_stat_t *netstat,
int flags,
sigar_net_address_t *address,
unsigned long port)
{
sigar_net_connection_walker_t walker;
net_stat_port_getter_t getter;
SIGAR_ZERO(netstat);
getter.netstat = netstat;
getter.address = address;
getter.port = port;
walker.sigar = sigar;
walker.data = &getter;
walker.add_connection = net_stat_port_walker;
walker.flags = flags;
if (SIGAR_LOG_IS_DEBUG(sigar)) {
char name[SIGAR_FQDN_LEN];
sigar_net_address_to_string(sigar, address, name);
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[net_stat_port] using address '%s:%d'",
name, port);
}
return sigar_net_connection_walk(&walker);
}
int sigar_who_list_create(sigar_who_list_t *wholist) int sigar_who_list_create(sigar_who_list_t *wholist)
{ {
wholist->number = 0; wholist->number = 0;
@ -1798,6 +1877,26 @@ static int sigar_ether_ntoa(char *buff, unsigned char *ptr)
return SIGAR_OK; return SIGAR_OK;
} }
SIGAR_DECLARE(int) sigar_net_address_equals(sigar_net_address_t *addr1,
sigar_net_address_t *addr2)
{
if (addr1->family != addr2->family) {
return EINVAL;
}
switch (addr1->family) {
case SIGAR_AF_INET:
return memcmp(&addr1->addr.in, &addr2->addr.in, sizeof(addr1->addr.in));
case SIGAR_AF_INET6:
return memcmp(&addr1->addr.in6, &addr2->addr.in6, sizeof(addr1->addr.in6));
case SIGAR_AF_LINK:
return memcmp(&addr1->addr.mac, &addr2->addr.mac, sizeof(addr1->addr.mac));
default:
return EINVAL;
}
}
SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar, SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar,
sigar_net_address_t *address, sigar_net_address_t *address,
char *addr_str) char *addr_str)