diff options
Diffstat (limited to 'xtables.c')
-rw-r--r-- | xtables.c | 89 |
1 files changed, 71 insertions, 18 deletions
@@ -55,6 +55,59 @@ #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" #endif +void basic_exit_err(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); + +struct xtables_globals *xt_params = NULL; + +void basic_exit_err(enum xtables_exittype status, const char *msg, ...) +{ + va_list args; + + va_start(args, msg); + fprintf(stderr, "%s v%s: ", xt_params->program_name, xt_params->program_version); + vfprintf(stderr, msg, args); + va_end(args); + fprintf(stderr, "\n"); + exit(status); +} + + +/** + * xtables_set_params - set the global parameters used by xtables + * @xtp: input xtables_globals structure + * + * The app is expected to pass a valid xtables_globals data-filled + * with proper values + * @xtp cannot be NULL + * + * Returns -1 on failure to set and 0 on success + */ +int xtables_set_params(struct xtables_globals *xtp) +{ + if (!xtp) { + fprintf(stderr, "%s: Illegal global params\n",__func__); + return -1; + } + + xt_params = xtp; + + if (!xt_params->exit_err) + xt_params->exit_err = basic_exit_err; + + return 0; +} + +void xtables_free_opts(int reset_offset, struct option *original_opts) +{ + if (xt_params->opts != original_opts) { + if (original_opts) + free(xt_params->opts); + xt_params->opts = original_opts; + if (reset_offset) + xt_params->option_offset = 0; + } +} + /** * xtables_afinfo - protocol family dependent information * @kmod: kernel module basename (e.g. "ip_tables") @@ -331,7 +384,7 @@ u_int16_t xtables_parse_port(const char *port, const char *proto) (portnum = xtables_service_to_port(port, proto)) != (unsigned)-1) return portnum; - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "invalid port/service `%s' specified", port); } @@ -345,7 +398,7 @@ void xtables_parse_interface(const char *arg, char *vianame, memset(vianame, 0, IFNAMSIZ); if (vialen + 1 > IFNAMSIZ) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "interface name `%s' must be shorter than IFNAMSIZ" " (%i)", arg, IFNAMSIZ-1); @@ -467,7 +520,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, name, false); if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't load match `%s':%s\n", name, dlerror()); } @@ -479,7 +532,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, ptr = NULL; } if(!ptr && (tryload == XTF_LOAD_MUST_SUCCEED)) { - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't find match `%s'\n", name); } #endif @@ -527,7 +580,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) name, true); if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't load target `%s':%s\n", name, dlerror()); } @@ -539,7 +592,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) ptr = NULL; } if(!ptr && (tryload == LOAD_MUST_SUCCEED)) { - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't find target `%s'\n", name); } #endif @@ -792,7 +845,7 @@ void xtables_param_act(unsigned int status, const char *p1, ...) b = va_arg(args, unsigned int); if (!b) return; - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "%s: \"%s\" option may only be specified once", p1, p2); break; @@ -801,13 +854,13 @@ void xtables_param_act(unsigned int status, const char *p1, ...) b = va_arg(args, unsigned int); if (!b) return; - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "%s: \"%s\" option cannot be inverted", p1, p2); break; case XTF_BAD_VALUE: p2 = va_arg(args, const char *); p3 = va_arg(args, const char *); - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "%s: Bad value for \"%s\" option: \"%s\"", p1, p2, p3); break; @@ -815,11 +868,11 @@ void xtables_param_act(unsigned int status, const char *p1, ...) b = va_arg(args, unsigned int); if (!b) return; - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "%s: At most one action is possible", p1); break; default: - exit_error(status, p1, args); + xt_params->exit_err(status, p1, args); break; } @@ -1002,7 +1055,7 @@ ipparse_hostnetwork(const char *name, unsigned int *naddrs) if ((addrptmp = host_to_ipaddr(name, naddrs)) != NULL) return addrptmp; - exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", name); + xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); } static struct in_addr *parse_ipmask(const char *mask) @@ -1020,7 +1073,7 @@ static struct in_addr *parse_ipmask(const char *mask) /* dotted_to_addr already returns a network byte order addr */ return addrp; if (!xtables_strtoui(mask, NULL, &bits, 0, 32)) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "invalid mask `%s' specified", mask); if (bits != 0) { maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); @@ -1231,7 +1284,7 @@ ip6parse_hostnetwork(const char *name, unsigned int *naddrs) if ((addrp = host_to_ip6addr(name, naddrs)) != NULL) return addrp; - exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", name); + xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); } static struct in6_addr *parse_ip6mask(char *mask) @@ -1248,7 +1301,7 @@ static struct in6_addr *parse_ip6mask(char *mask) if ((addrp = xtables_numeric_to_ip6addr(mask)) != NULL) return addrp; if (!xtables_strtoui(mask, NULL, &bits, 0, 128)) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "invalid mask `%s' specified", mask); if (bits != 0) { char *p = (void *)&maskaddr; @@ -1348,13 +1401,13 @@ int xtables_check_inverse(const char option[], int *invert, "extrapositioned (`! --option this`).\n"); if (*invert) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "Multiple `!' flags not allowed"); *invert = true; if (my_optind != NULL) { ++*my_optind; if (argc && *my_optind > argc) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "no argument following `!'"); } @@ -1405,7 +1458,7 @@ xtables_parse_protocol(const char *s) } } if (i == ARRAY_SIZE(xtables_chain_protos)) - exit_error(PARAMETER_PROBLEM, + xt_params->exit_err(PARAMETER_PROBLEM, "unknown protocol `%s' specified", s); } |