8 #include <libmnl/libmnl.h>
9 #include <linux/netfilter.h>
10 #include <linux/netfilter/nfnetlink.h>
12 #include <linux/types.h>
13 #include <linux/netfilter/nfnetlink_queue.h>
15 #include <libnetfilter_queue/libnetfilter_queue.h>
17 static struct mnl_socket *nl;
19 static struct nlmsghdr *
20 nfq_build_header(
char *buf,
int type, uint32_t queue_num)
22 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
23 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | type;
24 nlh->nlmsg_flags = NLM_F_REQUEST;
26 struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh,
sizeof(*nfg));
27 nfg->nfgen_family = AF_UNSPEC;
28 nfg->version = NFNETLINK_V0;
29 nfg->res_id = htons(queue_num);
35 nfq_send_verdict(
int queue_num, uint32_t
id, uint8_t *pkt, uint16_t pktlen)
37 char buf[MNL_SOCKET_BUFFER_SIZE];
41 nlh = nfq_build_header(buf, NFQNL_MSG_VERDICT, queue_num);
42 nfq_nlmsg_verdict_build(nlh,
id, NF_ACCEPT);
43 nfq_nlmsg_verdict_payload(nlh, pkt, pktlen);
45 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
46 perror(
"mnl_socket_send");
53 static int queue_cb(
const struct nlmsghdr *nlh,
void *data)
55 struct nfqnl_msg_packet_hdr *ph = NULL;
56 struct nlattr *attr[NFQA_MAX+1];
63 perror(
"problems parsing");
67 nfg = mnl_nlmsg_get_payload(nlh);
69 ph = (
struct nfqnl_msg_packet_hdr *)
70 mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
72 perror(
"problems retrieving metaheader");
76 id = ntohl(ph->packet_id);
78 printf(
"packet received (id=%u hw=0x%04x hook=%u)\n",
79 id, ntohs(ph->hw_protocol), ph->hook);
81 pkt = mnl_attr_get_payload(attr[NFQA_PAYLOAD]);
82 pktlen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
84 nfq_send_verdict(ntohs(nfg->res_id),
id, pkt, pktlen);
89 int main(
int argc,
char *argv[])
91 char buf[MNL_SOCKET_BUFFER_SIZE];
94 unsigned int portid, queue_num;
97 printf(
"Usage: %s [queue_num]\n", argv[0]);
100 queue_num = atoi(argv[1]);
102 nl = mnl_socket_open(NETLINK_NETFILTER);
104 perror(
"mnl_socket_open");
108 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
109 perror(
"mnl_socket_bind");
112 portid = mnl_socket_get_portid(nl);
114 nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, 0);
115 nfq_nlmsg_cfg_build_request(nlh, AF_INET, NFQNL_CFG_CMD_PF_UNBIND);
117 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
118 perror(
"mnl_socket_send");
122 nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, 0);
123 nfq_nlmsg_cfg_build_request(nlh, AF_INET, NFQNL_CFG_CMD_PF_BIND);
125 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
126 perror(
"mnl_socket_send");
130 nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, queue_num);
131 nfq_nlmsg_cfg_build_request(nlh, AF_INET, NFQNL_CFG_CMD_BIND);
133 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
134 perror(
"mnl_socket_send");
138 nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, queue_num);
139 nfq_nlmsg_cfg_add_copy(nlh, NFQNL_COPY_PACKET, 0xffff);
141 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
142 perror(
"mnl_socket_send");
146 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
148 perror(
"mnl_socket_recvfrom");
154 ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
156 perror(
"mnl_cb_run");
160 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
162 perror(
"mnl_socket_recvfrom");
167 mnl_socket_close(nl);
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)