tweaking makefile
[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         {NULL},
33 };
34
35
36 /* Debugging prototype. */
37 static int for_each_table(int (*func)(const char *tablename))
38 {
39         int ret = 1;
40         FILE *procfile = NULL;
41         char tablename[IP6T_TABLE_MAXNAMELEN+1];
42
43         procfile = fopen("/proc/net/ip6_tables_names", "r");
44         if (!procfile)
45                 exit_error(OTHER_PROBLEM,
46                            "Unable to open /proc/net/ip6_tables_names: %s\n",
47                            strerror(errno));
48
49         while (fgets(tablename, sizeof(tablename), procfile)) {
50                 if (tablename[strlen(tablename) - 1] != '\n')
51                         exit_error(OTHER_PROBLEM, 
52                                    "Badly formed tablename `%s'\n",
53                                    tablename);
54                 tablename[strlen(tablename) - 1] = '\0';
55                 ret &= func(tablename);
56         }
57
58         return ret;
59 }
60
61
62 static int do_output(const char *tablename)
63 {
64         ip6tc_handle_t 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)
72                 exit_error(OTHER_PROBLEM, "Can't initialize: %s\n",
73                            ip6tc_strerror(errno));
74
75         if (!show_binary) {
76                 time_t now = time(NULL);
77
78                 printf("# Generated by ip6tables-save v%s on %s",
79                        XTABLES_VERSION, ctime(&now));
80                 printf("*%s\n", tablename);
81
82                 /* Dump out chain names first,
83                  * thereby preventing dependency conflicts */
84                 for (chain = ip6tc_first_chain(&h);
85                      chain;
86                      chain = ip6tc_next_chain(&h)) {
87
88                         printf(":%s ", chain);
89                         if (ip6tc_builtin(chain, h)) {
90                                 struct ip6t_counters count;
91                                 printf("%s ",
92                                        ip6tc_get_policy(chain, &count, &h));
93                                 printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
94                         } else {
95                                 printf("- [0:0]\n");
96                         }
97                 }
98
99
100                 for (chain = ip6tc_first_chain(&h);
101                      chain;
102                      chain = ip6tc_next_chain(&h)) {
103                         const struct ip6t_entry *e;
104
105                         /* Dump out rules */
106                         e = ip6tc_first_rule(chain, &h);
107                         while(e) {
108                                 print_rule(e, &h, chain, show_counters);
109                                 e = ip6tc_next_rule(e, &h);
110                         }
111                 }
112
113                 now = time(NULL);
114                 printf("COMMIT\n");
115                 printf("# Completed on %s", ctime(&now));
116         } else {
117                 /* Binary, huh?  OK. */
118                 exit_error(OTHER_PROBLEM, "Binary NYI\n");
119         }
120
121         ip6tc_free(&h);
122
123         return 1;
124 }
125
126 /* Format:
127  * :Chain name POLICY packets bytes
128  * rule
129  */
130 #ifdef IPTABLES_MULTI
131 int ip6tables_save_main(int argc, char *argv[])
132 #else
133 int main(int argc, char *argv[])
134 #endif
135 {
136         const char *tablename = NULL;
137         int c;
138
139         program_name = "ip6tables-save";
140         program_version = XTABLES_VERSION;
141
142         lib_dir = getenv("XTABLES_LIBDIR");
143         if (lib_dir == NULL) {
144                 lib_dir = getenv("IP6TABLES_LIB_DIR");
145                 if (lib_dir != NULL)
146                         fprintf(stderr, "IP6TABLES_LIB_DIR is deprecated\n");
147         }
148         if (lib_dir == NULL)
149                 lib_dir = XTABLES_LIBDIR;
150
151 #ifdef 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 'd':
170                         do_output(tablename);
171                         exit(0);
172                 }
173         }
174
175         if (optind < argc) {
176                 fprintf(stderr, "Unknown arguments found on commandline\n");
177                 exit(1);
178         }
179
180         return !do_output(tablename);
181 }