From: Florian Forster Date: Tue, 19 Aug 2008 07:35:07 +0000 (+0200) Subject: Merge branch 'ms/tcpconns' X-Git-Tag: collectd-4.5.0~76 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=5db1547c947a42577709f74fe3324bf2d00ea87c;hp=31604b175ea62f9af1b0e36a1f32a77ba0712808;p=collectd.git Merge branch 'ms/tcpconns' --- diff --git a/AUTHORS b/AUTHORS index 7f92d55c..ff3dce30 100644 --- a/AUTHORS +++ b/AUTHORS @@ -47,6 +47,9 @@ tape plugin by: teamspeak2 plugin by: Stefan Hacker +tcpconns plugin: + Michael Stapelberg (OpenBSD port) + users plugin by: Sebastian Harl diff --git a/configure.in b/configure.in index 02e06fe6..dc3e4ede 100644 --- a/configure.in +++ b/configure.in @@ -45,6 +45,9 @@ case $host_os in *darwin*) ac_system="Darwin" ;; + *openbsd*) + ac_system="OpenBSD" + ;; *) ac_system="unknown" esac @@ -2529,6 +2532,11 @@ then fi fi +if test "x$ac_system" = "xOpenBSD" +then + plugin_tcpconns="yes" +fi + # Mac OS X devices if test "x$with_libiokit" = "xyes" then diff --git a/src/Makefile.am b/src/Makefile.am index 789f7f8a..25d30473 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -683,8 +683,12 @@ if BUILD_PLUGIN_TCPCONNS pkglib_LTLIBRARIES += tcpconns.la tcpconns_la_SOURCES = tcpconns.c tcpconns_la_LDFLAGS = -module -avoid-version +tcpconns_la_LIBADD = collectd_LDADD += "-dlopen" tcpconns.la collectd_DEPENDENCIES += tcpconns.la +if BUILD_WITH_LIBKVM +tcpconns_la_LIBADD += -lkvm +endif endif if BUILD_PLUGIN_TEAMSPEAK2 diff --git a/src/tcpconns.c b/src/tcpconns.c index fac6a18a..d53cb5aa 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -19,11 +19,46 @@ * Florian octo Forster **/ +/** + * Code within `__OpenBSD__' 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 $ + * $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ + * + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + #include "collectd.h" #include "common.h" #include "plugin.h" -#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME +#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !__OpenBSD__ # error "No applicable input method." #endif @@ -57,7 +92,24 @@ # include # include # include -#endif /* HAVE_SYSCTLBYNAME */ +/* #endif HAVE_SYSCTLBYNAME */ + +#elif __OpenBSD__ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif /* __OpenBSD__ */ #if KERNEL_LINUX static const char *tcp_state[] = @@ -100,7 +152,32 @@ static const char *tcp_state[] = # define TCP_STATE_LISTEN 1 # define TCP_STATE_MIN 0 # define TCP_STATE_MAX 10 -#endif /* HAVE_SYSCTLBYNAME */ +/* #endif HAVE_SYSCTLBYNAME */ + +#elif __OpenBSD__ +static const char *tcp_state[] = +{ + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RECV", + "ESTABLISHED", + "CLOSE_WAIT", + "FIN_WAIT1", + "CLOSING", + "LAST_ACK", + "FIN_WAIT2", + "TIME_WAIT" +}; + +static kvm_t *kvmd; +static u_long inpcbtable_off = 0; +struct inpcbtable *inpcbtable_ptr = NULL; + +# define TCP_STATE_LISTEN 1 +# define TCP_STATE_MIN 1 +# define TCP_STATE_MAX 10 +#endif /* __OpenBSD__ */ #define PORT_COLLECT_LOCAL 0x01 #define PORT_COLLECT_REMOTE 0x02 @@ -360,7 +437,10 @@ static int conn_read_file (const char *file) /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -#endif /* HAVE_SYSCTLBYNAME */ +/* #endif HAVE_SYSCTLBYNAME */ + +#elif __OpenBSD__ +#endif /* __OpenBSD__ */ static int conn_config (const char *key, const char *value) { @@ -514,7 +594,107 @@ static int conn_read (void) return (0); } /* int conn_read */ -#endif /* HAVE_SYSCTLBYNAME */ +/* #endif HAVE_SYSCTLBYNAME */ + +#elif __OpenBSD__ +static int kread (u_long addr, void *buf, int size) +{ + int status; + + status = kvm_read (kvmd, addr, buf, size); + if (status != size) + { + ERROR ("tcpconns plugin: kvm_read failed (got %i, expected %i): %s\n", + status, size, kvm_geterr (kvmd)); + return (-1); + } + return (0); +} /* int kread */ + +static int conn_init (void) +{ + char buf[_POSIX2_LINE_MAX]; + struct nlist nl[] = + { +#define N_TCBTABLE 0 + { "_tcbtable" }, + { "" } + }; + int status; + + kvmd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, buf); + if (kvmd == NULL) + { + ERROR ("tcpconns plugin: kvm_openfiles failed: %s", buf); + return (-1); + } + + status = kvm_nlist (kvmd, nl); + if (status < 0) + { + ERROR ("tcpconns plugin: kvm_nlist failed with status %i.", status); + return (-1); + } + + if (nl[N_TCBTABLE].n_type == 0) + { + ERROR ("tcpconns plugin: Error looking up kernel's namelist: " + "N_TCBTABLE is invalid."); + return (-1); + } + + inpcbtable_off = (u_long) nl[N_TCBTABLE].n_value; + inpcbtable_ptr = (struct inpcbtable *) nl[N_TCBTABLE].n_value; + + return (0); +} /* int conn_init */ + +static int conn_read (void) +{ + struct inpcbtable table; + struct inpcb *head; + struct inpcb *next; + struct inpcb inpcb; + struct tcpcb tcpcb; + int status; + + conn_reset_port_entry (); + + /* Read the pcbtable from the kernel */ + status = kread (inpcbtable_off, &table, sizeof (table)); + if (status != 0) + return (-1); + + /* Get the `head' pcb */ + head = (struct inpcb *) &(inpcbtable_ptr->inpt_queue); + /* Get the first pcb */ + next = CIRCLEQ_FIRST (&table.inpt_queue); + + while (next != head) + { + /* Read the pcb pointed to by `next' into `inpcb' */ + kread ((u_long) next, &inpcb, sizeof (inpcb)); + + /* Advance `next' */ + next = CIRCLEQ_NEXT (&inpcb, inp_queue); + + /* Ignore sockets, that are not connected. */ + 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; + + kread ((u_long) inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); + conn_handle_ports (ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), tcpcb.t_state); + } /* while (next != head) */ + + conn_submit_all (); + + return (0); +} +#endif /* __OpenBSD__ */ void module_register (void) { @@ -522,10 +702,14 @@ void module_register (void) config_keys, config_keys_num); #if KERNEL_LINUX plugin_register_init ("tcpconns", conn_init); +#elif HAVE_SYSCTLBYNAME + /* no initialization */ +#elif __OpenBSD__ + plugin_register_init ("tcpconns", conn_init); #endif plugin_register_read ("tcpconns", conn_read); } /* void module_register */ /* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 : + * vim: set shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker : */