13#include <netinet/in.h>
16#include <linux/netfilter.h>
17#include <linux/netfilter/nf_tables.h>
19#include <libmnl/libmnl.h>
20#include <libnftnl/common.h>
21#include <libnftnl/ruleset.h>
22#include <libnftnl/table.h>
23#include <libnftnl/chain.h>
24#include <libnftnl/set.h>
25#include <libnftnl/rule.h>
29static void memory_allocation_error(
void)
36mnl_talk(
struct mnl_socket *nf_sock,
const void *data,
unsigned int len,
37 int (*cb)(
const struct nlmsghdr *nlh,
void *data),
void *cb_data)
39 char buf[MNL_SOCKET_BUFFER_SIZE];
40 uint32_t portid = mnl_socket_get_portid(nf_sock);
43 if (mnl_socket_sendto(nf_sock, data, len) < 0)
46 ret = mnl_socket_recvfrom(nf_sock, buf,
sizeof(buf));
48 ret = mnl_cb_run(buf, ret, seq, portid, cb, cb_data);
52 ret = mnl_socket_recvfrom(nf_sock, buf,
sizeof(buf));
55 if (ret < 0 && errno == EAGAIN)
64static int rule_cb(
const struct nlmsghdr *nlh,
void *data)
69 r = nftnl_rule_alloc();
71 memory_allocation_error();
73 if (nftnl_rule_nlmsg_parse(nlh, r) < 0)
76 nftnl_rule_list_add_tail(r, nlr_list);
87 char buf[MNL_SOCKET_BUFFER_SIZE];
92 nlr_list = nftnl_rule_list_alloc();
94 memory_allocation_error();
96 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family,
99 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, rule_cb, nlr_list);
105 nftnl_rule_list_free(nlr_list);
112static int chain_cb(
const struct nlmsghdr *nlh,
void *data)
117 c = nftnl_chain_alloc();
119 memory_allocation_error();
121 if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
124 nftnl_chain_list_add_tail(c, nlc_list);
135 char buf[MNL_SOCKET_BUFFER_SIZE];
136 struct nlmsghdr *nlh;
140 nlc_list = nftnl_chain_list_alloc();
141 if (nlc_list == NULL)
142 memory_allocation_error();
144 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, family,
147 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, chain_cb, nlc_list);
153 nftnl_chain_list_free(nlc_list);
160static int table_cb(
const struct nlmsghdr *nlh,
void *data)
165 t = nftnl_table_alloc();
167 memory_allocation_error();
169 if (nftnl_table_nlmsg_parse(nlh, t) < 0)
172 nftnl_table_list_add_tail(t, nlt_list);
183 char buf[MNL_SOCKET_BUFFER_SIZE];
184 struct nlmsghdr *nlh;
188 nlt_list = nftnl_table_list_alloc();
189 if (nlt_list == NULL)
190 memory_allocation_error();
192 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, family,
195 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, table_cb, nlt_list);
201 nftnl_table_list_free(nlt_list);
208static int set_elem_cb(
const struct nlmsghdr *nlh,
void *data)
210 nftnl_set_elems_nlmsg_parse(nlh, data);
214static int mnl_setelem_get(
struct mnl_socket *nf_sock,
struct nftnl_set *nls)
216 char buf[MNL_SOCKET_BUFFER_SIZE];
217 struct nlmsghdr *nlh;
218 uint32_t family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY);
220 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, family,
221 NLM_F_DUMP | NLM_F_ACK, seq);
222 nftnl_set_nlmsg_build_payload(nlh, nls);
224 return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_elem_cb, nls);
230static int set_cb(
const struct nlmsghdr *nlh,
void *data)
235 s = nftnl_set_alloc();
237 memory_allocation_error();
239 if (nftnl_set_nlmsg_parse(nlh, s) < 0)
242 nftnl_set_list_add_tail(s, nls_list);
251mnl_set_dump(
struct mnl_socket *nf_sock,
int family)
253 char buf[MNL_SOCKET_BUFFER_SIZE];
254 struct nlmsghdr *nlh;
257 struct nftnl_set *si;
261 s = nftnl_set_alloc();
263 memory_allocation_error();
265 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSET, family,
266 NLM_F_DUMP | NLM_F_ACK, seq);
267 nftnl_set_nlmsg_build_payload(nlh, s);
270 nls_list = nftnl_set_list_alloc();
271 if (nls_list == NULL)
272 memory_allocation_error();
274 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_cb, nls_list);
278 i = nftnl_set_list_iter_create(nls_list);
280 memory_allocation_error();
282 si = nftnl_set_list_iter_next(i);
284 if (mnl_setelem_get(nf_sock, si) != 0) {
285 perror(
"E: Unable to get set elements");
286 nftnl_set_list_iter_destroy(i);
289 si = nftnl_set_list_iter_next(i);
292 nftnl_set_list_iter_destroy(i);
296 nftnl_set_list_free(nls_list);
304static struct nftnl_ruleset *mnl_ruleset_dump(
struct mnl_socket *nf_sock)
312 rs = nftnl_ruleset_alloc();
314 memory_allocation_error();
316 t = mnl_table_dump(nf_sock, NFPROTO_UNSPEC);
318 nftnl_ruleset_set(rs, NFTNL_RULESET_TABLELIST, t);
320 c = mnl_chain_dump(nf_sock, NFPROTO_UNSPEC);
322 nftnl_ruleset_set(rs, NFTNL_RULESET_CHAINLIST, c);
324 s = mnl_set_dump(nf_sock, NFPROTO_UNSPEC);
326 nftnl_ruleset_set(rs, NFTNL_RULESET_SETLIST, s);
328 r = mnl_rule_dump(nf_sock, NFPROTO_UNSPEC);
330 nftnl_ruleset_set(rs, NFTNL_RULESET_RULELIST, r);
335int main(
int argc,
char *argv[])
337 struct mnl_socket *nl;
338 uint32_t type = NFTNL_OUTPUT_DEFAULT;
343 fprintf(stderr,
"%s\n", argv[0]);
347 nl = mnl_socket_open(NETLINK_NETFILTER);
349 perror(
"mnl_socket_open");
353 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
354 perror(
"mnl_socket_bind");
360 rs = mnl_ruleset_dump(nl);
362 perror(
"ruleset_dump");
366 ret = nftnl_ruleset_fprintf(stdout, rs, type, 0);
367 fprintf(stdout,
"\n");
370 perror(
"E: Error during fprintf operations");