From: Ruben Kerkhof Date: Sun, 2 Jul 2017 18:52:18 +0000 (+0200) Subject: Merge branch 'collectd-5.7' X-Git-Tag: collectd-5.8.0~129 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=867ad628dc6fcd05bd584b605d7093cfc00c3d07;hp=-c Merge branch 'collectd-5.7' --- 867ad628dc6fcd05bd584b605d7093cfc00c3d07 diff --combined src/tcpconns.c index 419d8c19,7036d08b..f12ce5c6 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@@ -62,15 -62,11 +62,15 @@@ #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 +#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && !HAVE_LIBKVM_NLIST && !KERNEL_AIX #error "No applicable input method." #endif @@@ -109,27 -105,15 +109,27 @@@ #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 @@@ -185,19 -169,6 +185,19 @@@ static const char *tcp_state[] = {"CLOS #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", @@@ -356,14 -327,14 +356,14 @@@ static port_entry_t *conn_get_port_entr 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' @@@ -417,7 -388,7 +417,7 @@@ static int conn_handle_ports(uint16_t p NOTICE("tcpconns plugin: Ignoring connection with " "unknown state 0x%02" PRIx8 ".", state); - return (-1); + return -1; } count_total[state]++; @@@ -440,7 -411,7 +440,7 @@@ if (pe != NULL) pe->count_remote[state]++; - return (0); + return 0; } /* int conn_handle_ports */ #if KERNEL_LINUX @@@ -459,7 -430,7 +459,7 @@@ static int conn_read_netlink(void) ERROR("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, " "NETLINK_INET_DIAG) failed: %s", sstrerror(errno, buf, sizeof(buf))); - return (-1); + return -1; } struct sockaddr_nl nladdr = {.nl_family = AF_NETLINK}; @@@ -491,7 -462,7 +491,7 @@@ ERROR("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s", sstrerror(errno, buf, sizeof(buf))); close(fd); - return (-1); + return -1; } iov.iov_base = buf; @@@ -515,12 -486,12 +515,12 @@@ ERROR("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s", sstrerror(errno, buf, sizeof(buf))); close(fd); - return (-1); + return -1; } else if (status == 0) { close(fd); DEBUG("tcpconns plugin: conn_read_netlink: Unexpected zero-sized " "reply from netlink socket."); - return (0); + return 0; } h = (struct nlmsghdr *)buf; @@@ -532,7 -503,7 +532,7 @@@ if (h->nlmsg_type == NLMSG_DONE) { close(fd); - return (0); + return 0; } else if (h->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *msg_error; @@@ -541,7 -512,7 +541,7 @@@ msg_error->error); close(fd); - return (1); + return 1; } r = NLMSG_DATA(h); @@@ -555,9 -526,9 +555,9 @@@ } /* 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 */ @@@ -579,40 -550,40 +579,40 @@@ static int conn_handle_line(char *buffe 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); + return -1; } 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); if ((endptr == NULL) || (*endptr != '\0')) - return (-1); + return -1; endptr = NULL; 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); 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) { @@@ -621,7 -592,7 +621,7 @@@ fh = fopen(file, "r"); if (fh == NULL) - return (-1); + return -1; while (fgets(buffer, sizeof(buffer), fh) != NULL) { conn_handle_line(buffer); @@@ -629,7 -600,7 +629,7 @@@ fclose(fh); - return (0); + return 0; } /* int conn_read_file */ /* #endif KERNEL_LINUX */ @@@ -652,13 -623,13 +652,13 @@@ static int conn_config(const char *key if ((port < 1) || (port > 65535)) { ERROR("tcpconns plugin: Invalid port: %i", port); - return (1); + 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); + return 1; } if (strcasecmp(key, "LocalPort") == 0) @@@ -671,10 -642,10 +671,10 @@@ else port_collect_total = 0; } else { - return (-1); + return -1; } - return (0); + return 0; } /* int conn_config */ #if KERNEL_LINUX @@@ -682,7 -653,7 +682,7 @@@ 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) { @@@ -719,16 -690,16 +719,16 @@@ linux_source = SRC_PROC; /* return success here to avoid the "plugin failed" message. */ - return (0); + return 0; } } if (status == 0) conn_submit_all(); else - return (status); + return status; - return (0); + return 0; } /* int conn_read */ /* #endif KERNEL_LINUX */ @@@ -748,35 -719,41 +748,41 @@@ static int conn_read(void) status = sysctlbyname("net.inet.tcp.pcblist", NULL, &buffer_len, 0, 0); if (status < 0) { ERROR("tcpconns plugin: sysctlbyname failed."); - return (-1); + return -1; } buffer = malloc(buffer_len); if (buffer == NULL) { ERROR("tcpconns plugin: malloc failed."); - return (-1); + 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); + return -1; } if (buffer_len <= sizeof(struct xinpgen)) { ERROR("tcpconns plugin: (buffer_len <= sizeof (struct xinpgen))"); sfree(buffer); - return (-1); + 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)) { + #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) @@@ -800,53 -777,10 +806,53 @@@ conn_submit_all(); - return (0); + return 0; } /* int conn_read */ /* #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) { int status; @@@ -855,9 -789,9 +861,9 @@@ if (status != size) { ERROR("tcpconns plugin: kvm_read failed (got %i, expected %i): %s\n", status, size, kvm_geterr(kvmd)); - return (-1); + return -1; } - return (0); + return 0; } /* int kread */ static int conn_init(void) { @@@ -870,25 -804,25 +876,25 @@@ kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf); if (kvmd == NULL) { ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf); - return (-1); + return -1; } status = kvm_nlist(kvmd, nl); if (status < 0) { ERROR("tcpconns plugin: kvm_nlist failed with status %i.", status); - return (-1); + return -1; } if (nl[N_TCBTABLE].n_type == 0) { ERROR("tcpconns plugin: Error looking up kernel's namelist: " "N_TCBTABLE is invalid."); - return (-1); + return -1; } 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) { @@@ -907,7 -841,7 +913,7 @@@ /* Read the pcbtable from the kernel */ status = kread(inpcbtable_off, &table, sizeof(table)); if (status != 0) - return (-1); + return -1; #if defined(__OpenBSD__) || \ (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) @@@ -927,7 -861,7 +933,7 @@@ /* Read the pcb pointed to by `next' into `inpcb' */ status = kread((u_long)next, &inpcb, sizeof(inpcb)); if (status != 0) - return (-1); + return -1; /* Advance `next' */ #if defined(__OpenBSD__) || \ @@@ -953,14 -887,14 +959,14 @@@ status = kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof(tcpcb)); if (status != 0) - return (-1); + return -1; conn_handle_ports(ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), tcpcb.t_state); } /* while (next != head) */ conn_submit_all(); - return (0); + return 0; } /* #endif HAVE_LIBKVM_NLIST */ @@@ -978,27 -912,27 +984,27 @@@ static int conn_read(void) size = netinfo(NETINFO_TCP, 0, 0, 0); if (size < 0) { ERROR("tcpconns plugin: netinfo failed return: %i", size); - return (-1); + 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); + return -1; } data = malloc(size); if (data == NULL) { ERROR("tcpconns plugin: malloc failed"); - return (-1); + return -1; } if (netinfo(NETINFO_TCP, data, &size, 0) < 0) { ERROR("tcpconns plugin: netinfo failed"); free(data); - return (-1); + return -1; } header = (struct netinfo_header *)data; @@@ -1013,7 -947,7 +1019,7 @@@ conn_submit_all(); - return (0); + return 0; } #endif /* KERNEL_AIX */ @@@ -1030,3 -964,7 +1036,3 @@@ void module_register(void) #endif plugin_register_read("tcpconns", conn_read); } /* void module_register */ - -/* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker : - */