Home | History | Annotate | Download | only in iptables
      1 /* Code to save the iptables state, in human readable-form. */
      2 /* (C) 1999 by Paul 'Rusty' Russell <rusty (at) rustcorp.com.au> and
      3  * (C) 2000-2002 by Harald Welte <laforge (at) gnumonks.org>
      4  *
      5  * This code is distributed under the terms of GNU GPL v2
      6  *
      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 "libiptc/libiptc.h"
     17 #include "iptables.h"
     18 #include "iptables-multi.h"
     19 
     20 #ifndef NO_SHARED_LIBS
     21 #include <dlfcn.h>
     22 #endif
     23 
     24 static int show_counters = 0;
     25 
     26 static const struct option options[] = {
     27 	{.name = "counters", .has_arg = false, .val = 'c'},
     28 	{.name = "dump",     .has_arg = false, .val = 'd'},
     29 	{.name = "table",    .has_arg = true,  .val = 't'},
     30 	{.name = "modprobe", .has_arg = true,  .val = 'M'},
     31 	{NULL},
     32 };
     33 
     34 /* Debugging prototype. */
     35 static int for_each_table(int (*func)(const char *tablename))
     36 {
     37 	int ret = 1;
     38 	FILE *procfile = NULL;
     39 	char tablename[XT_TABLE_MAXNAMELEN+1];
     40 
     41 	procfile = fopen("/proc/net/ip_tables_names", "re");
     42 	if (!procfile)
     43 		return ret;
     44 
     45 	while (fgets(tablename, sizeof(tablename), procfile)) {
     46 		if (tablename[strlen(tablename) - 1] != '\n')
     47 			xtables_error(OTHER_PROBLEM,
     48 				   "Badly formed tablename `%s'\n",
     49 				   tablename);
     50 		tablename[strlen(tablename) - 1] = '\0';
     51 		ret &= func(tablename);
     52 	}
     53 
     54 	fclose(procfile);
     55 	return ret;
     56 }
     57 
     58 
     59 static int do_output(const char *tablename)
     60 {
     61 	struct xtc_handle *h;
     62 	const char *chain = NULL;
     63 
     64 	if (!tablename)
     65 		return for_each_table(&do_output);
     66 
     67 	h = iptc_init(tablename);
     68 	if (h == NULL) {
     69 		xtables_load_ko(xtables_modprobe_program, false);
     70 		h = iptc_init(tablename);
     71 	}
     72 	if (!h)
     73 		xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
     74 			   iptc_strerror(errno));
     75 
     76 	time_t now = time(NULL);
     77 
     78 	printf("# Generated by iptables-save v%s on %s",
     79 	       IPTABLES_VERSION, ctime(&now));
     80 	printf("*%s\n", tablename);
     81 
     82 	/* Dump out chain names first,
     83 	 * thereby preventing dependency conflicts */
     84 	for (chain = iptc_first_chain(h);
     85 	     chain;
     86 	     chain = iptc_next_chain(h)) {
     87 
     88 		printf(":%s ", chain);
     89 		if (iptc_builtin(chain, h)) {
     90 			struct xt_counters count;
     91 			printf("%s ",
     92 			       iptc_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 	for (chain = iptc_first_chain(h);
    100 	     chain;
    101 	     chain = iptc_next_chain(h)) {
    102 		const struct ipt_entry *e;
    103 
    104 		/* Dump out rules */
    105 		e = iptc_first_rule(chain, h);
    106 		while(e) {
    107 			print_rule4(e, h, chain, show_counters);
    108 			e = iptc_next_rule(e, h);
    109 		}
    110 	}
    111 
    112 	now = time(NULL);
    113 	printf("COMMIT\n");
    114 	printf("# Completed on %s", ctime(&now));
    115 	iptc_free(h);
    116 
    117 	return 1;
    118 }
    119 
    120 /* Format:
    121  * :Chain name POLICY packets bytes
    122  * rule
    123  */
    124 int
    125 iptables_save_main(int argc, char *argv[])
    126 {
    127 	const char *tablename = NULL;
    128 	int c;
    129 
    130 	iptables_globals.program_name = "iptables-save";
    131 	c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
    132 	if (c < 0) {
    133 		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
    134 				iptables_globals.program_name,
    135 				iptables_globals.program_version);
    136 		exit(1);
    137 	}
    138 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
    139 	init_extensions();
    140 	init_extensions4();
    141 #endif
    142 
    143 	while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) {
    144 		switch (c) {
    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