Home | History | Annotate | Download | only in iptables
      1 /* Code to save the ip6tables state, in human readable-form. */
      2 /* Author:  Andras Kis-Szabo <kisza (at) sch.bme.hu>
      3  * Original code: iptables-save
      4  * Authors: Paul 'Rusty' Russel <rusty (at) linuxcare.com.au> and
      5  *          Harald Welte <laforge (at) 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. */
     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 
     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  */
    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