• 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 	static const char filename[] = "/proc/net/ip6_tables_names";
39 
40 	procfile = fopen(filename, "re");
41 	if (!procfile) {
42 		if (errno == ENOENT)
43 			return ret;
44 		fprintf(stderr, "Failed to list table names in %s: %s\n",
45 		        filename, strerror(errno));
46 		exit(1);
47 	}
48 
49 	while (fgets(tablename, sizeof(tablename), procfile)) {
50 		if (tablename[strlen(tablename) - 1] != '\n')
51 			xtables_error(OTHER_PROBLEM,
52 				   "Badly formed tablename `%s'\n",
53 				   tablename);
54 		tablename[strlen(tablename) - 1] = '\0';
55 		ret &= func(tablename);
56 	}
57 
58 	fclose(procfile);
59 	return ret;
60 }
61 
62 
do_output(const char * tablename)63 static int do_output(const char *tablename)
64 {
65 	struct xtc_handle *h;
66 	const char *chain = NULL;
67 
68 	if (!tablename)
69 		return for_each_table(&do_output);
70 
71 	h = ip6tc_init(tablename);
72 	if (h == NULL) {
73 		xtables_load_ko(xtables_modprobe_program, false);
74 		h = ip6tc_init(tablename);
75 	}
76 	if (!h)
77 		xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
78 			   ip6tc_strerror(errno));
79 
80 	time_t now = time(NULL);
81 
82 	printf("# Generated by ip6tables-save v%s on %s",
83 	       IPTABLES_VERSION, ctime(&now));
84 	printf("*%s\n", tablename);
85 
86 	/* Dump out chain names first,
87 	 * thereby preventing dependency conflicts */
88 	for (chain = ip6tc_first_chain(h);
89 	     chain;
90 	     chain = ip6tc_next_chain(h)) {
91 
92 		printf(":%s ", chain);
93 		if (ip6tc_builtin(chain, h)) {
94 			struct xt_counters count;
95 			printf("%s ",
96 			       ip6tc_get_policy(chain, &count, h));
97 			printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
98 		} else {
99 			printf("- [0:0]\n");
100 		}
101 	}
102 
103 	for (chain = ip6tc_first_chain(h);
104 	     chain;
105 	     chain = ip6tc_next_chain(h)) {
106 		const struct ip6t_entry *e;
107 
108 		/* Dump out rules */
109 		e = ip6tc_first_rule(chain, h);
110 		while(e) {
111 			print_rule6(e, h, chain, show_counters);
112 			e = ip6tc_next_rule(e, h);
113 		}
114 	}
115 
116 	now = time(NULL);
117 	printf("COMMIT\n");
118 	printf("# Completed on %s", ctime(&now));
119 	ip6tc_free(h);
120 
121 	return 1;
122 }
123 
124 /* Format:
125  * :Chain name POLICY packets bytes
126  * rule
127  */
ip6tables_save_main(int argc,char * argv[])128 int ip6tables_save_main(int argc, char *argv[])
129 {
130 	const char *tablename = NULL;
131 	int c;
132 
133 	ip6tables_globals.program_name = "ip6tables-save";
134 	c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
135 	if (c < 0) {
136 		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
137 				ip6tables_globals.program_name,
138 				ip6tables_globals.program_version);
139 		exit(1);
140 	}
141 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
142 	init_extensions();
143 	init_extensions6();
144 #endif
145 
146 	while ((c = getopt_long(argc, argv, "bcdt:M:", options, NULL)) != -1) {
147 		switch (c) {
148 		case 'b':
149 			fprintf(stderr, "-b/--binary option is not implemented\n");
150 			break;
151 		case 'c':
152 			show_counters = 1;
153 			break;
154 
155 		case 't':
156 			/* Select specific table. */
157 			tablename = optarg;
158 			break;
159 		case 'M':
160 			xtables_modprobe_program = optarg;
161 			break;
162 		case 'd':
163 			do_output(tablename);
164 			exit(0);
165 		}
166 	}
167 
168 	if (optind < argc) {
169 		fprintf(stderr, "Unknown arguments found on commandline\n");
170 		exit(1);
171 	}
172 
173 	return !do_output(tablename);
174 }
175