ip6tables-save.c 3.7 KB

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