diff options
author | Patrick McHardy <kaber@trash.net> | 2011-06-30 13:35:56 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-06-30 13:35:56 +0200 |
commit | 411b390f3ffcd4708a0dfc0f2824a637de511cea (patch) | |
tree | 50645beb44d0a617d17eb15636f149720061e31f | |
parent | 3b7a22b44d74b9b05d5e4b0529ebf72c49dcbff5 (diff) | |
parent | 1c9508e1f3f853f33683eb7118e19b193a6c80b7 (diff) |
Merge branch 'master' of git://dev.medozas.de/iptables
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | extensions/libip6t_HL.c | 6 | ||||
-rw-r--r-- | extensions/libip6t_LOG.c | 10 | ||||
-rw-r--r-- | extensions/libipt_LOG.c | 10 | ||||
-rw-r--r-- | extensions/libxt_NFLOG.man | 2 | ||||
-rw-r--r-- | extensions/libxt_RATEEST.c | 109 | ||||
-rw-r--r-- | extensions/libxt_hashlimit.c | 57 | ||||
-rw-r--r-- | extensions/libxt_rateest.c | 12 | ||||
-rw-r--r-- | extensions/libxt_state.c | 2 | ||||
-rw-r--r-- | include/xtables.h.in | 18 | ||||
-rw-r--r-- | iptables/Makefile.am | 4 | ||||
-rw-r--r-- | iptables/ip6tables-restore.c | 3 | ||||
-rw-r--r-- | iptables/ip6tables.8.in | 3 | ||||
-rw-r--r-- | iptables/ip6tables.c | 9 | ||||
-rwxr-xr-x | iptables/iptables-apply | 25 | ||||
-rw-r--r-- | iptables/iptables-restore.c | 3 | ||||
-rw-r--r-- | iptables/iptables-xml.c | 3 | ||||
-rw-r--r-- | iptables/iptables.8.in | 3 | ||||
-rw-r--r-- | iptables/iptables.c | 10 | ||||
-rw-r--r-- | iptables/xshared.c | 33 | ||||
-rw-r--r-- | iptables/xshared.h | 2 | ||||
-rw-r--r-- | iptables/xtables.c | 20 | ||||
-rw-r--r-- | iptables/xtoptions.c | 4 | ||||
-rw-r--r-- | libipq/libipq.c | 1 | ||||
-rw-r--r-- | libiptc/libiptc.c | 4 | ||||
-rw-r--r-- | tests/options-most.rules | 25 |
26 files changed, 222 insertions, 162 deletions
diff --git a/configure.ac b/configure.ac index e902ab92..6c90caaf 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_INIT([iptables], [1.4.11.1]) # See libtool.info "Libtool's versioning system" -libxtables_vcurrent=6 +libxtables_vcurrent=7 libxtables_vage=0 AC_CONFIG_HEADERS([config.h]) @@ -59,12 +59,10 @@ AC_SUBST([libiptc_LDFLAGS2]) blacklist_modules=""; -AC_CHECK_HEADER([linux/dccp.h]) +AC_CHECK_HEADERS([linux/dccp.h linux/ip_vs.h linux/magic.h linux/proc_fs.h]) if test "$ac_cv_header_linux_dccp_h" != "yes"; then blacklist_modules="$blacklist_modules dccp"; fi; - -AC_CHECK_HEADER([linux/ip_vs.h]) if test "$ac_cv_header_linux_ip_vs_h" != "yes"; then blacklist_modules="$blacklist_modules ipvs"; fi; diff --git a/extensions/libip6t_HL.c b/extensions/libip6t_HL.c index 254b1914..52ca5d3e 100644 --- a/extensions/libip6t_HL.c +++ b/extensions/libip6t_HL.c @@ -20,12 +20,12 @@ enum { #define s struct ip6t_HL_info static const struct xt_option_entry HL_opts[] = { - {.name = "ttl-set", .type = XTTYPE_UINT8, .id = O_HL_SET, + {.name = "hl-set", .type = XTTYPE_UINT8, .id = O_HL_SET, .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)}, - {.name = "ttl-dec", .type = XTTYPE_UINT8, .id = O_HL_DEC, + {.name = "hl-dec", .type = XTTYPE_UINT8, .id = O_HL_DEC, .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit), .min = 1}, - {.name = "ttl-inc", .type = XTTYPE_UINT8, .id = O_HL_INC, + {.name = "hl-inc", .type = XTTYPE_UINT8, .id = O_HL_INC, .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit), .min = 1}, XTOPT_TABLEEND, diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c index a419ec91..2b1ae289 100644 --- a/extensions/libip6t_LOG.c +++ b/extensions/libip6t_LOG.c @@ -87,19 +87,19 @@ static void LOG_parse(struct xt_option_call *cb) "Newlines not allowed in --log-prefix"); break; case O_LOG_TCPSEQ: - info->logflags = IP6T_LOG_TCPSEQ; + info->logflags |= IP6T_LOG_TCPSEQ; break; case O_LOG_TCPOPTS: - info->logflags = IP6T_LOG_TCPOPT; + info->logflags |= IP6T_LOG_TCPOPT; break; case O_LOG_IPOPTS: - info->logflags = IP6T_LOG_IPOPT; + info->logflags |= IP6T_LOG_IPOPT; break; case O_LOG_UID: - info->logflags = IP6T_LOG_UID; + info->logflags |= IP6T_LOG_UID; break; case O_LOG_MAC: - info->logflags = IP6T_LOG_MACDECODE; + info->logflags |= IP6T_LOG_MACDECODE; break; } } diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c index b270bcf6..77f16d19 100644 --- a/extensions/libipt_LOG.c +++ b/extensions/libipt_LOG.c @@ -87,19 +87,19 @@ static void LOG_parse(struct xt_option_call *cb) "Newlines not allowed in --log-prefix"); break; case O_LOG_TCPSEQ: - info->logflags = IPT_LOG_TCPSEQ; + info->logflags |= IPT_LOG_TCPSEQ; break; case O_LOG_TCPOPTS: - info->logflags = IPT_LOG_TCPOPT; + info->logflags |= IPT_LOG_TCPOPT; break; case O_LOG_IPOPTS: - info->logflags = IPT_LOG_IPOPT; + info->logflags |= IPT_LOG_IPOPT; break; case O_LOG_UID: - info->logflags = IPT_LOG_UID; + info->logflags |= IPT_LOG_UID; break; case O_LOG_MAC: - info->logflags = IPT_LOG_MACDECODE; + info->logflags |= IPT_LOG_MACDECODE; break; } } diff --git a/extensions/libxt_NFLOG.man b/extensions/libxt_NFLOG.man index 66f0b973..1b6dbf16 100644 --- a/extensions/libxt_NFLOG.man +++ b/extensions/libxt_NFLOG.man @@ -9,7 +9,7 @@ may subscribe to the group to receive the packets. Like LOG, this is a non-terminating target, i.e. rule traversal continues at the next rule. .TP \fB\-\-nflog\-group\fP \fInlgroup\fP -The netlink group (1 \- 2^32\-1) to which packets are (only applicable for +The netlink group (0 - 2^16\-1) to which packets are (only applicable for nfnetlink_log). The default value is 0. .TP \fB\-\-nflog\-prefix\fP \fIprefix\fP diff --git a/extensions/libxt_RATEEST.c b/extensions/libxt_RATEEST.c index 6369e9e4..acdefb90 100644 --- a/extensions/libxt_RATEEST.c +++ b/extensions/libxt_RATEEST.c @@ -1,19 +1,16 @@ -#include <stdbool.h> #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <stddef.h> -#include <getopt.h> #include <math.h> #include <xtables.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_RATEEST.h> -/* hack to pass raw values to final_check */ -static struct xt_rateest_target_info *RATEEST_info; -static unsigned int interval; -static unsigned int ewma_log; +struct rateest_tg_udata { + unsigned int interval; + unsigned int ewma_log; +}; static void RATEEST_help(void) @@ -25,18 +22,23 @@ RATEEST_help(void) " --rateest-ewmalog value Rate measurement averaging time constant\n"); } -enum RATEEST_options { - RATEEST_OPT_NAME, - RATEEST_OPT_INTERVAL, - RATEEST_OPT_EWMALOG, +enum { + O_NAME = 0, + O_INTERVAL, + O_EWMALOG, }; -static const struct option RATEEST_opts[] = { - {.name = "rateest-name", .has_arg = true, .val = RATEEST_OPT_NAME}, - {.name = "rateest-interval", .has_arg = true, .val = RATEEST_OPT_INTERVAL}, - {.name = "rateest-ewmalog", .has_arg = true, .val = RATEEST_OPT_EWMALOG}, - XT_GETOPT_TABLEEND, +#define s struct xt_rateest_target_info +static const struct xt_option_entry RATEEST_opts[] = { + {.name = "rateest-name", .id = O_NAME, .type = XTTYPE_STRING, + .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, name)}, + {.name = "rateest-interval", .id = O_INTERVAL, .type = XTTYPE_STRING, + .flags = XTOPT_MAND}, + {.name = "rateest-ewmalog", .id = O_EWMALOG, .type = XTTYPE_STRING, + .flags = XTOPT_MAND}, + XTOPT_TABLEEND, }; +#undef s /* Copied from iproute */ #define TIME_UNITS_PER_SEC 1000000 @@ -82,66 +84,34 @@ RATEEST_print_time(unsigned int time) printf(" %uus", time); } -static int -RATEEST_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void RATEEST_parse(struct xt_option_call *cb) { - struct xt_rateest_target_info *info = (void *)(*target)->data; - - RATEEST_info = info; + struct rateest_tg_udata *udata = cb->udata; - switch (c) { - case RATEEST_OPT_NAME: - if (*flags & (1 << c)) + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_INTERVAL: + if (RATEEST_get_time(&udata->interval, cb->arg) < 0) xtables_error(PARAMETER_PROBLEM, - "RATEEST: can't specify --rateest-name twice"); - *flags |= 1 << c; - - strncpy(info->name, optarg, sizeof(info->name) - 1); + "RATEEST: bad interval value \"%s\"", + cb->arg); break; - - case RATEEST_OPT_INTERVAL: - if (*flags & (1 << c)) + case O_EWMALOG: + if (RATEEST_get_time(&udata->ewma_log, cb->arg) < 0) xtables_error(PARAMETER_PROBLEM, - "RATEEST: can't specify --rateest-interval twice"); - *flags |= 1 << c; - - if (RATEEST_get_time(&interval, optarg) < 0) - xtables_error(PARAMETER_PROBLEM, - "RATEEST: bad interval value `%s'", optarg); - - break; - - case RATEEST_OPT_EWMALOG: - if (*flags & (1 << c)) - xtables_error(PARAMETER_PROBLEM, - "RATEEST: can't specify --rateest-ewmalog twice"); - *flags |= 1 << c; - - if (RATEEST_get_time(&ewma_log, optarg) < 0) - xtables_error(PARAMETER_PROBLEM, - "RATEEST: bad ewmalog value `%s'", optarg); - + "RATEEST: bad ewmalog value \"%s\"", + cb->arg); break; } - - return 1; } -static void -RATEEST_final_check(unsigned int flags) +static void RATEEST_final_check(struct xt_fcheck_call *cb) { - struct xt_rateest_target_info *info = RATEEST_info; - - if (!(flags & (1 << RATEEST_OPT_NAME))) - xtables_error(PARAMETER_PROBLEM, "RATEEST: no name specified"); - if (!(flags & (1 << RATEEST_OPT_INTERVAL))) - xtables_error(PARAMETER_PROBLEM, "RATEEST: no interval specified"); - if (!(flags & (1 << RATEEST_OPT_EWMALOG))) - xtables_error(PARAMETER_PROBLEM, "RATEEST: no ewmalog specified"); + struct xt_rateest_target_info *info = cb->data; + struct rateest_tg_udata *udata = cb->udata; for (info->interval = 0; info->interval <= 5; info->interval++) { - if (interval <= (1 << info->interval) * (TIME_UNITS_PER_SEC / 4)) + if (udata->interval <= (1 << info->interval) * (TIME_UNITS_PER_SEC / 4)) break; } @@ -152,7 +122,7 @@ RATEEST_final_check(unsigned int flags) for (info->ewma_log = 1; info->ewma_log < 32; info->ewma_log++) { double w = 1.0 - 1.0 / (1 << info->ewma_log); - if (interval / (-log(w)) > ewma_log) + if (udata->interval / (-log(w)) > udata->ewma_log) break; } info->ewma_log--; @@ -197,13 +167,14 @@ static struct xtables_target rateest_tg_reg = { .name = "RATEEST", .version = XTABLES_VERSION, .size = XT_ALIGN(sizeof(struct xt_rateest_target_info)), - .userspacesize = XT_ALIGN(sizeof(struct xt_rateest_target_info)), + .userspacesize = offsetof(struct xt_rateest_target_info, est), .help = RATEEST_help, - .parse = RATEEST_parse, - .final_check = RATEEST_final_check, + .x6_parse = RATEEST_parse, + .x6_fcheck = RATEEST_final_check, .print = RATEEST_print, .save = RATEEST_save, - .extra_opts = RATEEST_opts, + .x6_options = RATEEST_opts, + .udata_size = sizeof(struct rateest_tg_udata), }; void _init(void) diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c index e683f9ad..a838680c 100644 --- a/extensions/libxt_hashlimit.c +++ b/extensions/libxt_hashlimit.c @@ -25,6 +25,10 @@ #define XT_HASHLIMIT_GCINTERVAL 1000 #define XT_HASHLIMIT_EXPIRE 10000 +struct hashlimit_mt_udata { + uint32_t mult; +}; + static void hashlimit_help(void) { printf( @@ -56,8 +60,9 @@ enum { O_HTABLE_MAX, O_HTABLE_GCINT, O_HTABLE_EXPIRE, - F_UPTO = 1 << O_UPTO, - F_ABOVE = 1 << O_ABOVE, + F_UPTO = 1 << O_UPTO, + F_ABOVE = 1 << O_ABOVE, + F_HTABLE_EXPIRE = 1 << O_HTABLE_EXPIRE, }; static void hashlimit_mt_help(void) @@ -141,25 +146,25 @@ static const struct xt_option_entry hashlimit_mt_opts[] = { #undef s static -int parse_rate(const char *rate, uint32_t *val) +int parse_rate(const char *rate, uint32_t *val, struct hashlimit_mt_udata *ud) { const char *delim; uint32_t r; - uint32_t mult = 1; /* Seconds by default. */ + ud->mult = 1; /* Seconds by default. */ delim = strchr(rate, '/'); if (delim) { if (strlen(delim+1) == 0) return 0; if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0) - mult = 1; + ud->mult = 1; else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0) - mult = 60; + ud->mult = 60; else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0) - mult = 60*60; + ud->mult = 60*60; else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0) - mult = 24*60*60; + ud->mult = 24*60*60; else return 0; } @@ -169,10 +174,10 @@ int parse_rate(const char *rate, uint32_t *val) /* This would get mapped to infinite (1/day is minimum they can specify, so we're ok at that end). */ - if (r / mult > XT_HASHLIMIT_SCALE) + if (r / ud->mult > XT_HASHLIMIT_SCALE) xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate); - *val = XT_HASHLIMIT_SCALE * mult / r; + *val = XT_HASHLIMIT_SCALE * ud->mult / r; return 1; } @@ -248,14 +253,14 @@ static void hashlimit_parse(struct xt_option_call *cb) case O_UPTO: if (cb->invert) info->cfg.mode |= XT_HASHLIMIT_INVERT; - if (!parse_rate(cb->arg, &info->cfg.avg)) + if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata)) xtables_param_act(XTF_BAD_VALUE, "hashlimit", "--hashlimit-upto", cb->arg); break; case O_ABOVE: if (!cb->invert) info->cfg.mode |= XT_HASHLIMIT_INVERT; - if (!parse_rate(cb->arg, &info->cfg.avg)) + if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata)) xtables_param_act(XTF_BAD_VALUE, "hashlimit", "--hashlimit-above", cb->arg); break; @@ -276,14 +281,14 @@ static void hashlimit_mt_parse(struct xt_option_call *cb) case O_UPTO: if (cb->invert) info->cfg.mode |= XT_HASHLIMIT_INVERT; - if (!parse_rate(cb->arg, &info->cfg.avg)) + if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata)) xtables_param_act(XTF_BAD_VALUE, "hashlimit", "--hashlimit-upto", cb->arg); break; case O_ABOVE: if (!cb->invert) info->cfg.mode |= XT_HASHLIMIT_INVERT; - if (!parse_rate(cb->arg, &info->cfg.avg)) + if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata)) xtables_param_act(XTF_BAD_VALUE, "hashlimit", "--hashlimit-above", cb->arg); break; @@ -303,9 +308,26 @@ static void hashlimit_mt_parse(struct xt_option_call *cb) static void hashlimit_check(struct xt_fcheck_call *cb) { + const struct hashlimit_mt_udata *udata = cb->udata; + struct xt_hashlimit_info *info = cb->data; + if (!(cb->xflags & (F_UPTO | F_ABOVE))) xtables_error(PARAMETER_PROBLEM, "You have to specify --hashlimit"); + if (!(cb->xflags & F_HTABLE_EXPIRE)) + info->cfg.expire = udata->mult; +} + +static void hashlimit_mt_check(struct xt_fcheck_call *cb) +{ + const struct hashlimit_mt_udata *udata = cb->udata; + struct xt_hashlimit_mtinfo1 *info = cb->data; + + if (!(cb->xflags & (F_UPTO | F_ABOVE))) + xtables_error(PARAMETER_PROBLEM, + "You have to specify --hashlimit"); + if (!(cb->xflags & F_HTABLE_EXPIRE)) + info->cfg.expire = udata->mult; } static const struct rates @@ -508,6 +530,7 @@ static struct xtables_match hashlimit_mt_reg[] = { .print = hashlimit_print, .save = hashlimit_save, .x6_options = hashlimit_mt_opts, + .udata_size = sizeof(struct hashlimit_mt_udata), }, { .version = XTABLES_VERSION, @@ -519,10 +542,11 @@ static struct xtables_match hashlimit_mt_reg[] = { .help = hashlimit_mt_help, .init = hashlimit_mt4_init, .x6_parse = hashlimit_mt_parse, - .x6_fcheck = hashlimit_check, + .x6_fcheck = hashlimit_mt_check, .print = hashlimit_mt4_print, .save = hashlimit_mt4_save, .x6_options = hashlimit_mt_opts, + .udata_size = sizeof(struct hashlimit_mt_udata), }, { .version = XTABLES_VERSION, @@ -534,10 +558,11 @@ static struct xtables_match hashlimit_mt_reg[] = { .help = hashlimit_mt_help, .init = hashlimit_mt6_init, .x6_parse = hashlimit_mt_parse, - .x6_fcheck = hashlimit_check, + .x6_fcheck = hashlimit_mt_check, .print = hashlimit_mt6_print, .save = hashlimit_mt6_save, .x6_options = hashlimit_mt_opts, + .udata_size = sizeof(struct hashlimit_mt_udata), }, }; diff --git a/extensions/libxt_rateest.c b/extensions/libxt_rateest.c index 509b3e31..5f42a137 100644 --- a/extensions/libxt_rateest.c +++ b/extensions/libxt_rateest.c @@ -8,9 +8,6 @@ #include <xtables.h> #include <linux/netfilter/xt_rateest.h> -/* Ugly hack to pass info to final_check function. We should fix the API */ -static struct xt_rateest_match_info *rateest_info; - static void rateest_help(void) { printf( @@ -115,8 +112,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, struct xt_rateest_match_info *info = (void *)(*match)->data; unsigned int val; - rateest_info = info; - switch (c) { case OPT_RATEEST1: xtables_check_inverse(optarg, &invert, &optind, 0, argv); @@ -302,10 +297,9 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, return 1; } -static void -rateest_final_check(unsigned int flags) +static void rateest_final_check(struct xt_fcheck_call *cb) { - struct xt_rateest_match_info *info = rateest_info; + struct xt_rateest_match_info *info = cb->data; if (info == NULL) xtables_error(PARAMETER_PROBLEM, "rateest match: " @@ -439,7 +433,7 @@ static struct xtables_match rateest_mt_reg = { .userspacesize = XT_ALIGN(offsetof(struct xt_rateest_match_info, est1)), .help = rateest_help, .parse = rateest_parse, - .final_check = rateest_final_check, + .x6_fcheck = rateest_final_check, .print = rateest_print, .save = rateest_save, .extra_opts = rateest_opts, diff --git a/extensions/libxt_state.c b/extensions/libxt_state.c index 3fc747d8..eff444c8 100644 --- a/extensions/libxt_state.c +++ b/extensions/libxt_state.c @@ -23,7 +23,7 @@ state_help(void) static const struct xt_option_entry state_opts[] = { {.name = "state", .id = O_STATE, .type = XTTYPE_STRING, - .flags = XTOPT_MAND}, + .flags = XTOPT_MAND | XTOPT_INVERT}, XTOPT_TABLEEND, }; diff --git a/include/xtables.h.in b/include/xtables.h.in index 2565dd23..0dead268 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -137,11 +137,13 @@ struct xt_option_entry { * @arg: input from command line * @ext_name: name of extension currently being processed * @entry: current option being processed - * @data: per-extension data block + * @data: per-extension kernel data block * @xflags: options of the extension that have been used * @invert: whether option was used with ! * @nvals: number of results in uXX_multi * @val: parsed result + * @udata: per-extension private scratch area + * (cf. xtables_{match,target}->udata_size) */ struct xt_option_call { const char *arg, *ext_name; @@ -174,16 +176,19 @@ struct xt_option_call { struct xt_entry_target **target; }; void *xt_entry; + void *udata; }; /** * @ext_name: name of extension currently being processed - * @data: per-extension data block + * @data: per-extension (kernel) data block + * @udata: per-extension private scratch area + * (cf. xtables_{match,target}->udata_size) * @xflags: options of the extension that have been used */ struct xt_fcheck_call { const char *ext_name; - void *data; + void *data, *udata; unsigned int xflags; }; @@ -254,7 +259,11 @@ struct xtables_match void (*x6_fcheck)(struct xt_fcheck_call *); const struct xt_option_entry *x6_options; + /* Size of per-extension instance extra "global" scratch space */ + size_t udata_size; + /* Ignore these men behind the curtain: */ + void *udata; unsigned int option_offset; struct xt_entry_match *m; unsigned int mflags; @@ -318,7 +327,10 @@ struct xtables_target void (*x6_fcheck)(struct xt_fcheck_call *); const struct xt_option_entry *x6_options; + size_t udata_size; + /* Ignore these men behind the curtain: */ + void *udata; unsigned int option_offset; struct xt_entry_target *t; unsigned int tflags; diff --git a/iptables/Makefile.am b/iptables/Makefile.am index 13cca9c6..a0682788 100644 --- a/iptables/Makefile.am +++ b/iptables/Makefile.am @@ -51,10 +51,10 @@ v6_sbin_links = ip6tables ip6tables-restore ip6tables-save endif iptables.8: ${srcdir}/iptables.8.in ../extensions/matches4.man ../extensions/targets4.man - ${AM_VERBOSE_GEN} sed -e 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' -e '/@MATCH@/ r extensions/matches4.man' -e '/@TARGET@/ r extensions/targets4.man' $< >$@; + ${AM_VERBOSE_GEN} sed -e 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' -e '/@MATCH@/ r ../extensions/matches4.man' -e '/@TARGET@/ r ../extensions/targets4.man' $< >$@; ip6tables.8: ${srcdir}/ip6tables.8.in ../extensions/matches6.man ../extensions/targets6.man - ${AM_VERBOSE_GEN} sed -e 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' -e '/@MATCH@/ r extensions/matches6.man' -e '/@TARGET@/ r extensions/targets6.man' $< >$@; + ${AM_VERBOSE_GEN} sed -e 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' -e '/@MATCH@/ r ../extensions/matches6.man' -e '/@TARGET@/ r ../extensions/targets6.man' $< >$@; pkgconfig_DATA = xtables.pc diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c index 420bc523..ae147d55 100644 --- a/iptables/ip6tables-restore.c +++ b/iptables/ip6tables-restore.c @@ -460,7 +460,6 @@ int main(int argc, char *argv[]) exit(1); } - if (in != NULL) - fclose(in); + fclose(in); return 0; } diff --git a/iptables/ip6tables.8.in b/iptables/ip6tables.8.in index 48ba18e1..20e271de 100644 --- a/iptables/ip6tables.8.in +++ b/iptables/ip6tables.8.in @@ -333,7 +333,8 @@ byte counters are also listed, with the suffix 'K', 'M' or 'G' for 1000, 1,000,000 and 1,000,000,000 multipliers respectively (but see the \fB\-x\fP flag to change this). For appending, insertion, deletion and replacement, this causes -detailed information on the rule or rules to be printed. +detailed information on the rule or rules to be printed. \fB\-v\fP may be +specified multiple times to possibly emit more detailed debug statements. .TP \fB\-n\fP, \fB\-\-numeric\fP Numeric output. diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c index 4037acfb..d13744ca 100644 --- a/iptables/ip6tables.c +++ b/iptables/ip6tables.c @@ -1288,8 +1288,7 @@ static void command_jump(struct iptables_command_state *cs) cs->target->t->u.target_size = size; strcpy(cs->target->t->u.user.name, cs->jumpto); cs->target->t->u.user.revision = cs->target->revision; - if (cs->target->init != NULL) - cs->target->init(cs->target->t); + xs_init_target(cs->target); if (cs->target->x6_options != NULL) opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts, cs->target->x6_options, @@ -1317,8 +1316,7 @@ static void command_match(struct iptables_command_state *cs) m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); m->m->u.user.revision = m->revision; - if (m->init != NULL) - m->init(m->m); + xs_init_match(m); if (m == m->next) return; /* Merge options for non-cloned matches */ @@ -1839,8 +1837,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand cs.target->t = xtables_calloc(1, size); cs.target->t->u.target_size = size; strcpy(cs.target->t->u.user.name, cs.jumpto); - if (cs.target->init != NULL) - cs.target->init(cs.target->t); + xs_init_target(cs.target); } if (!cs.target) { diff --git a/iptables/iptables-apply b/iptables/iptables-apply index 5fec76b0..86b8d5a2 100755 --- a/iptables/iptables-apply +++ b/iptables/iptables-apply @@ -11,7 +11,6 @@ PROGNAME="${0##*/}"; VERSION=1.0 TIMEOUT=10 -DEFAULT_FILE=/etc/network/iptables function blurb() { @@ -87,6 +86,19 @@ for opt in $OPTS; do shift done +case "$PROGNAME" in + (*6*) + SAVE=ip6tables-save + RESTORE=ip6tables-restore + DEFAULT_FILE=/etc/network/ip6tables + ;; + (*) + SAVE=iptables-save + RESTORE=iptables-restore + DEFAULT_FILE=/etc/network/iptables + ;; +esac + FILE="${1:-$DEFAULT_FILE}"; if [[ -z "$FILE" ]]; then @@ -99,17 +111,6 @@ if [[ ! -r "$FILE" ]]; then exit 2 fi -case "${0##*/}" in - (*6*) - SAVE=ip6tables-save - RESTORE=ip6tables-restore - ;; - (*) - SAVE=iptables-save - RESTORE=iptables-restore - ;; -esac - COMMANDS=(tempfile "$SAVE" "$RESTORE") for cmd in "${COMMANDS[@]}"; do diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c index 26245997..1cb833c0 100644 --- a/iptables/iptables-restore.c +++ b/iptables/iptables-restore.c @@ -465,7 +465,6 @@ main(int argc, char *argv[]) exit(1); } - if (in != NULL) - fclose(in); + fclose(in); return 0; } diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c index 5aa638c0..502b2d96 100644 --- a/iptables/iptables-xml.c +++ b/iptables/iptables-xml.c @@ -865,8 +865,7 @@ main(int argc, char *argv[]) exit(1); } - if (in != NULL) - fclose(in); + fclose(in); printf("</iptables-rules>\n"); free_argv(); diff --git a/iptables/iptables.8.in b/iptables/iptables.8.in index d09bf7aa..3b717a11 100644 --- a/iptables/iptables.8.in +++ b/iptables/iptables.8.in @@ -332,7 +332,8 @@ byte counters are also listed, with the suffix 'K', 'M' or 'G' for 1000, 1,000,000 and 1,000,000,000 multipliers respectively (but see the \fB\-x\fP flag to change this). For appending, insertion, deletion and replacement, this causes -detailed information on the rule or rules to be printed. +detailed information on the rule or rules to be printed. \fB\-v\fP may be +specified multiple times to possibly emit more detailed debug statements. .TP \fB\-n\fP, \fB\-\-numeric\fP Numeric output. diff --git a/iptables/iptables.c b/iptables/iptables.c index 4ae75419..477e8f1d 100644 --- a/iptables/iptables.c +++ b/iptables/iptables.c @@ -1315,8 +1315,8 @@ static void command_jump(struct iptables_command_state *cs) cs->target->t->u.target_size = size; strcpy(cs->target->t->u.user.name, cs->jumpto); cs->target->t->u.user.revision = cs->target->revision; - if (cs->target->init != NULL) - cs->target->init(cs->target->t); + xs_init_target(cs->target); + if (cs->target->x6_options != NULL) opts = xtables_options_xfrm(iptables_globals.orig_opts, opts, cs->target->x6_options, @@ -1344,8 +1344,7 @@ static void command_match(struct iptables_command_state *cs) m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); m->m->u.user.revision = m->revision; - if (m->init != NULL) - m->init(m->m); + xs_init_match(m); if (m == m->next) return; /* Merge options for non-cloned matches */ @@ -1871,8 +1870,7 @@ int do_command4(int argc, char *argv[], char **table, struct iptc_handle **handl strcpy(cs.target->t->u.user.name, cs.jumpto); if (!iptc_is_chain(cs.jumpto, *handle)) cs.target->t->u.user.revision = cs.target->revision; - if (cs.target->init != NULL) - cs.target->init(cs.target->t); + xs_init_target(cs.target); } if (!cs.target) { diff --git a/iptables/xshared.c b/iptables/xshared.c index 0e3857bb..79da507d 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -145,8 +145,7 @@ int command_default(struct iptables_command_state *cs, m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); m->m->u.user.revision = m->revision; - if (m->init != NULL) - m->init(m->m); + xs_init_match(m); if (m->x6_options != NULL) gl->opts = xtables_options_xfrm(gl->orig_opts, @@ -207,3 +206,33 @@ int subcmd_main(int argc, char **argv, const struct subcommand *cb) fprintf(stderr, " * %s\n", cb->name); exit(EXIT_FAILURE); } + +void xs_init_target(struct xtables_target *target) +{ + if (target->udata_size != 0) { + free(target->udata); + target->udata = calloc(1, target->udata_size); + if (target->udata == NULL) + xtables_error(RESOURCE_PROBLEM, "malloc"); + } + if (target->init != NULL) + target->init(target->t); +} + +void xs_init_match(struct xtables_match *match) +{ + if (match->udata_size != 0) { + /* + * As soon as a subsequent instance of the same match + * is used, e.g. "-m time -m time", the first instance + * is no longer reachable anyway, so we can free udata. + * Same goes for target. + */ + free(match->udata); + match->udata = calloc(1, match->udata_size); + if (match->udata == NULL) + xtables_error(RESOURCE_PROBLEM, "malloc"); + } + if (match->init != NULL) + match->init(match->m); +} diff --git a/iptables/xshared.h b/iptables/xshared.h index b44a3a35..b804aafe 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -81,6 +81,8 @@ extern int command_default(struct iptables_command_state *, struct xtables_globals *); extern struct xtables_match *load_proto(struct iptables_command_state *); extern int subcmd_main(int, char **, const struct subcommand *); +extern void xs_init_target(struct xtables_target *); +extern void xs_init_match(struct xtables_match *); extern const struct xtables_afinfo *afinfo; diff --git a/iptables/xtables.c b/iptables/xtables.c index acfcf8bd..c4b1c2a8 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -15,6 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "config.h" #include <ctype.h> #include <errno.h> #include <fcntl.h> @@ -32,7 +33,11 @@ #include <sys/types.h> #include <sys/wait.h> #include <arpa/inet.h> -#include <linux/magic.h> /* for PROC_SUPER_MAGIC */ +#if defined(HAVE_LINUX_MAGIC_H) +# include <linux/magic.h> /* for PROC_SUPER_MAGIC */ +#elif defined(HAVE_LINUX_PROC_FS_H) +# include <linux/proc_fs.h> /* Linux 2.4 */ +#endif #include <xtables.h> #include <limits.h> /* INT_MAX in ip_tables.h/ip6_tables.h */ @@ -362,6 +367,7 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet) /* not usually reached */ exit(1); case -1: + free(buf); return -1; default: /* parent */ @@ -1042,8 +1048,10 @@ void xtables_param_act(unsigned int status, const char *p1, ...) case XTF_ONLY_ONCE: p2 = va_arg(args, const char *); b = va_arg(args, unsigned int); - if (!b) + if (!b) { + va_end(args); return; + } xt_params->exit_err(PARAMETER_PROBLEM, "%s: \"%s\" option may only be specified once", p1, p2); @@ -1051,8 +1059,10 @@ void xtables_param_act(unsigned int status, const char *p1, ...) case XTF_NO_INVERT: p2 = va_arg(args, const char *); b = va_arg(args, unsigned int); - if (!b) + if (!b) { + va_end(args); return; + } xt_params->exit_err(PARAMETER_PROBLEM, "%s: \"%s\" option cannot be inverted", p1, p2); break; @@ -1065,8 +1075,10 @@ void xtables_param_act(unsigned int status, const char *p1, ...) break; case XTF_ONE_ACTION: b = va_arg(args, unsigned int); - if (!b) + if (!b) { + va_end(args); return; + } xt_params->exit_err(PARAMETER_PROBLEM, "%s: At most one action is possible", p1); break; diff --git a/iptables/xtoptions.c b/iptables/xtoptions.c index ac0601f2..1423724b 100644 --- a/iptables/xtoptions.c +++ b/iptables/xtoptions.c @@ -908,6 +908,7 @@ void xtables_option_tpcall(unsigned int c, char **argv, bool invert, cb.xflags = t->tflags; cb.target = &t->t; cb.xt_entry = fw; + cb.udata = t->udata; t->x6_parse(&cb); t->tflags = cb.xflags; } @@ -943,6 +944,7 @@ void xtables_option_mpcall(unsigned int c, char **argv, bool invert, cb.xflags = m->mflags; cb.match = &m->m; cb.xt_entry = fw; + cb.udata = m->udata; m->x6_parse(&cb); m->mflags = cb.xflags; } @@ -1028,6 +1030,7 @@ void xtables_option_tfcall(struct xtables_target *t) cb.ext_name = t->name; cb.data = t->t->data; cb.xflags = t->tflags; + cb.udata = t->udata; t->x6_fcheck(&cb); } else if (t->final_check != NULL) { t->final_check(t->tflags); @@ -1048,6 +1051,7 @@ void xtables_option_mfcall(struct xtables_match *m) cb.ext_name = m->name; cb.data = m->m->data; cb.xflags = m->mflags; + cb.udata = m->udata; m->x6_fcheck(&cb); } else if (m->final_check != NULL) { m->final_check(m->mflags); diff --git a/libipq/libipq.c b/libipq/libipq.c index e3304875..fb65971a 100644 --- a/libipq/libipq.c +++ b/libipq/libipq.c @@ -231,7 +231,6 @@ struct ipq_handle *ipq_create_handle(uint32_t flags, uint32_t protocol) if (h->fd == -1) { ipq_errno = IPQ_ERR_SOCKET; - close(h->fd); free(h); return NULL; } diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c index 0b6d5e3a..42d9784a 100644 --- a/libiptc/libiptc.c +++ b/libiptc/libiptc.c @@ -403,7 +403,7 @@ __iptcc_bsearch_chain_index(const char *name, unsigned int offset, } debug("jump back to pos:%d (end:%d)\n", pos, end); goto loop; - } else if (res > 0 ){ /* Not far enough, jump forward */ + } else { /* res > 0; Not far enough, jump forward */ /* Exit case: Last element of array */ if (pos == handle->chain_index_sz-1) { @@ -430,8 +430,6 @@ __iptcc_bsearch_chain_index(const char *name, unsigned int offset, debug("jump forward to pos:%d (end:%d)\n", pos, end); goto loop; } - - return list_pos; } /* Wrapper for string chain name based bsearch */ diff --git a/tests/options-most.rules b/tests/options-most.rules index 6c4a8313..7298a1f9 100644 --- a/tests/options-most.rules +++ b/tests/options-most.rules @@ -1,4 +1,3 @@ -# Generated by ip6tables-save v1.4.10 on Mon Jan 31 02:19:53 2011 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] @@ -76,6 +75,8 @@ -A matches -A matches -m conntrack --ctexpire 5:4294967295 -A matches +-A matches -m conntrack ! --ctstate NEW ! --ctproto tcp ! --ctorigsrc ::1/127 ! --ctorigdst ::2/127 ! --ctreplsrc ::2/127 ! --ctrepldst ::2/127 ! --ctorigsrcport 3 ! --ctorigdstport 4 ! --ctreplsrcport 5 ! --ctrepldstport 6 ! --ctstatus ASSURED ! --ctexpire 8:9 +-A matches -A matches -p esp -m esp --espspi 1 -A matches -A matches -p esp -m esp --espspi :2 @@ -86,6 +87,11 @@ -A matches -A matches -p esp -m esp --espspi 5:4294967295 -A matches +-A matches -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-name mini1 +-A matches -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 1 --hashlimit-name mini2 +-A matches -m hashlimit --hashlimit-upto 1/hour --hashlimit-burst 1 --hashlimit-name mini3 +-A matches -m hashlimit --hashlimit-upto 1/day --hashlimit-burst 1 --hashlimit-name mini4 +-A matches -A matches -m ipvs --vaddr fe80::/64 --vport 1 --vdir REPLY --vmethod GATE --vportctl 21 -A matches -A matches -m length --length 1 @@ -146,6 +152,8 @@ -A matches -A matches -m rt --rt-segsleft 5:4294967295 -A matches +-A ntarg -j LOG --log-tcp-sequence --log-tcp-options --log-ip-options +-A ntarg -A ntarg -j NFQUEUE --queue-num 1 -A ntarg -A ntarg -j NFQUEUE --queue-balance 8:99 @@ -169,4 +177,17 @@ #-A zmatches -m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-eq --rateest-pps2 9 #-A zmatches -m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-gt --rateest-pps2 9 COMMIT -# Completed on Mon Jan 31 02:19:54 2011 +*mangle +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +:matches - - +:ntarg - - +:zmatches - - +-A INPUT -m u32 --u32 "0x0=0x0&&0x0=0x1" -j ntarg +-A ntarg -j HL --hl-inc 1 +-A ntarg -j HL --hl-dec 1 +-A ntarg +COMMIT |