Author: jfrederic.clere(a)jboss.com
Date: 2007-10-02 16:29:19 -0400 (Tue, 02 Oct 2007)
New Revision: 1073
Modified:
trunk/sight/native/os/solaris/tcpstat.c
Log:
Port to Solaris.
Modified: trunk/sight/native/os/solaris/tcpstat.c
===================================================================
--- trunk/sight/native/os/solaris/tcpstat.c 2007-10-01 11:37:03 UTC (rev 1072)
+++ trunk/sight/native/os/solaris/tcpstat.c 2007-10-02 20:29:19 UTC (rev 1073)
@@ -38,14 +38,6 @@
#include <inet/mib2.h>
#include <inet/tcp.h>
-typedef struct mib_item_s {
- struct mib_item_s *next_item;
- long group;
- long mib_id;
- long length;
- char *valp;
-} mib_item_t;
-
/*
* TCP statistics implementation
*/
@@ -169,11 +161,19 @@
static const char *eiftype = "Unsupported NetworkAddressFamily type";
-/* Initialize volume enumeration */
-SIGHT_EXPORT_DECLARE(void, TcpStatistics, info0)(SIGHT_STDARGS,
- jobject thiz,
- jint iftype,
- jlong pool)
+extern apr_pool_t *sight_temp_pool;
+
+typedef struct tcpconn_enum_t {
+ int type;
+ int idx;
+ int numcons;
+ void *conn; /* mib2_tcp6ConnEntry_t / mib2_tcpConnEntry_t */
+ void *stat; /* mib2_tcp_t */
+ apr_pool_t *pool;
+} tcpconn_enum_t;
+
+/* Read the mib2 object and fill the structures */
+static void read_mib2(JNIEnv *_E, tcpconn_enum_t *e)
{
apr_status_t rc = APR_ENOTIMPL;
int sd;
@@ -181,17 +181,23 @@
int flags;
int i, j, getcode;
struct strbuf ctlbuf, databuf;
+
struct T_optmgmt_req *tor = (struct T_optmgmt_req *)buf;
struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *)buf;
struct T_error_ack *tea = (struct T_error_ack *)buf;
+
struct opthdr *req;
- mib_item_t *last_item = NULL;
+ int numcons = 0;
- UNREFERENCED_O;
-
- if ((sd = open("/dev/tcp", O_RDWR)) < 0) {
+ if ((sd = open("/dev/arp", O_RDWR)) < 0) {
throwAprException(_E, apr_get_os_error());
+ return;
}
+ if (ioctl(sd, I_PUSH, "tcp") <0) {
+ close(sd);
+ throwAprException(_E, apr_get_os_error());
+ return;
+ }
tor->PRIM_type = T_SVR4_OPTMGMT_REQ;
tor->OPT_offset = sizeof (struct T_optmgmt_req);
@@ -208,52 +214,103 @@
if (putmsg(sd, &ctlbuf, (struct strbuf *)0, flags) == -1) {
close(sd);
throwAprException(_E, apr_get_os_error());
+ return;
}
- req = (struct opthdr *)&toa[1];
- ctlbuf.maxlen = sizeof (buf);
- flags = 0;
- if (getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags) == -1) {
- close(sd);
- throwAprException(_E, apr_get_os_error());
- }
+ for(;;) {
+ req = (struct opthdr *)&toa[1];
+ ctlbuf.buf = (char *) buf;
+ ctlbuf.maxlen = sizeof (buf);
+ flags = 0;
+ if (getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags) == -1) {
+ close(sd);
+ throwAprException(_E, apr_get_os_error());
+ return;
+ }
+ if (toa->PRIM_type == T_OPTMGMT_ACK &&
+ toa->MGMT_flags == T_SUCCESS &&
+ req->len == 0)
+ break; /* done */
- last_item = (mib_item_t *)malloc(sizeof (mib_item_t));;
- last_item->next_item = NULL;
- last_item->group = req->level;
- last_item->mib_id = req->name;
- last_item->length = req->len;
- last_item->valp = malloc((int)req->len);
+ /* read the data */
+ databuf.maxlen = req->len;
+ databuf.buf = malloc((int)req->len);
+ databuf.len = 0;
+ flags = 0;
+ if (getmsg(sd, (struct strbuf *)0, &databuf, &flags) == -1) {
+ close(sd);
+ throwAprException(_E, apr_get_os_error());
+ return;
+ }
- databuf.maxlen = last_item->length;
- databuf.buf = (char *)last_item->valp;
- databuf.len = 0;
- flags = 0;
- if (getmsg(sd, (struct strbuf *)0, &databuf, &flags) == -1) {
- close(sd);
- throwAprException(_E, apr_get_os_error());
+ /* Process the TPC statics */
+ if ((req->level == MIB2_TCP && req->name == 0 && e->type
== 1) ||
+ (req->level == MIB2_TCP6 && req->name == 0 &&
e->type == 2)) {
+ e->stat = (void *) databuf.buf;
+ } else if (req->level == MIB2_TCP && req->name == MIB2_TCP_CONN
&& e->type == 1) {
+ /* Process the TPC4 statics */
+ mib2_tcpConnEntry_t *tcp = (mib2_tcpConnEntry_t *)databuf.buf;
+ char *end;
+ int numcons = 0;
+ end = (char*) tcp + databuf.len;
+ while ((char*) tcp < end) {
+ numcons++;
+ tcp++;
+ }
+ e->conn = (void *) databuf.buf;
+ e->numcons = numcons;
+ } else if (req->level == MIB2_TCP6 && req->name == MIB2_TCP6_CONN
&& e->type == 2) {
+ /* Process the TPC6 statics */
+ mib2_tcp6ConnEntry_t *tcp = (mib2_tcp6ConnEntry_t *)databuf.buf;
+ char *end;
+ int numcons = 0;
+ end = (char*) tcp + databuf.len;
+ while ((char*) tcp < end) {
+ numcons++;
+ tcp++;
+ }
+ e->conn = (void *) databuf.buf;
+ e->numcons = numcons;
+ } /* else {
+ printf("Missing logic info0: level %d name %d\n", req->level,
req->name);
+ } */
}
close(sd);
+}
- for (; last_item; last_item = last_item->next_item) {
- if (last_item->group == MIB2_TCP) {
- mib2_tcp_t *tcp = (mib2_tcp_t *)last_item->valp;
- SET_IFIELD_I(0000, thiz, tcp->tcpRtoMin);
- SET_IFIELD_I(0001, thiz, tcp->tcpRtoMax);
- SET_IFIELD_I(0002, thiz, tcp->tcpMaxConn);
- SET_IFIELD_I(0003, thiz, tcp->tcpActiveOpens);
- SET_IFIELD_I(0004, thiz, tcp->tcpPassiveOpens);
- SET_IFIELD_I(0005, thiz, tcp->tcpAttemptFails);
- SET_IFIELD_I(0006, thiz, tcp->tcpEstabResets);
- SET_IFIELD_I(0007, thiz, tcp->tcpCurrEstab);
- SET_IFIELD_I(0008, thiz, tcp->tcpInSegs);
- SET_IFIELD_I(0009, thiz, tcp->tcpOutSegs);
- SET_IFIELD_I(0010, thiz, tcp->tcpRetransSegs);
+/* Initialize volume enumeration */
+SIGHT_EXPORT_DECLARE(void, TcpStatistics, info0)(SIGHT_STDARGS,
+ jobject thiz,
+ jint iftype,
+ jlong pool)
+{
+ tcpconn_enum_t *e;
+ if (!(e = (tcpconn_enum_t *)sight_calloc(_E,
+ sizeof(tcpconn_enum_t),
+ THROW_FMARK))) {
+ return;
+ }
+ e->type = iftype;
+ read_mib2(_E, e);
- SET_IFIELD_I(0012, thiz, tcp->tcpOutRsts);
+ if (e->stat != NULL) {
+ mib2_tcp_t *tcp = (mib2_tcp_t *)e->stat;
+ SET_IFIELD_I(0000, thiz, tcp->tcpRtoMin);
+ SET_IFIELD_I(0001, thiz, tcp->tcpRtoMax);
+ SET_IFIELD_I(0002, thiz, tcp->tcpMaxConn);
+ SET_IFIELD_I(0003, thiz, tcp->tcpActiveOpens);
+ SET_IFIELD_I(0004, thiz, tcp->tcpPassiveOpens);
+ SET_IFIELD_I(0005, thiz, tcp->tcpAttemptFails);
+ SET_IFIELD_I(0006, thiz, tcp->tcpEstabResets);
+ SET_IFIELD_I(0007, thiz, tcp->tcpCurrEstab);
+ SET_IFIELD_I(0008, thiz, tcp->tcpInSegs);
+ SET_IFIELD_I(0009, thiz, tcp->tcpOutSegs);
+ SET_IFIELD_I(0010, thiz, tcp->tcpRetransSegs);
- }
+ SET_IFIELD_I(0012, thiz, tcp->tcpOutRsts);
}
+
+ SET_IFIELD_I(0013, thiz, e->numcons);
}
/* Initialize TCP conn enumeration */
@@ -261,14 +318,43 @@
jint iftype,
jlong pool)
{
- return 0;
+ tcpconn_enum_t *e;
+ apr_status_t rc;
+
+ UNREFERENCED_O;
+ if (iftype < 1 || iftype > 2) {
+ throwOSException(_E, eiftype);
+ return 0;
+ }
+
+ if (!(e = (tcpconn_enum_t *)sight_calloc(_E,
+ sizeof(tcpconn_enum_t),
+ THROW_FMARK))) {
+ return 0;
+ }
+
+ if ((rc = sight_create_pool(&e->pool, sight_temp_pool)) != APR_SUCCESS) {
+ throwAprMemoryException(_E, THROW_FMARK, rc);
+ return 0;
+ }
+ e->type = iftype;
+ read_mib2(_E, e);
+
+ return P2J(e);
}
/* Get the number of entries */
SIGHT_EXPORT_DECLARE(jint, TcpStatistics, enum1)(SIGHT_STDARGS,
jlong handle)
{
- return 0;
+ tcpconn_enum_t *e = J2P(handle, tcpconn_enum_t *);
+ UNREFERENCED_STDARGS;
+ if (e) {
+ e->idx = 1;
+ return e->numcons;
+ } else {
+ return 0;
+ }
}
SIGHT_EXPORT_DECLARE(void, TcpStatistics, enum2)(SIGHT_STDARGS,
@@ -276,12 +362,63 @@
jint index,
jlong handle)
{
+ tcpconn_enum_t *e = J2P(handle, tcpconn_enum_t *);
+ char las[128] = "";
+ char ras[128] = "";
+ jobject la, ra;
+ jint lp = 0, rp = 0;
+ jint st;
+ if (!e)
+ return;
+ if (e->idx > e->numcons) {
+ return;
+ }
+ if (e->type == 1) {
+ mib2_tcpConnEntry_t *tcp = (mib2_tcpConnEntry_t *) e->conn;
+ int i;
+ for (i=1; i<e->idx; i++)
+ tcp++;
+ inet_ntop(AF_INET, &tcp->tcpConnLocalAddress, las, 64);
+ inet_ntop(AF_INET, &tcp->tcpConnRemAddress, ras, 64);
+ lp = tcp->tcpConnLocalPort;
+ rp = tcp->tcpConnRemPort;
+ st = tcp->tcpConnState;
+ } else {
+ mib2_tcp6ConnEntry_t *tcp = (mib2_tcp6ConnEntry_t *) e->conn;
+ int i;
+ for (i=1; i<e->idx; i++)
+ tcp++;
+ sight_inet_ntop6(tcp->tcp6ConnLocalAddress.s6_addr, las, 64);
+ sight_inet_ntop6(tcp->tcp6ConnRemAddress.s6_addr, ras, 64);
+ lp = tcp->tcp6ConnLocalPort;
+ rp = tcp->tcp6ConnRemPort;
+ st = tcp->tcp6ConnState;
+ }
+ sight_tcpconn_set_tmo(_E, conn, 0);
+ sight_tcpconn_set_cts(_E, conn, 0);
+ sight_tcpconn_set_pid(_E, conn, 0);
+
+ sight_tcpconn_set_state(_E, conn, st);
+
+ la = sight_new_netaddr_class(_E, _O);
+ sight_netaddr_set_addr(_E, la, las);
+ sight_netaddr_set_port(_E, la, lp);
+ sight_tcpconn_set_local(_E, conn, la);
+ (*_E)->DeleteLocalRef(_E, la);
+
+ ra = sight_new_netaddr_class(_E, _O);
+ sight_netaddr_set_addr(_E, ra, ras);
+ sight_netaddr_set_port(_E, ra, rp);
+ sight_tcpconn_set_remote(_E, conn, ra);
+ (*_E)->DeleteLocalRef(_E, ra);
+
+ e->idx++;
}
/* Close TCP conn enumeration */
SIGHT_EXPORT_DECLARE(void, TcpStatistics, enum3)(SIGHT_STDARGS,
jlong handle)
{
-
+ /* XXX: Add cleanup */
}