]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
iptables: Add file output option to iptables-save
authorOliver Ford <ojford@gmail.com>
Fri, 26 May 2017 12:25:16 +0000 (12:25 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 29 May 2017 12:00:54 +0000 (14:00 +0200)
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 <ojford@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/ip6tables-save.c
iptables/iptables-save.8.in
iptables/iptables-save.c
iptables/xtables-save.c

index 250ca20492b65293c116994e6f3e664916bb769a..8e3a6afd939d515e53ac5c5a662fe3549fbb513b 100644 (file)
@@ -14,6 +14,7 @@
 #include <time.h>
 #include <netdb.h>
 #include <arpa/inet.h>
+#include <unistd.h>
 #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);
index 7f99d8a356f569197636b89bb39b9e0066cbbd34..51e11f3e7adca0d5550814b6979ea38d41f20907 100644 (file)
 .\"
 .\"
 .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
index 52929b0996e909772454dab82e2db2d4c574c3eb..d59bd34a62b6869329f100d79a62fa0a61a7115e 100644 (file)
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <time.h>
 #include <netdb.h>
+#include <unistd.h>
 #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);
index abd840af6607fe4eba77e36c56073988629b6a3a..5b498b0433242d6b0161efacff53c4d701b81431 100644 (file)
@@ -14,6 +14,7 @@
 #include <string.h>
 #include <time.h>
 #include <netdb.h>
+#include <unistd.h>
 #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;