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/common.h>
27 static uint32_t event2flag(uint32_t event)
30 case NFT_MSG_NEWTABLE:
31 case NFT_MSG_NEWCHAIN:
34 case NFT_MSG_NEWSETELEM:
35 return NFT_OF_EVENT_NEW;
36 case NFT_MSG_DELTABLE:
37 case NFT_MSG_DELCHAIN:
40 case NFT_MSG_DELSETELEM:
41 return NFT_OF_EVENT_DEL;
47 static int table_cb(
const struct nlmsghdr *nlh,
int event,
int type)
51 t = nft_table_alloc();
57 if (nft_table_nlmsg_parse(nlh, t) < 0) {
58 perror(
"nft_table_nlmsg_parse");
62 nft_table_fprintf(stdout, t, type, event2flag(event));
63 fprintf(stdout,
"\n");
71 static int rule_cb(
const struct nlmsghdr *nlh,
int event,
int type)
81 if (nft_rule_nlmsg_parse(nlh, t) < 0) {
82 perror(
"nft_rule_nlmsg_parse");
86 nft_rule_fprintf(stdout, t, type, event2flag(event));
87 fprintf(stdout,
"\n");
95 static int chain_cb(
const struct nlmsghdr *nlh,
int event,
int type)
99 t = nft_chain_alloc();
105 if (nft_chain_nlmsg_parse(nlh, t) < 0) {
106 perror(
"nft_chain_nlmsg_parse");
110 nft_chain_fprintf(stdout, t, type, event2flag(event));
111 fprintf(stdout,
"\n");
119 static int set_cb(
const struct nlmsghdr *nlh,
int event,
int type)
129 if (nft_set_nlmsg_parse(nlh, t) < 0) {
130 perror(
"nft_set_nlmsg_parse");
134 nft_set_fprintf(stdout, t, type, event2flag(event));
135 fprintf(stdout,
"\n");
143 static int setelem_cb(
const struct nlmsghdr *nlh,
int event,
int type)
154 if (nft_set_elems_nlmsg_parse(nlh, s) < 0) {
155 perror(
"nft_set_nlmsg_parse");
159 nft_set_fprintf(stdout, s, type, event2flag(event));
160 fprintf(stdout,
"\n");
168 static int events_cb(
const struct nlmsghdr *nlh,
void *data)
171 int event = NFNL_MSG_TYPE(nlh->nlmsg_type);
172 int type = *((
int *)data);
175 case NFT_MSG_NEWTABLE:
176 case NFT_MSG_DELTABLE:
177 ret = table_cb(nlh, event, type);
179 case NFT_MSG_NEWCHAIN:
180 case NFT_MSG_DELCHAIN:
181 ret = chain_cb(nlh, event, type);
183 case NFT_MSG_NEWRULE:
184 case NFT_MSG_DELRULE:
185 ret = rule_cb(nlh, event, type);
189 ret = set_cb(nlh, event, type);
191 case NFT_MSG_NEWSETELEM:
192 case NFT_MSG_DELSETELEM:
193 ret = setelem_cb(nlh, event, type);
200 int main(
int argc,
char *argv[])
202 struct mnl_socket *nl;
203 char buf[MNL_SOCKET_BUFFER_SIZE];
208 type = NFT_OUTPUT_DEFAULT;
211 if (strcmp(argv[1],
"xml") == 0) {
212 type = NFT_OUTPUT_XML;
213 }
else if (strcmp(argv[1],
"json") == 0) {
214 type = NFT_OUTPUT_JSON;
215 }
else if (strcmp(argv[1],
"default") == 0) {
216 type = NFT_OUTPUT_DEFAULT;
218 fprintf(stderr,
"unknown format type `%s'\n", argv[1]);
223 fprintf(stderr,
"%s [<default|xml|json>]\n", argv[0]);
227 nl = mnl_socket_open(NETLINK_NETFILTER);
229 perror(
"mnl_socket_open");
233 if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
234 perror(
"mnl_socket_bind");
238 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
240 ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type);
243 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
249 mnl_socket_close(nl);