dns plugin: Only include and build with `utils_dns.c' if it's actually used.
[collectd.git] / src / utils_dns.c
index 2f6c191..6541b89 100644 (file)
@@ -35,6 +35,9 @@
 
 #include "collectd.h"
 
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
 #if HAVE_NETINET_IN_H
 # include <netinet/in.h>
 #endif
 # include <netdb.h>
 #endif
 
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
 #if HAVE_NETINET_IP_H
 # include <netinet/ip.h>
 #endif
 # define PPP_CONTROL_VAL 0x03  /* The control byte value */
 #endif
 
-#ifdef __linux__
-#define uh_sport source
-#define uh_dport dest
+#if HAVE_STRUCT_UDPHDR_UH_DPORT && HAVE_STRUCT_UDPHDR_UH_SPORT
+# define UDP_DEST uh_dport
+# define UDP_SRC  uh_dport
+#elif HAVE_STRUCT_UDPHDR_DEST && HAVE_STRUCT_UDPHDR_SOURCE
+# define UDP_DEST dest
+# define UDP_SRC  source
+#else
+# error "`struct udphdr' is unusable."
 #endif
 
 #include "utils_dns.h"
@@ -154,29 +156,33 @@ static pcap_t *pcap_obj = NULL;
 
 static ip_list_t *IgnoreList = NULL;
 
+#if HAVE_PCAP_H
 static void (*Callback) (const rfc1035_header_t *) = NULL;
 
 static int query_count_intvl = 0;
 static int query_count_total = 0;
-#ifdef __OpenBSD__
+# ifdef __OpenBSD__
 static struct bpf_timeval last_ts;
-#else
+# else
 static struct timeval last_ts;
-#endif
+# endif /* __OpenBSD__ */
+#endif /* HAVE_PCAP_H */
 
 static int cmp_in6_addr (const struct in6_addr *a,
        const struct in6_addr *b)
 {
     int i;
 
-    for (i = 0; i < 4; i++)
-       if (a->s6_addr32[i] != b->s6_addr32[i])
+    assert (sizeof (struct in6_addr) == 16);
+
+    for (i = 0; i < 16; i++)
+       if (a->s6_addr[i] != b->s6_addr[i])
            break;
 
-    if (i >= 4)
+    if (i >= 16)
        return (0);
 
-    return (a->s6_addr32[i] > b->s6_addr32[i] ? 1 : -1);
+    return (a->s6_addr[i] > b->s6_addr[i] ? 1 : -1);
 } /* int cmp_addrinfo */
 
 static inline int ignore_list_match (const struct in6_addr *addr)
@@ -224,10 +230,10 @@ void ignore_list_add_name (const char *name)
     {
        if (ai_ptr->ai_family == AF_INET)
        {
-           addr.s6_addr32[0] = 0;
-           addr.s6_addr32[1] = 0;
-           addr.s6_addr32[2] = htonl (0x0000FFFF);
-           addr.s6_addr32[3] = ((struct sockaddr_in *) ai_ptr->ai_addr)->sin_addr.s_addr;
+           memset (&addr, '\0', sizeof (addr));
+           addr.s6_addr[10] = 0xFF;
+           addr.s6_addr[11] = 0xFF;
+           memcpy (addr.s6_addr + 12, &((struct sockaddr_in *) ai_ptr->ai_addr)->sin_addr, 4);
 
            ignore_list_add (&addr);
        }
@@ -240,6 +246,7 @@ void ignore_list_add_name (const char *name)
     freeaddrinfo (ai_list);
 }
 
+#if HAVE_PCAP_H
 static void in6_addr_from_buffer (struct in6_addr *ia,
        const void *buf, size_t buf_len,
        int family)
@@ -247,8 +254,9 @@ static void in6_addr_from_buffer (struct in6_addr *ia,
     memset (ia, 0, sizeof (struct in6_addr));
     if ((AF_INET == family) && (sizeof (uint32_t) == buf_len))
     {
-       ia->s6_addr32[2] = htonl (0x0000FFFF);
-       ia->s6_addr32[3] = *((uint32_t *) buf);
+       ia->s6_addr[10] = 0xFF;
+       ia->s6_addr[11] = 0xFF;
+       memcpy (ia->s6_addr + 12, buf, buf_len);
     }
     else if ((AF_INET6 == family) && (sizeof (struct in6_addr) == buf_len))
     {
@@ -256,12 +264,10 @@ static void in6_addr_from_buffer (struct in6_addr *ia,
     }
 } /* void in6_addr_from_buffer */
 
-#if HAVE_PCAP_H
 void dnstop_set_pcap_obj (pcap_t *po)
 {
        pcap_obj = po;
 }
-#endif
 
 void dnstop_set_callback (void (*cb) (const rfc1035_header_t *))
 {
@@ -405,8 +411,8 @@ handle_udp(const struct udphdr *udp, int len,
        const struct in6_addr *d_addr)
 {
     char buf[PCAP_SNAPLEN];
-    if ((ntohs (udp->uh_dport) != 53)
-                   && (ntohs (udp->uh_sport) != 53))
+    if ((ntohs (udp->UDP_DEST) != 53)
+                   && (ntohs (udp->UDP_SRC) != 53))
        return 0;
     memcpy(buf, udp + 1, len - sizeof(*udp));
     if (0 == handle_dns(buf, len - sizeof(*udp), s_addr, d_addr))
@@ -506,6 +512,7 @@ handle_ip(const struct ip *ip, int len)
     return 1;
 }
 
+#if HAVE_NET_IF_PPP_H
 static int
 handle_ppp(const u_char * pkt, int len)
 {
@@ -535,6 +542,7 @@ handle_ppp(const u_char * pkt, int len)
     memcpy(buf, pkt, len);
     return handle_ip((struct ip *) buf, len);
 }
+#endif /* HAVE_NET_IF_PPP_H */
 
 static int
 handle_null(const u_char * pkt, int len)
@@ -593,8 +601,41 @@ handle_ether(const u_char * pkt, int len)
        return handle_ip((struct ip *) buf, len);
 }
 
+#ifdef DLT_LINUX_SLL
+static int
+handle_linux_sll (const u_char *pkt, int len)
+{
+    struct sll_header
+    {
+       uint16_t pkt_type;
+       uint16_t dev_type;
+       uint16_t addr_len;
+       uint8_t  addr[8];
+       uint16_t proto_type;
+    } *hdr;
+    uint16_t etype;
+
+    if (len < sizeof (struct sll_header))
+       return (0);
+
+    hdr  = (struct sll_header *) pkt;
+    pkt  = (u_char *) (hdr + 1);
+    len -= sizeof (struct sll_header);
+
+    etype = ntohs (hdr->proto_type);
+
+    if ((ETHERTYPE_IP != etype)
+           && (ETHERTYPE_IPV6 != etype))
+       return 0;
+
+    if (ETHERTYPE_IPV6 == etype)
+       return (handle_ipv6 ((struct ip6_hdr *) pkt, len));
+    else
+       return handle_ip((struct ip *) pkt, len);
+}
+#endif /* DLT_LINUX_SLL */
+
 /* public function */
-#if HAVE_PCAP_H
 void handle_pcap(u_char *udata, const struct pcap_pkthdr *hdr, const u_char *pkt)
 {
     int status;
@@ -611,9 +652,11 @@ void handle_pcap(u_char *udata, const struct pcap_pkthdr *hdr, const u_char *pkt
        case DLT_EN10MB:
            status = handle_ether (pkt, hdr->caplen);
            break;
+#if HAVE_NET_IF_PPP_H
        case DLT_PPP:
            status = handle_ppp (pkt, hdr->caplen);
            break;
+#endif
 #ifdef DLT_LOOP
        case DLT_LOOP:
            status = handle_loop (pkt, hdr->caplen);
@@ -624,6 +667,11 @@ void handle_pcap(u_char *udata, const struct pcap_pkthdr *hdr, const u_char *pkt
            status = handle_raw (pkt, hdr->caplen);
            break;
 #endif
+#ifdef DLT_LINUX_SLL
+       case DLT_LINUX_SLL:
+           status = handle_linux_sll (pkt, hdr->caplen);
+           break;
+#endif
        case DLT_NULL:
            status = handle_null (pkt, hdr->caplen);
            break;
@@ -642,7 +690,7 @@ void handle_pcap(u_char *udata, const struct pcap_pkthdr *hdr, const u_char *pkt
     query_count_total++;
     last_ts = hdr->ts;
 }
-#endif
+#endif /* HAVE_PCAP_H */
 
 const char *qtype_str(int t)
 {
@@ -859,7 +907,7 @@ main(int argc, char *argv[])
     case DLT_EN10MB:
        handle_datalink = handle_ether;
        break;
-#if USE_PPP
+#if HAVE_NET_IF_PPP_H
     case DLT_PPP:
        handle_datalink = handle_ppp;
        break;
@@ -926,3 +974,6 @@ main(int argc, char *argv[])
     return 0;
 } /* static int main(int argc, char *argv[]) */
 #endif
+/*
+ * vim:shiftwidth=4:tabstop=8:softtabstop=4
+ */