X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Ftcpconns.c;h=6a7e32d72007e216ff739bd491e6e34a6abefe11;hb=a49ed2ad7f046517f1e48b417a71ac2005362d2f;hp=4db6f8ac4ba73e5f75354ab5ebea076b2f65e490;hpb=c01301e8a69b8d53b06b522b107c97dcb65093ad;p=collectd.git diff --git a/src/tcpconns.c b/src/tcpconns.c index 4db6f8ac..6a7e32d7 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -61,7 +61,11 @@ #include "common.h" #include "plugin.h" -#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST +#if defined(__OpenBSD__) || 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." #endif @@ -97,7 +101,7 @@ # include /* #endif HAVE_SYSCTLBYNAME */ -/* This is for OpenBSD and possibly NetBSD. */ +/* This is for OpenBSD and NetBSD. */ #elif HAVE_LIBKVM_NLIST # include # include @@ -105,6 +109,7 @@ # include # include # include +# include # include # include # include @@ -113,7 +118,12 @@ # include # include # include -#endif /* HAVE_LIBKVM_NLIST */ +/* #endif HAVE_LIBKVM_NLIST */ + +#elif KERNEL_AIX +# include +# include +#endif /* KERNEL_AIX */ #if KERNEL_LINUX static const char *tcp_state[] = @@ -181,7 +191,49 @@ struct inpcbtable *inpcbtable_ptr = NULL; # define TCP_STATE_LISTEN 1 # define TCP_STATE_MIN 1 # define TCP_STATE_MAX 10 -#endif /* HAVE_LIBKVM_NLIST */ +/* #endif HAVE_LIBKVM_NLIST */ + +#elif KERNEL_AIX +static const char *tcp_state[] = +{ + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "CLOSE_WAIT", + "FIN_WAIT_1", + "CLOSING", + "LAST_ACK", + "FIN_WAIT_2", + "TIME_WAIT" +}; + +# define TCP_STATE_LISTEN 1 +# define TCP_STATE_MIN 0 +# define TCP_STATE_MAX 10 + +struct netinfo_conn { + uint32_t unknow1[2]; + uint16_t dstport; + uint16_t unknow2; + struct in6_addr dstaddr; + uint16_t srcport; + uint16_t unknow3; + struct in6_addr srcaddr; + uint32_t unknow4[36]; + uint16_t tcp_state; + uint16_t unknow5[7]; +}; + +struct netinfo_header { + unsigned int proto; + unsigned int size; +}; + +# 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_REMOTE 0x02 @@ -449,9 +501,7 @@ static int conn_config (const char *key, const char *value) { if (strcasecmp (key, "ListeningPorts") == 0) { - if ((strcasecmp (value, "Yes") == 0) - || (strcasecmp (value, "True") == 0) - || (strcasecmp (value, "On") == 0)) + if (IS_TRUE (value)) port_collect_listening = 1; else port_collect_listening = 0; @@ -672,7 +722,7 @@ static int conn_read (void) /* 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) { @@ -680,15 +730,20 @@ static int conn_read (void) 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); @@ -698,7 +753,67 @@ static int conn_read (void) return (0); } -#endif /* HAVE_LIBKVM_NLIST */ +/* #endif HAVE_LIBKVM_NLIST */ + +#elif KERNEL_AIX + +static int conn_read (void) +{ + int size; + int i; + int nconn; + void *data; + struct netinfo_header *header; + struct netinfo_conn *conn; + + 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) + return (0); + + 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 (netinfo(NETINFO_TCP, data, &size, 0) < 0) + { + ERROR ("tcpconns plugin: netinfo failed"); + free(data); + return (-1); + } + + header = (struct netinfo_header *)data; + nconn = header->size; + conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header)); + + for (i=0; i < nconn; conn++, i++) + { + conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state); + } + + free(data); + + conn_submit_all (); + + return (0); +} +#endif /* KERNEL_AIX */ void module_register (void) { @@ -710,6 +825,8 @@ void module_register (void) /* no initialization */ #elif HAVE_LIBKVM_NLIST plugin_register_init ("tcpconns", conn_init); +#elif KERNEL_AIX + /* no initialization */ #endif plugin_register_read ("tcpconns", conn_read); } /* void module_register */