iptables-save.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* Code to save the iptables state, in human readable-form. */
  2. /* (C) 1999 by Paul 'Rusty' Russell <rusty@rustcorp.com.au> and
  3. * (C) 2000-2002 by Harald Welte <laforge@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. #ifndef NO_SHARED_LIBS
  20. #include <dlfcn.h>
  21. #endif
  22. static int show_counters = 0;
  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. /* 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. procfile = fopen("/proc/net/ip_tables_names", "re");
  37. if (!procfile)
  38. return ret;
  39. while (fgets(tablename, sizeof(tablename), procfile)) {
  40. if (tablename[strlen(tablename) - 1] != '\n')
  41. xtables_error(OTHER_PROBLEM,
  42. "Badly formed tablename `%s'\n",
  43. tablename);
  44. tablename[strlen(tablename) - 1] = '\0';
  45. ret &= func(tablename);
  46. }
  47. fclose(procfile);
  48. return ret;
  49. }
  50. static int do_output(const char *tablename)
  51. {
  52. struct xtc_handle *h;
  53. const char *chain = NULL;
  54. if (!tablename)
  55. return for_each_table(&do_output);
  56. h = iptc_init(tablename);
  57. if (h == NULL) {
  58. xtables_load_ko(xtables_modprobe_program, false);
  59. h = iptc_init(tablename);
  60. }
  61. if (!h)
  62. xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
  63. iptc_strerror(errno));
  64. time_t now = time(NULL);
  65. printf("# Generated by iptables-save v%s on %s",
  66. IPTABLES_VERSION, ctime(&now));
  67. printf("*%s\n", tablename);
  68. /* Dump out chain names first,
  69. * thereby preventing dependency conflicts */
  70. for (chain = iptc_first_chain(h);
  71. chain;
  72. chain = iptc_next_chain(h)) {
  73. printf(":%s ", chain);
  74. if (iptc_builtin(chain, h)) {
  75. struct xt_counters count;
  76. printf("%s ",
  77. iptc_get_policy(chain, &count, h));
  78. printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
  79. } else {
  80. printf("- [0:0]\n");
  81. }
  82. }
  83. for (chain = iptc_first_chain(h);
  84. chain;
  85. chain = iptc_next_chain(h)) {
  86. const struct ipt_entry *e;
  87. /* Dump out rules */
  88. e = iptc_first_rule(chain, h);
  89. while(e) {
  90. print_rule4(e, h, chain, show_counters);
  91. e = iptc_next_rule(e, h);
  92. }
  93. }
  94. now = time(NULL);
  95. printf("COMMIT\n");
  96. printf("# Completed on %s", ctime(&now));
  97. iptc_free(h);
  98. return 1;
  99. }
  100. /* Format:
  101. * :Chain name POLICY packets bytes
  102. * rule
  103. */
  104. int
  105. iptables_save_main(int argc, char *argv[])
  106. {
  107. const char *tablename = NULL;
  108. int c;
  109. iptables_globals.program_name = "iptables-save";
  110. c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
  111. if (c < 0) {
  112. fprintf(stderr, "%s/%s Failed to initialize xtables\n",
  113. iptables_globals.program_name,
  114. iptables_globals.program_version);
  115. exit(1);
  116. }
  117. #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
  118. init_extensions();
  119. init_extensions4();
  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. }