[collectd] [PATCH] tcpconns plugin: add support for AIX
Manuel Luis Sanmartín Rozada
manuel.luis at gmail.com
Mon Jun 6 14:14:27 CEST 2011
Hi.
In AIX there is a undocumented function/syscall in libc: netinfo
returns a structure with the state of the tcp connections.
I didn't found the description or info abut this syscall, I guess is
something like this:
int netinfo (int proto, void *data, int *size, int n);
and the struct something like this: (with some work we can guess the
unknow remaining bytes)
struct netinfo_header {
unsigned int proto;
unsigned int size;
struct netinfo_entry e[];
};
struct netinfo_entry {
uint32_t unknow1;
uint32_t unknow2;
uint16_t dstport;
uint16_t unknow3;
struct in6_addr dstaddr;
uint16_t srcport;
uint16_t unknow4;
struct in6_addr srcaddr;
uint32_t unknow01[4];
uint32_t unknow02[2];
uint16_t so_options;
uint16_t unknow02a;
uint16_t so_q0len;
uint16_t so_qlen;
uint16_t so_qlimit;
uint16_t so_dqlen;
uint32_t unknow03[4];
struct {
uint32_t sb_hiwat;
uint32_t unknow01;
uint32_t unknow02;
uint32_t unknow03;
uint32_t sb_mbmax;
uint32_t unknow04;
uint32_t sb_lowat;
uint16_t sb_flags;
uint16_t unknow05;
} rcvbuf;
uint32_t unknow07;
uint32_t unknow08[2];
uint32_t unknow09;
struct {
uint32_t sb_hiwat;
uint32_t unknow01;
uint32_t unknow02;
uint32_t unknow03;
uint32_t sb_mbmax;
uint32_t unknow04;
uint32_t sb_lowat;
uint16_t sb_flags;
uint16_t unknow05;
} sndbuf;
uint32_t unknow11;
uint32_t so_uid;
uint16_t so_special;
uint16_t so_special2;
uint16_t tcp_state;
uint16_t unknow12;
uint32_t tcp_flags;
uint32_t tcp_mss;
uint32_t unknow15;
};
---
configure.in | 6 +++
src/tcpconns.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 119 insertions(+), 4 deletions(-)
diff --git a/configure.in b/configure.in
index 8043d9a..4fd08ce 100644
--- a/configure.in
+++ b/configure.in
@@ -4361,6 +4361,12 @@ then
fi
# AIX
+
+if test "x$ac_system" = "xAIX"
+then
+ plugin_tcpconns="yes"
+fi
+
if test "x$with_perfstat" = "xyes"
then
plugin_cpu="yes"
diff --git a/src/tcpconns.c b/src/tcpconns.c
index d68cd09..ae1fabb 100644
--- a/src/tcpconns.c
+++ b/src/tcpconns.c
@@ -65,7 +65,7 @@
#undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
#endif
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
# error "No applicable input method."
#endif
@@ -118,7 +118,12 @@
# include <arpa/inet.h>
# include <nlist.h>
# include <kvm.h>
-#endif /* HAVE_LIBKVM_NLIST */
+/* #endif HAVE_LIBKVM_NLIST */
+
+#elif KERNEL_AIX
+# include <arpa/inet.h>
+# include <sys/socketvar.h>
+#endif /* KERNEL_AIX */
#if KERNEL_LINUX
static const char *tcp_state[] =
@@ -186,7 +191,49 @@ struct inpcbtable *inpcbtable_ptr = NULL;
# define TCP_STATE_LISTEN 1
# define TCP_STATE_MIN 1
# define TCP_STATE_MAX 10
-#endif /* HAVE_LIBKVM_NLIST */
+/* #endif HAVE_LIBKVM_NLIST */
+
+#elif KERNEL_AIX
+static const char *tcp_state[] =
+{
+ "CLOSED",
+ "LISTEN",
+ "SYN_SENT",
+ "SYN_RCVD",
+ "ESTABLISHED",
+ "CLOSE_WAIT",
+ "FIN_WAIT_1",
+ "CLOSING",
+ "LAST_ACK",
+ "FIN_WAIT_2",
+ "TIME_WAIT"
+};
+
+# define TCP_STATE_LISTEN 1
+# define TCP_STATE_MIN 0
+# define TCP_STATE_MAX 10
+
+struct netinfo_conn {
+ uint32_t unknow1[2];
+ uint16_t dstport;
+ uint16_t unknow2;
+ struct in6_addr dstaddr;
+ uint16_t srcport;
+ uint16_t unknow3;
+ struct in6_addr srcaddr;
+ uint32_t unknow4[36];
+ uint16_t tcp_state;
+ uint16_t unknow5[7];
+};
+
+struct netinfo_header {
+ unsigned int proto;
+ unsigned int size;
+};
+
+# define NETINFO_TCP 3
+extern int netinfo (int proto, void *data, int *size, int n);
+#endif /* KERNEL_AIX */
#define PORT_COLLECT_LOCAL 0x01
#define PORT_COLLECT_REMOTE 0x02
@@ -706,7 +753,67 @@ static int conn_read (void)
return (0);
}
-#endif /* HAVE_LIBKVM_NLIST */
+/* #endif HAVE_LIBKVM_NLIST */
+
+#elif KERNEL_AIX
+
+static int conn_read (void)
+{
+ int size;
+ int i;
+ int nconn;
+ void *data;
+ struct netinfo_header *header;
+ struct netinfo_conn *conn;
+
+ conn_reset_port_entry ();
+
+ size = netinfo(NETINFO_TCP, 0, 0, 0);
+ if (size < 0)
+ {
+ ERROR ("tcpconns plugin: netinfo failed return: %d", size);
+ return (-1);
+ }
+
+ if (size == 0)
+ return 0;
+
+ if ((size - sizeof(struct netinfo_header)) % sizeof(struct netinfo_conn))
+ {
+ ERROR ("tcpconns plugin: invalid buffer size");
+ return (-1);
+ }
+
+ data = malloc(size);
+ if (data == NULL)
+ {
+ ERROR ("tcpconns plugin: malloc failed");
+ return (-1);
+ }
+
+ if (netinfo(NETINFO_TCP, data, &size, 0) < 0)
+ {
+ ERROR ("tcpconns plugin: netinfo failed");
+ free(data);
+ return (-1);
+ }
+
+ header = (struct netinfo_header *)data;
+ nconn = header->size;
+ conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header));
+
+ for (i=0; i < nconn; conn++, i++)
+ {
+ conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state);
+ }
+
+ free(data);
+
+ conn_submit_all ();
+
+ return (0);
+}
+#endif /* KERNEL_AIX */
void module_register (void)
{
@@ -718,6 +825,8 @@ void module_register (void)
/* no initialization */
#elif HAVE_LIBKVM_NLIST
plugin_register_init ("tcpconns", conn_init);
+#elif KERNEL_AIX
+ /* no initialization */
#endif
plugin_register_read ("tcpconns", conn_read);
} /* void module_register */
--
1.7.1.1
More information about the collectd
mailing list