9#include <libmnl/libmnl.h>
10#include <linux/netfilter.h>
11#include <linux/netfilter/nfnetlink.h>
12#include <linux/netfilter/nfnetlink_queue.h>
14static int parse_attr_cb(
const struct nlattr *attr,
void *data)
16 const struct nlattr **tb = data;
25 case NFQA_IFINDEX_INDEV:
26 case NFQA_IFINDEX_OUTDEV:
27 case NFQA_IFINDEX_PHYSINDEV:
28 case NFQA_IFINDEX_PHYSOUTDEV:
30 perror(
"mnl_attr_validate");
36 sizeof(
struct nfqnl_msg_packet_timestamp)) < 0) {
37 perror(
"mnl_attr_validate2");
43 sizeof(
struct nfqnl_msg_packet_hw)) < 0) {
44 perror(
"mnl_attr_validate2");
55static int queue_cb(
const struct nlmsghdr *nlh,
void *data)
57 struct nlattr *tb[NFQA_MAX+1] = {};
58 struct nfqnl_msg_packet_hdr *ph = NULL;
62 if (tb[NFQA_PACKET_HDR]) {
64 id = ntohl(ph->packet_id);
66 printf(
"packet received (id=%u hw=0x%04x hook=%u)\n",
67 id, ntohs(ph->hw_protocol), ph->hook);
70 return MNL_CB_OK + id;
73static struct nlmsghdr *
74nfq_build_cfg_pf_request(
char *buf, uint8_t command)
77 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
78 nlh->nlmsg_flags = NLM_F_REQUEST;
81 nfg->nfgen_family = AF_UNSPEC;
82 nfg->version = NFNETLINK_V0;
84 struct nfqnl_msg_config_cmd cmd = {
93static struct nlmsghdr *
94nfq_build_cfg_request(
char *buf, uint8_t command,
int queue_num)
97 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
98 nlh->nlmsg_flags = NLM_F_REQUEST;
101 nfg->nfgen_family = AF_UNSPEC;
102 nfg->version = NFNETLINK_V0;
103 nfg->res_id = htons(queue_num);
105 struct nfqnl_msg_config_cmd cmd = {
107 .pf = htons(AF_INET),
114static struct nlmsghdr *
115nfq_build_cfg_params(
char *buf, uint8_t mode,
int range,
int queue_num)
118 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
119 nlh->nlmsg_flags = NLM_F_REQUEST;
122 nfg->nfgen_family = AF_UNSPEC;
123 nfg->version = NFNETLINK_V0;
124 nfg->res_id = htons(queue_num);
126 struct nfqnl_msg_config_params params = {
127 .copy_range = htonl(range),
130 mnl_attr_put(nlh, NFQA_CFG_PARAMS,
sizeof(params), ¶ms);
135static struct nlmsghdr *
136nfq_build_verdict(
char *buf,
int id,
int queue_num,
int verd)
138 struct nlmsghdr *nlh;
139 struct nfgenmsg *nfg;
142 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT;
143 nlh->nlmsg_flags = NLM_F_REQUEST;
145 nfg->nfgen_family = AF_UNSPEC;
146 nfg->version = NFNETLINK_V0;
147 nfg->res_id = htons(queue_num);
149 struct nfqnl_msg_verdict_hdr vh = {
150 .verdict = htonl(verd),
158int main(
int argc,
char *argv[])
160 struct mnl_socket *nl;
161 char buf[MNL_SOCKET_BUFFER_SIZE];
162 struct nlmsghdr *nlh;
164 unsigned int portid, queue_num;
167 printf(
"Usage: %s [queue_num]\n", argv[0]);
170 queue_num = atoi(argv[1]);
174 perror(
"mnl_socket_open");
179 perror(
"mnl_socket_bind");
184 nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_UNBIND);
187 perror(
"mnl_socket_sendto");
191 nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_BIND);
194 perror(
"mnl_socket_sendto");
198 nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num);
201 perror(
"mnl_socket_sendto");
205 nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num);
208 perror(
"mnl_socket_sendto");
214 perror(
"mnl_socket_recvfrom");
220 ret =
mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
222 perror(
"mnl_cb_run");
226 id = ret - MNL_CB_OK;
227 nlh = nfq_build_verdict(buf,
id, queue_num, NF_ACCEPT);
229 perror(
"mnl_socket_sendto");
235 perror(
"mnl_socket_recvfrom");
void * mnl_attr_get_payload(const struct nlattr *attr)
int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data)
int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
uint16_t mnl_attr_get_type(const struct nlattr *attr)
int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t exp_len)
void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data)
struct nlmsghdr * mnl_nlmsg_put_header(void *buf)
void * mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
int mnl_socket_close(struct mnl_socket *nl)
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
struct mnl_socket * mnl_socket_open(int bus)
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)