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;
24 nfq_send_verdict(
int queue_num, uint32_t
id)
26 char buf[MNL_SOCKET_BUFFER_SIZE];
34 nest = mnl_attr_nest_start(nlh, NFQA_CT);
37 mnl_attr_put_u32(nlh, CTA_MARK, htonl(42));
41 mnl_attr_nest_end(nlh, nest);
43 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
44 perror(
"mnl_socket_send");
49 static int queue_cb(
const struct nlmsghdr *nlh,
void *data)
51 struct nfqnl_msg_packet_hdr *ph = NULL;
52 struct nlattr *attr[NFQA_MAX+1] = {};
53 uint32_t
id = 0, skbinfo;
58 perror(
"problems parsing");
62 nfg = mnl_nlmsg_get_payload(nlh);
64 if (attr[NFQA_PACKET_HDR] == NULL) {
65 fputs(
"metaheader not set\n", stderr);
69 ph = mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
71 plen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
74 skbinfo = attr[NFQA_SKB_INFO] ? ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO])) : 0;
76 if (attr[NFQA_CAP_LEN]) {
77 uint32_t orig_len = ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN]));
82 if (skbinfo & NFQA_SKB_GSO)
85 id = ntohl(ph->packet_id);
86 printf(
"packet received (id=%u hw=0x%04x hook=%u, payload len %u",
87 id, ntohs(ph->hw_protocol), ph->hook, plen);
96 if (skbinfo & NFQA_SKB_CSUMNOTREADY)
97 printf(
", checksum not ready");
100 nfq_send_verdict(ntohs(nfg->res_id),
id);
105 int main(
int argc,
char *argv[])
109 size_t sizeof_buf = 0xffff + (MNL_SOCKET_BUFFER_SIZE/2);
110 struct nlmsghdr *nlh;
112 unsigned int portid, queue_num;
115 printf(
"Usage: %s [queue_num]\n", argv[0]);
118 queue_num = atoi(argv[1]);
120 nl = mnl_socket_open(NETLINK_NETFILTER);
122 perror(
"mnl_socket_open");
126 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
127 perror(
"mnl_socket_bind");
130 portid = mnl_socket_get_portid(nl);
132 buf = malloc(sizeof_buf);
134 perror(
"allocate receive buffer");
141 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
142 perror(
"mnl_socket_send");
149 mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(NFQA_CFG_F_GSO));
150 mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(NFQA_CFG_F_GSO));
152 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
153 perror(
"mnl_socket_send");
162 mnl_socket_setsockopt(nl, NETLINK_NO_ENOBUFS, &ret,
sizeof(
int));
165 ret = mnl_socket_recvfrom(nl, buf, sizeof_buf);
167 perror(
"mnl_socket_recvfrom");
171 ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
173 perror(
"mnl_cb_run");
178 mnl_socket_close(nl);
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict)
struct nlmsghdr * nfq_nlmsg_put(char *buf, int type, uint32_t queue_num)
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range)