1 /* Code to save the xtables state, in human readable-form. */
2 /* (C) 1999 by Paul 'Rusty' Russell <rusty@rustcorp.com.au> and
3 * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
5 *
6 * This code is distributed under the terms of GNU GPL v2
7 *
8 */
9 #include <getopt.h>
10 #include <errno.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <time.h>
16 #include <netdb.h>
17 #include "libiptc/libiptc.h"
18 #include "iptables.h"
19 #include "xtables-multi.h"
20 #include "nft.h"
21
22 #include <libnftnl/chain.h>
23
24 #ifndef NO_SHARED_LIBS
25 #include <dlfcn.h>
26 #endif
27
28 static bool show_counters = false;
29
30 static const struct option options[] = {
31 {.name = "counters", .has_arg = false, .val = 'c'},
32 {.name = "dump", .has_arg = false, .val = 'd'},
33 {.name = "table", .has_arg = true, .val = 't'},
34 {.name = "modprobe", .has_arg = true, .val = 'M'},
35 {.name = "ipv4", .has_arg = false, .val = '4'},
36 {.name = "ipv6", .has_arg = false, .val = '6'},
37 {NULL},
38 };
39
40 static int
do_output(struct nft_handle * h,const char * tablename,bool counters)41 do_output(struct nft_handle *h, const char *tablename, bool counters)
42 {
43 struct nftnl_chain_list *chain_list;
44
45 if (!tablename)
46 return nft_for_each_table(h, do_output, counters);
47
48 if (!nft_table_find(h, tablename)) {
49 printf("Table `%s' does not exist\n", tablename);
50 return 0;
51 }
52
53 chain_list = nft_chain_dump(h);
54
55 time_t now = time(NULL);
56
57 printf("# Generated by xtables-save v%s on %s",
58 IPTABLES_VERSION, ctime(&now));
59 printf("*%s\n", tablename);
60
61 /* Dump out chain names first,
62 * thereby preventing dependency conflicts */
63 nft_chain_save(h, chain_list, tablename);
64 nft_rule_save(h, tablename, counters);
65
66 now = time(NULL);
67 printf("COMMIT\n");
68 printf("# Completed on %s", ctime(&now));
69
70 return 1;
71 }
72
73 /* Format:
74 * :Chain name POLICY packets bytes
75 * rule
76 */
77 static int
xtables_save_main(int family,const char * progname,int argc,char * argv[])78 xtables_save_main(int family, const char *progname, int argc, char *argv[])
79 {
80 const char *tablename = NULL;
81 bool dump = false;
82 struct nft_handle h = {
83 .family = family,
84 };
85 int c;
86
87 xtables_globals.program_name = progname;
88 c = xtables_init_all(&xtables_globals, family);
89 if (c < 0) {
90 fprintf(stderr, "%s/%s Failed to initialize xtables\n",
91 xtables_globals.program_name,
92 xtables_globals.program_version);
93 exit(1);
94 }
95 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
96 init_extensions();
97 init_extensions4();
98 #endif
99 if (nft_init(&h, xtables_ipv4) < 0) {
100 fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
101 xtables_globals.program_name,
102 xtables_globals.program_version,
103 strerror(errno));
104 exit(EXIT_FAILURE);
105 }
106
107 while ((c = getopt_long(argc, argv, "bcdt:M:46", options, NULL)) != -1) {
108 switch (c) {
109 case 'b':
110 fprintf(stderr, "-b/--binary option is not implemented\n");
111 break;
112 case 'c':
113 show_counters = true;
114 break;
115
116 case 't':
117 /* Select specific table. */
118 tablename = optarg;
119 break;
120 case 'M':
121 xtables_modprobe_program = optarg;
122 break;
123 case 'd':
124 dump = true;
125 break;
126 case '4':
127 h.family = AF_INET;
128 break;
129 case '6':
130 h.family = AF_INET6;
131 xtables_set_nfproto(AF_INET6);
132 break;
133 }
134 }
135
136 if (optind < argc) {
137 fprintf(stderr, "Unknown arguments found on commandline\n");
138 exit(1);
139 }
140
141 if (nft_is_ruleset_compatible(&h) == 1) {
142 printf("ERROR: You're using nft features that cannot be mapped to iptables, please keep using nft.\n");
143 exit(EXIT_FAILURE);
144 }
145
146 if (dump) {
147 do_output(&h, tablename, show_counters);
148 exit(0);
149 }
150
151 return !do_output(&h, tablename, show_counters);
152 }
153
xtables_ip4_save_main(int argc,char * argv[])154 int xtables_ip4_save_main(int argc, char *argv[])
155 {
156 return xtables_save_main(NFPROTO_IPV4, "iptables-save", argc, argv);
157 }
158
xtables_ip6_save_main(int argc,char * argv[])159 int xtables_ip6_save_main(int argc, char *argv[])
160 {
161 return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv);
162 }
163