From 8d994bcf6be09cd0a13d6f22c6e01e98fb130415 Mon Sep 17 00:00:00 2001 From: Oliver Ford Date: Fri, 26 May 2017 12:25:16 +0000 Subject: iptables: Add file output option to iptables-save Adds an option to output the results of iptables-save, ip6tables-save, and xtables-save save to a file. Updates the man page with this new option. Uses the dup2 call to replace stdout with the specified file. Error output is unchanged. This is a feature requested by a Gentoo developer in Bugzilla #905. Signed-off-by: Oliver Ford Signed-off-by: Pablo Neira Ayuso --- iptables/ip6tables-save.c | 22 ++++++++++++++++++++-- iptables/iptables-save.8.in | 14 +++++++++----- iptables/iptables-save.c | 22 ++++++++++++++++++++-- iptables/xtables-save.c | 22 ++++++++++++++++++++-- 4 files changed, 69 insertions(+), 11 deletions(-) (limited to 'iptables') diff --git a/iptables/ip6tables-save.c b/iptables/ip6tables-save.c index 250ca204..8e3a6afd 100644 --- a/iptables/ip6tables-save.c +++ b/iptables/ip6tables-save.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "libiptc/libip6tc.h" #include "ip6tables.h" #include "ip6tables-multi.h" @@ -25,6 +26,7 @@ static const struct option options[] = { {.name = "dump", .has_arg = false, .val = 'd'}, {.name = "table", .has_arg = true, .val = 't'}, {.name = "modprobe", .has_arg = true, .val = 'M'}, + {.name = "file", .has_arg = true, .val = 'f'}, {NULL}, }; @@ -128,7 +130,8 @@ static int do_output(const char *tablename) int ip6tables_save_main(int argc, char *argv[]) { const char *tablename = NULL; - int c; + FILE *file = NULL; + int ret, c; ip6tables_globals.program_name = "ip6tables-save"; c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); @@ -143,7 +146,7 @@ int ip6tables_save_main(int argc, char *argv[]) init_extensions6(); #endif - while ((c = getopt_long(argc, argv, "bcdt:M:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcdt:M:f:", options, NULL)) != -1) { switch (c) { case 'b': fprintf(stderr, "-b/--binary option is not implemented\n"); @@ -159,6 +162,21 @@ int ip6tables_save_main(int argc, char *argv[]) case 'M': xtables_modprobe_program = optarg; break; + case 'f': + file = fopen(optarg, "w"); + if (file == NULL) { + fprintf(stderr, "Failed to open file, error: %s\n", + strerror(errno)); + exit(1); + } + ret = dup2(fileno(file), STDOUT_FILENO); + if (ret == -1) { + fprintf(stderr, "Failed to redirect stdout, error: %s\n", + strerror(errno)); + exit(1); + } + fclose(file); + break; case 'd': do_output(tablename); exit(0); diff --git a/iptables/iptables-save.8.in b/iptables/iptables-save.8.in index 7f99d8a3..51e11f3e 100644 --- a/iptables/iptables-save.8.in +++ b/iptables/iptables-save.8.in @@ -19,27 +19,31 @@ .\" .\" .SH NAME -iptables-save \(em dump iptables rules to stdout +iptables-save \(em dump iptables rules .P -ip6tables-save \(em dump iptables rules to stdout +ip6tables-save \(em dump iptables rules .SH SYNOPSIS \fBiptables\-save\fP [\fB\-M\fP \fImodprobe\fP] [\fB\-c\fP] -[\fB\-t\fP \fItable\fP] +[\fB\-t\fP \fItable\fP] [\fB\-f\fP \fIfilename\fP] .P \fBip6tables\-save\fP [\fB\-M\fP \fImodprobe\fP] [\fB\-c\fP] -[\fB\-t\fP \fItable\fP] +[\fB\-t\fP \fItable\fP] [\fB\-f\fP \fIfilename\fP] .SH DESCRIPTION .PP .B iptables-save and .B ip6tables-save are used to dump the contents of IP or IPv6 Table in easily parseable format -to STDOUT. Use I/O-redirection provided by your shell to write to a file. +either to STDOUT or to a specified file. .TP \fB\-M\fR, \fB\-\-modprobe\fR \fImodprobe_program\fP Specify the path to the modprobe program. By default, iptables-save will inspect /proc/sys/kernel/modprobe to determine the executable's path. .TP +\fB\-f\fR, \fB\-\-file\fR \fIfilename\fP +Specify a filename to log the output to. If not specified, iptables-save +will log to STDOUT. +.TP \fB\-c\fR, \fB\-\-counters\fR include the current values of all packet and byte counters in the output .TP diff --git a/iptables/iptables-save.c b/iptables/iptables-save.c index 52929b09..d59bd34a 100644 --- a/iptables/iptables-save.c +++ b/iptables/iptables-save.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "libiptc/libiptc.h" #include "iptables.h" #include "iptables-multi.h" @@ -24,6 +25,7 @@ static const struct option options[] = { {.name = "dump", .has_arg = false, .val = 'd'}, {.name = "table", .has_arg = true, .val = 't'}, {.name = "modprobe", .has_arg = true, .val = 'M'}, + {.name = "file", .has_arg = true, .val = 'f'}, {NULL}, }; @@ -127,7 +129,8 @@ int iptables_save_main(int argc, char *argv[]) { const char *tablename = NULL; - int c; + FILE *file = NULL; + int ret, c; iptables_globals.program_name = "iptables-save"; c = xtables_init_all(&iptables_globals, NFPROTO_IPV4); @@ -142,7 +145,7 @@ iptables_save_main(int argc, char *argv[]) init_extensions4(); #endif - while ((c = getopt_long(argc, argv, "bcdt:M:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcdt:M:f:", options, NULL)) != -1) { switch (c) { case 'b': fprintf(stderr, "-b/--binary option is not implemented\n"); @@ -158,6 +161,21 @@ iptables_save_main(int argc, char *argv[]) case 'M': xtables_modprobe_program = optarg; break; + case 'f': + file = fopen(optarg, "w"); + if (file == NULL) { + fprintf(stderr, "Failed to open file, error: %s\n", + strerror(errno)); + exit(1); + } + ret = dup2(fileno(file), STDOUT_FILENO); + if (ret == -1) { + fprintf(stderr, "Failed to redirect stdout, error: %s\n", + strerror(errno)); + exit(1); + } + fclose(file); + break; case 'd': do_output(tablename); exit(0); diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index abd840af..5b498b04 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "libiptc/libiptc.h" #include "iptables.h" #include "xtables-multi.h" @@ -32,6 +33,7 @@ static const struct option options[] = { {.name = "dump", .has_arg = false, .val = 'd'}, {.name = "table", .has_arg = true, .val = 't'}, {.name = "modprobe", .has_arg = true, .val = 'M'}, + {.name = "file", .has_arg = true, .val = 'f'}, {.name = "ipv4", .has_arg = false, .val = '4'}, {.name = "ipv6", .has_arg = false, .val = '6'}, {NULL}, @@ -82,7 +84,8 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) struct nft_handle h = { .family = family, }; - int c; + FILE *file = NULL; + int ret, c; xtables_globals.program_name = progname; c = xtables_init_all(&xtables_globals, family); @@ -104,7 +107,7 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) exit(EXIT_FAILURE); } - while ((c = getopt_long(argc, argv, "bcdt:M:46", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcdt:M:f:46", options, NULL)) != -1) { switch (c) { case 'b': fprintf(stderr, "-b/--binary option is not implemented\n"); @@ -120,6 +123,21 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) case 'M': xtables_modprobe_program = optarg; break; + case 'f': + file = fopen(optarg, "w"); + if (file == NULL) { + fprintf(stderr, "Failed to open file, error: %s\n", + strerror(errno)); + exit(1); + } + ret = dup2(fileno(file), STDOUT_FILENO); + if (ret == -1) { + fprintf(stderr, "Failed to redirect stdout, error: %s\n", + strerror(errno)); + exit(1); + } + fclose(file); + break; case 'd': dump = true; break; -- cgit v1.2.3