OSDN Git Service

Fix no pic
[uclinux-h8/uClinux-dist.git] / user / iptables / 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         return ret;
58 }
59
60
61 static int do_output(const char *tablename)
62 {
63         struct ip6tc_handle *h;
64         const char *chain = NULL;
65
66         if (!tablename)
67                 return for_each_table(&do_output);
68
69         h = ip6tc_init(tablename);
70         if (h == NULL) {
71                 xtables_load_ko(xtables_modprobe_program, false);
72                 h = ip6tc_init(tablename);
73         }
74         if (!h)
75                 xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
76                            ip6tc_strerror(errno));
77
78         if (!show_binary) {
79                 time_t now = time(NULL);
80
81                 printf("# Generated by ip6tables-save v%s on %s",
82                        IPTABLES_VERSION, ctime(&now));
83                 printf("*%s\n", tablename);
84
85                 /* Dump out chain names first,
86                  * thereby preventing dependency conflicts */
87                 for (chain = ip6tc_first_chain(h);
88                      chain;
89                      chain = ip6tc_next_chain(h)) {
90
91                         printf(":%s ", chain);
92                         if (ip6tc_builtin(chain, h)) {
93                                 struct ip6t_counters count;
94                                 printf("%s ",
95                                        ip6tc_get_policy(chain, &count, h));
96                                 printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
97                         } else {
98                                 printf("- [0:0]\n");
99                         }
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_rule(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         } else {
120                 /* Binary, huh?  OK. */
121                 xtables_error(OTHER_PROBLEM, "Binary NYI\n");
122         }
123
124         ip6tc_free(h);
125
126         return 1;
127 }
128
129 /* Format:
130  * :Chain name POLICY packets bytes
131  * rule
132  */
133 #ifdef IPTABLES_MULTI
134 int ip6tables_save_main(int argc, char *argv[])
135 #else
136 int main(int argc, char *argv[])
137 #endif
138 {
139         const char *tablename = NULL;
140         int c;
141
142         ip6tables_globals.program_name = "ip6tables-save";
143         c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
144         if (c < 0) {
145                 fprintf(stderr, "%s/%s Failed to initialize xtables\n",
146                                 ip6tables_globals.program_name,
147                                 ip6tables_globals.program_version);
148                 exit(1);
149         }
150 #ifdef NO_SHARED_LIBS
151         init_extensions();
152 #endif
153
154         while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) {
155                 switch (c) {
156                 case 'b':
157                         show_binary = 1;
158                         break;
159
160                 case 'c':
161                         show_counters = 1;
162                         break;
163
164                 case 't':
165                         /* Select specific table. */
166                         tablename = optarg;
167                         break;
168                 case 'M':
169                         xtables_modprobe_program = optarg;
170                         break;
171                 case 'd':
172                         do_output(tablename);
173                         exit(0);
174                 }
175         }
176
177         if (optind < argc) {
178                 fprintf(stderr, "Unknown arguments found on commandline\n");
179                 exit(1);
180         }
181
182         return !do_output(tablename);
183 }