• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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