11 #include <netinet/in.h>
13 #include <linux/netfilter/nfnetlink.h>
14 #include <linux/netfilter/nf_tables.h>
16 #include <libmnl/libmnl.h>
17 #include <libnftnl/table.h>
18 #include <libnftnl/chain.h>
19 #include <libnftnl/rule.h>
20 #include <libnftnl/set.h>
21 #include <libnftnl/gen.h>
22 #include <libnftnl/common.h>
24 static uint32_t event2flag(uint32_t event)
27 case NFT_MSG_NEWTABLE:
28 case NFT_MSG_NEWCHAIN:
31 case NFT_MSG_NEWSETELEM:
33 return NFTNL_OF_EVENT_NEW;
34 case NFT_MSG_DELTABLE:
35 case NFT_MSG_DELCHAIN:
38 case NFT_MSG_DELSETELEM:
39 return NFTNL_OF_EVENT_DEL;
45 static int table_cb(
const struct nlmsghdr *nlh,
int event,
int type)
49 t = nftnl_table_alloc();
55 if (nftnl_table_nlmsg_parse(nlh, t) < 0) {
56 perror(
"nftnl_table_nlmsg_parse");
60 nftnl_table_fprintf(stdout, t, type, event2flag(event));
61 fprintf(stdout,
"\n");
69 static int rule_cb(
const struct nlmsghdr *nlh,
int event,
int type)
73 t = nftnl_rule_alloc();
79 if (nftnl_rule_nlmsg_parse(nlh, t) < 0) {
80 perror(
"nftnl_rule_nlmsg_parse");
84 nftnl_rule_fprintf(stdout, t, type, event2flag(event));
85 fprintf(stdout,
"\n");
93 static int chain_cb(
const struct nlmsghdr *nlh,
int event,
int type)
97 t = nftnl_chain_alloc();
103 if (nftnl_chain_nlmsg_parse(nlh, t) < 0) {
104 perror(
"nftnl_chain_nlmsg_parse");
108 nftnl_chain_fprintf(stdout, t, type, event2flag(event));
109 fprintf(stdout,
"\n");
117 static int set_cb(
const struct nlmsghdr *nlh,
int event,
int type)
121 t = nftnl_set_alloc();
127 if (nftnl_set_nlmsg_parse(nlh, t) < 0) {
128 perror(
"nftnl_set_nlmsg_parse");
132 nftnl_set_fprintf(stdout, t, type, event2flag(event));
133 fprintf(stdout,
"\n");
141 static int setelem_cb(
const struct nlmsghdr *nlh,
int event,
int type)
146 s = nftnl_set_alloc();
152 if (nftnl_set_elems_nlmsg_parse(nlh, s) < 0) {
153 perror(
"nftnl_set_nlmsg_parse");
157 nftnl_set_fprintf(stdout, s, type, event2flag(event));
158 fprintf(stdout,
"\n");
166 static int gen_cb(
const struct nlmsghdr *nlh,
int event,
int type)
170 gen = nftnl_gen_alloc();
176 if (nftnl_gen_nlmsg_parse(nlh, gen) < 0) {
177 perror(
"nftnl_gen_parse");
181 nftnl_gen_fprintf(stdout, gen, type, event2flag(event));
182 fprintf(stdout,
"\n");
189 static int events_cb(
const struct nlmsghdr *nlh,
void *data)
192 int event = NFNL_MSG_TYPE(nlh->nlmsg_type);
193 int type = *((
int *)data);
196 case NFT_MSG_NEWTABLE:
197 case NFT_MSG_DELTABLE:
198 ret = table_cb(nlh, event, type);
200 case NFT_MSG_NEWCHAIN:
201 case NFT_MSG_DELCHAIN:
202 ret = chain_cb(nlh, event, type);
204 case NFT_MSG_NEWRULE:
205 case NFT_MSG_DELRULE:
206 ret = rule_cb(nlh, event, type);
210 ret = set_cb(nlh, event, type);
212 case NFT_MSG_NEWSETELEM:
213 case NFT_MSG_DELSETELEM:
214 ret = setelem_cb(nlh, event, type);
217 ret = gen_cb(nlh, event, type);
224 int main(
int argc,
char *argv[])
226 struct mnl_socket *nl;
227 char buf[MNL_SOCKET_BUFFER_SIZE];
232 type = NFTNL_OUTPUT_DEFAULT;
235 fprintf(stderr,
"%s\n", argv[0]);
239 nl = mnl_socket_open(NETLINK_NETFILTER);
241 perror(
"mnl_socket_open");
245 if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
246 perror(
"mnl_socket_bind");
250 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
252 ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type);
255 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
261 mnl_socket_close(nl);