15#include <netinet/in.h>
17#include <linux/netfilter/nfnetlink.h>
18#include <linux/netfilter/nf_tables.h>
20#include <libmnl/libmnl.h>
21#include <libnftnl/table.h>
22#include <libnftnl/chain.h>
23#include <libnftnl/rule.h>
24#include <libnftnl/set.h>
25#include <libnftnl/gen.h>
26#include <libnftnl/common.h>
28static uint32_t event2flag(uint32_t event)
31 case NFT_MSG_NEWTABLE:
32 case NFT_MSG_NEWCHAIN:
35 case NFT_MSG_NEWSETELEM:
37 return NFTNL_OF_EVENT_NEW;
38 case NFT_MSG_DELTABLE:
39 case NFT_MSG_DELCHAIN:
42 case NFT_MSG_DELSETELEM:
43 return NFTNL_OF_EVENT_DEL;
49static int table_cb(
const struct nlmsghdr *nlh,
int event,
int type)
53 t = nftnl_table_alloc();
59 if (nftnl_table_nlmsg_parse(nlh, t) < 0) {
60 perror(
"nftnl_table_nlmsg_parse");
64 nftnl_table_fprintf(stdout, t, type, event2flag(event));
65 fprintf(stdout,
"\n");
73static int rule_cb(
const struct nlmsghdr *nlh,
int event,
int type)
77 t = nftnl_rule_alloc();
83 if (nftnl_rule_nlmsg_parse(nlh, t) < 0) {
84 perror(
"nftnl_rule_nlmsg_parse");
88 nftnl_rule_fprintf(stdout, t, type, event2flag(event));
89 fprintf(stdout,
"\n");
97static int chain_cb(
const struct nlmsghdr *nlh,
int event,
int type)
101 t = nftnl_chain_alloc();
107 if (nftnl_chain_nlmsg_parse(nlh, t) < 0) {
108 perror(
"nftnl_chain_nlmsg_parse");
112 nftnl_chain_fprintf(stdout, t, type, event2flag(event));
113 fprintf(stdout,
"\n");
121static int set_cb(
const struct nlmsghdr *nlh,
int event,
int type)
125 t = nftnl_set_alloc();
131 if (nftnl_set_nlmsg_parse(nlh, t) < 0) {
132 perror(
"nftnl_set_nlmsg_parse");
136 nftnl_set_fprintf(stdout, t, type, event2flag(event));
137 fprintf(stdout,
"\n");
145static int setelem_cb(
const struct nlmsghdr *nlh,
int event,
int type)
150 s = nftnl_set_alloc();
156 if (nftnl_set_elems_nlmsg_parse(nlh, s) < 0) {
157 perror(
"nftnl_set_nlmsg_parse");
161 nftnl_set_fprintf(stdout, s, type, event2flag(event));
162 fprintf(stdout,
"\n");
170static int gen_cb(
const struct nlmsghdr *nlh,
int event,
int type)
174 gen = nftnl_gen_alloc();
180 if (nftnl_gen_nlmsg_parse(nlh, gen) < 0) {
181 perror(
"nftnl_gen_parse");
185 nftnl_gen_fprintf(stdout, gen, type, event2flag(event));
186 fprintf(stdout,
"\n");
193static int events_cb(
const struct nlmsghdr *nlh,
void *data)
196 int event = NFNL_MSG_TYPE(nlh->nlmsg_type);
197 int type = *((
int *)data);
200 case NFT_MSG_NEWTABLE:
201 case NFT_MSG_DELTABLE:
202 ret = table_cb(nlh, event, type);
204 case NFT_MSG_NEWCHAIN:
205 case NFT_MSG_DELCHAIN:
206 ret = chain_cb(nlh, event, type);
208 case NFT_MSG_NEWRULE:
209 case NFT_MSG_DELRULE:
210 ret = rule_cb(nlh, event, type);
214 ret = set_cb(nlh, event, type);
216 case NFT_MSG_NEWSETELEM:
217 case NFT_MSG_DELSETELEM:
218 ret = setelem_cb(nlh, event, type);
221 ret = gen_cb(nlh, event, type);
228int main(
int argc,
char *argv[])
230 struct mnl_socket *nl;
231 char buf[MNL_SOCKET_BUFFER_SIZE];
236 type = NFTNL_OUTPUT_DEFAULT;
239 fprintf(stderr,
"%s\n", argv[0]);
243 nl = mnl_socket_open(NETLINK_NETFILTER);
245 perror(
"mnl_socket_open");
249 if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
250 perror(
"mnl_socket_bind");
254 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
256 ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type);
259 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
265 mnl_socket_close(nl);