X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Ftcpconns.c;h=da916950e301c5a705fdfe5c18c80b48b336d4a3;hb=610204218564e01513607a0f077c33145f2b41f7;hp=0236c9d0fc6dbbf6ede8da7fcfa90709e65f3ac9;hpb=102e4f4ff7e99650b5624a7af1ba3885975a0b8c;p=collectd.git diff --git a/src/tcpconns.c b/src/tcpconns.c index 0236c9d0..da916950 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -71,13 +71,10 @@ #if KERNEL_LINUX # include -/* sys/socket.h is necessary to compile when using netlink on older systems. */ -# include # include #if HAVE_LINUX_INET_DIAG_H # include #endif -# include # include /* #endif KERNEL_LINUX */ @@ -90,9 +87,6 @@ #if HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NET_IF_H # include #endif @@ -113,7 +107,6 @@ /* This is for OpenBSD and NetBSD. */ #elif HAVE_LIBKVM_NLIST # include -# include # include # include # include @@ -290,7 +283,7 @@ static uint32_t count_total[TCP_STATE_MAX + 1]; static uint32_t sequence_number = 0; #endif -enum +static enum { SRC_DUNNO, SRC_NETLINK, @@ -392,10 +385,9 @@ static port_entry_t *conn_get_port_entry (uint16_t port, int create) if ((ret == NULL) && (create != 0)) { - ret = (port_entry_t *) malloc (sizeof (port_entry_t)); + ret = calloc (1, sizeof (*ret)); if (ret == NULL) return (NULL); - memset (ret, '\0', sizeof (port_entry_t)); ret->port = port; ret->next = port_list_head; @@ -419,18 +411,18 @@ static void conn_reset_port_entry (void) /* 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) + | 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); + "for listening port %"PRIu16, pe->port); if (prev == NULL) - port_list_head = next; + port_list_head = next; else - prev->next = next; + prev->next = next; sfree (pe); pe = next; @@ -442,6 +434,7 @@ static void conn_reset_port_entry (void) memset (pe->count_remote, '\0', sizeof (pe->count_remote)); pe->flags &= ~PORT_IS_LISTENING; + prev = pe; pe = pe->next; } } /* void conn_reset_port_entry */ @@ -492,10 +485,6 @@ static int conn_read_netlink (void) { #if HAVE_STRUCT_LINUX_INET_DIAG_REQ int fd; - struct sockaddr_nl nladdr; - struct nlreq req; - struct msghdr msg; - struct iovec iov; struct inet_diag_msg *r; char buf[8192]; @@ -510,34 +499,38 @@ static int conn_read_netlink (void) return (-1); } - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - - memset(&req, 0, sizeof(req)); - req.nlh.nlmsg_len = sizeof(req); - 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 */ - req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; - req.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. */ - req.nlh.nlmsg_seq = ++sequence_number; - req.r.idiag_family = AF_INET; - req.r.idiag_states = 0xfff; - req.r.idiag_ext = 0; - - memset(&iov, 0, sizeof(iov)); - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - memset(&msg, 0, sizeof(msg)); - msg.msg_name = (void*)&nladdr; - msg.msg_namelen = sizeof(nladdr); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; + 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) { @@ -838,7 +831,7 @@ static int conn_read (void) return (-1); } - buffer = (char *) malloc (buffer_len); + buffer = malloc (buffer_len); if (buffer == NULL) { ERROR ("tcpconns plugin: malloc failed."); @@ -981,7 +974,9 @@ static int conn_read (void) #endif { /* Read the pcb pointed to by `next' into `inpcb' */ - kread ((u_long) next, &inpcb, sizeof (inpcb)); + status = kread ((u_long) next, &inpcb, sizeof (inpcb)); + if (status != 0) + return (-1); /* Advance `next' */ #if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) @@ -1004,7 +999,9 @@ static int conn_read (void) continue; #endif - 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); } /* while (next != head) */