X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Ftcpconns.c;h=9fdd16e9c1b30b7d336c18e0b3620c8a587340e4;hb=e746ad785774de37a30302fef65f1c4aaf8698ab;hp=e74e4bc8856d6360472a44d52a7dae93a3586ca2;hpb=9c962b99a3acd77f1d6e2499052b47356819511a;p=collectd.git diff --git a/src/tcpconns.c b/src/tcpconns.c index e74e4bc8..9fdd16e9 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -62,74 +62,91 @@ #include "common.h" #include "plugin.h" -#if defined(__OpenBSD__) || defined(__NetBSD__) +#if defined(__OpenBSD__) +#define HAVE_KVM_GETFILES 1 +#endif + +#if defined(__NetBSD__) #undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */ #endif -#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX -# error "No applicable input method." +#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && \ + !HAVE_LIBKVM_NLIST && !KERNEL_AIX +#error "No applicable input method." #endif #if KERNEL_LINUX -# include -# include +#include +#include #if HAVE_LINUX_INET_DIAG_H -# include +#include #endif -# include +#include /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -# include -# include +#include +#include /* Some includes needed for compiling on FreeBSD */ #include #if HAVE_SYS_TYPES_H -# include +#include #endif #if HAVE_NET_IF_H -# include +#include #endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* #endif HAVE_SYSCTLBYNAME */ -/* This is for OpenBSD and NetBSD. */ +#elif HAVE_KVM_GETFILES +#include +#include +#define _KERNEL /* for DTYPE_SOCKET */ +#include +#undef _KERNEL + +#include + +#include +/* #endif HAVE_KVM_GETFILES */ + +/* This is for NetBSD. */ #elif HAVE_LIBKVM_NLIST -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# if !defined(HAVE_BSD_NLIST_H) || !HAVE_BSD_NLIST_H -# include -# else /* HAVE_BSD_NLIST_H */ -# include -# endif -# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(HAVE_BSD_NLIST_H) || !HAVE_BSD_NLIST_H +#include +#else /* HAVE_BSD_NLIST_H */ +#include +#endif +#include /* #endif HAVE_LIBKVM_NLIST */ #elif KERNEL_AIX -# include -# include +#include +#include #endif /* KERNEL_AIX */ #if KERNEL_LINUX @@ -140,92 +157,72 @@ struct nlreq { }; #endif -static const char *tcp_state[] = -{ - "", /* 0 */ - "ESTABLISHED", - "SYN_SENT", - "SYN_RECV", - "FIN_WAIT1", - "FIN_WAIT2", - "TIME_WAIT", - "CLOSED", - "CLOSE_WAIT", - "LAST_ACK", - "LISTEN", /* 10 */ - "CLOSING" -}; - -# define TCP_STATE_LISTEN 10 -# define TCP_STATE_MIN 1 -# define TCP_STATE_MAX 11 +static const char *tcp_state[] = {"", /* 0 */ + "ESTABLISHED", + "SYN_SENT", + "SYN_RECV", + "FIN_WAIT1", + "FIN_WAIT2", + "TIME_WAIT", + "CLOSED", + "CLOSE_WAIT", + "LAST_ACK", + "LISTEN", /* 10 */ + "CLOSING"}; + +#define TCP_STATE_LISTEN 10 +#define TCP_STATE_MIN 1 +#define TCP_STATE_MAX 11 /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -static const char *tcp_state[] = -{ - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "CLOSE_WAIT", - "FIN_WAIT1", - "CLOSING", - "LAST_ACK", - "FIN_WAIT2", - "TIME_WAIT" -}; - -# define TCP_STATE_LISTEN 1 -# define TCP_STATE_MIN 0 -# define TCP_STATE_MAX 10 +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; + +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 0 +#define TCP_STATE_MAX 10 /* #endif HAVE_SYSCTLBYNAME */ +#elif HAVE_KVM_GETFILES +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; + +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 0 +#define TCP_STATE_MAX 10 + +static kvm_t *kvmd; +/* #endif HAVE_KVM_GETFILES */ + #elif HAVE_LIBKVM_NLIST -static const char *tcp_state[] = -{ - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "CLOSE_WAIT", - "FIN_WAIT1", - "CLOSING", - "LAST_ACK", - "FIN_WAIT2", - "TIME_WAIT" -}; +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; +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 +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 1 +#define TCP_STATE_MAX 10 /* #endif HAVE_LIBKVM_NLIST */ #elif KERNEL_AIX -static const char *tcp_state[] = -{ - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "CLOSE_WAIT", - "FIN_WAIT1", - "CLOSING", - "LAST_ACK", - "FIN_WAIT2", - "TIME_WAIT" -}; +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; -# define TCP_STATE_LISTEN 1 -# define TCP_STATE_MIN 0 -# define TCP_STATE_MAX 10 +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 0 +#define TCP_STATE_MAX 10 struct netinfo_conn { uint32_t unknow1[2]; @@ -245,16 +242,15 @@ struct netinfo_header { unsigned int size; }; -# define NETINFO_TCP 3 -extern int netinfo (int proto, void *data, int *size, int n); +#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_LOCAL 0x01 #define PORT_COLLECT_REMOTE 0x02 -#define PORT_IS_LISTENING 0x04 +#define PORT_IS_LISTENING 0x04 -typedef struct port_entry_s -{ +typedef struct port_entry_s { uint16_t port; uint16_t flags; uint32_t count_local[TCP_STATE_MAX + 1]; @@ -262,14 +258,9 @@ typedef struct port_entry_s struct port_entry_s *next; } port_entry_t; -static const char *config_keys[] = -{ - "ListeningPorts", - "LocalPort", - "RemotePort", - "AllPortsSummary" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"ListeningPorts", "LocalPort", "RemotePort", + "AllPortsSummary"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static int port_collect_listening = 0; static int port_collect_total = 0; @@ -284,151 +275,130 @@ static uint32_t count_total[TCP_STATE_MAX + 1]; static uint32_t sequence_number = 0; #endif -static enum -{ - SRC_DUNNO, - SRC_NETLINK, - SRC_PROC -} linux_source = SRC_DUNNO; +static enum { SRC_DUNNO, SRC_NETLINK, SRC_PROC } linux_source = SRC_DUNNO; #endif -static void conn_prepare_vl (value_list_t *vl, value_t *values) -{ +static void conn_prepare_vl(value_list_t *vl, value_t *values) { vl->values = values; vl->values_len = 1; - sstrncpy (vl->host, hostname_g, sizeof (vl->host)); - sstrncpy (vl->plugin, "tcpconns", sizeof (vl->plugin)); - sstrncpy (vl->type, "tcp_connections", sizeof (vl->type)); + sstrncpy(vl->plugin, "tcpconns", sizeof(vl->plugin)); + sstrncpy(vl->type, "tcp_connections", sizeof(vl->type)); } -static void conn_submit_port_entry (port_entry_t *pe) -{ +static void conn_submit_port_entry(port_entry_t *pe) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - conn_prepare_vl (&vl, values); + conn_prepare_vl(&vl, values); - if (((port_collect_listening != 0) && (pe->flags & PORT_IS_LISTENING)) - || (pe->flags & PORT_COLLECT_LOCAL)) - { - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%"PRIu16"-local", pe->port); + if (((port_collect_listening != 0) && (pe->flags & PORT_IS_LISTENING)) || + (pe->flags & PORT_COLLECT_LOCAL)) { + snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), + "%" PRIu16 "-local", pe->port); - for (int i = 1; i <= TCP_STATE_MAX; i++) - { + for (int i = 1; i <= TCP_STATE_MAX; i++) { vl.values[0].gauge = pe->count_local[i]; - sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, tcp_state[i], sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } } - if (pe->flags & PORT_COLLECT_REMOTE) - { - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%"PRIu16"-remote", pe->port); + if (pe->flags & PORT_COLLECT_REMOTE) { + snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), + "%" PRIu16 "-remote", pe->port); - for (int i = 1; i <= TCP_STATE_MAX; i++) - { + for (int i = 1; i <= TCP_STATE_MAX; i++) { vl.values[0].gauge = pe->count_remote[i]; - sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, tcp_state[i], sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } } } /* void conn_submit */ -static void conn_submit_port_total (void) -{ +static void conn_submit_port_total(void) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - conn_prepare_vl (&vl, values); + conn_prepare_vl(&vl, values); - sstrncpy (vl.plugin_instance, "all", sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, "all", sizeof(vl.plugin_instance)); - for (int i = 1; i <= TCP_STATE_MAX; i++) - { + for (int i = 1; i <= TCP_STATE_MAX; i++) { vl.values[0].gauge = count_total[i]; - sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, tcp_state[i], sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } } -static void conn_submit_all (void) -{ +static void conn_submit_all(void) { if (port_collect_total) - conn_submit_port_total (); + conn_submit_port_total(); for (port_entry_t *pe = port_list_head; pe != NULL; pe = pe->next) - conn_submit_port_entry (pe); + conn_submit_port_entry(pe); } /* void conn_submit_all */ -static port_entry_t *conn_get_port_entry (uint16_t port, int create) -{ +static port_entry_t *conn_get_port_entry(uint16_t port, int create) { port_entry_t *ret; ret = port_list_head; - while (ret != NULL) - { + while (ret != NULL) { if (ret->port == port) break; ret = ret->next; } - if ((ret == NULL) && (create != 0)) - { - ret = calloc (1, sizeof (*ret)); + if ((ret == NULL) && (create != 0)) { + ret = calloc(1, sizeof(*ret)); if (ret == NULL) - return (NULL); + return NULL; ret->port = port; ret->next = port_list_head; port_list_head = ret; } - return (ret); + return ret; } /* port_entry_t *conn_get_port_entry */ /* Removes ports that were added automatically due to the `ListeningPorts' * setting but which are no longer listening. */ -static void conn_reset_port_entry (void) -{ +static void conn_reset_port_entry(void) { port_entry_t *prev = NULL; port_entry_t *pe = port_list_head; - memset (&count_total, '\0', sizeof(count_total)); + memset(&count_total, '\0', sizeof(count_total)); - while (pe != NULL) - { + while (pe != NULL) { /* If this entry was created while reading the files (ant not when handling * the configuration) remove it now. */ - if ((pe->flags & (PORT_COLLECT_LOCAL - | PORT_COLLECT_REMOTE - | PORT_IS_LISTENING)) == 0) - { + if ((pe->flags & + (PORT_COLLECT_LOCAL | PORT_COLLECT_REMOTE | PORT_IS_LISTENING)) == 0) { port_entry_t *next = pe->next; - DEBUG ("tcpconns plugin: Removing temporary entry " - "for listening port %"PRIu16, pe->port); + DEBUG("tcpconns plugin: Removing temporary entry " + "for listening port %" PRIu16, + pe->port); if (prev == NULL) port_list_head = next; else prev->next = next; - sfree (pe); + sfree(pe); pe = next; continue; } - memset (pe->count_local, '\0', sizeof (pe->count_local)); - memset (pe->count_remote, '\0', sizeof (pe->count_remote)); + memset(pe->count_local, '\0', sizeof(pe->count_local)); + memset(pe->count_remote, '\0', sizeof(pe->count_remote)); pe->flags &= ~PORT_IS_LISTENING; prev = pe; @@ -436,50 +406,48 @@ static void conn_reset_port_entry (void) } } /* void conn_reset_port_entry */ -static int conn_handle_ports (uint16_t port_local, uint16_t port_remote, uint8_t state) -{ +static int conn_handle_ports(uint16_t port_local, uint16_t port_remote, + uint8_t state) { port_entry_t *pe = NULL; if ((state > TCP_STATE_MAX) #if TCP_STATE_MIN > 0 || (state < TCP_STATE_MIN) #endif - ) - { - NOTICE ("tcpconns plugin: Ignoring connection with " - "unknown state 0x%02"PRIx8".", state); - return (-1); + ) { + NOTICE("tcpconns plugin: Ignoring connection with " + "unknown state 0x%02" PRIx8 ".", + state); + return -1; } count_total[state]++; /* Listening sockets */ - if ((state == TCP_STATE_LISTEN) && (port_collect_listening != 0)) - { - pe = conn_get_port_entry (port_local, 1 /* create */); + if ((state == TCP_STATE_LISTEN) && (port_collect_listening != 0)) { + pe = conn_get_port_entry(port_local, 1 /* create */); if (pe != NULL) pe->flags |= PORT_IS_LISTENING; } - DEBUG ("tcpconns plugin: Connection %"PRIu16" <-> %"PRIu16" (%s)", - port_local, port_remote, tcp_state[state]); + DEBUG("tcpconns plugin: Connection %" PRIu16 " <-> %" PRIu16 " (%s)", + port_local, port_remote, tcp_state[state]); - pe = conn_get_port_entry (port_local, 0 /* no create */); + pe = conn_get_port_entry(port_local, 0 /* no create */); if (pe != NULL) pe->count_local[state]++; - pe = conn_get_port_entry (port_remote, 0 /* no create */); + pe = conn_get_port_entry(port_remote, 0 /* no create */); if (pe != NULL) pe->count_remote[state]++; - return (0); + return 0; } /* int conn_handle_ports */ #if KERNEL_LINUX /* Returns zero on success, less than zero on socket error and greater than * zero on other errors. */ -static int conn_read_netlink (void) -{ +static int conn_read_netlink(void) { #if HAVE_STRUCT_LINUX_INET_DIAG_REQ int fd; struct inet_diag_msg *r; @@ -488,136 +456,115 @@ static int conn_read_netlink (void) /* If this fails, it's likely a permission problem. We'll fall back to * reading this information from files below. */ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG); - if (fd < 0) - { - ERROR ("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, " - "NETLINK_INET_DIAG) failed: %s", - sstrerror (errno, buf, sizeof (buf))); - return (-1); + if (fd < 0) { + ERROR("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, " + "NETLINK_INET_DIAG) failed: %s", + sstrerror(errno, buf, sizeof(buf))); + return -1; } - struct sockaddr_nl nladdr = { - .nl_family = AF_NETLINK - }; + struct sockaddr_nl nladdr = {.nl_family = AF_NETLINK}; struct nlreq req = { - .nlh.nlmsg_len = sizeof(req), - .nlh.nlmsg_type = TCPDIAG_GETSOCK, - /* NLM_F_ROOT: return the complete table instead of a single entry. - * NLM_F_MATCH: return all entries matching criteria (not implemented) - * NLM_F_REQUEST: must be set on all request messages */ - .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST, - .nlh.nlmsg_pid = 0, - /* The sequence_number is used to track our messages. Since netlink is not - * reliable, we don't want to end up with a corrupt or incomplete old - * message in case the system is/was out of memory. */ - .nlh.nlmsg_seq = ++sequence_number, - .r.idiag_family = AF_INET, - .r.idiag_states = 0xfff, - .r.idiag_ext = 0 - }; - - struct iovec iov = { - .iov_base = &req, - .iov_len = sizeof(req) - }; - - struct msghdr msg = { - .msg_name = (void*)&nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1 - }; - - if (sendmsg (fd, &msg, 0) < 0) - { - ERROR ("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s", - sstrerror (errno, buf, sizeof (buf))); - close (fd); - return (-1); + .nlh.nlmsg_len = sizeof(req), + .nlh.nlmsg_type = TCPDIAG_GETSOCK, + /* NLM_F_ROOT: return the complete table instead of a single entry. + * NLM_F_MATCH: return all entries matching criteria (not implemented) + * NLM_F_REQUEST: must be set on all request messages */ + .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST, + .nlh.nlmsg_pid = 0, + /* The sequence_number is used to track our messages. Since netlink is not + * reliable, we don't want to end up with a corrupt or incomplete old + * message in case the system is/was out of memory. */ + .nlh.nlmsg_seq = ++sequence_number, + .r.idiag_family = AF_INET, + .r.idiag_states = 0xfff, + .r.idiag_ext = 0}; + + struct iovec iov = {.iov_base = &req, .iov_len = sizeof(req)}; + + struct msghdr msg = {.msg_name = (void *)&nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1}; + + if (sendmsg(fd, &msg, 0) < 0) { + ERROR("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s", + sstrerror(errno, buf, sizeof(buf))); + close(fd); + return -1; } iov.iov_base = buf; iov.iov_len = sizeof(buf); - while (1) - { + while (1) { int status; struct nlmsghdr *h; memset(&msg, 0, sizeof(msg)); - msg.msg_name = (void*)&nladdr; + msg.msg_name = (void *)&nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov; msg.msg_iovlen = 1; - status = recvmsg(fd, (void *) &msg, /* flags = */ 0); - if (status < 0) - { + status = recvmsg(fd, (void *)&msg, /* flags = */ 0); + if (status < 0) { if ((errno == EINTR) || (errno == EAGAIN)) continue; - ERROR ("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s", - sstrerror (errno, buf, sizeof (buf))); - close (fd); - return (-1); - } - else if (status == 0) - { - close (fd); - DEBUG ("tcpconns plugin: conn_read_netlink: Unexpected zero-sized " - "reply from netlink socket."); - return (0); + ERROR("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s", + sstrerror(errno, buf, sizeof(buf))); + close(fd); + return -1; + } else if (status == 0) { + close(fd); + DEBUG("tcpconns plugin: conn_read_netlink: Unexpected zero-sized " + "reply from netlink socket."); + return 0; } - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) - { - if (h->nlmsg_seq != sequence_number) - { - h = NLMSG_NEXT(h, status); - continue; + h = (struct nlmsghdr *)buf; + while (NLMSG_OK(h, status)) { + if (h->nlmsg_seq != sequence_number) { + h = NLMSG_NEXT(h, status); + continue; } - if (h->nlmsg_type == NLMSG_DONE) - { - close (fd); - return (0); - } - else if (h->nlmsg_type == NLMSG_ERROR) - { - struct nlmsgerr *msg_error; + if (h->nlmsg_type == NLMSG_DONE) { + close(fd); + return 0; + } else if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *msg_error; - msg_error = NLMSG_DATA(h); - WARNING ("tcpconns plugin: conn_read_netlink: Received error %i.", - msg_error->error); + msg_error = NLMSG_DATA(h); + WARNING("tcpconns plugin: conn_read_netlink: Received error %i.", + msg_error->error); - close (fd); - return (1); + close(fd); + return 1; } r = NLMSG_DATA(h); /* This code does not (need to) distinguish between IPv4 and IPv6. */ - conn_handle_ports (ntohs(r->id.idiag_sport), - ntohs(r->id.idiag_dport), - r->idiag_state); + conn_handle_ports(ntohs(r->id.idiag_sport), ntohs(r->id.idiag_dport), + r->idiag_state); h = NLMSG_NEXT(h, status); } /* while (NLMSG_OK) */ - } /* while (1) */ + } /* while (1) */ /* Not reached because the while() loop above handles the exit condition. */ - return (0); + return 0; #else - return (1); + return 1; #endif /* HAVE_STRUCT_LINUX_INET_DIAG_REQ */ } /* int conn_read_netlink */ -static int conn_handle_line (char *buffer) -{ +static int conn_handle_line(char *buffer) { char *fields[32]; - int fields_len; + int fields_len; char *endptr; @@ -628,65 +575,62 @@ static int conn_handle_line (char *buffer) uint8_t state; - int buffer_len = strlen (buffer); + int buffer_len = strlen(buffer); while ((buffer_len > 0) && (buffer[buffer_len - 1] < 32)) buffer[--buffer_len] = '\0'; if (buffer_len <= 0) - return (-1); + return -1; - fields_len = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (fields_len < 12) - { - DEBUG ("tcpconns plugin: Got %i fields, expected at least 12.", fields_len); - return (-1); + fields_len = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_len < 12) { + DEBUG("tcpconns plugin: Got %i fields, expected at least 12.", fields_len); + return -1; } - port_local_str = strchr (fields[1], ':'); - port_remote_str = strchr (fields[2], ':'); + port_local_str = strchr(fields[1], ':'); + port_remote_str = strchr(fields[2], ':'); if ((port_local_str == NULL) || (port_remote_str == NULL)) - return (-1); + return -1; port_local_str++; port_remote_str++; if ((*port_local_str == '\0') || (*port_remote_str == '\0')) - return (-1); + return -1; endptr = NULL; - port_local = (uint16_t) strtol (port_local_str, &endptr, 16); + port_local = (uint16_t)strtol(port_local_str, &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) - return (-1); + return -1; endptr = NULL; - port_remote = (uint16_t) strtol (port_remote_str, &endptr, 16); + port_remote = (uint16_t)strtol(port_remote_str, &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) - return (-1); + return -1; endptr = NULL; - state = (uint8_t) strtol (fields[3], &endptr, 16); + state = (uint8_t)strtol(fields[3], &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) - return (-1); + return -1; - return (conn_handle_ports (port_local, port_remote, state)); + return conn_handle_ports(port_local, port_remote, state); } /* int conn_handle_line */ -static int conn_read_file (const char *file) -{ +static int conn_read_file(const char *file) { FILE *fh; char buffer[1024]; - fh = fopen (file, "r"); + fh = fopen(file, "r"); if (fh == NULL) - return (-1); + return -1; - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - conn_handle_line (buffer); + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + conn_handle_line(buffer); } /* while (fgets) */ - fclose (fh); + fclose(fh); - return (0); + return 0; } /* int conn_read_file */ /* #endif KERNEL_LINUX */ @@ -696,168 +640,150 @@ static int conn_read_file (const char *file) #elif HAVE_LIBKVM_NLIST #endif /* HAVE_LIBKVM_NLIST */ -static int conn_config (const char *key, const char *value) -{ - if (strcasecmp (key, "ListeningPorts") == 0) - { - if (IS_TRUE (value)) +static int conn_config(const char *key, const char *value) { + if (strcasecmp(key, "ListeningPorts") == 0) { + if (IS_TRUE(value)) port_collect_listening = 1; else port_collect_listening = 0; - } - else if ((strcasecmp (key, "LocalPort") == 0) - || (strcasecmp (key, "RemotePort") == 0)) - { - port_entry_t *pe; - int port = atoi (value); - - if ((port < 1) || (port > 65535)) - { - ERROR ("tcpconns plugin: Invalid port: %i", port); - return (1); - } + } else if ((strcasecmp(key, "LocalPort") == 0) || + (strcasecmp(key, "RemotePort") == 0)) { + port_entry_t *pe; + int port = atoi(value); + + if ((port < 1) || (port > 65535)) { + ERROR("tcpconns plugin: Invalid port: %i", port); + return 1; + } - pe = conn_get_port_entry ((uint16_t) port, 1 /* create */); - if (pe == NULL) - { - ERROR ("tcpconns plugin: conn_get_port_entry failed."); - return (1); - } + pe = conn_get_port_entry((uint16_t)port, 1 /* create */); + if (pe == NULL) { + ERROR("tcpconns plugin: conn_get_port_entry failed."); + return 1; + } - if (strcasecmp (key, "LocalPort") == 0) - pe->flags |= PORT_COLLECT_LOCAL; - else - pe->flags |= PORT_COLLECT_REMOTE; - } - else if (strcasecmp (key, "AllPortsSummary") == 0) - { - if (IS_TRUE (value)) + if (strcasecmp(key, "LocalPort") == 0) + pe->flags |= PORT_COLLECT_LOCAL; + else + pe->flags |= PORT_COLLECT_REMOTE; + } else if (strcasecmp(key, "AllPortsSummary") == 0) { + if (IS_TRUE(value)) port_collect_total = 1; else port_collect_total = 0; - } - else - { - return (-1); + } else { + return -1; } - return (0); + return 0; } /* int conn_config */ #if KERNEL_LINUX -static int conn_init (void) -{ +static int conn_init(void) { if (port_collect_total == 0 && port_list_head == NULL) port_collect_listening = 1; - return (0); + return 0; } /* int conn_init */ -static int conn_read (void) -{ +static int conn_read(void) { int status; - conn_reset_port_entry (); + conn_reset_port_entry(); - if (linux_source == SRC_NETLINK) - { - status = conn_read_netlink (); - } - else if (linux_source == SRC_PROC) - { + if (linux_source == SRC_NETLINK) { + status = conn_read_netlink(); + } else if (linux_source == SRC_PROC) { int errors_num = 0; - if (conn_read_file ("/proc/net/tcp") != 0) + if (conn_read_file("/proc/net/tcp") != 0) errors_num++; - if (conn_read_file ("/proc/net/tcp6") != 0) + if (conn_read_file("/proc/net/tcp6") != 0) errors_num++; if (errors_num < 2) status = 0; else status = ENOENT; - } - else /* if (linux_source == SRC_DUNNO) */ + } else /* if (linux_source == SRC_DUNNO) */ { /* Try to use netlink for getting this data, it is _much_ faster on systems * with a large amount of connections. */ - status = conn_read_netlink (); - if (status == 0) - { - INFO ("tcpconns plugin: Reading from netlink succeeded. " - "Will use the netlink method from now on."); + status = conn_read_netlink(); + if (status == 0) { + INFO("tcpconns plugin: Reading from netlink succeeded. " + "Will use the netlink method from now on."); linux_source = SRC_NETLINK; - } - else - { - INFO ("tcpconns plugin: Reading from netlink failed. " - "Will read from /proc from now on."); + } else { + INFO("tcpconns plugin: Reading from netlink failed. " + "Will read from /proc from now on."); linux_source = SRC_PROC; /* return success here to avoid the "plugin failed" message. */ - return (0); + return 0; } } if (status == 0) - conn_submit_all (); + conn_submit_all(); else - return (status); + return status; - return (0); + return 0; } /* int conn_read */ /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -static int conn_read (void) -{ +static int conn_read(void) { int status; char *buffer; - size_t buffer_len;; + size_t buffer_len; + ; struct xinpgen *in_orig; struct xinpgen *in_ptr; - conn_reset_port_entry (); + conn_reset_port_entry(); buffer_len = 0; - status = sysctlbyname ("net.inet.tcp.pcblist", NULL, &buffer_len, 0, 0); - if (status < 0) - { - ERROR ("tcpconns plugin: sysctlbyname failed."); - return (-1); + status = sysctlbyname("net.inet.tcp.pcblist", NULL, &buffer_len, 0, 0); + if (status < 0) { + ERROR("tcpconns plugin: sysctlbyname failed."); + return -1; } - buffer = malloc (buffer_len); - if (buffer == NULL) - { - ERROR ("tcpconns plugin: malloc failed."); - return (-1); + buffer = malloc(buffer_len); + if (buffer == NULL) { + ERROR("tcpconns plugin: malloc failed."); + return -1; } - status = sysctlbyname ("net.inet.tcp.pcblist", buffer, &buffer_len, 0, 0); - if (status < 0) - { - ERROR ("tcpconns plugin: sysctlbyname failed."); - sfree (buffer); - return (-1); + status = sysctlbyname("net.inet.tcp.pcblist", buffer, &buffer_len, 0, 0); + if (status < 0) { + ERROR("tcpconns plugin: sysctlbyname failed."); + sfree(buffer); + return -1; } - if (buffer_len <= sizeof (struct xinpgen)) - { - ERROR ("tcpconns plugin: (buffer_len <= sizeof (struct xinpgen))"); - sfree (buffer); - return (-1); + if (buffer_len <= sizeof(struct xinpgen)) { + ERROR("tcpconns plugin: (buffer_len <= sizeof (struct xinpgen))"); + sfree(buffer); + return -1; } - in_orig = (struct xinpgen *) buffer; - for (in_ptr = (struct xinpgen *) (((char *) in_orig) + in_orig->xig_len); - in_ptr->xig_len > sizeof (struct xinpgen); - in_ptr = (struct xinpgen *) (((char *) in_ptr) + in_ptr->xig_len)) - { - struct tcpcb *tp = &((struct xtcpcb *) in_ptr)->xt_tp; - struct inpcb *inp = &((struct xtcpcb *) in_ptr)->xt_inp; - struct xsocket *so = &((struct xtcpcb *) in_ptr)->xt_socket; + in_orig = (struct xinpgen *)buffer; + for (in_ptr = (struct xinpgen *)(((char *)in_orig) + in_orig->xig_len); + in_ptr->xig_len > sizeof(struct xinpgen); + in_ptr = (struct xinpgen *)(((char *)in_ptr) + in_ptr->xig_len)) { +#if __FreeBSD_version >= 1200026 + struct xtcpcb *tp = (struct xtcpcb *)in_ptr; + struct xinpcb *inp = &tp->xt_inp; + struct xsocket *so = &inp->xi_socket; +#else + struct tcpcb *tp = &((struct xtcpcb *)in_ptr)->xt_tp; + struct inpcb *inp = &((struct xtcpcb *)in_ptr)->xt_inp; + struct xsocket *so = &((struct xtcpcb *)in_ptr)->xt_socket; +#endif /* Ignore non-TCP sockets */ if (so->xso_protocol != IPPROTO_TCP) @@ -867,81 +793,114 @@ static int conn_read (void) if (inp->inp_gencnt > in_orig->xig_gen) continue; - if (((inp->inp_vflag & INP_IPV4) == 0) - && ((inp->inp_vflag & INP_IPV6) == 0)) + if (((inp->inp_vflag & INP_IPV4) == 0) && + ((inp->inp_vflag & INP_IPV6) == 0)) continue; - conn_handle_ports (ntohs (inp->inp_lport), ntohs (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; in_ptr = NULL; - sfree (buffer); + sfree(buffer); - conn_submit_all (); + conn_submit_all(); - return (0); + return 0; } /* int conn_read */ -/* #endif HAVE_SYSCTLBYNAME */ + /* #endif HAVE_SYSCTLBYNAME */ + +#elif HAVE_KVM_GETFILES + +static int conn_init(void) { + char buf[_POSIX2_LINE_MAX]; + + kvmd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf); + if (kvmd == NULL) { + ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf); + return -1; + } + + return 0; +} /* int conn_init */ + +static int conn_read(void) { + struct kinfo_file *kf; + int i, fcnt; + + conn_reset_port_entry(); + + kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET, sizeof(*kf), &fcnt); + if (kf == NULL) { + ERROR("tcpconns plugin: kvm_getfiles failed."); + return -1; + } + + for (i = 0; i < fcnt; i++) { + if (kf[i].so_protocol != IPPROTO_TCP) + continue; + if (kf[i].inp_fport == 0) + continue; + conn_handle_ports(ntohs(kf[i].inp_lport), ntohs(kf[i].inp_fport), + kf[i].t_state); + } + + conn_submit_all(); + + return 0; +} +/* int conn_read */ +/* #endif HAVE_KVM_GETFILES */ #elif HAVE_LIBKVM_NLIST -static int kread (u_long addr, void *buf, int size) -{ +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); + 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); + return 0; } /* int kread */ -static int conn_init (void) -{ +static int conn_init(void) { char buf[_POSIX2_LINE_MAX]; - struct nlist nl[] = - { + struct nlist nl[] = { #define N_TCBTABLE 0 - { "_tcbtable" }, - { "" } - }; + {"_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); + 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); + 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); + 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; + inpcbtable_off = (u_long)nl[N_TCBTABLE].n_value; + inpcbtable_ptr = (struct inpcbtable *)nl[N_TCBTABLE].n_value; - return (0); + return 0; } /* int conn_init */ -static int conn_read (void) -{ +static int conn_read(void) { struct inpcbtable table; -#if !defined(__OpenBSD__) && (defined(__NetBSD_Version__) && __NetBSD_Version__ <= 699002700) +#if !defined(__OpenBSD__) && \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ <= 699002700) struct inpcb *head; #endif struct inpcb *next; @@ -949,140 +908,131 @@ static int conn_read (void) struct tcpcb tcpcb; int status; - conn_reset_port_entry (); + conn_reset_port_entry(); /* Read the pcbtable from the kernel */ - status = kread (inpcbtable_off, &table, sizeof (table)); + status = kread(inpcbtable_off, &table, sizeof(table)); if (status != 0) - return (-1); + return -1; -#if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) +#if defined(__OpenBSD__) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) /* inpt_queue is a TAILQ on OpenBSD */ /* Get the first pcb */ - next = (struct inpcb *)TAILQ_FIRST (&table.inpt_queue); + next = (struct inpcb *)TAILQ_FIRST(&table.inpt_queue); while (next) #else /* Get the `head' pcb */ - head = (struct inpcb *) &(inpcbtable_ptr->inpt_queue); + head = (struct inpcb *)&(inpcbtable_ptr->inpt_queue); /* Get the first pcb */ - next = (struct inpcb *)CIRCLEQ_FIRST (&table.inpt_queue); + next = (struct inpcb *)CIRCLEQ_FIRST(&table.inpt_queue); while (next != head) #endif { /* Read the pcb pointed to by `next' into `inpcb' */ - status = kread ((u_long) next, &inpcb, sizeof (inpcb)); + status = kread((u_long)next, &inpcb, sizeof(inpcb)); if (status != 0) - return (-1); + return -1; - /* Advance `next' */ -#if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) +/* Advance `next' */ +#if defined(__OpenBSD__) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) /* inpt_queue is a TAILQ on OpenBSD */ - next = (struct inpcb *)TAILQ_NEXT (&inpcb, inp_queue); + next = (struct inpcb *)TAILQ_NEXT(&inpcb, inp_queue); #else - next = (struct inpcb *)CIRCLEQ_NEXT (&inpcb, inp_queue); + next = (struct inpcb *)CIRCLEQ_NEXT(&inpcb, inp_queue); #endif - /* Ignore sockets, that are not connected. */ +/* 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)) + 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)) + if ((inpcb.inp_flags & INP_IPV6) && + IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_laddr6)) continue; #endif - status = kread ((u_long) inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); + status = kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof(tcpcb)); if (status != 0) - return (-1); - conn_handle_ports (ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), tcpcb.t_state); + return -1; + conn_handle_ports(ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), + tcpcb.t_state); } /* while (next != head) */ - conn_submit_all (); + conn_submit_all(); - return (0); + return 0; } /* #endif HAVE_LIBKVM_NLIST */ #elif KERNEL_AIX -static int conn_read (void) -{ +static int conn_read(void) { int size; int nconn; void *data; struct netinfo_header *header; struct netinfo_conn *conn; - conn_reset_port_entry (); + conn_reset_port_entry(); size = netinfo(NETINFO_TCP, 0, 0, 0); - if (size < 0) - { - ERROR ("tcpconns plugin: netinfo failed return: %i", size); - return (-1); + if (size < 0) { + ERROR("tcpconns plugin: netinfo failed return: %i", size); + return -1; } if (size == 0) - return (0); + return 0; - if ((size - sizeof (struct netinfo_header)) % sizeof (struct netinfo_conn)) - { - ERROR ("tcpconns plugin: invalid buffer size"); - return (-1); + 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 (data == NULL) { + ERROR("tcpconns plugin: malloc failed"); + return -1; } - if (netinfo(NETINFO_TCP, data, &size, 0) < 0) - { - ERROR ("tcpconns plugin: netinfo failed"); + if (netinfo(NETINFO_TCP, data, &size, 0) < 0) { + ERROR("tcpconns plugin: netinfo failed"); free(data); - return (-1); + return -1; } header = (struct netinfo_header *)data; nconn = header->size; conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header)); - for (int i = 0; i < nconn; conn++, i++) - { - conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state); + for (int i = 0; i < nconn; conn++, i++) { + conn_handle_ports(conn->srcport, conn->dstport, conn->tcp_state); } free(data); - conn_submit_all (); + conn_submit_all(); - return (0); + return 0; } #endif /* KERNEL_AIX */ -void module_register (void) -{ - plugin_register_config ("tcpconns", conn_config, - config_keys, config_keys_num); +void module_register(void) { + plugin_register_config("tcpconns", conn_config, config_keys, config_keys_num); #if KERNEL_LINUX - plugin_register_init ("tcpconns", conn_init); + plugin_register_init("tcpconns", conn_init); #elif HAVE_SYSCTLBYNAME - /* no initialization */ + /* no initialization */ #elif HAVE_LIBKVM_NLIST - plugin_register_init ("tcpconns", conn_init); + plugin_register_init("tcpconns", conn_init); #elif KERNEL_AIX - /* no initialization */ +/* no initialization */ #endif - plugin_register_read ("tcpconns", conn_read); + plugin_register_read("tcpconns", conn_read); } /* void module_register */ - -/* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker : - */