From: Jo-Philipp Wich Date: Tue, 2 May 2017 13:01:02 +0000 (+0200) Subject: iptables: add exception handling X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffirewall3.git;a=commitdiff_plain;h=e5dfc8253bebb7cfed06f81f34bbe1afdf285735 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 --- diff --git a/iptables.c b/iptables.c index 10bfea5..319c5f6 100644 --- a/iptables.c +++ b/iptables.c @@ -40,6 +40,8 @@ #include #include +#include + #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,