Add net_stat_port function to provide metrics on specific port+address
This commit is contained in:
parent
808a7deeba
commit
86deb1a2d9
|
@ -1,5 +1,7 @@
|
|||
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
|
||||
|
||||
2007-03-29 Doug MacEachern <dougm@hyperic.com>
|
||||
|
|
|
@ -847,6 +847,12 @@ my %classes = (
|
|||
{
|
||||
name => 'tcp_outbound_total', type => 'Int',
|
||||
},
|
||||
{
|
||||
name => 'all_inbound_total', type => 'Int',
|
||||
},
|
||||
{
|
||||
name => 'all_outbound_total', type => 'Int',
|
||||
},
|
||||
],
|
||||
ResourceLimit => [
|
||||
{
|
||||
|
|
|
@ -851,8 +851,31 @@ JNIEXPORT jobjectArray SIGAR_JNIx(getNetConnectionList)
|
|||
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)
|
||||
(JNIEnv *env, jobject obj, jobject sigar_obj, jint flags)
|
||||
(JNIEnv *env, jobject obj, jobject sigar_obj, jint flags,
|
||||
jbyteArray jaddress, jlong port)
|
||||
{
|
||||
int status;
|
||||
sigar_net_stat_t netstat;
|
||||
|
@ -860,9 +883,21 @@ JNIEXPORT void SIGAR_JNI(NetStat_stat)
|
|||
jfieldID id;
|
||||
jintArray states;
|
||||
jint tcp_states[SIGAR_TCP_UNKNOWN];
|
||||
sigar_net_address_t address;
|
||||
jboolean has_port = (port != -1);
|
||||
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) {
|
||||
sigar_throw_error(env, jsigar, status);
|
||||
return;
|
||||
|
@ -891,8 +926,6 @@ JNIEXPORT void SIGAR_JNI(NetStat_stat)
|
|||
|
||||
id = JENV->GetFieldID(env, cls, "tcpStates", "[I");
|
||||
JENV->SetObjectField(env, obj, id, states);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring SIGAR_JNI(NetConnection_getTypeString)
|
||||
|
|
|
@ -20,12 +20,14 @@ package org.hyperic.sigar;
|
|||
|
||||
public class NetStat implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 02242007L;
|
||||
private static final long serialVersionUID = 04052007L;
|
||||
|
||||
protected int[] tcpStates;
|
||||
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() { }
|
||||
|
||||
|
@ -34,7 +36,17 @@ public class NetStat implements java.io.Serializable {
|
|||
NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT |
|
||||
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() {
|
||||
|
@ -45,6 +57,14 @@ public class NetStat implements java.io.Serializable {
|
|||
return this.tcpOutboundTotal;
|
||||
}
|
||||
|
||||
public int getAllInboundTotal() {
|
||||
return this.allInboundTotal;
|
||||
}
|
||||
|
||||
public int getAllOutboundTotal() {
|
||||
return this.allOutboundTotal;
|
||||
}
|
||||
|
||||
public int[] getTcpStates() {
|
||||
return this.tcpStates;
|
||||
}
|
||||
|
|
|
@ -799,7 +799,14 @@ public class Sigar implements SigarProxy {
|
|||
netstat.stat(this);
|
||||
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()
|
||||
throws SigarException;
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ public class SigarTestRunner extends SigarCommandBase {
|
|||
TestNetInfo.class,
|
||||
TestNetRoute.class,
|
||||
TestNetStat.class,
|
||||
TestNetStatPort.class,
|
||||
TestProcArgs.class,
|
||||
TestProcEnv.class,
|
||||
TestProcExe.class,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -461,6 +461,9 @@ typedef struct {
|
|||
} addr;
|
||||
} 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_net_address_t *address,
|
||||
char *addr_str);
|
||||
|
@ -666,12 +669,22 @@ typedef struct {
|
|||
int tcp_states[SIGAR_TCP_UNKNOWN];
|
||||
sigar_uint32_t tcp_inbound_total;
|
||||
sigar_uint32_t tcp_outbound_total;
|
||||
sigar_uint32_t all_inbound_total;
|
||||
sigar_uint32_t all_outbound_total;
|
||||
} sigar_net_stat_t;
|
||||
|
||||
SIGAR_DECLARE(int)
|
||||
sigar_net_stat_get(sigar_t *sigar,
|
||||
sigar_net_stat_t *netstat,
|
||||
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);
|
||||
|
||||
|
|
99
src/sigar.c
99
src/sigar.c
|
@ -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)
|
||||
{
|
||||
wholist->number = 0;
|
||||
|
@ -1798,6 +1877,26 @@ static int sigar_ether_ntoa(char *buff, unsigned char *ptr)
|
|||
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_net_address_t *address,
|
||||
char *addr_str)
|
||||
|
|
Loading…
Reference in New Issue