diff options
author | Jo-Philipp Wich <jo@mein.io> | 2017-05-02 15:01:02 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2017-05-12 16:10:06 +0200 |
commit | e5dfc8253bebb7cfed06f81f34bbe1afdf285735 (patch) | |
tree | f26b2c79e62782ca141b516a2bfb831abc2b5ed9 | |
parent | f62595480555f4034841cfbdec5858645528ae7d (diff) | |
download | firewall3-e5dfc8253bebb7cfed06f81f34bbe1afdf285735.tar.gz |
iptables: add exception handling
Override libxtables standard error handler to not exit the program but to
longjmp() back to error handling code which is simply skipping the rule.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | iptables.c | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -40,6 +40,8 @@ #include <libiptc/libip6tc.h> #include <xtables.h> +#include <setjmp.h> + #include "options.h" /* xtables interface */ @@ -78,10 +80,29 @@ static struct option base_opts[] = { { NULL } }; + +static jmp_buf fw3_ipt_error_jmp; + +static __attribute__((noreturn)) +void fw3_ipt_error_handler(enum xtables_exittype status, + const char *fmt, ...) +{ + va_list args; + + fprintf(stderr, " ! Exception: "); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + longjmp(fw3_ipt_error_jmp, status); +} + static struct xtables_globals xtg = { .option_offset = 0, .program_version = "4", .orig_opts = base_opts, + .exit_err = fw3_ipt_error_handler, #if XTABLES_VERSION_CODE > 10 .compat_rev = xtables_compatible_revision, #endif @@ -91,6 +112,7 @@ static struct xtables_globals xtg6 = { .option_offset = 0, .program_version = "6", .orig_opts = base_opts, + .exit_err = fw3_ipt_error_handler, #if XTABLES_VERSION_CODE > 10 .compat_rev = xtables_compatible_revision, #endif @@ -1524,6 +1546,8 @@ __fw3_ipt_rule_append(struct fw3_ipt_rule *r, bool repl, const char *fmt, ...) struct xtables_target *et; struct xtables_globals *g; + enum xtables_exittype status; + int i, optc; bool inv = false; char buf[32]; @@ -1539,6 +1563,14 @@ __fw3_ipt_rule_append(struct fw3_ipt_rule *r, bool repl, const char *fmt, ...) optind = 0; opterr = 0; + status = setjmp(fw3_ipt_error_jmp); + + if (status > 0) + { + info(" ! Skipping due to previous exception (code %u)", status); + goto free; + } + set_rule_tag(r); while ((optc = getopt_long(r->argc, r->argv, "-:m:j:", g->opts, |