9 #include <libmnl/libmnl.h>
10 #include <linux/netfilter.h>
11 #include <linux/netfilter/nfnetlink.h>
13 #include <linux/types.h>
14 #include <linux/netfilter/nfnetlink_queue.h>
16 #include <libnetfilter_queue/libnetfilter_queue.h>
19 #include <linux/netfilter/nfnetlink_conntrack.h>
21 static struct mnl_socket *nl;
23 static struct nlmsghdr *
24 nfq_hdr_put(
char *buf,
int type, uint32_t queue_num)
26 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
27 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | type;
28 nlh->nlmsg_flags = NLM_F_REQUEST;
30 struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh,
sizeof(*nfg));
31 nfg->nfgen_family = AF_UNSPEC;
32 nfg->version = NFNETLINK_V0;
33 nfg->res_id = htons(queue_num);
39 nfq_send_verdict(
int queue_num, uint32_t
id)
41 char buf[MNL_SOCKET_BUFFER_SIZE];
45 nlh = nfq_hdr_put(buf, NFQNL_MSG_VERDICT, queue_num);
46 nfq_nlmsg_verdict_put(nlh,
id, NF_ACCEPT);
49 nest = mnl_attr_nest_start(nlh, NFQA_CT);
52 mnl_attr_put_u32(nlh, CTA_MARK, htonl(42));
56 mnl_attr_nest_end(nlh, nest);
58 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
59 perror(
"mnl_socket_send");
64 static int queue_cb(
const struct nlmsghdr *nlh,
void *data)
66 struct nfqnl_msg_packet_hdr *ph = NULL;
67 struct nlattr *attr[NFQA_MAX+1] = {};
68 uint32_t
id = 0, skbinfo;
73 perror(
"problems parsing");
77 nfg = mnl_nlmsg_get_payload(nlh);
79 if (attr[NFQA_PACKET_HDR] == NULL) {
80 fputs(
"metaheader not set\n", stderr);
84 ph = mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
86 plen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
89 skbinfo = attr[NFQA_SKB_INFO] ? ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO])) : 0;
91 if (attr[NFQA_CAP_LEN]) {
92 uint32_t orig_len = ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN]));
97 if (skbinfo & NFQA_SKB_GSO)
100 id = ntohl(ph->packet_id);
101 printf(
"packet received (id=%u hw=0x%04x hook=%u, payload len %u",
102 id, ntohs(ph->hw_protocol), ph->hook, plen);
111 if (skbinfo & NFQA_SKB_CSUMNOTREADY)
112 printf(
", checksum not ready");
115 nfq_send_verdict(ntohs(nfg->res_id),
id);
120 int main(
int argc,
char *argv[])
124 size_t sizeof_buf = 0xffff + (MNL_SOCKET_BUFFER_SIZE/2);
125 struct nlmsghdr *nlh;
127 unsigned int portid, queue_num;
130 printf(
"Usage: %s [queue_num]\n", argv[0]);
133 queue_num = atoi(argv[1]);
135 nl = mnl_socket_open(NETLINK_NETFILTER);
137 perror(
"mnl_socket_open");
141 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
142 perror(
"mnl_socket_bind");
145 portid = mnl_socket_get_portid(nl);
147 buf = malloc(sizeof_buf);
149 perror(
"allocate receive buffer");
154 nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, 0);
157 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
158 perror(
"mnl_socket_send");
162 nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, 0);
165 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
166 perror(
"mnl_socket_send");
170 nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, queue_num);
173 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
174 perror(
"mnl_socket_send");
178 nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, queue_num);
179 nfq_nlmsg_cfg_put_params(nlh, NFQNL_COPY_PACKET, 0xffff);
181 mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(NFQA_CFG_F_GSO));
182 mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(NFQA_CFG_F_GSO));
184 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
185 perror(
"mnl_socket_send");
194 mnl_socket_setsockopt(nl, NETLINK_NO_ENOBUFS, &ret,
sizeof(
int));
197 ret = mnl_socket_recvfrom(nl, buf, sizeof_buf);
199 perror(
"mnl_socket_recvfrom");
203 ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
205 perror(
"mnl_cb_run");
210 mnl_socket_close(nl);
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)