1 /* libnfqnetlink.c: generic library for access to nf_queue
3 * (C) 2005 by Harald Welte <laforge@gnumonks.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <netinet/in.h>
27 #include <sys/socket.h>
28 #include <linux/netlink.h>
29 #include <linux/netfilter/nfnetlink.h>
30 #include <linux/netfilter/nfnetlink_queue.h>
31 #include "libnfnetlink_queue.h"
33 /***********************************************************************
35 ***********************************************************************/
37 int nfqnl_open(struct nfqnl_handle *h)
41 memset(h, 0, sizeof(*h));
43 err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_QUEUE, 0);
50 int nfqnl_close(struct nfqnl_handle *h)
52 return nfnl_close(&h->nfnlh);
55 /* build a NFQNL_MSG_CONFIG message */
57 __build_send_cfg_msg(struct nfqnl_handle *h, u_int8_t command,
58 u_int16_t queuenum, u_int16_t pf)
60 char buf[NLMSG_LENGTH(sizeof(struct nlmsghdr))
61 +NLMSG_LENGTH(sizeof(struct nfgenmsg))
62 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
63 struct nfqnl_msg_config_cmd cmd;
64 struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
66 nfnl_fill_hdr(&h->nfnlh, nmh, 0, AF_UNSPEC, queuenum,
67 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
69 cmd.command = command;
71 nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_CMD, &cmd, sizeof(cmd));
73 return nfnl_send(&h->nfnlh, nmh);
76 /* bind nf_queue from a specific protocol family */
77 int nfqnl_bind_pf(struct nfqnl_handle *h, u_int16_t pf)
79 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
82 /* unbind nf_queue from a specific protocol family */
83 int nfqnl_unbind_pf(struct nfqnl_handle *h, u_int16_t pf)
85 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
88 /* bind this socket to a specific queue number */
89 int nfqnl_create_queue(struct nfqnl_handle *h,
90 struct nfqnl_q_handle *qh, u_int16_t num)
95 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
98 /* unbind this socket from a specific queue number */
99 int nfqnl_destroy_queue(struct nfqnl_q_handle *qh)
101 int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
108 int nfqnl_set_mode(struct nfqnl_q_handle *qh,
109 u_int8_t mode, u_int32_t range)
111 char buf[NLMSG_LENGTH(sizeof(struct nlmsghdr))
112 +NLMSG_LENGTH(sizeof(struct nfgenmsg))
113 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
114 struct nfqnl_msg_config_params params;
115 struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
117 nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id,
118 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
120 params.copy_range = htonl(range);
121 params.copy_mode = mode;
122 nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_PARAMS, ¶ms,
125 return nfnl_send(&qh->h->nfnlh, nmh);
128 static int __set_verdict(struct nfqnl_q_handle *qh, u_int32_t id,
129 u_int32_t verdict, u_int32_t mark, int set_mark,
130 u_int32_t data_len, unsigned char *data)
132 struct nfqnl_msg_verdict_hdr vh;
133 char buf[NLMSG_LENGTH(sizeof(struct nlmsghdr))
134 +NLMSG_LENGTH(sizeof(struct nfgenmsg))
135 +NFA_LENGTH(sizeof(mark))
136 +NFA_LENGTH(sizeof(vh))];
137 struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
142 vh.verdict = htonl(verdict);
145 nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id,
146 NFQNL_MSG_VERDICT, NLM_F_REQUEST);
148 /* add verdict header */
149 nfnl_addattr_l(nmh, sizeof(buf), NFQA_VERDICT_HDR, &vh, sizeof(vh));
152 nfnl_addattr32(nmh, sizeof(buf), NFQA_MARK, mark);
154 iov[0].iov_base = nmh;
155 iov[0].iov_len = NLMSG_TAIL(nmh) - (void *)nmh;
159 struct nfattr data_attr;
161 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
166 return nfnl_sendiov(&qh->h->nfnlh, iov, nvecs, 0);
169 int nfqnl_set_verdict(struct nfqnl_q_handle *qh, u_int32_t id,
170 u_int32_t verdict, u_int32_t data_len,
173 return __set_verdict(qh, id, verdict, 0, 0, data_len, buf);
176 int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh, u_int32_t id,
177 u_int32_t verdict, u_int32_t mark,
178 u_int32_t datalen, unsigned char *buf)
180 return __set_verdict(qh, id, verdict, mark, 1, datalen, buf);