iptables: include libiptc headers before capability.h
[collectd.git] / src / dns.c
index aea41c4..be6d0dc 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
  *   Mirko Buffoni <briareos at eswat.org>
  **/
 
+#define _DEFAULT_SOURCE
 #define _BSD_SOURCE
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "configfile.h"
 
 #include "utils_dns.h"
-#include <pthread.h>
 #include <poll.h>
 
 #include <pcap.h>
-#include <pcap-bpf.h>
+
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
 
 /*
  * Private data types
@@ -94,11 +98,10 @@ static counter_list_t *counter_list_create (counter_list_t **list,
 {
        counter_list_t *entry;
 
-       entry = (counter_list_t *) malloc (sizeof (counter_list_t));
+       entry = calloc (1, sizeof (*entry));
        if (entry == NULL)
                return (NULL);
 
-       memset (entry, 0, sizeof (counter_list_t));
        entry->key = key;
        entry->value = value;
 
@@ -212,7 +215,7 @@ static int dns_run_pcap_loop (void)
 {
        pcap_t *pcap_obj;
        char    pcap_error[PCAP_ERRBUF_SIZE];
-       struct  bpf_program fp;
+       struct  bpf_program fp = { 0 };
 
        int status;
 
@@ -239,7 +242,6 @@ static int dns_run_pcap_loop (void)
                return (PCAP_ERROR);
        }
 
-       memset (&fp, 0, sizeof (fp));
        status = pcap_compile (pcap_obj, &fp, "udp port 53", 1, 0);
        if (status < 0)
        {
@@ -275,12 +277,47 @@ static int dns_run_pcap_loop (void)
        return (status);
 } /* int dns_run_pcap_loop */
 
+static int dns_sleep_one_interval (void) /* {{{ */
+{
+       cdtime_t interval;
+       struct timespec ts = { 0, 0 };
+       int status = 0;
+
+       interval = plugin_get_interval ();
+       CDTIME_T_TO_TIMESPEC (interval, &ts);
+
+       while (42)
+       {
+               struct timespec rem = { 0, 0 };
+
+               status = nanosleep (&ts, &rem);
+               if (status == 0)
+                       break;
+               else if ((errno == EINTR) || (errno == EAGAIN))
+               {
+                       ts = rem;
+                       continue;
+               }
+               else
+                       break;
+       }
+
+       return (status);
+} /* }}} int dns_sleep_one_interval */
+
 static void *dns_child_loop (__attribute__((unused)) void *dummy) /* {{{ */
 {
-       int status = PCAP_ERROR_IFACE_NOT_UP;
+       int status;
 
-       while (status == PCAP_ERROR_IFACE_NOT_UP)
+       while (42)
+       {
                status = dns_run_pcap_loop ();
+               if (status != PCAP_ERROR_IFACE_NOT_UP)
+                       break;
+
+               dns_sleep_one_interval ();
+       }
+
        if (status != PCAP_ERROR_BREAK)
                ERROR ("dns plugin: PCAP returned error %s.",
                                pcap_statustostr (status));
@@ -314,6 +351,20 @@ static int dns_init (void)
 
        listen_thread_init = 1;
 
+#ifdef HAVE_SYS_CAPABILITY_H
+       if (check_capability (CAP_NET_RAW) != 0)
+       {
+               if (getuid () == 0)
+                       WARNING ("dns plugin: Running collectd as root, but the CAP_NET_RAW "
+                                       "capability is missing. The plugin's read function will probably "
+                                       "fail. Is your init system dropping capabilities ?");
+               else
+                       WARNING ("dns plugin: collectd doesn't have the CAP_NET_RAW capability. "
+                                       "If you don't want to run collectd as root, try running \"setcap "
+                                       "cap_net_raw=ep\" on the collectd binary.");
+       }
+#endif
+
        return (0);
 } /* int dns_init */
 
@@ -357,7 +408,6 @@ static int dns_read (void)
        unsigned int keys[T_MAX];
        unsigned int values[T_MAX];
        int len;
-       int i;
 
        counter_list_t *ptr;
 
@@ -379,7 +429,7 @@ static int dns_read (void)
        }
        pthread_mutex_unlock (&qtype_mutex);
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                DEBUG ("dns plugin: qtype = %u; counter = %u;", keys[i], values[i]);
                submit_derive ("dns_qtype", qtype_str (keys[i]), values[i]);
@@ -395,7 +445,7 @@ static int dns_read (void)
        }
        pthread_mutex_unlock (&opcode_mutex);
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                DEBUG ("dns plugin: opcode = %u; counter = %u;", keys[i], values[i]);
                submit_derive ("dns_opcode", opcode_str (keys[i]), values[i]);
@@ -411,7 +461,7 @@ static int dns_read (void)
        }
        pthread_mutex_unlock (&rcode_mutex);
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                DEBUG ("dns plugin: rcode = %u; counter = %u;", keys[i], values[i]);
                submit_derive ("dns_rcode", rcode_str (keys[i]), values[i]);