9 #include <libmnl/libmnl.h>
10 #include <linux/netfilter.h>
11 #include <linux/netfilter/nfnetlink.h>
14 #define aligned_be64 u_int64_t __attribute__((aligned(8)))
17 #include <linux/netfilter/nfnetlink_queue.h>
19 static int parse_attr_cb(
const struct nlattr *attr,
void *data)
21 const struct nlattr **tb = data;
30 case NFQA_IFINDEX_INDEV:
31 case NFQA_IFINDEX_OUTDEV:
32 case NFQA_IFINDEX_PHYSINDEV:
33 case NFQA_IFINDEX_PHYSOUTDEV:
35 perror(
"mnl_attr_validate");
41 sizeof(
struct nfqnl_msg_packet_timestamp)) < 0) {
42 perror(
"mnl_attr_validate");
48 sizeof(
struct nfqnl_msg_packet_hw)) < 0) {
49 perror(
"mnl_attr_validate");
60 static int queue_cb(
const struct nlmsghdr *nlh,
void *data)
62 struct nlattr *tb[NFQA_MAX+1] = {};
63 struct nfqnl_msg_packet_hdr *ph = NULL;
67 if (tb[NFQA_PACKET_HDR]) {
69 id = ntohl(ph->packet_id);
71 printf(
"packet received (id=%u hw=0x%04x hook=%u)\n",
72 id, ntohs(ph->hw_protocol), ph->hook);
74 return MNL_CB_OK + id;
77 static struct nlmsghdr *
78 nfq_build_cfg_pf_request(
char *buf, uint8_t command)
81 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
82 nlh->nlmsg_flags = NLM_F_REQUEST;
85 nfg->nfgen_family = AF_UNSPEC;
86 nfg->version = NFNETLINK_V0;
88 struct nfqnl_msg_config_cmd cmd = {
97 static struct nlmsghdr *
98 nfq_build_cfg_request(
char *buf, uint8_t command,
int queue_num)
101 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
102 nlh->nlmsg_flags = NLM_F_REQUEST;
105 nfg->nfgen_family = AF_UNSPEC;
106 nfg->version = NFNETLINK_V0;
107 nfg->res_id = htons(queue_num);
109 struct nfqnl_msg_config_cmd cmd = {
111 .pf = htons(AF_INET),
118 static struct nlmsghdr *
119 nfq_build_cfg_params(
char *buf, uint8_t mode,
int range,
int queue_num)
122 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
123 nlh->nlmsg_flags = NLM_F_REQUEST;
126 nfg->nfgen_family = AF_UNSPEC;
127 nfg->version = NFNETLINK_V0;
128 nfg->res_id = htons(queue_num);
130 struct nfqnl_msg_config_params params = {
131 .copy_range = htonl(range),
134 mnl_attr_put(nlh, NFQA_CFG_PARAMS,
sizeof(params), ¶ms);
139 static struct nlmsghdr *
140 nfq_build_verdict(
char *buf,
int id,
int queue_num,
int verd)
142 struct nlmsghdr *nlh;
143 struct nfgenmsg *nfg;
146 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT;
147 nlh->nlmsg_flags = NLM_F_REQUEST;
149 nfg->nfgen_family = AF_UNSPEC;
150 nfg->version = NFNETLINK_V0;
151 nfg->res_id = htons(queue_num);
153 struct nfqnl_msg_verdict_hdr vh = {
154 .verdict = htonl(verd),
162 int main(
int argc,
char *argv[])
165 char buf[MNL_SOCKET_BUFFER_SIZE];
166 struct nlmsghdr *nlh;
168 unsigned int portid, queue_num;
171 printf(
"Usage: %s [queue_num]\n", argv[0]);
174 queue_num = atoi(argv[1]);
178 perror(
"mnl_socket_open");
183 perror(
"mnl_socket_bind");
188 nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_UNBIND);
191 perror(
"mnl_socket_send");
195 nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_BIND);
198 perror(
"mnl_socket_send");
202 nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num);
205 perror(
"mnl_socket_send");
209 nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num);
212 perror(
"mnl_socket_send");
218 perror(
"mnl_socket_recvfrom");
224 ret =
mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
226 perror(
"mnl_cb_run");
230 id = ret - MNL_CB_OK;
231 nlh = nfq_build_verdict(buf,
id, queue_num, NF_ACCEPT);
233 perror(
"mnl_socket_send");
239 perror(
"mnl_socket_recvfrom");
int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len)
int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data)
void * mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
uint16_t mnl_attr_get_type(const struct nlattr *attr)
struct mnl_socket * mnl_socket_open(int type)
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz)
void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
void * mnl_attr_get_payload(const struct nlattr *attr)
int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data)
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
int mnl_socket_close(struct mnl_socket *nl)
int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype)
struct nlmsghdr * mnl_nlmsg_put_header(void *buf)
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz)
int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)