From 68da8129a4bf46457a733c3eb030ec22e0dce3ba Mon Sep 17 00:00:00 2001 From: Arturo Borrero Gonzalez Date: Thu, 2 Jan 2014 11:49:06 +0100 Subject: tests: add table 'use' attr to testfiles Parsing tests were failing because a missing 'use' attribute in tables. validating xmlfiles/02-table.xml: FAILED from file: 0 f from snprintf: 00 Signed-off-by: Pablo Neira Ayuso --- tests/jsonfiles/01-table.json | 2 +- tests/jsonfiles/02-table.json | 2 +- tests/jsonfiles/64-ruleset.json | 2 +- tests/xmlfiles/01-table.xml | 2 +- tests/xmlfiles/02-table.xml | 2 +- tests/xmlfiles/75-ruleset.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/jsonfiles/01-table.json b/tests/jsonfiles/01-table.json index cfe7e9d..f217189 100644 --- a/tests/jsonfiles/01-table.json +++ b/tests/jsonfiles/01-table.json @@ -1 +1 @@ -{"table":{"name":"filter","family":"ip","flags":0}} +{"table":{"name":"filter","family":"ip","flags":0,"use":0}} diff --git a/tests/jsonfiles/02-table.json b/tests/jsonfiles/02-table.json index ddd119c..c23e7b0 100644 --- a/tests/jsonfiles/02-table.json +++ b/tests/jsonfiles/02-table.json @@ -1 +1 @@ -{"table":{"name":"filter2","family":"ip6","flags":0}} +{"table":{"name":"filter2","family":"ip6","flags":0,"use":0}} diff --git a/tests/jsonfiles/64-ruleset.json b/tests/jsonfiles/64-ruleset.json index 533d7fa..d1c22b8 100644 --- a/tests/jsonfiles/64-ruleset.json +++ b/tests/jsonfiles/64-ruleset.json @@ -1,2 +1,2 @@ -{"nftables":[{"table":{"name":"filter","family":"ip","flags":0}},{"table":{"name":"filter2","family":"ip6","flags":0}},{"chain":{"name":"input","handle":1,"bytes":10681449,"packets":16216,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}},{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}},{"chain":{"name":"output","handle":3,"bytes":2375830,"packets":15184,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}},{"chain":{"name":"chain1","handle":4,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0}},{"set":{"name":"set0","table":"filter","flags":3,"family":"ip","key_type":12,"key_len":2}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":6,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":9,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":10,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":11,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}}]} +{"nftables":[{"table":{"name":"filter","family":"ip","flags":0,"use":0}},{"table":{"name":"filter2","family":"ip6","flags":0,"use":0}},{"chain":{"name":"input","handle":1,"bytes":10681449,"packets":16216,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}},{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}},{"chain":{"name":"output","handle":3,"bytes":2375830,"packets":15184,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}},{"chain":{"name":"chain1","handle":4,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0}},{"set":{"name":"set0","table":"filter","flags":3,"family":"ip","key_type":12,"key_len":2}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":6,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":9,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":10,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter", "chain":"output","handle":11,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}}]} diff --git a/tests/xmlfiles/01-table.xml b/tests/xmlfiles/01-table.xml index fefcf67..1a11aa3 100644 --- a/tests/xmlfiles/01-table.xml +++ b/tests/xmlfiles/01-table.xml @@ -1 +1 @@ -filterip0
+filterip00
diff --git a/tests/xmlfiles/02-table.xml b/tests/xmlfiles/02-table.xml index d0873ca..ece0455 100644 --- a/tests/xmlfiles/02-table.xml +++ b/tests/xmlfiles/02-table.xml @@ -1 +1 @@ -natip60
+natip600
diff --git a/tests/xmlfiles/75-ruleset.xml b/tests/xmlfiles/75-ruleset.xml index 76f36a5..9e88433 100644 --- a/tests/xmlfiles/75-ruleset.xml +++ b/tests/xmlfiles/75-ruleset.xml @@ -1 +1 @@ -filterip0
filterip60
input100filter
ip
output200filter
ip
forward100filter
ip6
ip6filter
set0312200020x00004300020x00003500
ipfilter
map011122429496704016020x00005000drop020x00001600accept
ipfilter
input8000accept
ipfilter
output9191network1eq10x00000006122transportmap010
ip6filter
forward2161network1eq10x00000011122transportset010000accept
+filterip00
filterip600
input100filter
ip
output200filter
ip
forward100filter
ip6
ip6filter
set0312200020x00004300020x00003500
ipfilter
map011122429496704016020x00005000drop020x00001600accept
ipfilter
input8000accept
ipfilter
output9191network1eq10x00000006122transportmap010
ip6filter
forward2161network1eq10x00000011122transportset010000accept
-- cgit v1.2.3 From f7273ff2b9dcad6edf38b4ee1b66970c8118bed5 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Wed, 9 Oct 2013 12:18:12 +0200 Subject: examples: nft-set-get: retrieve all sets via unspec Other nftables objects are allowed to be dumped with NFPROTO_UNSPEC. With sets is also possible since kernel patch c9c8e48 ("netfilter: nf_tables: dump sets in all existing families"). Signed-off-by: Arturo Borrero Gonzalez --- examples/nft-set-get.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/nft-set-get.c b/examples/nft-set-get.c index 6762032..b774199 100644 --- a/examples/nft-set-get.c +++ b/examples/nft-set-get.c @@ -74,8 +74,10 @@ int main(int argc, char *argv[]) family = NFPROTO_BRIDGE; else if (strcmp(argv[1], "arp") == 0) family = NFPROTO_ARP; + else if (strcmp(argv[1], "unspec") == 0) + family = NFPROTO_UNSPEC; else { - fprintf(stderr, "Unknown family: ip, ip6, bridge, arp\n"); + fprintf(stderr, "Unknown family: ip, ip6, bridge, arp, unspec\n"); exit(EXIT_FAILURE); } -- cgit v1.2.3 From 44ab5902045a5cc0aad8e145d1a32f8a3b3cc157 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Mon, 23 Dec 2013 15:18:22 +0100 Subject: examples: add nft-ruleset-get This example prints the ruleset, using the ruleset API of nftables. The kernel patch c9c8e48 ("netfilter: nf_tables: dump sets in all existing families") is required. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- examples/Makefile.am | 4 + examples/nft-ruleset-get.c | 389 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 393 insertions(+) create mode 100644 examples/nft-ruleset-get.c diff --git a/examples/Makefile.am b/examples/Makefile.am index 9965387..b909684 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -25,6 +25,7 @@ check_PROGRAMS = nft-table-add \ nft-set-elem-add \ nft-set-elem-get \ nft-set-elem-del \ + nft-ruleset-get \ nft-compat-get nft_table_add_SOURCES = nft-table-add.c @@ -102,5 +103,8 @@ nft_set_elem_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} nft_set_elem_get_SOURCES = nft-set-elem-get.c nft_set_elem_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} +nft_ruleset_get_SOURCES = nft-ruleset-get.c +nft_ruleset_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} + nft_compat_get_SOURCES = nft-compat-get.c nft_compat_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} diff --git a/examples/nft-ruleset-get.c b/examples/nft-ruleset-get.c new file mode 100644 index 0000000..25c6d7c --- /dev/null +++ b/examples/nft-ruleset-get.c @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2013 Arturo Borrero Gonzalez + * + * based on previous code from: + * + * Copyright (c) 2013 Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static int seq; + +static void memory_allocation_error(void) +{ + perror("OOM"); + exit(EXIT_FAILURE); +} + +static int +mnl_talk(struct mnl_socket *nf_sock, const void *data, unsigned int len, + int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + uint32_t portid = mnl_socket_get_portid(nf_sock); + int ret; + + if (mnl_socket_sendto(nf_sock, data, len) < 0) + return -1; + + ret = mnl_socket_recvfrom(nf_sock, buf, sizeof(buf)); + while (ret > 0) { + ret = mnl_cb_run(buf, ret, seq, portid, cb, cb_data); + if (ret <= 0) + goto out; + + ret = mnl_socket_recvfrom(nf_sock, buf, sizeof(buf)); + } +out: + if (ret < 0 && errno == EAGAIN) + return 0; + + return ret; +} + +/* + * Rule + */ +static int rule_cb(const struct nlmsghdr *nlh, void *data) +{ + struct nft_rule_list *nlr_list = data; + struct nft_rule *r; + + r = nft_rule_alloc(); + if (r == NULL) + memory_allocation_error(); + + if (nft_rule_nlmsg_parse(nlh, r) < 0) + goto err_free; + + nft_rule_list_add_tail(r, nlr_list); + return MNL_CB_OK; + +err_free: + nft_rule_free(r); + return MNL_CB_OK; +} + +static struct nft_rule_list *mnl_rule_dump(struct mnl_socket *nf_sock, + int family) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *nlh; + struct nft_rule_list *nlr_list; + int ret; + + nlr_list = nft_rule_list_alloc(); + if (nlr_list == NULL) + memory_allocation_error(); + + nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, + NLM_F_DUMP, seq); + + ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, rule_cb, nlr_list); + if (ret < 0) + goto err; + + return nlr_list; +err: + nft_rule_list_free(nlr_list); + return NULL; +} + +/* + * Chain + */ +static int chain_cb(const struct nlmsghdr *nlh, void *data) +{ + struct nft_chain_list *nlc_list = data; + struct nft_chain *c; + + c = nft_chain_alloc(); + if (c == NULL) + memory_allocation_error(); + + if (nft_chain_nlmsg_parse(nlh, c) < 0) + goto err_free; + + nft_chain_list_add_tail(c, nlc_list); + return MNL_CB_OK; + +err_free: + nft_chain_free(c); + return MNL_CB_OK; +} + +static struct nft_chain_list *mnl_chain_dump(struct mnl_socket *nf_sock, + int family) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *nlh; + struct nft_chain_list *nlc_list; + int ret; + + nlc_list = nft_chain_list_alloc(); + if (nlc_list == NULL) + memory_allocation_error(); + + nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, family, + NLM_F_DUMP, seq); + + ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, chain_cb, nlc_list); + if (ret < 0) + goto err; + + return nlc_list; +err: + nft_chain_list_free(nlc_list); + return NULL; +} + +/* + * Table + */ +static int table_cb(const struct nlmsghdr *nlh, void *data) +{ + struct nft_table_list *nlt_list = data; + struct nft_table *t; + + t = nft_table_alloc(); + if (t == NULL) + memory_allocation_error(); + + if (nft_table_nlmsg_parse(nlh, t) < 0) + goto err_free; + + nft_table_list_add_tail(t, nlt_list); + return MNL_CB_OK; + +err_free: + nft_table_free(t); + return MNL_CB_OK; +} + +static struct nft_table_list *mnl_table_dump(struct mnl_socket *nf_sock, + int family) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *nlh; + struct nft_table_list *nlt_list; + int ret; + + nlt_list = nft_table_list_alloc(); + if (nlt_list == NULL) + memory_allocation_error(); + + nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, family, + NLM_F_DUMP, seq); + + ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, table_cb, nlt_list); + if (ret < 0) + goto err; + + return nlt_list; +err: + nft_table_list_free(nlt_list); + return NULL; +} + +/* + * Set elements + */ +static int set_elem_cb(const struct nlmsghdr *nlh, void *data) +{ + nft_set_elems_nlmsg_parse(nlh, data); + return MNL_CB_OK; +} + +static int mnl_setelem_get(struct mnl_socket *nf_sock, struct nft_set *nls) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *nlh; + uint32_t family = nft_set_attr_get_u32(nls, NFT_SET_ATTR_FAMILY); + + nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, family, + NLM_F_DUMP|NLM_F_ACK, seq); + nft_set_nlmsg_build_payload(nlh, nls); + + return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_elem_cb, nls); +} + +/* + * Set + */ +static int set_cb(const struct nlmsghdr *nlh, void *data) +{ + struct nft_set_list *nls_list = data; + struct nft_set *s; + + s = nft_set_alloc(); + if (s == NULL) + memory_allocation_error(); + + if (nft_set_nlmsg_parse(nlh, s) < 0) + goto err_free; + + nft_set_list_add_tail(s, nls_list); + return MNL_CB_OK; + +err_free: + nft_set_free(s); + return MNL_CB_OK; +} + +static struct nft_set_list * +mnl_set_dump(struct mnl_socket *nf_sock, int family) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *nlh; + struct nft_set *s; + struct nft_set_list *nls_list; + struct nft_set *si; + struct nft_set_list_iter *i; + int ret; + + s = nft_set_alloc(); + if (s == NULL) + memory_allocation_error(); + + nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_GETSET, family, + NLM_F_DUMP|NLM_F_ACK, seq); + nft_set_nlmsg_build_payload(nlh, s); + nft_set_free(s); + + nls_list = nft_set_list_alloc(); + if (nls_list == NULL) + memory_allocation_error(); + + ret = mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_cb, nls_list); + if (ret < 0) + goto err; + + i = nft_set_list_iter_create(nls_list); + if (i == NULL) + memory_allocation_error(); + + si = nft_set_list_iter_next(i); + while (si != NULL) { + if (mnl_setelem_get(nf_sock, si) != 0) { + perror("E: Unable to get set elements"); + nft_set_list_iter_destroy(i); + goto err; + } + si = nft_set_list_iter_next(i); + } + + nft_set_list_iter_destroy(i); + + return nls_list; +err: + nft_set_list_free(nls_list); + return NULL; +} + +/* + * ruleset + */ + +static struct nft_ruleset *mnl_ruleset_dump(struct mnl_socket *nf_sock) +{ + struct nft_ruleset *rs; + struct nft_table_list *t; + struct nft_chain_list *c; + struct nft_set_list *s; + struct nft_rule_list *r; + + rs = nft_ruleset_alloc(); + if (rs == NULL) + memory_allocation_error(); + + t = mnl_table_dump(nf_sock, NFPROTO_UNSPEC); + if (t != NULL) + nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_TABLELIST, t); + + c = mnl_chain_dump(nf_sock, NFPROTO_UNSPEC); + if (c != NULL) + nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_CHAINLIST, c); + + s = mnl_set_dump(nf_sock, NFPROTO_UNSPEC); + if (s != NULL) + nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_SETLIST, s); + + r = mnl_rule_dump(nf_sock, NFPROTO_UNSPEC); + if (r != NULL) + nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_RULELIST, r); + + return rs; +} + +int main(int argc, char *argv[]) +{ + struct mnl_socket *nl; + uint32_t type = NFT_OUTPUT_DEFAULT; + struct nft_ruleset *rs; + int ret; + + if (argc > 2) { + fprintf(stderr, "%s {xml|json}\n", + argv[0]); + exit(EXIT_FAILURE); + } + + if (argc == 2) { + if (strcmp(argv[1], "xml") == 0) + type = NFT_OUTPUT_XML; + else if (strcmp(argv[1], "json") == 0) + type = NFT_OUTPUT_JSON; + else { + fprintf(stderr, "Unknown type: {xml|json}\n"); + exit(EXIT_FAILURE); + } + } + + nl = mnl_socket_open(NETLINK_NETFILTER); + if (nl == NULL) { + perror("mnl_socket_open"); + exit(EXIT_FAILURE); + } + + if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { + perror("mnl_socket_bind"); + exit(EXIT_FAILURE); + } + + seq = time(NULL); + + rs = mnl_ruleset_dump(nl); + if (rs == NULL) { + perror("ruleset_dump"); + exit(EXIT_FAILURE); + } + + ret = nft_ruleset_fprintf(stdout, rs, type, 0); + fprintf(stdout, "\n"); + + if (ret == -1) + perror("E: Error during fprintf operations"); + + return 0; +} -- cgit v1.2.3