nft: Drop interface mask leftovers from post_parse callbacks
[iptables-mirror.git] / iptables / iptables-save.c
blob094adf22b12d20b0ddfb04fe144837ba525fd99b
1 /* Code to save the iptables 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>
5 * This code is distributed under the terms of GNU GPL v2
7 */
8 #include "config.h"
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 <unistd.h>
18 #include "libiptc/libiptc.h"
19 #include "libiptc/libip6tc.h"
20 #include "iptables.h"
21 #include "ip6tables.h"
22 #include "iptables-multi.h"
23 #include "ip6tables-multi.h"
24 #include "xshared.h"
26 static int show_counters;
28 static const struct option options[] = {
29 {.name = "counters", .has_arg = false, .val = 'c'},
30 {.name = "dump", .has_arg = false, .val = 'd'},
31 {.name = "table", .has_arg = true, .val = 't'},
32 {.name = "modprobe", .has_arg = true, .val = 'M'},
33 {.name = "file", .has_arg = true, .val = 'f'},
34 {.name = "version", .has_arg = false, .val = 'V'},
35 {NULL},
38 struct iptables_save_cb {
39 const struct xtc_ops *ops;
41 void (*dump_rules)(const char *chain, struct xtc_handle *handle);
44 static int
45 for_each_table(int (*func)(struct iptables_save_cb *cb, const char *tablename),
46 struct iptables_save_cb *cb)
48 int ret = 1;
49 FILE *procfile = NULL;
50 char tablename[XT_TABLE_MAXNAMELEN+1];
52 procfile = fopen(afinfo->proc_exists, "re");
53 if (!procfile) {
54 if (errno == ENOENT)
55 return ret;
56 fprintf(stderr, "Failed to list table names in %s: %s\n",
57 afinfo->proc_exists, strerror(errno));
58 exit(1);
61 while (fgets(tablename, sizeof(tablename), procfile)) {
62 if (tablename[strlen(tablename) - 1] != '\n')
63 xtables_error(OTHER_PROBLEM,
64 "Badly formed tablename `%s'", tablename);
65 tablename[strlen(tablename) - 1] = '\0';
66 ret &= func(cb, tablename);
69 fclose(procfile);
70 return ret;
73 static int do_output(struct iptables_save_cb *cb, const char *tablename)
75 struct xtc_handle *h;
76 const char *chain = NULL;
78 if (!tablename)
79 return for_each_table(&do_output, cb);
81 h = cb->ops->init(tablename);
82 if (h == NULL) {
83 xtables_load_ko(xtables_modprobe_program, false);
84 h = cb->ops->init(tablename);
86 if (!h)
87 xtables_error(OTHER_PROBLEM, "Cannot initialize: %s",
88 cb->ops->strerror(errno));
90 time_t now = time(NULL);
92 printf("# Generated by %s v%s on %s",
93 xt_params->program_name, PACKAGE_VERSION, ctime(&now));
94 printf("*%s\n", tablename);
96 /* Dump out chain names first,
97 * thereby preventing dependency conflicts */
98 for (chain = cb->ops->first_chain(h);
99 chain;
100 chain = cb->ops->next_chain(h)) {
102 printf(":%s ", chain);
103 if (cb->ops->builtin(chain, h)) {
104 struct xt_counters count;
106 printf("%s ", cb->ops->get_policy(chain, &count, h));
107 printf("[%llu:%llu]\n",
108 (unsigned long long)count.pcnt,
109 (unsigned long long)count.bcnt);
110 } else {
111 printf("- [0:0]\n");
115 for (chain = cb->ops->first_chain(h);
116 chain;
117 chain = cb->ops->next_chain(h)) {
118 cb->dump_rules(chain, h);
121 now = time(NULL);
122 printf("COMMIT\n");
123 printf("# Completed on %s", ctime(&now));
124 cb->ops->free(h);
126 return 1;
129 /* Format:
130 * :Chain name POLICY packets bytes
131 * rule
133 static int
134 do_iptables_save(struct iptables_save_cb *cb, int argc, char *argv[])
136 const char *tablename = NULL;
137 FILE *file = NULL;
138 int ret, c;
140 while ((c = getopt_long(argc, argv, "bcdt:M:f:V", options, NULL)) != -1) {
141 switch (c) {
142 case 'b':
143 fprintf(stderr, "-b/--binary option is not implemented\n");
144 break;
145 case 'c':
146 show_counters = 1;
147 break;
149 case 't':
150 /* Select specific table. */
151 tablename = optarg;
152 break;
153 case 'M':
154 xtables_modprobe_program = optarg;
155 break;
156 case 'f':
157 file = fopen(optarg, "w");
158 if (file == NULL) {
159 fprintf(stderr, "Failed to open file, error: %s\n",
160 strerror(errno));
161 exit(1);
163 ret = dup2(fileno(file), STDOUT_FILENO);
164 if (ret == -1) {
165 fprintf(stderr, "Failed to redirect stdout, error: %s\n",
166 strerror(errno));
167 exit(1);
169 fclose(file);
170 break;
171 case 'd':
172 do_output(cb, tablename);
173 exit(0);
174 case 'V':
175 printf("%s v%s\n",
176 xt_params->program_name,
177 xt_params->program_version);
178 exit(0);
179 default:
180 fprintf(stderr,
181 "Look at manual page `%s.8' for more information.\n",
182 xt_params->program_name);
183 exit(1);
187 if (optind < argc) {
188 fprintf(stderr, "Unknown arguments found on commandline\n");
189 exit(1);
192 return !do_output(cb, tablename);
195 #ifdef ENABLE_IPV4
196 static void iptables_dump_rules(const char *chain, struct xtc_handle *h)
198 const struct ipt_entry *e;
200 /* Dump out rules */
201 e = iptc_first_rule(chain, h);
202 while(e) {
203 print_rule4(e, h, chain, show_counters);
204 e = iptc_next_rule(e, h);
208 struct iptables_save_cb ipt_save_cb = {
209 .ops = &iptc_ops,
210 .dump_rules = iptables_dump_rules,
213 /* Format:
214 * :Chain name POLICY packets bytes
215 * rule
218 iptables_save_main(int argc, char *argv[])
220 int ret;
222 iptables_globals.program_name = "iptables-save";
223 if (xtables_init_all(&iptables_globals, NFPROTO_IPV4) < 0) {
224 fprintf(stderr, "%s/%s Failed to initialize xtables\n",
225 iptables_globals.program_name,
226 iptables_globals.program_version);
227 exit(1);
229 init_extensions();
230 init_extensions4();
232 ret = do_iptables_save(&ipt_save_cb, argc, argv);
234 xtables_fini();
235 return ret;
237 #endif /* ENABLE_IPV4 */
239 #ifdef ENABLE_IPV6
240 static void ip6tables_dump_rules(const char *chain, struct xtc_handle *h)
242 const struct ip6t_entry *e;
244 /* Dump out rules */
245 e = ip6tc_first_rule(chain, h);
246 while(e) {
247 print_rule6(e, h, chain, show_counters);
248 e = ip6tc_next_rule(e, h);
252 struct iptables_save_cb ip6t_save_cb = {
253 .ops = &ip6tc_ops,
254 .dump_rules = ip6tables_dump_rules,
257 /* Format:
258 * :Chain name POLICY packets bytes
259 * rule
262 ip6tables_save_main(int argc, char *argv[])
264 int ret;
266 ip6tables_globals.program_name = "ip6tables-save";
267 if (xtables_init_all(&ip6tables_globals, NFPROTO_IPV6) < 0) {
268 fprintf(stderr, "%s/%s Failed to initialize xtables\n",
269 ip6tables_globals.program_name,
270 ip6tables_globals.program_version);
271 exit(1);
273 init_extensions();
274 init_extensions6();
276 ret = do_iptables_save(&ip6t_save_cb, argc, argv);
278 xtables_fini();
279 return ret;
281 #endif /* ENABLE_IPV6 */