Author: mladen.turk(a)jboss.com
Date: 2007-09-10 03:04:48 -0400 (Mon, 10 Sep 2007)
New Revision: 1004
Modified:
trunk/sight/native/configure.in
trunk/sight/native/include/arch/unix/sight_private.h
trunk/sight/native/os/linux/tcpstat.c
trunk/sight/native/os/linux/udpstat.c
Log:
Added UDP connection lister implementation
Modified: trunk/sight/native/configure.in
===================================================================
--- trunk/sight/native/configure.in 2007-09-10 06:44:23 UTC (rev 1003)
+++ trunk/sight/native/configure.in 2007-09-10 07:04:48 UTC (rev 1004)
@@ -262,6 +262,7 @@
AC_SUBST(INCLUDE_RULES)
AC_SUBST(INCLUDE_OUTPUTS)
+AC_CHECK_HEADERS([netinet/tcp.h])
dnl ----------------------------- Checking for missing POSIX thread functions
AC_CHECK_FUNCS([getpwnam_r getpwuid_r getgrnam_r getgrgid_r])
Modified: trunk/sight/native/include/arch/unix/sight_private.h
===================================================================
--- trunk/sight/native/include/arch/unix/sight_private.h 2007-09-10 06:44:23 UTC (rev
1003)
+++ trunk/sight/native/include/arch/unix/sight_private.h 2007-09-10 07:04:48 UTC (rev
1004)
@@ -32,7 +32,30 @@
#include "apr.h"
#include "apr_general.h"
#include <jni.h>
+#include "sight_platform.h"
+#if HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#else
+
+/* These enums are defined in netinet/tcp.h */
+typedef enum {
+ TCP_ESTABLISHED = 1,
+ TCP_SYN_SENT,
+ TCP_SYN_RECV,
+ TCP_FIN_WAIT1,
+ TCP_FIN_WAIT2,
+ TCP_TIME_WAIT,
+ TCP_CLOSE,
+ TCP_CLOSE_WAIT,
+ TCP_LAST_ACK,
+ TCP_LISTEN,
+ TCP_CLOSING /* now a valid state */
+} sight_tcp_state_e;
+
+#endif
+
+
#define SIGHT_PLATFORM_CLASS_PATH SIGHT_CLASS_PATH "platform/unix/"
#define SIGHT_PLATFORM_DECLARE(RT, CL, FN) \
Modified: trunk/sight/native/os/linux/tcpstat.c
===================================================================
--- trunk/sight/native/os/linux/tcpstat.c 2007-09-10 06:44:23 UTC (rev 1003)
+++ trunk/sight/native/os/linux/tcpstat.c 2007-09-10 07:04:48 UTC (rev 1004)
@@ -156,21 +156,6 @@
#define PROC_NET_FS "/proc/net/"
static const char *eiftype = "Unsupported NetworkAddressFamily type";
-/* These enums are used by IPX too. :-( */
-typedef enum {
- TCP_ESTABLISHED = 1,
- TCP_SYN_SENT,
- TCP_SYN_RECV,
- TCP_FIN_WAIT1,
- TCP_FIN_WAIT2,
- TCP_TIME_WAIT,
- TCP_CLOSE,
- TCP_CLOSE_WAIT,
- TCP_LAST_ACK,
- TCP_LISTEN,
- TCP_CLOSING /* now a valid state */
-} sight_tcp_state_e;
-
static int tcp2sstate[] = {
0,
SIGHT_TCP_ESTABLISHED,
@@ -341,7 +326,7 @@
char ras[128] = "";
char ssi[32] = "";
struct in_addr ial, iar;
- jint cts = 0;
+ jint tmo = 0;
unsigned long rxq, txq, timelen, retr, inode;
int num, d, uid, timer_run, timeout;
char more[512];
Modified: trunk/sight/native/os/linux/udpstat.c
===================================================================
--- trunk/sight/native/os/linux/udpstat.c 2007-09-10 06:44:23 UTC (rev 1003)
+++ trunk/sight/native/os/linux/udpstat.c 2007-09-10 07:04:48 UTC (rev 1004)
@@ -91,6 +91,7 @@
sight_unload_class(_E, &_clazzn);
}
+#define PROC_NET_FS "/proc/net/"
static const char *eiftype = "Unsupported NetworkAddressFamily type";
/* Initialize volume enumeration */
@@ -99,69 +100,123 @@
jint iftype,
jlong pool)
{
- sight_arr_t *tgrp;
int i;
+ sight_arr_t *tnet;
int InDatagrams, NoPorts, InErrors, OutDatagrams, RcvbufErrors, SndbufErrors;
+ int NumCons = 0;
UNREFERENCED_O;
- if (!(tgrp = sight_arr_rload("/proc/net/snmp"))) {
+ if (iftype == 1) {
+ if (!(tnet = sight_arr_rload(PROC_NET_FS "sockstat"))) {
+ throwAprException(_E, apr_get_os_error());
+ }
+ for (i = 0; i < tnet->siz; i++) {
+ if (memcmp(tnet->arr.ca[i], "UDP: inuse ", 11) == 0) {
+ NumCons = atoi(tnet->arr.ca[i] + 11);
+ break;
+ }
+ }
+ }
+ else if (iftype == 2) {
+ if (!(tnet = sight_arr_rload(PROC_NET_FS "sockstat6"))) {
+ throwAprException(_E, apr_get_os_error());
+ }
+ for (i = 0; i < tnet->siz; i++) {
+ if (memcmp(tnet->arr.ca[i], "UDP6: inuse ", 12) == 0) {
+ NumCons = atoi(tnet->arr.ca[i] + 12);
+ break;
+ }
+ }
+ }
+ else {
+ throwOSException(_E, eiftype);
+ return;
+ }
+ sight_arr_free(tnet);
+
+ if (!(tnet = sight_arr_rload("/proc/net/snmp"))) {
throwAprException(_E, apr_get_os_error());
}
/* Get the information corresponding to the second entry Tcp: */
- for (i = 0; i < tgrp->siz; i++) {
- if (memcmp(tgrp->arr.ca[i], "Udp:", 4) == 0) {
- if (memcmp(tgrp->arr.ca[i], "Udp: InDatagrams", 16) != 0) {
- sscanf(tgrp->arr.ca[i], "Udp: %d %d %d %d %d %d",
+ for (i = 0; i < tnet->siz; i++) {
+ if (memcmp(tnet->arr.ca[i], "Udp:", 4) == 0) {
+ if (memcmp(tnet->arr.ca[i], "Udp: InDatagrams", 16) != 0) {
+ sscanf(tnet->arr.ca[i], "Udp: %d %d %d %d %d %d",
&InDatagrams, &NoPorts, &InErrors, &OutDatagrams,
&RcvbufErrors, &SndbufErrors);
break;
}
}
}
- sight_arr_free(tgrp);
+ sight_arr_free(tnet);
SET_IFIELD_I(0000, thiz, InDatagrams);
SET_IFIELD_I(0001, thiz, NoPorts);
SET_IFIELD_I(0002, thiz, InErrors);
SET_IFIELD_I(0003, thiz, OutDatagrams);
- /* XXX: We can't get Number of entries in UDP listener table that way.
- SET_IFIELD_I(0004, thiz, s.dwNumAddrs);
- */
+ SET_IFIELD_I(0004, thiz, NumCons);
}
+typedef struct udpconn_enum_t {
+ int type;
+ int idx;
+ sight_arr_t *tnet;
+} udpconn_enum_t;
+
+
SIGHT_EXPORT_DECLARE(jlong, UdpStatistics, enum0)(SIGHT_STDARGS,
jint iftype,
jlong pool)
{
- apr_status_t rc = APR_ENOTIMPL;
+ udpconn_enum_t *e;
+
UNREFERENCED_O;
-
+ if (iftype < 1 || iftype > 2) {
+ throwOSException(_E, eiftype);
+ return 0;
+ }
+ if (!(e = (udpconn_enum_t *)calloc(1, sizeof(udpconn_enum_t)))) {
+ throwAprMemoryException(_E, THROW_FMARK,
+ apr_get_os_error());
+ return 0;
+ }
+ e->type = iftype;
if (iftype == 1) {
- /* AF_INET */
- rc = 0;
+ if (!(e->tnet = sight_arr_rload(PROC_NET_FS "udp"))) {
+ throwAprException(_E, apr_get_os_error());
+ goto cleanup;
+ }
}
- else if (iftype == 2) {
- /* AF_INET6 */
- rc = 0;
- }
else {
- throwOSException(_E, eiftype);
+ if (!(e->tnet = sight_arr_rload(PROC_NET_FS "udp6"))) {
+ throwAprException(_E, apr_get_os_error());
+ goto cleanup;
+ }
}
- if (rc) {
- throwAprException(_E, APR_FROM_OS_ERROR(rc));
- return;
- }
+
+ return P2J(e);
+cleanup:
+ sight_arr_free(e->tnet);
+ free(e);
+ return 0;
}
/* Get the number of entries */
SIGHT_EXPORT_DECLARE(jint, UdpStatistics, enum1)(SIGHT_STDARGS,
jlong handle)
{
+ udpconn_enum_t *e = J2P(handle, udpconn_enum_t *);
+
UNREFERENCED_STDARGS;
- return 0;
+ if (e && e->tnet) {
+ e->idx = 1;
+ return e->tnet->siz - 1; /* Skip description field */
+ }
+ else
+ return 0;
}
SIGHT_EXPORT_DECLARE(void, UdpStatistics, enum2)(SIGHT_STDARGS,
@@ -169,12 +224,115 @@
jint index,
jlong handle)
{
+ jint pid = -1;
+ jint state = 0;
+ jint lp = 0, rp = 0;
+ jobject la, ra;
+ char las[128] = "";
+ char ras[128] = "";
+ char ssi[32] = "";
+ struct in_addr ial, iar;
+ jint tmo = 0;
+ unsigned long rxq, txq, timelen, retr, inode;
+ int num, d, uid, timer_run, timeout;
+ char more[512];
+
+ udpconn_enum_t *e = J2P(handle, udpconn_enum_t *);
+
+ if (!e || !e->tnet)
+ return;
+ if (e->idx > e->tnet->siz) {
+ /* TODO: Throw overflow */
+ return;
+ }
+ num = sscanf(e->tnet->arr.ca[e->idx],
+ "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld
%512s",
+ &d, las, &lp, ras, &rp, &state,
+ &txq, &rxq, &timer_run, &timelen, &retr,
+ &uid, &timeout, &inode, more);
+
+ if (e->type == 1) {
+ /* IPV4 entries */
+ int al;
+ struct in_addr in4;
+
+ al = sscanf(las, "%X", &in4.s_addr);
+ if (al == 1)
+ inet_ntop(AF_INET, &in4, las, 64);
+ else
+ las[0] = '\0';
+
+ al = sscanf(ras, "%X", &in4.s_addr);
+ if (al == 1)
+ inet_ntop(AF_INET, &in4, ras, 64);
+ else
+ ras[0] = '\0';
+ }
+ else {
+ /* IPV6 entries */
+ int al;
+ struct in6_addr in6;
+
+ al = sscanf(las, "%08X%08X%08X%08X",
+ &in6.s6_addr32[0], &in6.s6_addr32[1],
+ &in6.s6_addr32[2], &in6.s6_addr32[3]);
+
+ if (al == 4)
+ sight_inet_ntop6(in6.s6_addr, las, 64);
+ else
+ las[0] = '\0';
+ al = sscanf(ras, "%08X%08X%08X%08X",
+ &in6.s6_addr32[0], &in6.s6_addr32[1],
+ &in6.s6_addr32[2], &in6.s6_addr32[3]);
+
+ if (al == 4)
+ sight_inet_ntop6(in6.s6_addr, ras, 64);
+ else
+ ras[0] = '\0';
+ }
+ /* TODO: See what's the actual value of timelen */
+ tmo = timelen;
+ sight_udpconn_set_tmo(_E, conn, tmo);
+ /* TODO: Search for create timestamp and pid by browsing
+ * the /proc/pid/fd for matching inode
+ */
+ sight_udpconn_set_pid(_E, conn, pid);
+
+ switch (state) {
+ case TCP_ESTABLISHED:
+ sight_tcpconn_set_state(_E, conn, 1);
+ break;
+ default:
+ sight_tcpconn_set_state(_E, conn, 0);
+ break;
+ }
+
+ la = sight_new_netaddr_class(_E, _O);
+ sight_netaddr_set_addr(_E, la, las);
+ sight_netaddr_set_port(_E, la, lp);
+ sight_udpconn_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_udpconn_set_remote(_E, conn, ra);
+ (*_E)->DeleteLocalRef(_E, ra);
+ /* Increment the index counter */
+ e->idx++;
+
}
-/* Close TCP conn enumeration */
+/* Close UDP conn enumeration */
SIGHT_EXPORT_DECLARE(void, UdpStatistics, enum3)(SIGHT_STDARGS,
jlong handle)
{
+ udpconn_enum_t *e = J2P(handle, udpconn_enum_t *);
+
UNREFERENCED_STDARGS;
+ if (e) {
+ sight_arr_free(e->tnet);
+ free(e);
+ }
}