17#include <netinet/in.h>
20#include <linux/netfilter.h>
21#include <linux/netfilter/nf_tables.h>
23#include <libmnl/libmnl.h>
24#include <libnftnl/common.h>
25#include <libnftnl/ruleset.h>
26#include <libnftnl/table.h>
27#include <libnftnl/chain.h>
28#include <libnftnl/set.h>
29#include <libnftnl/rule.h>
33static void memory_allocation_error(
void)
40mnl_talk(
struct mnl_socket *nf_sock,
const void *data,
unsigned int len,
41 int (*cb)(
const struct nlmsghdr *nlh,
void *data),
void *cb_data)
43 char buf[MNL_SOCKET_BUFFER_SIZE];
44 uint32_t portid = mnl_socket_get_portid(nf_sock);
47 if (mnl_socket_sendto(nf_sock, data, len) < 0)
50 ret = mnl_socket_recvfrom(nf_sock, buf,
sizeof(buf));
52 ret = mnl_cb_run(buf, ret, seq, portid, cb, cb_data);
56 ret = mnl_socket_recvfrom(nf_sock, buf,
sizeof(buf));
59 if (ret < 0 && errno == EAGAIN)
68static int rule_cb(
const struct nlmsghdr *nlh,
void *data)
73 r = nftnl_rule_alloc();
75 memory_allocation_error();
77 if (nftnl_rule_nlmsg_parse(nlh, r) < 0)
80 nftnl_rule_list_add_tail(r, nlr_list);
91 char buf[MNL_SOCKET_BUFFER_SIZE];
96 nlr_list = nftnl_rule_list_alloc();
98 memory_allocation_error();
100 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family,
103 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, rule_cb, nlr_list);
109 nftnl_rule_list_free(nlr_list);
116static int chain_cb(
const struct nlmsghdr *nlh,
void *data)
121 c = nftnl_chain_alloc();
123 memory_allocation_error();
125 if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
128 nftnl_chain_list_add_tail(c, nlc_list);
139 char buf[MNL_SOCKET_BUFFER_SIZE];
140 struct nlmsghdr *nlh;
144 nlc_list = nftnl_chain_list_alloc();
145 if (nlc_list == NULL)
146 memory_allocation_error();
148 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, family,
151 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, chain_cb, nlc_list);
157 nftnl_chain_list_free(nlc_list);
164static int table_cb(
const struct nlmsghdr *nlh,
void *data)
169 t = nftnl_table_alloc();
171 memory_allocation_error();
173 if (nftnl_table_nlmsg_parse(nlh, t) < 0)
176 nftnl_table_list_add_tail(t, nlt_list);
187 char buf[MNL_SOCKET_BUFFER_SIZE];
188 struct nlmsghdr *nlh;
192 nlt_list = nftnl_table_list_alloc();
193 if (nlt_list == NULL)
194 memory_allocation_error();
196 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, family,
199 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, table_cb, nlt_list);
205 nftnl_table_list_free(nlt_list);
212static int set_elem_cb(
const struct nlmsghdr *nlh,
void *data)
214 nftnl_set_elems_nlmsg_parse(nlh, data);
218static int mnl_setelem_get(
struct mnl_socket *nf_sock,
struct nftnl_set *nls)
220 char buf[MNL_SOCKET_BUFFER_SIZE];
221 struct nlmsghdr *nlh;
222 uint32_t family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY);
224 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, family,
225 NLM_F_DUMP | NLM_F_ACK, seq);
226 nftnl_set_nlmsg_build_payload(nlh, nls);
228 return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_elem_cb, nls);
234static int set_cb(
const struct nlmsghdr *nlh,
void *data)
239 s = nftnl_set_alloc();
241 memory_allocation_error();
243 if (nftnl_set_nlmsg_parse(nlh, s) < 0)
246 nftnl_set_list_add_tail(s, nls_list);
255mnl_set_dump(
struct mnl_socket *nf_sock,
int family)
257 char buf[MNL_SOCKET_BUFFER_SIZE];
258 struct nlmsghdr *nlh;
261 struct nftnl_set *si;
265 s = nftnl_set_alloc();
267 memory_allocation_error();
269 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSET, family,
270 NLM_F_DUMP | NLM_F_ACK, seq);
271 nftnl_set_nlmsg_build_payload(nlh, s);
274 nls_list = nftnl_set_list_alloc();
275 if (nls_list == NULL)
276 memory_allocation_error();
278 ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_cb, nls_list);
282 i = nftnl_set_list_iter_create(nls_list);
284 memory_allocation_error();
286 si = nftnl_set_list_iter_next(i);
288 if (mnl_setelem_get(nf_sock, si) != 0) {
289 perror(
"E: Unable to get set elements");
290 nftnl_set_list_iter_destroy(i);
293 si = nftnl_set_list_iter_next(i);
296 nftnl_set_list_iter_destroy(i);
300 nftnl_set_list_free(nls_list);
308static struct nftnl_ruleset *mnl_ruleset_dump(
struct mnl_socket *nf_sock)
316 rs = nftnl_ruleset_alloc();
318 memory_allocation_error();
320 t = mnl_table_dump(nf_sock, NFPROTO_UNSPEC);
322 nftnl_ruleset_set(rs, NFTNL_RULESET_TABLELIST, t);
324 c = mnl_chain_dump(nf_sock, NFPROTO_UNSPEC);
326 nftnl_ruleset_set(rs, NFTNL_RULESET_CHAINLIST, c);
328 s = mnl_set_dump(nf_sock, NFPROTO_UNSPEC);
330 nftnl_ruleset_set(rs, NFTNL_RULESET_SETLIST, s);
332 r = mnl_rule_dump(nf_sock, NFPROTO_UNSPEC);
334 nftnl_ruleset_set(rs, NFTNL_RULESET_RULELIST, r);
339int main(
int argc,
char *argv[])
341 struct mnl_socket *nl;
342 uint32_t type = NFTNL_OUTPUT_DEFAULT;
347 fprintf(stderr,
"%s\n", argv[0]);
351 nl = mnl_socket_open(NETLINK_NETFILTER);
353 perror(
"mnl_socket_open");
357 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
358 perror(
"mnl_socket_bind");
364 rs = mnl_ruleset_dump(nl);
366 perror(
"ruleset_dump");
370 ret = nftnl_ruleset_fprintf(stdout, rs, type, 0);
371 fprintf(stdout,
"\n");
374 perror(
"E: Error during fprintf operations");