/*
 * Copyright (c) 2011 Jakub Zawadzki
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 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
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "pcap-int.h"
#include "diag-control.h"

#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif

#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <time.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <linux/types.h>

#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h>
#include <linux/netfilter/nfnetlink_queue.h>

/* NOTE: if your program drops privileges after pcap_activate() it WON'T work with nfqueue.
 *       It took me quite some time to debug ;/
 *
 *       Sending any data to nfnetlink socket requires CAP_NET_ADMIN privileges,
 *       and in nfqueue we need to send verdict reply after receiving packet.
 *
 *       In tcpdump you can disable dropping privileges with -Z root
 */

#include "pcap-netfilter-linux.h"

#define HDR_LENGTH (NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))

#define NFLOG_IFACE "nflog"
#define NFQUEUE_IFACE "nfqueue"

typedef enum { OTHER = -1, NFLOG, NFQUEUE } nftype_t;

/*
 * Private data for capturing on Linux netfilter sockets.
 */
struct pcap_netfilter {
	u_int	packets_read;	/* count of packets read with recvfrom() */
	u_int   packets_nobufs; /* ENOBUFS counter */
};

static int nfqueue_send_verdict(const pcap_t *handle, uint16_t group_id, u_int32_t id, u_int32_t verdict);


static int
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
	struct pcap_netfilter *handlep = handle->priv;
	register u_char *bp, *ep;
	int count = 0;
	ssize_t len;

	/*
	 * Has "pcap_breakloop()" been called?
	 */
	if (handle->break_loop) {
		/*
		 * Yes - clear the flag that indicates that it
		 * has, and return PCAP_ERROR_BREAK to indicate
		 * that we were told to break out of the loop.
		 */
		handle->break_loop = 0;
		return PCAP_ERROR_BREAK;
	}
	len = handle->cc;
	if (len == 0) {
		/*
		 * The buffer is empty; refill it.
		 *
		 * We ignore EINTR, as that might just be due to a signal
		 * being delivered - if the signal should interrupt the
		 * loop, the signal handler should call pcap_breakloop()
		 * to set handle->break_loop (we ignore it on other
		 * platforms as well).
		 */
		do {
			len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
			if (handle->break_loop) {
				handle->break_loop = 0;
				return PCAP_ERROR_BREAK;
			}
			if (len == -1 && errno == ENOBUFS)
				handlep->packets_nobufs++;
		} while ((len == -1) && (errno == EINTR || errno == ENOBUFS));

		if (len < 0) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno, "Can't receive packet");
			return PCAP_ERROR;
		}

		bp = (unsigned char *)handle->buffer;
	} else
		bp = handle->bp;

	/*
	 * Loop through each message.
	 *
	 * This assumes that a single buffer of message will have
	 * <= INT_MAX packets, so the message count doesn't overflow.
	 */
	ep = bp + len;
	while (bp < ep) {
		const struct nlmsghdr *nlh = (const struct nlmsghdr *) bp;
		uint32_t msg_len;
		nftype_t type = OTHER;
		/*
		 * Has "pcap_breakloop()" been called?
		 * If so, return immediately - if we haven't read any
		 * packets, clear the flag and return PCAP_ERROR_BREAK
		 * to indicate that we were told to break out of the loop,
		 * otherwise leave the flag set, so that the *next* call
		 * will break out of the loop without having read any
		 * packets, and return the number of packets we've
		 * processed so far.
		 */
		if (handle->break_loop) {
			handle->bp = bp;
			handle->cc = (int)(ep - bp);
			if (count == 0) {
				handle->break_loop = 0;
				return PCAP_ERROR_BREAK;
			} else
				return count;
		}
		/*
		 * NLMSG_SPACE(0) might be signed or might be unsigned,
		 * depending on whether the kernel defines NLMSG_ALIGNTO
		 * as 4, which older kernels do, or as 4U, which newer
		 * kernels do.
		 *
		 * ep - bp is of type ptrdiff_t, which is signed.
		 *
		 * To squelch warnings, we cast both to size_t, which
		 * is unsigned; ep >= bp, so the cast is safe.
		 */
		if ((size_t)(ep - bp) < (size_t)NLMSG_SPACE(0)) {
			/*
			 * There's less than one netlink message left
			 * in the buffer.  Give up.
			 */
			break;
		}

		if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) {
			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %zd) (nlmsg_len: %u)", len, nlh->nlmsg_len);
			return -1;
		}

		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 &&
		         NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
			type = NFQUEUE;

		if (type != OTHER) {
			const unsigned char *payload = NULL;
			struct pcap_pkthdr pkth;

			const struct nfgenmsg *nfg = NULL;
			int id = 0;

			if (handle->linktype != DLT_NFLOG) {
				const struct nfattr *payload_attr = NULL;

				if (nlh->nlmsg_len < HDR_LENGTH) {
					snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len);
					return -1;
				}

				nfg = NLMSG_DATA(nlh);
				if (nlh->nlmsg_len > HDR_LENGTH) {
					struct nfattr *attr = NFM_NFA(nfg);
					int attr_len = nlh->nlmsg_len - NLMSG_ALIGN(HDR_LENGTH);

					while (NFA_OK(attr, attr_len)) {
						if (type == NFQUEUE) {
							switch (NFA_TYPE(attr)) {
								case NFQA_PACKET_HDR:
									{
										const struct nfqnl_msg_packet_hdr *pkt_hdr = (const struct nfqnl_msg_packet_hdr *) NFA_DATA(attr);

										id = ntohl(pkt_hdr->packet_id);
										break;
									}
								case NFQA_PAYLOAD:
									payload_attr = attr;
									break;
							}

						} else if (type == NFLOG) {
							switch (NFA_TYPE(attr)) {
								case NFULA_PAYLOAD:
									payload_attr = attr;
									break;
							}
						}
						attr = NFA_NEXT(attr, attr_len);
					}
				}

				if (payload_attr) {
					payload = NFA_DATA(payload_attr);
					pkth.len = pkth.caplen = NFA_PAYLOAD(payload_attr);
				}

			} else {
				payload = NLMSG_DATA(nlh);
				pkth.caplen = pkth.len = nlh->nlmsg_len-NLMSG_ALIGN(sizeof(struct nlmsghdr));
			}

			if (payload) {
				/* pkth.caplen = min (payload_len, handle->snapshot); */

				gettimeofday(&pkth.ts, NULL);
				if (handle->fcode.bf_insns == NULL ||
						pcapint_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
				{
					handlep->packets_read++;
					callback(user, &pkth, payload);
					count++;
				}
			}

			if (type == NFQUEUE) {
				/* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
				/* 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);
			}
		}

		msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
		/*
		 * If the message length would run past the end of the
		 * buffer, truncate it to the remaining space in the
		 * buffer.
		 *
		 * To squelch warnings, we cast ep - bp to uint32_t, which
		 * is unsigned and is the type of msg_len; ep >= bp, and
		 * len should fit in 32 bits (either it's set from an int
		 * or it's set from a recv() call with a buffer size that's
		 * an int, and we're assuming either ILP32 or LP64), so
		 * the cast is safe.
		 */
		if (msg_len > (uint32_t)(ep - bp))
			msg_len = (uint32_t)(ep - bp);

		bp += msg_len;
		if (count >= max_packets && !PACKET_COUNT_IS_UNLIMITED(max_packets)) {
			handle->bp = bp;
			handle->cc = (int)(ep - bp);
			if (handle->cc < 0)
				handle->cc = 0;
			return count;
		}
	}

	handle->cc = 0;
	return count;
}

static int
netfilter_set_datalink(pcap_t *handle, int dlt)
{
	handle->linktype = dlt;
	return 0;
}

static int
netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
	struct pcap_netfilter *handlep = handle->priv;

	stats->ps_recv = handlep->packets_read;
	stats->ps_drop = handlep->packets_nobufs;
	stats->ps_ifdrop = 0;
	return 0;
}

static int
netfilter_inject_linux(pcap_t *handle, const void *buf _U_, int size _U_)
{
	snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
	    "Packet injection is not supported on netfilter devices");
	return (-1);
}

struct my_nfattr {
	uint16_t nfa_len;
	uint16_t nfa_type;
	void *data;
};

static int
netfilter_send_config_msg(const pcap_t *handle, uint16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
{
	char buf[1024] __attribute__ ((aligned));
	memset(buf, 0, sizeof(buf));

	struct nlmsghdr *nlh = (struct nlmsghdr *) buf;
	struct nfgenmsg *nfg = (struct nfgenmsg *) (buf + sizeof(struct nlmsghdr));

	struct sockaddr_nl snl;
	static unsigned int seq_id;

	if (!seq_id)
DIAG_OFF_NARROWING
		seq_id = time(NULL);
DIAG_ON_NARROWING
	++seq_id;

	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg));
	nlh->nlmsg_type = msg_type;
	nlh->nlmsg_flags = NLM_F_REQUEST | (ack ? NLM_F_ACK : 0);
	nlh->nlmsg_pid = 0;	/* to kernel */
	nlh->nlmsg_seq = seq_id;

	nfg->nfgen_family = family;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(res_id);

	if (mynfa) {
		struct nfattr *nfa = (struct nfattr *) (buf + NLMSG_ALIGN(nlh->nlmsg_len));

		nfa->nfa_type = mynfa->nfa_type;
		nfa->nfa_len = NFA_LENGTH(mynfa->nfa_len);
		memcpy(NFA_DATA(nfa), mynfa->data, mynfa->nfa_len);
		nlh->nlmsg_len = NLMSG_ALIGN(nlh->nlmsg_len) + NFA_ALIGN(nfa->nfa_len);
	}

	memset(&snl, 0, sizeof(snl));
	snl.nl_family = AF_NETLINK;

	if (sendto(handle->fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *) &snl, sizeof(snl)) == -1)
		return -1;

	if (!ack)
		return 0;

	/* waiting for reply loop */
	do {
		socklen_t addrlen = sizeof(snl);
		int len;

		/* ignore interrupt system call error */
		do {
			/*
			 * The buffer is not so big that its size won't
			 * fit into an int.
			 */
			len = (int)recvfrom(handle->fd, buf, sizeof(buf), 0, (struct sockaddr *) &snl, &addrlen);
		} while ((len == -1) && (errno == EINTR));

		if (len <= 0)
			return len;

		if (addrlen != sizeof(snl) || snl.nl_family != AF_NETLINK) {
			errno = EINVAL;
			return -1;
		}

		nlh = (struct nlmsghdr *) buf;
		if (snl.nl_pid != 0 || seq_id != nlh->nlmsg_seq)	/* if not from kernel or wrong sequence skip */
			continue;

		while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, (u_int)len)) {
			if (nlh->nlmsg_type == NLMSG_ERROR || (nlh->nlmsg_type == NLMSG_DONE && nlh->nlmsg_flags & NLM_F_MULTI)) {
				if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) {
					errno = EBADMSG;
					return -1;
				}
				errno = -(*((int *)NLMSG_DATA(nlh)));
				return (errno == 0) ? 0 : -1;
			}
			nlh = NLMSG_NEXT(nlh, len);
		}
	} while (1);

	return -1; /* never here */
}

static int
nflog_send_config_msg(const pcap_t *handle, uint8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
	return netfilter_send_config_msg(handle, (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG, 1, family, group_id, mynfa);
}

static int
nflog_send_config_cmd(const pcap_t *handle, uint16_t group_id, u_int8_t cmd, u_int8_t family)
{
	struct nfulnl_msg_config_cmd msg;
	struct my_nfattr nfa;

	msg.command = cmd;

	nfa.data = &msg;
	nfa.nfa_type = NFULA_CFG_CMD;
	nfa.nfa_len = sizeof(msg);

	return nflog_send_config_msg(handle, family, group_id, &nfa);
}

static int
nflog_send_config_mode(const pcap_t *handle, uint16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
	struct nfulnl_msg_config_mode msg;
	struct my_nfattr nfa;

	msg.copy_range = htonl(copy_range);
	msg.copy_mode = copy_mode;

	nfa.data = &msg;
	nfa.nfa_type = NFULA_CFG_MODE;
	nfa.nfa_len = sizeof(msg);

	return nflog_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
}

static int
nfqueue_send_verdict(const pcap_t *handle, uint16_t group_id, u_int32_t id, u_int32_t verdict)
{
	struct nfqnl_msg_verdict_hdr msg;
	struct my_nfattr nfa;

	msg.id = htonl(id);
	msg.verdict = htonl(verdict);

	nfa.data = &msg;
	nfa.nfa_type = NFQA_VERDICT_HDR;
	nfa.nfa_len = sizeof(msg);

	return netfilter_send_config_msg(handle, (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT, 0, AF_UNSPEC, group_id, &nfa);
}

static int
nfqueue_send_config_msg(const pcap_t *handle, uint8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
	return netfilter_send_config_msg(handle, (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG, 1, family, group_id, mynfa);
}

static int
nfqueue_send_config_cmd(const pcap_t *handle, uint16_t group_id, u_int8_t cmd, u_int16_t pf)
{
	struct nfqnl_msg_config_cmd msg;
	struct my_nfattr nfa;

	msg.command = cmd;
	msg.pf = htons(pf);

	nfa.data = &msg;
	nfa.nfa_type = NFQA_CFG_CMD;
	nfa.nfa_len = sizeof(msg);

	return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
}

static int
nfqueue_send_config_mode(const pcap_t *handle, uint16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
	struct nfqnl_msg_config_params msg;
	struct my_nfattr nfa;

	msg.copy_range = htonl(copy_range);
	msg.copy_mode = copy_mode;

	nfa.data = &msg;
	nfa.nfa_type = NFQA_CFG_PARAMS;
	nfa.nfa_len = sizeof(msg);

	return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
}

static int
netfilter_activate(pcap_t* handle)
{
	const char *dev = handle->opt.device;
	unsigned short groups[32];
	int group_count = 0;
	nftype_t type = OTHER;
	int i;

	if (strncmp(dev, NFLOG_IFACE, strlen(NFLOG_IFACE)) == 0) {
		dev += strlen(NFLOG_IFACE);
		type = NFLOG;

	} else if (strncmp(dev, NFQUEUE_IFACE, strlen(NFQUEUE_IFACE)) == 0) {
		dev += strlen(NFQUEUE_IFACE);
		type = NFQUEUE;
	}

	if (type != OTHER && *dev == ':') {
		dev++;
		while (*dev) {
			long int group_id;
			char *end_dev;

			if (group_count == 32) {
				snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
						"Maximum 32 netfilter groups! dev: %s",
						handle->opt.device);
				return PCAP_ERROR;
			}

			group_id = strtol(dev, &end_dev, 0);
			if (end_dev != dev) {
				if (group_id < 0 || group_id > 65535) {
					snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
							"Netfilter group range from 0 to 65535 (got %ld)",
							group_id);
					return PCAP_ERROR;
				}

				groups[group_count++] = (unsigned short) group_id;
				dev = end_dev;
			}
			if (*dev != ',')
				break;
			dev++;
		}
	}

	if (type == OTHER || *dev) {
		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
				"Can't get netfilter group(s) index from %s",
				handle->opt.device);
		return PCAP_ERROR;
	}

	/* if no groups, add default: 0 */
	if (!group_count) {
		groups[0] = 0;
		group_count = 1;
	}

	/*
	 * Turn a negative snapshot value (invalid), a snapshot value of
	 * 0 (unspecified), or a value bigger than the normal maximum
	 * value, into the maximum allowed value.
	 *
	 * If some application really *needs* a bigger snapshot
	 * length, we should just increase MAXIMUM_SNAPLEN.
	 */
	if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
		handle->snapshot = MAXIMUM_SNAPLEN;

	/* Initialize some components of the pcap structure. */
	handle->bufsize = 128 + handle->snapshot;
	handle->offset = 0;
	handle->read_op = netfilter_read_linux;
	handle->inject_op = netfilter_inject_linux;
	handle->setfilter_op = pcapint_install_bpf_program; /* no kernel filtering */
	handle->setdirection_op = NULL;
	handle->set_datalink_op = netfilter_set_datalink;
	handle->getnonblock_op = pcapint_getnonblock_fd;
	handle->setnonblock_op = pcapint_setnonblock_fd;
	handle->stats_op = netfilter_stats_linux;

	/* Create netlink socket */
	handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
	if (handle->fd < 0) {
		pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "Can't create raw socket");
		return PCAP_ERROR;
	}

	if (type == NFLOG) {
		handle->linktype = DLT_NFLOG;
		handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
		if (handle->dlt_list == NULL) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno,
			    "Can't allocate DLT list");
			goto close_fail;
		}
		handle->dlt_list[0] = DLT_NFLOG;
		handle->dlt_list[1] = DLT_IPV4;
		handle->dlt_count = 2;
	} else
		handle->linktype = DLT_IPV4;

	handle->buffer = malloc(handle->bufsize);
	if (!handle->buffer) {
		pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "Can't allocate dump buffer");
		goto close_fail;
	}

	if (type == NFLOG) {
		if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno,
			    "NFULNL_CFG_CMD_PF_UNBIND");
			goto close_fail;
		}

		if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno, "NFULNL_CFG_CMD_PF_BIND");
			goto close_fail;
		}

		/* Bind socket to the nflog groups */
		for (i = 0; i < group_count; i++) {
			if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
				pcapint_fmt_errmsg_for_errno(handle->errbuf,
				    PCAP_ERRBUF_SIZE, errno,
				    "Can't listen on group index");
				goto close_fail;
			}

			if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
				pcapint_fmt_errmsg_for_errno(handle->errbuf,
				    PCAP_ERRBUF_SIZE, errno,
				    "NFULNL_COPY_PACKET");
				goto close_fail;
			}
		}

	} else {
		if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno, "NFQNL_CFG_CMD_PF_UNBIND");
			goto close_fail;
		}

		if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno, "NFQNL_CFG_CMD_PF_BIND");
			goto close_fail;
		}

		/* Bind socket to the nfqueue groups */
		for (i = 0; i < group_count; i++) {
			if (nfqueue_send_config_cmd(handle, groups[i], NFQNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
				pcapint_fmt_errmsg_for_errno(handle->errbuf,
				    PCAP_ERRBUF_SIZE, errno,
				    "Can't listen on group index");
				goto close_fail;
			}

			if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
				pcapint_fmt_errmsg_for_errno(handle->errbuf,
				    PCAP_ERRBUF_SIZE, errno,
				    "NFQNL_COPY_PACKET");
				goto close_fail;
			}
		}
	}

	if (handle->opt.rfmon) {
		/*
		 * Monitor mode doesn't apply to netfilter devices.
		 */
		pcapint_cleanup_live_common(handle);
		return PCAP_ERROR_RFMON_NOTSUP;
	}

	if (handle->opt.buffer_size != 0) {
		/*
		 * Set the socket buffer size to the specified value.
		 */
		if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF, &handle->opt.buffer_size, sizeof(handle->opt.buffer_size)) == -1) {
			pcapint_fmt_errmsg_for_errno(handle->errbuf,
			    PCAP_ERRBUF_SIZE, errno, "SO_RCVBUF");
			goto close_fail;
		}
	}

	handle->selectable_fd = handle->fd;
	return 0;

close_fail:
	pcapint_cleanup_live_common(handle);
	return PCAP_ERROR;
}

pcap_t *
netfilter_create(const char *device, char *ebuf, int *is_ours)
{
	const char *cp;
	pcap_t *p;

	/* Does this look like an netfilter device? */
	cp = strrchr(device, '/');
	if (cp == NULL)
		cp = device;

	/* 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)
		cp += sizeof NFQUEUE_IFACE - 1;
	else {
		/* Nope, doesn't begin with NFLOG_IFACE nor NFQUEUE_IFACE */
		*is_ours = 0;
		return NULL;
	}

	/*
	 * Yes - is that either the end of the name, or is it followed
	 * by a colon?
	 */
	if (*cp != ':' && *cp != '\0') {
		/* Nope */
		*is_ours = 0;
		return NULL;
	}

	/* OK, it's probably ours. */
	*is_ours = 1;

	p = PCAP_CREATE_COMMON(ebuf, struct pcap_netfilter);
	if (p == NULL)
		return (NULL);

	p->activate_op = netfilter_activate;
	return (p);
}

int
netfilter_findalldevs(pcap_if_list_t *devlistp, 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 */
		if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
			return 0;
		pcapint_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
		    errno, "Can't open netlink socket");
		return -1;
	}
	close(sock);

	/*
	 * The notion of "connected" vs. "disconnected" doesn't apply.
	 * XXX - what about "up" and "running"?
	 */
	if (pcapint_add_dev(devlistp, NFLOG_IFACE,
	    PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
	    "Linux netfilter log (NFLOG) interface", err_str) == NULL)
		return -1;
	if (pcapint_add_dev(devlistp, NFQUEUE_IFACE,
	    PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
	    "Linux netfilter queue (NFQUEUE) interface", err_str) == NULL)
		return -1;
	return 0;
}
