• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Code to save the ip6tables state, in human readable-form. */
2 /* Author:  Andras Kis-Szabo <kisza@sch.bme.hu>
3  * Original code: iptables-save
4  * Authors: Paul 'Rusty' Russel <rusty@linuxcare.com.au> and
5  *          Harald Welte <laforge@gnumonks.org>
6  * This code is distributed under the terms of GNU GPL v2
7  */
8 #include <getopt.h>
9 #include <errno.h>
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <time.h>
15 #include <netdb.h>
16 #include <arpa/inet.h>
17 #include "libiptc/libip6tc.h"
18 #include "ip6tables.h"
19 #include "ip6tables-multi.h"
20 
21 static int show_counters = 0;
22 
23 static const struct option options[] = {
24 	{.name = "counters", .has_arg = false, .val = 'c'},
25 	{.name = "dump",     .has_arg = false, .val = 'd'},
26 	{.name = "table",    .has_arg = true,  .val = 't'},
27 	{.name = "modprobe", .has_arg = true,  .val = 'M'},
28 	{NULL},
29 };
30 
31 
32 /* Debugging prototype. */
for_each_table(int (* func)(const char * tablename))33 static int for_each_table(int (*func)(const char *tablename))
34 {
35 	int ret = 1;
36 	FILE *procfile = NULL;
37 	char tablename[XT_TABLE_MAXNAMELEN+1];
38 
39 	procfile = fopen("/proc/net/ip6_tables_names", "re");
40 	if (!procfile)
41 		return ret;
42 
43 	while (fgets(tablename, sizeof(tablename), procfile)) {
44 		if (tablename[strlen(tablename) - 1] != '\n')
45 			xtables_error(OTHER_PROBLEM,
46 				   "Badly formed tablename `%s'\n",
47 				   tablename);
48 		tablename[strlen(tablename) - 1] = '\0';
49 		ret &= func(tablename);
50 	}
51 
52 	fclose(procfile);
53 	return ret;
54 }
55 
56 
do_output(const char * tablename)57 static int do_output(const char *tablename)
58 {
59 	struct xtc_handle *h;
60 	const char *chain = NULL;
61 
62 	if (!tablename)
63 		return for_each_table(&do_output);
64 
65 	h = ip6tc_init(tablename);
66 	if (h == NULL) {
67 		xtables_load_ko(xtables_modprobe_program, false);
68 		h = ip6tc_init(tablename);
69 	}
70 	if (!h)
71 		xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
72 			   ip6tc_strerror(errno));
73 
74 	time_t now = time(NULL);
75 
76 	printf("# Generated by ip6tables-save v%s on %s",
77 	       IPTABLES_VERSION, ctime(&now));
78 	printf("*%s\n", tablename);
79 
80 	/* Dump out chain names first,
81 	 * thereby preventing dependency conflicts */
82 	for (chain = ip6tc_first_chain(h);
83 	     chain;
84 	     chain = ip6tc_next_chain(h)) {
85 
86 		printf(":%s ", chain);
87 		if (ip6tc_builtin(chain, h)) {
88 			struct xt_counters count;
89 			printf("%s ",
90 			       ip6tc_get_policy(chain, &count, h));
91 			printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
92 		} else {
93 			printf("- [0:0]\n");
94 		}
95 	}
96 
97 	for (chain = ip6tc_first_chain(h);
98 	     chain;
99 	     chain = ip6tc_next_chain(h)) {
100 		const struct ip6t_entry *e;
101 
102 		/* Dump out rules */
103 		e = ip6tc_first_rule(chain, h);
104 		while(e) {
105 			print_rule6(e, h, chain, show_counters);
106 			e = ip6tc_next_rule(e, h);
107 		}
108 	}
109 
110 	now = time(NULL);
111 	printf("COMMIT\n");
112 	printf("# Completed on %s", ctime(&now));
113 	ip6tc_free(h);
114 
115 	return 1;
116 }
117 
118 /* Format:
119  * :Chain name POLICY packets bytes
120  * rule
121  */
ip6tables_save_main(int argc,char * argv[])122 int ip6tables_save_main(int argc, char *argv[])
123 {
124 	const char *tablename = NULL;
125 	int c;
126 
127 	ip6tables_globals.program_name = "ip6tables-save";
128 	c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
129 	if (c < 0) {
130 		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
131 				ip6tables_globals.program_name,
132 				ip6tables_globals.program_version);
133 		exit(1);
134 	}
135 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
136 	init_extensions();
137 	init_extensions6();
138 #endif
139 
140 	while ((c = getopt_long(argc, argv, "bcdt:M:", 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;
148 
149 		case 't':
150 			/* Select specific table. */
151 			tablename = optarg;
152 			break;
153 		case 'M':
154 			xtables_modprobe_program = optarg;
155 			break;
156 		case 'd':
157 			do_output(tablename);
158 			exit(0);
159 		}
160 	}
161 
162 	if (optind < argc) {
163 		fprintf(stderr, "Unknown arguments found on commandline\n");
164 		exit(1);
165 	}
166 
167 	return !do_output(tablename);
168 }
169