Update Packaging Spec file
[external/iptables.git] / ip6tables-save.c
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 <sys/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 #ifndef NO_SHARED_LIBS
22 #include <dlfcn.h>
23 #endif
24
25 static int show_binary = 0, show_counters = 0;
26
27 static const struct option options[] = {
28         {.name = "binary",   .has_arg = false, .val = 'b'},
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         {NULL},
34 };
35
36
37 /* Debugging prototype. */
38 static int for_each_table(int (*func)(const char *tablename))
39 {
40         int ret = 1;
41         FILE *procfile = NULL;
42         char tablename[IP6T_TABLE_MAXNAMELEN+1];
43
44         procfile = fopen("/proc/net/ip6_tables_names", "r");
45         if (!procfile)
46                 return ret;
47
48         while (fgets(tablename, sizeof(tablename), procfile)) {
49                 if (tablename[strlen(tablename) - 1] != '\n')
50                         xtables_error(OTHER_PROBLEM,
51                                    "Badly formed tablename `%s'\n",
52                                    tablename);
53                 tablename[strlen(tablename) - 1] = '\0';
54                 ret &= func(tablename);
55         }
56
57         fclose(procfile);
58         return ret;
59 }
60
61
62 static int do_output(const char *tablename)
63 {
64         struct ip6tc_handle *h;
65         const char *chain = NULL;
66
67         if (!tablename)
68                 return for_each_table(&do_output);
69
70         h = ip6tc_init(tablename);
71         if (h == NULL) {
72                 xtables_load_ko(xtables_modprobe_program, false);
73                 h = ip6tc_init(tablename);
74         }
75         if (!h)
76                 xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
77                            ip6tc_strerror(errno));
78
79         if (!show_binary) {
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 ip6t_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
104                 for (chain = ip6tc_first_chain(h);
105                      chain;
106                      chain = ip6tc_next_chain(h)) {
107                         const struct ip6t_entry *e;
108
109                         /* Dump out rules */
110                         e = ip6tc_first_rule(chain, h);
111                         while(e) {
112                                 print_rule(e, h, chain, show_counters);
113                                 e = ip6tc_next_rule(e, h);
114                         }
115                 }
116
117                 now = time(NULL);
118                 printf("COMMIT\n");
119                 printf("# Completed on %s", ctime(&now));
120         } else {
121                 /* Binary, huh?  OK. */
122                 xtables_error(OTHER_PROBLEM, "Binary NYI\n");
123         }
124
125         ip6tc_free(h);
126
127         return 1;
128 }
129
130 /* Format:
131  * :Chain name POLICY packets bytes
132  * rule
133  */
134 #ifdef IPTABLES_MULTI
135 int ip6tables_save_main(int argc, char *argv[])
136 #else
137 int main(int argc, char *argv[])
138 #endif
139 {
140         const char *tablename = NULL;
141         int c;
142
143         ip6tables_globals.program_name = "ip6tables-save";
144         c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
145         if (c < 0) {
146                 fprintf(stderr, "%s/%s Failed to initialize xtables\n",
147                                 ip6tables_globals.program_name,
148                                 ip6tables_globals.program_version);
149                 exit(1);
150         }
151 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
152         init_extensions();
153 #endif
154
155         while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) {
156                 switch (c) {
157                 case 'b':
158                         show_binary = 1;
159                         break;
160
161                 case 'c':
162                         show_counters = 1;
163                         break;
164
165                 case 't':
166                         /* Select specific table. */
167                         tablename = optarg;
168                         break;
169                 case 'M':
170                         xtables_modprobe_program = optarg;
171                         break;
172                 case 'd':
173                         do_output(tablename);
174                         exit(0);
175                 }
176         }
177
178         if (optind < argc) {
179                 fprintf(stderr, "Unknown arguments found on commandline\n");
180                 exit(1);
181         }
182
183         return !do_output(tablename);
184 }