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>
|
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>
|
||||||
|
|
|
@ -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 => [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -799,7 +799,14 @@ public class Sigar implements SigarProxy {
|
||||||
netstat.stat(this);
|
netstat.stat(this);
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
} 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,12 +669,22 @@ 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)
|
||||||
sigar_net_stat_get(sigar_t *sigar,
|
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);
|
||||||
|
|
||||||
|
|
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)
|
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)
|
||||||
|
|
Loading…
Reference in New Issue