]> The Tcpdump Group git mirrors - libpcap/blobdiff - pcap-netfilter-linux.c
Travis: Migrate from legacy to container-based infrastructure
[libpcap] / pcap-netfilter-linux.c
index 2a5812b273afb0272c124cfdd61a9ebb6bf02884..3ee6faa3b7b8af0c28d0884ec6266465c4f2b70d 100644 (file)
@@ -11,8 +11,8 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  * notice, this list of conditions and the following disclaimer in the
  * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote 
- * products derived from this software without specific prior written 
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
  * permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 #include <linux/netfilter/nfnetlink_queue.h>
 
 /* NOTE: if your program drops privilages after pcap_activate() it WON'T work with nfqueue.
- *       It took me quite some time to debug ;/ 
+ *       It took me quite some time to debug ;/
  *
  *       Sending any data to nfnetlink socket requires CAP_NET_ADMIN privilages,
  *       and in nfqueue we need to send verdict reply after recving packet.
  *
  *       In tcpdump you can disable dropping privilages with -Z root
  */
+
 #include "pcap-netfilter-linux.h"
 
 #define HDR_LENGTH (NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))
@@ -116,10 +116,10 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
                        return -1;
                }
 
-               if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG && 
-                   NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET) 
+               if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
+                   NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
                        type = NFLOG;
-               else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE && 
+               else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE &&
                         NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
                        type = NFQUEUE;
 
@@ -127,7 +127,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
                        const unsigned char *payload = NULL;
                        struct pcap_pkthdr pkth;
 
-                       const struct nfgenmsg *nfg;
+                       const struct nfgenmsg *nfg = NULL;
                        int id = 0;
 
                        if (handle->linktype != DLT_NFLOG) {
@@ -184,7 +184,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
 
                                gettimeofday(&pkth.ts, NULL);
                                if (handle->fcode.bf_insns == NULL ||
-                                               bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen)) 
+                                               bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
                                {
                                        handlep->packets_read++;
                                        callback(user, &pkth, payload);
@@ -194,7 +194,10 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
 
                        if (type == NFQUEUE) {
                                /* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
-                               nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
+                               /* if type == NFQUEUE, handle->linktype is always != DLT_NFLOG,
+                                  so nfg is always initialized to NLMSG_DATA(nlh). */
+                               if (nfg != NULL)
+                                       nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
                        }
                }
 
@@ -231,7 +234,7 @@ netfilter_inject_linux(pcap_t *handle, const void *buf, size_t size)
 {
        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
        return (-1);
-}                           
+}
 
 struct my_nfattr {
        u_int16_t nfa_len;
@@ -249,7 +252,7 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
 
        struct sockaddr_nl snl;
        static unsigned int seq_id;
-       
+
        if (!seq_id)
                seq_id = time(NULL);
        ++seq_id;
@@ -341,7 +344,7 @@ nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_
        return nflog_send_config_msg(handle, family, group_id, &nfa);
 }
 
-static int 
+static int
 nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
 {
        struct nfulnl_msg_config_mode msg;
@@ -395,7 +398,7 @@ nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd,
        return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
 }
 
-static int 
+static int
 nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
 {
        struct nfqnl_msg_config_params msg;
@@ -428,7 +431,7 @@ netfilter_activate(pcap_t* handle)
                dev += strlen(NFQUEUE_IFACE);
                type = NFQUEUE;
        }
+
        if (type != OTHER && *dev == ':') {
                dev++;
                while (*dev) {
@@ -437,7 +440,7 @@ netfilter_activate(pcap_t* handle)
 
                        if (group_count == 32) {
                                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                                               "Maximum 32 netfilter groups! dev: %s", 
+                                               "Maximum 32 netfilter groups! dev: %s",
                                                handle->opt.source);
                                return PCAP_ERROR;
                        }
@@ -462,7 +465,7 @@ netfilter_activate(pcap_t* handle)
 
        if (type == OTHER || *dev) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                               "Can't get netfilter group(s) index from %s", 
+                               "Can't get netfilter group(s) index from %s",
                                handle->opt.source);
                return PCAP_ERROR;
        }
@@ -599,7 +602,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
        /* Does it begin with NFLOG_IFACE or NFQUEUE_IFACE? */
        if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) == 0)
                cp += sizeof NFLOG_IFACE - 1;
-       else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0) 
+       else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0)
                cp += sizeof NFQUEUE_IFACE - 1;
        else {
                /* Nope, doesn't begin with NFLOG_IFACE nor NFQUEUE_IFACE */
@@ -628,11 +631,11 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
        return (p);
 }
 
-int 
+int
 netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
        int sock;
-       
+
        sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
        if (sock < 0) {
                /* if netlink is not supported this is not fatal */