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
18 #include "libiptc/libiptc.h"
19 #include "libiptc/libip6tc.h"
21 #include "ip6tables.h"
22 #include "iptables-multi.h"
23 #include "ip6tables-multi.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'},
38 struct iptables_save_cb
{
39 const struct xtc_ops
*ops
;
41 void (*dump_rules
)(const char *chain
, struct xtc_handle
*handle
);
45 for_each_table(int (*func
)(struct iptables_save_cb
*cb
, const char *tablename
),
46 struct iptables_save_cb
*cb
)
49 FILE *procfile
= NULL
;
50 char tablename
[XT_TABLE_MAXNAMELEN
+1];
52 procfile
= fopen(afinfo
->proc_exists
, "re");
56 fprintf(stderr
, "Failed to list table names in %s: %s\n",
57 afinfo
->proc_exists
, strerror(errno
));
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
);
73 static int do_output(struct iptables_save_cb
*cb
, const char *tablename
)
76 const char *chain
= NULL
;
79 return for_each_table(&do_output
, cb
);
81 h
= cb
->ops
->init(tablename
);
83 xtables_load_ko(xtables_modprobe_program
, false);
84 h
= cb
->ops
->init(tablename
);
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
);
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
);
115 for (chain
= cb
->ops
->first_chain(h
);
117 chain
= cb
->ops
->next_chain(h
)) {
118 cb
->dump_rules(chain
, h
);
123 printf("# Completed on %s", ctime(&now
));
130 * :Chain name POLICY packets bytes
134 do_iptables_save(struct iptables_save_cb
*cb
, int argc
, char *argv
[])
136 const char *tablename
= NULL
;
140 while ((c
= getopt_long(argc
, argv
, "bcdt:M:f:V", options
, NULL
)) != -1) {
143 fprintf(stderr
, "-b/--binary option is not implemented\n");
150 /* Select specific table. */
154 xtables_modprobe_program
= optarg
;
157 file
= fopen(optarg
, "w");
159 fprintf(stderr
, "Failed to open file, error: %s\n",
163 ret
= dup2(fileno(file
), STDOUT_FILENO
);
165 fprintf(stderr
, "Failed to redirect stdout, error: %s\n",
172 do_output(cb
, tablename
);
176 xt_params
->program_name
,
177 xt_params
->program_version
);
181 "Look at manual page `%s.8' for more information.\n",
182 xt_params
->program_name
);
188 fprintf(stderr
, "Unknown arguments found on commandline\n");
192 return !do_output(cb
, tablename
);
196 static void iptables_dump_rules(const char *chain
, struct xtc_handle
*h
)
198 const struct ipt_entry
*e
;
201 e
= iptc_first_rule(chain
, h
);
203 print_rule4(e
, h
, chain
, show_counters
);
204 e
= iptc_next_rule(e
, h
);
208 struct iptables_save_cb ipt_save_cb
= {
210 .dump_rules
= iptables_dump_rules
,
214 * :Chain name POLICY packets bytes
218 iptables_save_main(int argc
, char *argv
[])
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
);
232 ret
= do_iptables_save(&ipt_save_cb
, argc
, argv
);
237 #endif /* ENABLE_IPV4 */
240 static void ip6tables_dump_rules(const char *chain
, struct xtc_handle
*h
)
242 const struct ip6t_entry
*e
;
245 e
= ip6tc_first_rule(chain
, h
);
247 print_rule6(e
, h
, chain
, show_counters
);
248 e
= ip6tc_next_rule(e
, h
);
252 struct iptables_save_cb ip6t_save_cb
= {
254 .dump_rules
= ip6tables_dump_rules
,
258 * :Chain name POLICY packets bytes
262 ip6tables_save_main(int argc
, char *argv
[])
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
);
276 ret
= do_iptables_save(&ip6t_save_cb
, argc
, argv
);
281 #endif /* ENABLE_IPV6 */