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 <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 static int show_counters = 0;
     21 
     22 static const struct option options[] = {
     23 	{.name = "counters", .has_arg = false, .val = 'c'},
     24 	{.name = "dump",     .has_arg = false, .val = 'd'},
     25 	{.name = "table",    .has_arg = true,  .val = 't'},
     26 	{.name = "modprobe", .has_arg = true,  .val = 'M'},
     27 	{NULL},
     28 };
     29 
     30 /* Debugging prototype. */
     31 static int for_each_table(int (*func)(const char *tablename))
     32 {
     33 	int ret = 1;
     34 	FILE *procfile = NULL;
     35 	char tablename[XT_TABLE_MAXNAMELEN+1];
     36 
     37 	procfile = fopen("/proc/net/ip_tables_names", "re");
     38 	if (!procfile)
     39 		return ret;
     40 
     41 	while (fgets(tablename, sizeof(tablename), procfile)) {
     42 		if (tablename[strlen(tablename) - 1] != '\n')
     43 			xtables_error(OTHER_PROBLEM,
     44 				   "Badly formed tablename `%s'\n",
     45 				   tablename);
     46 		tablename[strlen(tablename) - 1] = '\0';
     47 		ret &= func(tablename);
     48 	}
     49 
     50 	fclose(procfile);
     51 	return ret;
     52 }
     53 
     54 
     55 static int do_output(const char *tablename)
     56 {
     57 	struct xtc_handle *h;
     58 	const char *chain = NULL;
     59 
     60 	if (!tablename)
     61 		return for_each_table(&do_output);
     62 
     63 	h = iptc_init(tablename);
     64 	if (h == NULL) {
     65 		xtables_load_ko(xtables_modprobe_program, false);
     66 		h = iptc_init(tablename);
     67 	}
     68 	if (!h)
     69 		xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
     70 			   iptc_strerror(errno));
     71 
     72 	time_t now = time(NULL);
     73 
     74 	printf("# Generated by iptables-save v%s on %s",
     75 	       IPTABLES_VERSION, ctime(&now));
     76 	printf("*%s\n", tablename);
     77 
     78 	/* Dump out chain names first,
     79 	 * thereby preventing dependency conflicts */
     80 	for (chain = iptc_first_chain(h);
     81 	     chain;
     82 	     chain = iptc_next_chain(h)) {
     83 
     84 		printf(":%s ", chain);
     85 		if (iptc_builtin(chain, h)) {
     86 			struct xt_counters count;
     87 			printf("%s ",
     88 			       iptc_get_policy(chain, &count, h));
     89 			printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
     90 		} else {
     91 			printf("- [0:0]\n");
     92 		}
     93 	}
     94 
     95 	for (chain = iptc_first_chain(h);
     96 	     chain;
     97 	     chain = iptc_next_chain(h)) {
     98 		const struct ipt_entry *e;
     99 
    100 		/* Dump out rules */
    101 		e = iptc_first_rule(chain, h);
    102 		while(e) {
    103 			print_rule4(e, h, chain, show_counters);
    104 			e = iptc_next_rule(e, h);
    105 		}
    106 	}
    107 
    108 	now = time(NULL);
    109 	printf("COMMIT\n");
    110 	printf("# Completed on %s", ctime(&now));
    111 	iptc_free(h);
    112 
    113 	return 1;
    114 }
    115 
    116 /* Format:
    117  * :Chain name POLICY packets bytes
    118  * rule
    119  */
    120 int
    121 iptables_save_main(int argc, char *argv[])
    122 {
    123 	const char *tablename = NULL;
    124 	int c;
    125 
    126 	iptables_globals.program_name = "iptables-save";
    127 	c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
    128 	if (c < 0) {
    129 		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
    130 				iptables_globals.program_name,
    131 				iptables_globals.program_version);
    132 		exit(1);
    133 	}
    134 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
    135 	init_extensions();
    136 	init_extensions4();
    137 #endif
    138 
    139 	while ((c = getopt_long(argc, argv, "bcdt:M:", options, NULL)) != -1) {
    140 		switch (c) {
    141 		case 'b':
    142 			fprintf(stderr, "-b/--binary option is not implemented\n");
    143 			break;
    144 		case 'c':
    145 			show_counters = 1;
    146 			break;
    147 
    148 		case 't':
    149 			/* Select specific table. */
    150 			tablename = optarg;
    151 			break;
    152 		case 'M':
    153 			xtables_modprobe_program = optarg;
    154 			break;
    155 		case 'd':
    156 			do_output(tablename);
    157 			exit(0);
    158 		}
    159 	}
    160 
    161 	if (optind < argc) {
    162 		fprintf(stderr, "Unknown arguments found on commandline\n");
    163 		exit(1);
    164 	}
    165 
    166 	return !do_output(tablename);
    167 }
    168