From 445a1e92c92d052007ab66b0a79d2bfa5683d493 Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org" Date: Wed, 26 Oct 2005 11:39:01 +0000 Subject: rename files correctly (Eric Leblond) --- configure.in | 4 +- include/libnetfilter_queue/libnetfilter_queue.h | 87 ++++++ include/libnetfilter_queue/libnfnetlink_queue.h | 87 ------ src/libnetfilter_queue.c | 375 ++++++++++++++++++++++++ src/libnfnetlink_queue.c | 375 ------------------------ 5 files changed, 464 insertions(+), 464 deletions(-) create mode 100644 include/libnetfilter_queue/libnetfilter_queue.h delete mode 100644 include/libnetfilter_queue/libnfnetlink_queue.h create mode 100644 src/libnetfilter_queue.c delete mode 100644 src/libnfnetlink_queue.c diff --git a/configure.in b/configure.in index 4570284..24c1c22 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Process this file with autoconf to create configure. AC_INIT AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(libnfnetlink_queue, 0.0.10) +AM_INIT_AUTOMAKE(libnetfilter_queue, 0.0.10) AC_PROG_CC AC_EXEEXT @@ -62,4 +62,4 @@ dnl-------------------------------- dnl Output the makefiles -AC_OUTPUT(Makefile include/Makefile include/libnfnetlink_queue/Makefile src/Makefile utils/Makefile) +AC_OUTPUT(Makefile include/Makefile include/libnetfilter_queue/Makefile src/Makefile utils/Makefile) diff --git a/include/libnetfilter_queue/libnetfilter_queue.h b/include/libnetfilter_queue/libnetfilter_queue.h new file mode 100644 index 0000000..9c2b40d --- /dev/null +++ b/include/libnetfilter_queue/libnetfilter_queue.h @@ -0,0 +1,87 @@ +/* libnfqnetlink.h: Header file for the Netfilter Queue library. + * + * (C) 2005 by Harald Welte + * + * + * Changelog : + * (2005/08/11) added parsing function (Eric Leblond ) + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef __LIBCTNETLINK_H +#define __LIBCTNETLINK_H + +#include + +#include +#include + +struct nfqnl_handle; +struct nfqnl_q_handle; + +extern int nfqnl_errno; + +extern struct nfnl_handle *nfqnl_nfnlh(struct nfqnl_handle *h); +extern int nfqnl_fd(struct nfqnl_handle *h); + +typedef int nfqnl_callback(struct nfqnl_q_handle *gh, struct nfgenmsg *nfmsg, + struct nfattr *nfa[], void *data); + + +extern struct nfqnl_handle *nfqnl_open(void); +extern int nfqnl_close(struct nfqnl_handle *h); + +extern int nfqnl_bind_pf(struct nfqnl_handle *h, u_int16_t pf); +extern int nfqnl_unbind_pf(struct nfqnl_handle *h, u_int16_t pf); + +extern struct nfqnl_q_handle *nfqnl_create_queue(struct nfqnl_handle *h, + u_int16_t num, + nfqnl_callback *cb, + void *data); +extern int nfqnl_destroy_queue(struct nfqnl_q_handle *qh); + +extern int nfqnl_handle_packet(struct nfqnl_handle *h, char *buf, int len); + +extern int nfqnl_set_mode(struct nfqnl_q_handle *qh, + u_int8_t mode, unsigned int len); + +extern int nfqnl_set_verdict(struct nfqnl_q_handle *qh, + u_int32_t id, + u_int32_t verdict, + u_int32_t data_len, + unsigned char *buf); + +extern int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh, + u_int32_t id, + u_int32_t verdict, + u_int32_t mark, + u_int32_t datalen, + unsigned char *buf); + +/* message parsing function */ + +extern struct nfqnl_msg_packet_hdr * + nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]); + +extern u_int32_t nfqnl_get_nfmark(struct nfattr *nfa[]); + +extern struct nfqnl_msg_packet_timestamp * + nfqnl_get_timestamp(struct nfattr *nfa[]); + +/* return 0 if not set */ +extern u_int32_t nfqnl_get_indev(struct nfattr *nfa[]); +extern u_int32_t nfqnl_get_physindev(struct nfattr *nfa[]); +extern u_int32_t nfqnl_get_outdev(struct nfattr *nfa[]); +extern u_int32_t nfqnl_get_physoutdev(struct nfattr *nfa[]); + +extern struct nfqnl_msg_packet_hw *nfqnl_get_packet_hw(struct nfattr *nfa[]); + +/* return 0 if problem */ +extern int nfqnl_get_payload(struct nfattr *nfa[], + char ** data, unsigned int* datalen); + + + +#endif /* __LIBNFQNETLINK_H */ diff --git a/include/libnetfilter_queue/libnfnetlink_queue.h b/include/libnetfilter_queue/libnfnetlink_queue.h deleted file mode 100644 index 9c2b40d..0000000 --- a/include/libnetfilter_queue/libnfnetlink_queue.h +++ /dev/null @@ -1,87 +0,0 @@ -/* libnfqnetlink.h: Header file for the Netfilter Queue library. - * - * (C) 2005 by Harald Welte - * - * - * Changelog : - * (2005/08/11) added parsing function (Eric Leblond ) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - */ - -#ifndef __LIBCTNETLINK_H -#define __LIBCTNETLINK_H - -#include - -#include -#include - -struct nfqnl_handle; -struct nfqnl_q_handle; - -extern int nfqnl_errno; - -extern struct nfnl_handle *nfqnl_nfnlh(struct nfqnl_handle *h); -extern int nfqnl_fd(struct nfqnl_handle *h); - -typedef int nfqnl_callback(struct nfqnl_q_handle *gh, struct nfgenmsg *nfmsg, - struct nfattr *nfa[], void *data); - - -extern struct nfqnl_handle *nfqnl_open(void); -extern int nfqnl_close(struct nfqnl_handle *h); - -extern int nfqnl_bind_pf(struct nfqnl_handle *h, u_int16_t pf); -extern int nfqnl_unbind_pf(struct nfqnl_handle *h, u_int16_t pf); - -extern struct nfqnl_q_handle *nfqnl_create_queue(struct nfqnl_handle *h, - u_int16_t num, - nfqnl_callback *cb, - void *data); -extern int nfqnl_destroy_queue(struct nfqnl_q_handle *qh); - -extern int nfqnl_handle_packet(struct nfqnl_handle *h, char *buf, int len); - -extern int nfqnl_set_mode(struct nfqnl_q_handle *qh, - u_int8_t mode, unsigned int len); - -extern int nfqnl_set_verdict(struct nfqnl_q_handle *qh, - u_int32_t id, - u_int32_t verdict, - u_int32_t data_len, - unsigned char *buf); - -extern int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh, - u_int32_t id, - u_int32_t verdict, - u_int32_t mark, - u_int32_t datalen, - unsigned char *buf); - -/* message parsing function */ - -extern struct nfqnl_msg_packet_hdr * - nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]); - -extern u_int32_t nfqnl_get_nfmark(struct nfattr *nfa[]); - -extern struct nfqnl_msg_packet_timestamp * - nfqnl_get_timestamp(struct nfattr *nfa[]); - -/* return 0 if not set */ -extern u_int32_t nfqnl_get_indev(struct nfattr *nfa[]); -extern u_int32_t nfqnl_get_physindev(struct nfattr *nfa[]); -extern u_int32_t nfqnl_get_outdev(struct nfattr *nfa[]); -extern u_int32_t nfqnl_get_physoutdev(struct nfattr *nfa[]); - -extern struct nfqnl_msg_packet_hw *nfqnl_get_packet_hw(struct nfattr *nfa[]); - -/* return 0 if problem */ -extern int nfqnl_get_payload(struct nfattr *nfa[], - char ** data, unsigned int* datalen); - - - -#endif /* __LIBNFQNETLINK_H */ diff --git a/src/libnetfilter_queue.c b/src/libnetfilter_queue.c new file mode 100644 index 0000000..8e84c50 --- /dev/null +++ b/src/libnetfilter_queue.c @@ -0,0 +1,375 @@ +/* libnfqnetlink.c: generic library for access to nf_queue + * + * (C) 2005 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct nfqnl_handle +{ + struct nfnl_handle nfnlh; + struct nfqnl_q_handle *qh_list; +}; + +struct nfqnl_q_handle +{ + struct nfqnl_q_handle *next; + struct nfqnl_handle *h; + u_int16_t id; + + nfqnl_callback *cb; + void *data; +}; + + +int nfqnl_errno; + +/*********************************************************************** + * low level stuff + ***********************************************************************/ + +static void del_qh(struct nfqnl_q_handle *qh) +{ + struct nfqnl_q_handle *cur_qh, *prev_qh = NULL; + + for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) { + if (cur_qh == qh) { + if (prev_qh) + prev_qh->next = qh->next; + else + qh->h->qh_list = qh->next; + return; + } + prev_qh = cur_qh; + } +} + +static void add_qh(struct nfqnl_q_handle *qh) +{ + qh->next = qh->h->qh_list; + qh->h->qh_list = qh; +} + +static struct nfqnl_q_handle *find_qh(struct nfqnl_handle *h, u_int16_t id) +{ + struct nfqnl_q_handle *qh; + + for (qh = h->qh_list; qh; qh = qh->next) { + if (qh->id == id) + return qh; + } + return NULL; +} + +/* build a NFQNL_MSG_CONFIG message */ + static int +__build_send_cfg_msg(struct nfqnl_handle *h, u_int8_t command, + u_int16_t queuenum, u_int16_t pf) +{ + char buf[NFNL_HEADER_LEN + +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))]; + struct nfqnl_msg_config_cmd cmd; + struct nlmsghdr *nmh = (struct nlmsghdr *) buf; + + nfnl_fill_hdr(&h->nfnlh, nmh, 0, AF_UNSPEC, queuenum, + NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); + + cmd.command = command; + cmd.pf = htons(pf); + nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_CMD, &cmd, sizeof(cmd)); + + return nfnl_talk(&h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); +} + +static int __nfqnl_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[], + void *data) +{ + struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); + struct nfqnl_handle *h = data; + u_int16_t queue_num = ntohs(nfmsg->res_id); + struct nfqnl_q_handle *qh = find_qh(h, queue_num); + + if (!qh) + return -ENODEV; + + if (!qh->cb) + return -ENODEV; + + return qh->cb(qh, nfmsg, nfa, qh->data); +} + +static struct nfnl_callback pkt_cb = { + .call = &__nfqnl_rcv_pkt, + .attr_count = NFQA_MAX, +}; + +/* public interface */ + +struct nfnl_handle *nfqnl_nfnlh(struct nfqnl_handle *h) +{ + return &h->nfnlh; +} + +int nfqnl_fd(struct nfqnl_handle *h) +{ + return nfnl_fd(nfqnl_nfnlh(h)); +} + +struct nfqnl_handle *nfqnl_open(void) +{ + struct nfqnl_handle *h; + int err; + + h = malloc(sizeof(*h)); + if (!h) + return NULL; + + memset(h, 0, sizeof(*h)); + + err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_QUEUE, NFQNL_MSG_MAX, 0); + if (err < 0) { + nfqnl_errno = err; + goto out_free; + } + + pkt_cb.data = h; + err = nfnl_callback_register(&h->nfnlh, NFQNL_MSG_PACKET, &pkt_cb); + if (err < 0) { + nfqnl_errno = err; + goto out_close; + } + + return h; +out_close: + nfnl_close(&h->nfnlh); +out_free: + free(h); + return NULL; +} + +int nfqnl_close(struct nfqnl_handle *h) +{ + int ret = nfnl_close(&h->nfnlh); + if (ret == 0) + free(h); + return ret; +} + +/* bind nf_queue from a specific protocol family */ +int nfqnl_bind_pf(struct nfqnl_handle *h, u_int16_t pf) +{ + return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf); +} + +/* unbind nf_queue from a specific protocol family */ +int nfqnl_unbind_pf(struct nfqnl_handle *h, u_int16_t pf) +{ + return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf); +} + +/* bind this socket to a specific queue number */ +struct nfqnl_q_handle *nfqnl_create_queue(struct nfqnl_handle *h, + u_int16_t num, + nfqnl_callback *cb, + void *data) +{ + int ret; + struct nfqnl_q_handle *qh; + + if (find_qh(h, num)) + return NULL; + + qh = malloc(sizeof(*qh)); + + memset(qh, 0, sizeof(*qh)); + qh->h = h; + qh->id = num; + qh->cb = cb; + qh->data = data; + + ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0); + if (ret < 0) { + nfqnl_errno = ret; + free(qh); + return NULL; + } + + add_qh(qh); + return qh; +} + +/* unbind this socket from a specific queue number */ +int nfqnl_destroy_queue(struct nfqnl_q_handle *qh) +{ + int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0); + if (ret == 0) { + del_qh(qh); + free(qh); + } + + return ret; +} + +int nfqnl_handle_packet(struct nfqnl_handle *h, char *buf, int len) +{ + return nfnl_handle_packet(&h->nfnlh, buf, len); +} + +int nfqnl_set_mode(struct nfqnl_q_handle *qh, + u_int8_t mode, u_int32_t range) +{ + char buf[NFNL_HEADER_LEN + +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))]; + struct nfqnl_msg_config_params params; + struct nlmsghdr *nmh = (struct nlmsghdr *) buf; + + nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id, + NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); + + params.copy_range = htonl(range); + params.copy_mode = mode; + nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_PARAMS, ¶ms, + sizeof(params)); + + return nfnl_talk(&qh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); +} + +static int __set_verdict(struct nfqnl_q_handle *qh, u_int32_t id, + u_int32_t verdict, u_int32_t mark, int set_mark, + u_int32_t data_len, unsigned char *data) +{ + struct nfqnl_msg_verdict_hdr vh; + char buf[NFNL_HEADER_LEN + +NFA_LENGTH(sizeof(mark)) + +NFA_LENGTH(sizeof(vh))]; + struct nlmsghdr *nmh = (struct nlmsghdr *) buf; + + struct iovec iov[3]; + int nvecs; + + memset(iov, 0, sizeof(iov)); + + vh.verdict = htonl(verdict); + vh.id = htonl(id); + + nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id, + NFQNL_MSG_VERDICT, NLM_F_REQUEST); + + /* add verdict header */ + nfnl_addattr_l(nmh, sizeof(buf), NFQA_VERDICT_HDR, &vh, sizeof(vh)); + + if (set_mark) + nfnl_addattr32(nmh, sizeof(buf), NFQA_MARK, mark); + + iov[0].iov_base = nmh; + iov[0].iov_len = NLMSG_TAIL(nmh) - (void *)nmh; + nvecs = 1; + + if (data_len) { + struct nfattr data_attr; + + nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD, + data_len, data); + nvecs += 2; + } + + return nfnl_sendiov(&qh->h->nfnlh, iov, nvecs, 0); +} + +int nfqnl_set_verdict(struct nfqnl_q_handle *qh, u_int32_t id, + u_int32_t verdict, u_int32_t data_len, + unsigned char *buf) +{ + return __set_verdict(qh, id, verdict, 0, 0, data_len, buf); +} + +int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh, u_int32_t id, + u_int32_t verdict, u_int32_t mark, + u_int32_t datalen, unsigned char *buf) +{ + return __set_verdict(qh, id, verdict, mark, 1, datalen, buf); +} + +/************************************************************* + * Message parsing functions + *************************************************************/ + +struct nfqnl_msg_packet_hdr *nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]) +{ + return nfnl_get_pointer_to_data(nfa, NFQA_PACKET_HDR, + struct nfqnl_msg_packet_hdr); +} + +uint32_t nfqnl_get_nfmark(struct nfattr *nfa[]) +{ + return ntohl(nfnl_get_data(nfa, NFQA_MARK, u_int32_t)); +} + +struct nfqnl_msg_packet_timestamp *nfqnl_get_timestamp(struct nfattr *nfa[]) +{ + return nfnl_get_pointer_to_data(nfa, NFQA_TIMESTAMP, + struct nfqnl_msg_packet_timestamp); +} + +/* all nfqnl_get_*dev() functions return 0 if not set, since linux only allows + * ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1) */ +u_int32_t nfqnl_get_indev(struct nfattr *nfa[]) +{ + return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_INDEV, u_int32_t)); +} + +u_int32_t nfqnl_get_physindev(struct nfattr *nfa[]) +{ + return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_PHYSINDEV, u_int32_t)); +} + +u_int32_t nfqnl_get_outdev(struct nfattr *nfa[]) +{ + return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_OUTDEV, u_int32_t)); +} + +u_int32_t nfqnl_get_physoutdev(struct nfattr *nfa[]) +{ + return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t)); +} + +struct nfqnl_msg_packet_hw *nfqnl_get_packet_hw(struct nfattr *nfa[]) +{ + return nfnl_get_pointer_to_data(nfa, NFQA_HWADDR, + struct nfqnl_msg_packet_hw); +} + +int nfqnl_get_payload(struct nfattr *nfa[], char **data, + unsigned int *datalen) +{ + *data = nfnl_get_pointer_to_data(nfa, NFQA_PAYLOAD, char*); + if (*data) { + *datalen = NFA_PAYLOAD(nfa[NFQA_PAYLOAD-1]); + return 1; + } + return 0; +} diff --git a/src/libnfnetlink_queue.c b/src/libnfnetlink_queue.c deleted file mode 100644 index 8e84c50..0000000 --- a/src/libnfnetlink_queue.c +++ /dev/null @@ -1,375 +0,0 @@ -/* libnfqnetlink.c: generic library for access to nf_queue - * - * (C) 2005 by Harald Welte - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -struct nfqnl_handle -{ - struct nfnl_handle nfnlh; - struct nfqnl_q_handle *qh_list; -}; - -struct nfqnl_q_handle -{ - struct nfqnl_q_handle *next; - struct nfqnl_handle *h; - u_int16_t id; - - nfqnl_callback *cb; - void *data; -}; - - -int nfqnl_errno; - -/*********************************************************************** - * low level stuff - ***********************************************************************/ - -static void del_qh(struct nfqnl_q_handle *qh) -{ - struct nfqnl_q_handle *cur_qh, *prev_qh = NULL; - - for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) { - if (cur_qh == qh) { - if (prev_qh) - prev_qh->next = qh->next; - else - qh->h->qh_list = qh->next; - return; - } - prev_qh = cur_qh; - } -} - -static void add_qh(struct nfqnl_q_handle *qh) -{ - qh->next = qh->h->qh_list; - qh->h->qh_list = qh; -} - -static struct nfqnl_q_handle *find_qh(struct nfqnl_handle *h, u_int16_t id) -{ - struct nfqnl_q_handle *qh; - - for (qh = h->qh_list; qh; qh = qh->next) { - if (qh->id == id) - return qh; - } - return NULL; -} - -/* build a NFQNL_MSG_CONFIG message */ - static int -__build_send_cfg_msg(struct nfqnl_handle *h, u_int8_t command, - u_int16_t queuenum, u_int16_t pf) -{ - char buf[NFNL_HEADER_LEN - +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))]; - struct nfqnl_msg_config_cmd cmd; - struct nlmsghdr *nmh = (struct nlmsghdr *) buf; - - nfnl_fill_hdr(&h->nfnlh, nmh, 0, AF_UNSPEC, queuenum, - NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); - - cmd.command = command; - cmd.pf = htons(pf); - nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_CMD, &cmd, sizeof(cmd)); - - return nfnl_talk(&h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); -} - -static int __nfqnl_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[], - void *data) -{ - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - struct nfqnl_handle *h = data; - u_int16_t queue_num = ntohs(nfmsg->res_id); - struct nfqnl_q_handle *qh = find_qh(h, queue_num); - - if (!qh) - return -ENODEV; - - if (!qh->cb) - return -ENODEV; - - return qh->cb(qh, nfmsg, nfa, qh->data); -} - -static struct nfnl_callback pkt_cb = { - .call = &__nfqnl_rcv_pkt, - .attr_count = NFQA_MAX, -}; - -/* public interface */ - -struct nfnl_handle *nfqnl_nfnlh(struct nfqnl_handle *h) -{ - return &h->nfnlh; -} - -int nfqnl_fd(struct nfqnl_handle *h) -{ - return nfnl_fd(nfqnl_nfnlh(h)); -} - -struct nfqnl_handle *nfqnl_open(void) -{ - struct nfqnl_handle *h; - int err; - - h = malloc(sizeof(*h)); - if (!h) - return NULL; - - memset(h, 0, sizeof(*h)); - - err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_QUEUE, NFQNL_MSG_MAX, 0); - if (err < 0) { - nfqnl_errno = err; - goto out_free; - } - - pkt_cb.data = h; - err = nfnl_callback_register(&h->nfnlh, NFQNL_MSG_PACKET, &pkt_cb); - if (err < 0) { - nfqnl_errno = err; - goto out_close; - } - - return h; -out_close: - nfnl_close(&h->nfnlh); -out_free: - free(h); - return NULL; -} - -int nfqnl_close(struct nfqnl_handle *h) -{ - int ret = nfnl_close(&h->nfnlh); - if (ret == 0) - free(h); - return ret; -} - -/* bind nf_queue from a specific protocol family */ -int nfqnl_bind_pf(struct nfqnl_handle *h, u_int16_t pf) -{ - return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf); -} - -/* unbind nf_queue from a specific protocol family */ -int nfqnl_unbind_pf(struct nfqnl_handle *h, u_int16_t pf) -{ - return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf); -} - -/* bind this socket to a specific queue number */ -struct nfqnl_q_handle *nfqnl_create_queue(struct nfqnl_handle *h, - u_int16_t num, - nfqnl_callback *cb, - void *data) -{ - int ret; - struct nfqnl_q_handle *qh; - - if (find_qh(h, num)) - return NULL; - - qh = malloc(sizeof(*qh)); - - memset(qh, 0, sizeof(*qh)); - qh->h = h; - qh->id = num; - qh->cb = cb; - qh->data = data; - - ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0); - if (ret < 0) { - nfqnl_errno = ret; - free(qh); - return NULL; - } - - add_qh(qh); - return qh; -} - -/* unbind this socket from a specific queue number */ -int nfqnl_destroy_queue(struct nfqnl_q_handle *qh) -{ - int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0); - if (ret == 0) { - del_qh(qh); - free(qh); - } - - return ret; -} - -int nfqnl_handle_packet(struct nfqnl_handle *h, char *buf, int len) -{ - return nfnl_handle_packet(&h->nfnlh, buf, len); -} - -int nfqnl_set_mode(struct nfqnl_q_handle *qh, - u_int8_t mode, u_int32_t range) -{ - char buf[NFNL_HEADER_LEN - +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))]; - struct nfqnl_msg_config_params params; - struct nlmsghdr *nmh = (struct nlmsghdr *) buf; - - nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id, - NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); - - params.copy_range = htonl(range); - params.copy_mode = mode; - nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_PARAMS, ¶ms, - sizeof(params)); - - return nfnl_talk(&qh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); -} - -static int __set_verdict(struct nfqnl_q_handle *qh, u_int32_t id, - u_int32_t verdict, u_int32_t mark, int set_mark, - u_int32_t data_len, unsigned char *data) -{ - struct nfqnl_msg_verdict_hdr vh; - char buf[NFNL_HEADER_LEN - +NFA_LENGTH(sizeof(mark)) - +NFA_LENGTH(sizeof(vh))]; - struct nlmsghdr *nmh = (struct nlmsghdr *) buf; - - struct iovec iov[3]; - int nvecs; - - memset(iov, 0, sizeof(iov)); - - vh.verdict = htonl(verdict); - vh.id = htonl(id); - - nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id, - NFQNL_MSG_VERDICT, NLM_F_REQUEST); - - /* add verdict header */ - nfnl_addattr_l(nmh, sizeof(buf), NFQA_VERDICT_HDR, &vh, sizeof(vh)); - - if (set_mark) - nfnl_addattr32(nmh, sizeof(buf), NFQA_MARK, mark); - - iov[0].iov_base = nmh; - iov[0].iov_len = NLMSG_TAIL(nmh) - (void *)nmh; - nvecs = 1; - - if (data_len) { - struct nfattr data_attr; - - nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD, - data_len, data); - nvecs += 2; - } - - return nfnl_sendiov(&qh->h->nfnlh, iov, nvecs, 0); -} - -int nfqnl_set_verdict(struct nfqnl_q_handle *qh, u_int32_t id, - u_int32_t verdict, u_int32_t data_len, - unsigned char *buf) -{ - return __set_verdict(qh, id, verdict, 0, 0, data_len, buf); -} - -int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh, u_int32_t id, - u_int32_t verdict, u_int32_t mark, - u_int32_t datalen, unsigned char *buf) -{ - return __set_verdict(qh, id, verdict, mark, 1, datalen, buf); -} - -/************************************************************* - * Message parsing functions - *************************************************************/ - -struct nfqnl_msg_packet_hdr *nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]) -{ - return nfnl_get_pointer_to_data(nfa, NFQA_PACKET_HDR, - struct nfqnl_msg_packet_hdr); -} - -uint32_t nfqnl_get_nfmark(struct nfattr *nfa[]) -{ - return ntohl(nfnl_get_data(nfa, NFQA_MARK, u_int32_t)); -} - -struct nfqnl_msg_packet_timestamp *nfqnl_get_timestamp(struct nfattr *nfa[]) -{ - return nfnl_get_pointer_to_data(nfa, NFQA_TIMESTAMP, - struct nfqnl_msg_packet_timestamp); -} - -/* all nfqnl_get_*dev() functions return 0 if not set, since linux only allows - * ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1) */ -u_int32_t nfqnl_get_indev(struct nfattr *nfa[]) -{ - return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_INDEV, u_int32_t)); -} - -u_int32_t nfqnl_get_physindev(struct nfattr *nfa[]) -{ - return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_PHYSINDEV, u_int32_t)); -} - -u_int32_t nfqnl_get_outdev(struct nfattr *nfa[]) -{ - return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_OUTDEV, u_int32_t)); -} - -u_int32_t nfqnl_get_physoutdev(struct nfattr *nfa[]) -{ - return ntohl(nfnl_get_data(nfa, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t)); -} - -struct nfqnl_msg_packet_hw *nfqnl_get_packet_hw(struct nfattr *nfa[]) -{ - return nfnl_get_pointer_to_data(nfa, NFQA_HWADDR, - struct nfqnl_msg_packet_hw); -} - -int nfqnl_get_payload(struct nfattr *nfa[], char **data, - unsigned int *datalen) -{ - *data = nfnl_get_pointer_to_data(nfa, NFQA_PAYLOAD, char*); - if (*data) { - *datalen = NFA_PAYLOAD(nfa[NFQA_PAYLOAD-1]); - return 1; - } - return 0; -} -- cgit v1.2.3