12f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó/* Code to save the ip6tables state, in human readable-form. */ 22f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó/* Author: Andras Kis-Szabo <kisza@sch.bme.hu> 32f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * Original code: iptables-save 42f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * Authors: Paul 'Rusty' Russel <rusty@linuxcare.com.au> and 55b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann * Harald Welte <laforge@gnumonks.org> 60c4188f446e7c0ed07076c69d1d7f336a92efc8bAndrás Kis-Szabó * This code is distributed under the terms of GNU GPL v2 72f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó */ 82f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <getopt.h> 92f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <sys/errno.h> 102f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <stdio.h> 112f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <fcntl.h> 122f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <stdlib.h> 132f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <string.h> 142f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <time.h> 152f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <netdb.h> 162f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include <arpa/inet.h> 172f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include "libiptc/libip6tc.h" 182f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó#include "ip6tables.h" 1933690a1aec0b6309ff90066ca56285b6e43013f2Jan Engelhardt#include "ip6tables-multi.h" 202f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 215a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#ifndef NO_SHARED_LIBS 225a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#include <dlfcn.h> 235a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#endif 245a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger 25296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardtstatic int show_counters = 0; 262f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 277bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajosstatic const struct option options[] = { 287bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos {.name = "counters", .has_arg = false, .val = 'c'}, 297bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos {.name = "dump", .has_arg = false, .val = 'd'}, 307bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos {.name = "table", .has_arg = true, .val = 't'}, 31fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt {.name = "modprobe", .has_arg = true, .val = 'M'}, 327bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos {NULL}, 332f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó}; 342f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 352f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 362f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó/* Debugging prototype. */ 372f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóstatic int for_each_table(int (*func)(const char *tablename)) 382f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 395b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann int ret = 1; 402f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó FILE *procfile = NULL; 4114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt char tablename[XT_TABLE_MAXNAMELEN+1]; 422f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 43a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski procfile = fopen("/proc/net/ip6_tables_names", "re"); 442f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!procfile) 45fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt return ret; 462f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 472f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó while (fgets(tablename, sizeof(tablename), procfile)) { 482f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (tablename[strlen(tablename) - 1] != '\n') 491829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(OTHER_PROBLEM, 502f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó "Badly formed tablename `%s'\n", 512f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó tablename); 522f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó tablename[strlen(tablename) - 1] = '\0'; 532f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ret &= func(tablename); 542f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 552f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 56f1afcc896e7f8be3a6419681fd8cdee1d600a3aaJan Engelhardt fclose(procfile); 572f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return ret; 582f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 595b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann 602f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 612f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabóstatic int do_output(const char *tablename) 622f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 631639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt struct xtc_handle *h; 642f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó const char *chain = NULL; 652f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 662f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!tablename) 672f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return for_each_table(&do_output); 682f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 692f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó h = ip6tc_init(tablename); 70fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt if (h == NULL) { 71fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt xtables_load_ko(xtables_modprobe_program, false); 72fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt h = ip6tc_init(tablename); 73fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt } 742f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (!h) 751829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n", 762f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó ip6tc_strerror(errno)); 772f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 78296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt time_t now = time(NULL); 79296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt 80296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("# Generated by ip6tables-save v%s on %s", 81296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt IPTABLES_VERSION, ctime(&now)); 82296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("*%s\n", tablename); 83296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt 84296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt /* Dump out chain names first, 85296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt * thereby preventing dependency conflicts */ 86296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt for (chain = ip6tc_first_chain(h); 87296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt chain; 88296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt chain = ip6tc_next_chain(h)) { 89296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt 90296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf(":%s ", chain); 91296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt if (ip6tc_builtin(chain, h)) { 9214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt struct xt_counters count; 93296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("%s ", 94296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt ip6tc_get_policy(chain, &count, h)); 95296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt); 96296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt } else { 97296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("- [0:0]\n"); 98885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte } 99296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt } 100885c6eb5ec8a186c77a4710808374dd612e82b20Harald Welte 101296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt for (chain = ip6tc_first_chain(h); 102296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt chain; 103296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt chain = ip6tc_next_chain(h)) { 104296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt const struct ip6t_entry *e; 10597fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó 106296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt /* Dump out rules */ 107296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt e = ip6tc_first_rule(chain, h); 108296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt while(e) { 109296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt print_rule6(e, h, chain, show_counters); 110296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt e = ip6tc_next_rule(e, h); 1112f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1122f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1132f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 114296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt now = time(NULL); 115296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("COMMIT\n"); 116296dca39be1166c4b7c6367c1b97ee95aebddfc3Jan Engelhardt printf("# Completed on %s", ctime(&now)); 1171c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt ip6tc_free(h); 118841e4aed2349046eb2c0b1375139c06569a93bd0Martin Josefsson 1192f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return 1; 1202f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 1212f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1222f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó/* Format: 1232f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * :Chain name POLICY packets bytes 1242f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó * rule 1252f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó */ 1264bc48331d2d1ef64ba452329f2c77137036f6437Hann-Huei Chiouint ip6tables_save_main(int argc, char *argv[]) 1272f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó{ 1282f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó const char *tablename = NULL; 1292f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó int c; 1302f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 131617d3d140f4739558dce2ef8ed01aef251cf5487Jamal Hadi Salim ip6tables_globals.program_name = "ip6tables-save"; 1327e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); 1337e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim if (c < 0) { 1347e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim fprintf(stderr, "%s/%s Failed to initialize xtables\n", 1357e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim ip6tables_globals.program_name, 1367e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim ip6tables_globals.program_version); 1377e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim exit(1); 1387e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim } 139b79ec69027fd8b65e7eccd78a445b6665e8ad53bJan Engelhardt#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) 1409a9694fbf1796a6a5011b60b2a15c01fa3c61368Maciej Żenczykowski init_extensions(); 14149d8c5d564cad70c5c1bef2d5571e8e494454210Maciej Zenczykowski init_extensions6(); 1423efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7cHarald Welte#endif 1433efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7cHarald Welte 14497fd91a58e7978338451471cfc2cd5ead3b22f26András Kis-Szabó while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) { 1452f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó switch (c) { 1462f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 'c': 147dbb77543ad6afe29e9a1881b2d4fc212de621a55Jan Engelhardt show_counters = 1; 1482f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó break; 1492f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1502f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 't': 1512f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó /* Select specific table. */ 1522f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó tablename = optarg; 1532f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó break; 154fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt case 'M': 155fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt xtables_modprobe_program = optarg; 156fbb5639c02218acfd84c4f25f134efecb564fee1Jan Engelhardt break; 1572f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó case 'd': 1582f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó do_output(tablename); 1592f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(0); 1602f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1612f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1622f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1632f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó if (optind < argc) { 164972af09e79618c5086e26ef6438bd38c45c4bb3fPavel Rusnak fprintf(stderr, "Unknown arguments found on commandline\n"); 1652f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó exit(1); 1662f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó } 1672f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó 1682f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó return !do_output(tablename); 1692f52379841217e55201fbc93872be9a21fa5d443András Kis-Szabó} 170