/**
* collectd - src/tcpconns.c
- * Copyright (C) 2007 Florian octo Forster
+ * Copyright (C) 2007,2008 Florian octo Forster
+ * Copyright (C) 2008 Michael Stapelberg
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
*
* Author:
* Florian octo Forster <octo at verplant.org>
+ * Michael Stapelberg <michael+git at stapelberg.de>
**/
/**
- * Code within `__OpenBSD__' blocks is provided under the following license:
+ * Code within `HAVE_LIBKVM_NLIST' blocks is provided under the following
+ * license:
*
* $collectd: parts of tcpconns.c, 2008/08/08 03:48:30 Michael Stapelberg $
* $OpenBSD: inet.c,v 1.100 2007/06/19 05:28:30 ray Exp $
#include "common.h"
#include "plugin.h"
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !__OpenBSD__
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+#undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
+#endif
+
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST
# error "No applicable input method."
#endif
# include <netinet/tcp_var.h>
/* #endif HAVE_SYSCTLBYNAME */
-#elif __OpenBSD__
+/* This is for OpenBSD and NetBSD. */
+#elif HAVE_LIBKVM_NLIST
# include <sys/queue.h>
# include <sys/socket.h>
# include <net/route.h>
# include <netinet/in.h>
# include <netinet/in_systm.h>
# include <netinet/ip.h>
+# include <netinet/ip_var.h>
# include <netinet/in_pcb.h>
# include <netinet/tcp.h>
# include <netinet/tcp_timer.h>
# include <arpa/inet.h>
# include <nlist.h>
# include <kvm.h>
-#endif /* __OpenBSD__ */
+#endif /* HAVE_LIBKVM_NLIST */
#if KERNEL_LINUX
static const char *tcp_state[] =
# define TCP_STATE_MAX 10
/* #endif HAVE_SYSCTLBYNAME */
-#elif __OpenBSD__
+#elif HAVE_LIBKVM_NLIST
static const char *tcp_state[] =
{
"CLOSED",
# define TCP_STATE_LISTEN 1
# define TCP_STATE_MIN 1
# define TCP_STATE_MAX 10
-#endif /* __OpenBSD__ */
+#endif /* HAVE_LIBKVM_NLIST */
#define PORT_COLLECT_LOCAL 0x01
#define PORT_COLLECT_REMOTE 0x02
vl.values = values;
vl.values_len = 1;
- vl.time = time (NULL);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "tcpconns", sizeof (vl.plugin));
sstrncpy (vl.type, "tcp_connections", sizeof (vl.type));
|| (pe->flags & PORT_COLLECT_LOCAL))
{
ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
- "%hu-local", pe->port);
+ "%"PRIu16"-local", pe->port);
for (i = 1; i <= TCP_STATE_MAX; i++)
{
if (pe->flags & PORT_COLLECT_REMOTE)
{
ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
- "%hu-remote", pe->port);
+ "%"PRIu16"-remote", pe->port);
for (i = 1; i <= TCP_STATE_MAX; i++)
{
port_entry_t *next = pe->next;
DEBUG ("tcpconns plugin: Removing temporary entry "
- "for listening port %hu", pe->port);
+ "for listening port %"PRIu16, pe->port);
if (prev == NULL)
port_list_head = next;
#endif
)
{
- NOTICE ("tcpconns plugin: Ignoring connection with unknown state 0x%02x.",
- state);
+ NOTICE ("tcpconns plugin: Ignoring connection with "
+ "unknown state 0x%02"PRIx8".", state);
return (-1);
}
pe->flags |= PORT_IS_LISTENING;
}
- DEBUG ("tcpconns plugin: Connection %hu <-> %hu (%s)",
+ DEBUG ("tcpconns plugin: Connection %"PRIu16" <-> %"PRIu16" (%s)",
port_local, port_remote, tcp_state[state]);
pe = conn_get_port_entry (port_local, 0 /* no create */);
#elif HAVE_SYSCTLBYNAME
/* #endif HAVE_SYSCTLBYNAME */
-#elif __OpenBSD__
-#endif /* __OpenBSD__ */
+#elif HAVE_LIBKVM_NLIST
+#endif /* HAVE_LIBKVM_NLIST */
static int conn_config (const char *key, const char *value)
{
&& ((inp->inp_vflag & INP_IPV6) == 0))
continue;
- conn_handle_ports (inp->inp_lport, inp->inp_fport, tp->t_state);
+ conn_handle_ports (ntohs (inp->inp_lport), ntohs (inp->inp_fport),
+ tp->t_state);
} /* for (in_ptr) */
in_orig = NULL;
} /* int conn_read */
/* #endif HAVE_SYSCTLBYNAME */
-#elif __OpenBSD__
+#elif HAVE_LIBKVM_NLIST
static int kread (u_long addr, void *buf, int size)
{
int status;
/* Get the `head' pcb */
head = (struct inpcb *) &(inpcbtable_ptr->inpt_queue);
/* Get the first pcb */
- next = CIRCLEQ_FIRST (&table.inpt_queue);
+ next = (struct inpcb *)CIRCLEQ_FIRST (&table.inpt_queue);
while (next != head)
{
kread ((u_long) next, &inpcb, sizeof (inpcb));
/* Advance `next' */
- next = CIRCLEQ_NEXT (&inpcb, inp_queue);
+ next = (struct inpcb *)CIRCLEQ_NEXT (&inpcb, inp_queue);
/* Ignore sockets, that are not connected. */
+#ifdef __NetBSD__
+ if (inpcb.inp_af == AF_INET6)
+ continue; /* XXX see netbsd/src/usr.bin/netstat/inet6.c */
+#else
if (!(inpcb.inp_flags & INP_IPV6)
&& (inet_lnaof(inpcb.inp_laddr) == INADDR_ANY))
continue;
if ((inpcb.inp_flags & INP_IPV6)
&& IN6_IS_ADDR_UNSPECIFIED (&inpcb.inp_laddr6))
continue;
+#endif
kread ((u_long) inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb));
conn_handle_ports (ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), tcpcb.t_state);
return (0);
}
-#endif /* __OpenBSD__ */
+#endif /* HAVE_LIBKVM_NLIST */
void module_register (void)
{
plugin_register_init ("tcpconns", conn_init);
#elif HAVE_SYSCTLBYNAME
/* no initialization */
-#elif __OpenBSD__
+#elif HAVE_LIBKVM_NLIST
plugin_register_init ("tcpconns", conn_init);
#endif
plugin_register_read ("tcpconns", conn_read);