From c02c92d1fcaa1223caf9a5eef32bedcb78f1e714 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 18 May 2011 22:48:51 +0200 Subject: libxtables: retract _NE types and use a flag instead Signed-off-by: Jan Engelhardt --- extensions/libxt_TPROXY.c | 8 ++++---- include/xtables.h.in | 12 ++++++------ xtoptions.c | 13 +++++-------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/extensions/libxt_TPROXY.c b/extensions/libxt_TPROXY.c index 61646c93..d13ec85f 100644 --- a/extensions/libxt_TPROXY.c +++ b/extensions/libxt_TPROXY.c @@ -20,8 +20,8 @@ enum { #define s struct xt_tproxy_target_info static const struct xt_option_entry tproxy_tg0_opts[] = { - {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT_NE, - .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, lport)}, + {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT, + .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)}, {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST}, {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32}, XTOPT_TABLEEND, @@ -29,8 +29,8 @@ static const struct xt_option_entry tproxy_tg0_opts[] = { #undef s #define s struct xt_tproxy_target_info_v1 static const struct xt_option_entry tproxy_tg1_opts[] = { - {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT_NE, - .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, lport)}, + {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT, + .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)}, {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST, .flags = XTOPT_PUT, XTOPT_POINTER(s, laddr)}, {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32}, diff --git a/include/xtables.h.in b/include/xtables.h.in index 38c0e5ee..f88813f5 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -64,10 +64,9 @@ struct in_addr; * %XTTYPE_HOSTMASK: one host or address, with an optional prefix length * (ptr: union nf_inet_addr; only host portion is stored) * %XTTYPE_PROTOCOL: protocol number/name from /etc/protocols (ptr: uint8_t) - * %XTTYPE_PORT: 16-bit port name or number - * %XTTYPE_PORT_NE: 16-bit port name or number, stored as network-endian - * %XTTYPE_PORTRC: colon-separated port range (names acceptable) - * %XTTYPE_PORTRC_NE: same as %XTTYPE_PORTRC, stored in network-endian + * %XTTYPE_PORT: 16-bit port name or number (supports %XTOPT_NBO) + * %XTTYPE_PORTRC: colon-separated port range (names acceptable), + * (supports %XTOPT_NBO) * %XTTYPE_PLEN: prefix length * %XTTYPE_PLENMASK: prefix length (ptr: union nf_inet_addr) * %XTTYPE_ETHERMAC: Ethernet MAC address in hex form @@ -91,9 +90,7 @@ enum xt_option_type { XTTYPE_HOSTMASK, XTTYPE_PROTOCOL, XTTYPE_PORT, - XTTYPE_PORT_NE, XTTYPE_PORTRC, - XTTYPE_PORTRC_NE, XTTYPE_PLEN, XTTYPE_PLENMASK, XTTYPE_ETHERMAC, @@ -104,12 +101,15 @@ enum xt_option_type { * %XTOPT_MAND: option is mandatory * %XTOPT_MULTI: option may be specified multiple times * %XTOPT_PUT: store value into memory at @ptroff + * %XTOPT_NBO: store value in network-byte order + * (only certain XTTYPEs recognize this) */ enum xt_option_flags { XTOPT_INVERT = 1 << 0, XTOPT_MAND = 1 << 1, XTOPT_MULTI = 1 << 2, XTOPT_PUT = 1 << 3, + XTOPT_NBO = 1 << 4, }; /** diff --git a/xtoptions.c b/xtoptions.c index eb9e4e6b..3c3ce5f1 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -509,6 +509,7 @@ static void xtopt_parse_protocol(struct xt_option_call *cb) */ static void xtopt_parse_port(struct xt_option_call *cb) { + const struct xt_option_entry *entry = cb->entry; int ret; ret = xtables_getportbyname(cb->arg); @@ -516,10 +517,10 @@ static void xtopt_parse_port(struct xt_option_call *cb) xt_params->exit_err(PARAMETER_PROBLEM, "Port \"%s\" does not resolve to anything.\n", cb->arg); + if (entry->flags & XTOPT_NBO) + ret = htons(ret); cb->val.port = ret; - if (cb->entry->type == XTTYPE_PORT_NE) - cb->val.port = htons(cb->val.port); - if (cb->entry->flags & XTOPT_PUT) + if (entry->flags & XTOPT_PUT) *(uint16_t *)XTOPT_MKPTR(cb) = cb->val.port; } @@ -561,7 +562,7 @@ static void xtopt_parse_mport(struct xt_option_call *cb) xt_params->exit_err(PARAMETER_PROBLEM, "Port \"%s\" does not resolve to " "anything.\n", arg); - if (entry->type == XTTYPE_PORTRC_NE) + if (entry->flags & XTOPT_NBO) value = htons(value); if (cb->nvals < ARRAY_SIZE(cb->val.port_range)) cb->val.port_range[cb->nvals] = value; @@ -702,9 +703,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = { [XTTYPE_HOSTMASK] = xtopt_parse_hostmask, [XTTYPE_PROTOCOL] = xtopt_parse_protocol, [XTTYPE_PORT] = xtopt_parse_port, - [XTTYPE_PORT_NE] = xtopt_parse_port, [XTTYPE_PORTRC] = xtopt_parse_mport, - [XTTYPE_PORTRC_NE] = xtopt_parse_mport, [XTTYPE_PLEN] = xtopt_parse_plen, [XTTYPE_PLENMASK] = xtopt_parse_plenmask, [XTTYPE_ETHERMAC] = xtopt_parse_ethermac, @@ -730,9 +729,7 @@ static const size_t xtopt_psize[] = { [XTTYPE_HOSTMASK] = sizeof(union nf_inet_addr), [XTTYPE_PROTOCOL] = sizeof(uint8_t), [XTTYPE_PORT] = sizeof(uint16_t), - [XTTYPE_PORT_NE] = sizeof(uint16_t), [XTTYPE_PORTRC] = sizeof(uint16_t[2]), - [XTTYPE_PORTRC_NE] = sizeof(uint16_t[2]), [XTTYPE_PLENMASK] = sizeof(union nf_inet_addr), [XTTYPE_ETHERMAC] = sizeof(uint8_t[6]), }; -- cgit v1.2.3 From ae06c6dc6d68d11ed15d4c6c47b7b7a709d3c9cb Mon Sep 17 00:00:00 2001 From: Lutz Jaenicke Date: Wed, 18 May 2011 15:11:47 +0200 Subject: libipt_REDIRECT: "--to-ports" is not mandatory The REDIRECT target can be called without the --to-ports option being specified. From the manual page: ...without this, the destination port is never altered. Signed-off-by: Lutz Jaenicke Signed-off-by: Jan Engelhardt --- extensions/libipt_REDIRECT.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extensions/libipt_REDIRECT.c b/extensions/libipt_REDIRECT.c index 426a7463..e67360a0 100644 --- a/extensions/libipt_REDIRECT.c +++ b/extensions/libipt_REDIRECT.c @@ -23,8 +23,7 @@ static void REDIRECT_help(void) } static const struct xt_option_entry REDIRECT_opts[] = { - {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING, - .flags = XTOPT_MAND}, + {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, XTOPT_TABLEEND, }; -- cgit v1.2.3 From 67db7615580f5c3490a39310f5adcb4e767ea6a8 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 20 May 2011 16:01:18 +0200 Subject: libxt_quota: readd missing XTOPT_PUT request Signed-off-by: Jan Engelhardt --- extensions/libxt_quota.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c index 988f404f..ff498da7 100644 --- a/extensions/libxt_quota.c +++ b/extensions/libxt_quota.c @@ -13,7 +13,8 @@ enum { static const struct xt_option_entry quota_opts[] = { {.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64, - .flags = XTOPT_MAND | XTOPT_INVERT}, + .flags = XTOPT_MAND | XTOPT_INVERT | XTOPT_PUT, + XTOPT_POINTER(struct xt_quota_info, quota)}, XTOPT_TABLEEND, }; -- cgit v1.2.3 From 2305d5fb42fc059f38fc1bdf53411dbeecdb310b Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Wed, 18 May 2011 20:26:14 -0700 Subject: libxt_quota: make sure uint64 is not truncated The xtables_strtoul() would cram a long long into a long. The parse_int would try to cram a UINT64 into a long. --- include/xtables.h.in | 2 +- xtables.c | 4 ++-- xtoptions.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/xtables.h.in b/include/xtables.h.in index f88813f5..90eb1b2b 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -408,7 +408,7 @@ extern void xtables_register_matches(struct xtables_match *, unsigned int); extern void xtables_register_target(struct xtables_target *me); extern void xtables_register_targets(struct xtables_target *, unsigned int); -extern bool xtables_strtoul(const char *, char **, unsigned long *, +extern bool xtables_strtoul(const char *, char **, unsigned long long *, unsigned long, unsigned long); extern bool xtables_strtoui(const char *, char **, unsigned int *, unsigned int, unsigned int); diff --git a/xtables.c b/xtables.c index f10cdb70..3c9a13f4 100644 --- a/xtables.c +++ b/xtables.c @@ -426,7 +426,7 @@ int xtables_load_ko(const char *modprobe, bool quiet) * Returns true/false whether number was accepted. On failure, *value has * undefined contents. */ -bool xtables_strtoul(const char *s, char **end, unsigned long *value, +bool xtables_strtoul(const char *s, char **end, unsigned long long *value, unsigned long min, unsigned long max) { unsigned long v; @@ -454,7 +454,7 @@ bool xtables_strtoul(const char *s, char **end, unsigned long *value, bool xtables_strtoui(const char *s, char **end, unsigned int *value, unsigned int min, unsigned int max) { - unsigned long v; + unsigned long long v; bool ret; ret = xtables_strtoul(s, end, &v, min, max); diff --git a/xtoptions.c b/xtoptions.c index 3c3ce5f1..ec2269b2 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -105,7 +105,7 @@ static void xtopt_parse_int(struct xt_option_call *cb) { const struct xt_option_entry *entry = cb->entry; unsigned long long lmin = 0, lmax = UINT32_MAX; - unsigned int value; + unsigned long long value; if (entry->type == XTTYPE_UINT8) lmax = UINT8_MAX; @@ -118,7 +118,7 @@ static void xtopt_parse_int(struct xt_option_call *cb) if (cb->entry->max != 0) lmax = cb->entry->max; - if (!xtables_strtoui(cb->arg, NULL, &value, lmin, lmax)) + if (!xtables_strtoul(cb->arg, NULL, &value, lmin, lmax)) xt_params->exit_err(PARAMETER_PROBLEM, "%s: bad value for option \"--%s\", " "or out of range (%llu-%llu).\n", -- cgit v1.2.3 From d61b02fbbbe7f6e643aad8649c8559c175c68c52 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 20 May 2011 16:26:04 +0200 Subject: libxtables: check for negative numbers in xtables_strtou* Signed-off-by: Jan Engelhardt --- xtables.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xtables.c b/xtables.c index 3c9a13f4..e11a77ee 100644 --- a/xtables.c +++ b/xtables.c @@ -15,7 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include #include #include @@ -430,11 +430,16 @@ bool xtables_strtoul(const char *s, char **end, unsigned long long *value, unsigned long min, unsigned long max) { unsigned long v; + const char *p; char *my_end; errno = 0; + /* Since strtoul allows leading minus, we have to check for ourself. */ + for (p = s; isspace(*p); ++p) + ; + if (*p == '-') + return false; v = strtoul(s, &my_end, 0); - if (my_end == s) return false; if (end != NULL) -- cgit v1.2.3 From 463628b03eec6e7456ca5121f9b81af7f4690e08 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 12 May 2011 17:36:25 +0200 Subject: libxt_rateest: streamline case display of units Signed-off-by: Jan Engelhardt --- extensions/libxt_rateest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/libxt_rateest.c b/extensions/libxt_rateest.c index e70edc67..509b3e31 100644 --- a/extensions/libxt_rateest.c +++ b/extensions/libxt_rateest.c @@ -65,11 +65,11 @@ static const struct rate_suffix { { "bit", 1. }, { "Kibit", 1024. }, { "kbit", 1000. }, - { "mibit", 1024.*1024. }, + { "Mibit", 1024.*1024. }, { "mbit", 1000000. }, - { "gibit", 1024.*1024.*1024. }, + { "Gibit", 1024.*1024.*1024. }, { "gbit", 1000000000. }, - { "tibit", 1024.*1024.*1024.*1024. }, + { "Tibit", 1024.*1024.*1024.*1024. }, { "tbit", 1000000000000. }, { "Bps", 8. }, { "KiBps", 8.*1024. }, -- cgit v1.2.3 From 88cfbe258b0d30ef26fae8da5484b08e65292a09 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 21 May 2011 00:59:11 +0200 Subject: doc: add some coded option examples to libxt_hashlimit Signed-off-by: Jan Engelhardt --- extensions/libxt_hashlimit.man | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/extensions/libxt_hashlimit.man b/extensions/libxt_hashlimit.man index e91d0c63..f90577e7 100644 --- a/extensions/libxt_hashlimit.man +++ b/extensions/libxt_hashlimit.man @@ -2,16 +2,7 @@ \fBlimit\fP match) for a group of connections using a \fBsingle\fP iptables rule. Grouping can be done per-hostgroup (source and/or destination address) and/or per-port. It gives you the ability to express "\fIN\fP packets per time -quantum per group": -.TP -matching on source host -"1000 packets per second for every host in 192.168.0.0/16" -.TP -matching on source port -"100 packets per second for every service of 192.168.1.1" -.TP -matching on subnet -"10000 packets per minute for every /28 subnet in 10.0.0.0/8" +quantum per group" (see below for some examples). .PP A hash limit option (\fB\-\-hashlimit\-upto\fP, \fB\-\-hashlimit\-above\fP) and \fB\-\-hashlimit\-name\fP are required. @@ -57,3 +48,18 @@ After how many milliseconds do hash entries expire. .TP \fB\-\-hashlimit\-htable\-gcinterval\fP \fImsec\fP How many milliseconds between garbage collection intervals. +.PP +Examples: +.TP +matching on source host +"1000 packets per second for every host in 192.168.0.0/16" => +\-s 192.168.0.0/16 \-\-hashlimit\-mode srcip \-\-hashlimit\-upto 1000/sec +.TP +matching on source port +"100 packets per second for every service of 192.168.1.1" => +\-s 192.168.1.1 \-\-hashlimit\-mode srcport \-\-hashlimit\-upto 100/sec +.TP +matching on subnet +"10000 packets per minute for every /28 subnet (groups of 8 addresses) +in 10.0.0.0/8" => +\-s 10.0.0.8 \-\-hashlimit\-mask 28 \-\-hashlimit\-upto 10000/min -- cgit v1.2.3 From 25ea60de20fb5f7981a0170eb05c0c9a61525763 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 17 May 2011 15:17:08 +0200 Subject: doc: make usage of libxt_rateest more obvious Signed-off-by: Jan Engelhardt --- extensions/libxt_rateest.man | 71 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/extensions/libxt_rateest.man b/extensions/libxt_rateest.man index 75303c50..42a82f32 100644 --- a/extensions/libxt_rateest.man +++ b/extensions/libxt_rateest.man @@ -1,34 +1,75 @@ The rate estimator can match on estimated rates as collected by the RATEEST target. It supports matching on absolute bps/pps values, comparing two rate estimators and matching on the difference between two rate estimators. +.PP +For a better understanding of the available options, these are all possible +combinations: +.\" * Absolute: +.IP \(bu 4 +\fBrateest\fP \fIoperator\fP \fBrateest-bps\fP +.IP \(bu 4 +\fBrateest\fP \fIoperator\fP \fBrateest-pps\fP +.\" * Absolute + Delta: +.IP \(bu 4 +(\fBrateest\fP minus \fBrateest-bps1\fP) \fIoperator\fP \fBrateest-bps2\fP +.IP \(bu 4 +(\fBrateest\fP minus \fBrateest-pps1\fP) \fIoperator\fP \fBrateest-pps2\fP +.\" * Relative: +.IP \(bu 4 +\fBrateest1\fP \fIoperator\fP \fBrateest2\fP \fBrateest-bps\fP(without rate!) +.IP \(bu 4 +\fBrateest1\fP \fIoperator\fP \fBrateest2\fP \fBrateest-pps\fP(without rate!) +.\" * Relative + Delta: +.IP \(bu 4 +(\fBrateest1\fP minus \fBrateest-bps1\fP) \fIoperator\fP +(\fBrateest2\fP minus \fBrateest-bps2\fP) +.IP \(bu 4 +(\fBrateest1\fP minus \fBrateest-pps1\fP) \fIoperator\fP +(\fBrateest2\fP minus \fBrateest-pps2\fP) +.TP +\fB\-\-rateest\-delta\fP +For each estimator (either absolute or relative mode), calculate the difference +between the estimator-determined flow rate and the static value chosen with the +BPS/PPS options. If the flow rate is higher than the specified BPS/PPS, 0 will +be used instead of a negative value. In other words, "max(0, rateest#_rate - +rateest#_bps)" is used. +.TP +[\fB!\fP] \fB\-\-rateest\-lt\fP +Match if rate is less than given rate/estimator. +.TP +[\fB!\fP] \fB\-\-rateest\-gt\fP +Match if rate is greater than given rate/estimator. +.TP +[\fB!\fP] \fB\-\-rateest\-eq\fP +Match if rate is equal to given rate/estimator. +.PP +In the so-called "absolute mode", only one rate estimator is used and compared +against a static value, while in "relative mode", two rate estimators are +compared against another. +.TP +\fB\-\-rateest\fP \fIname\fP +Name of the one rate estimator for absolute mode. .TP \fB\-\-rateest1\fP \fIname\fP -Name of the first rate estimator. .TP \fB\-\-rateest2\fP \fIname\fP -Name of the second rate estimator (if difference is to be calculated). +The names of the two rate estimators for relative mode. .TP -\fB\-\-rateest\-delta\fP -Compare difference(s) to given rate(s) +\fB\-\-rateest\-bps\fP [\fIvalue\fP] +.TP +\fB\-\-rateest\-pps\fP [\fIvalue\fP] .TP \fB\-\-rateest\-bps1\fP [\fIvalue\fP] .TP \fB\-\-rateest\-bps2\fP [\fIvalue\fP] -Compare bytes per second. .TP \fB\-\-rateest\-pps1\fP [\fIvalue\fP] .TP \fB\-\-rateest\-pps2\fP [\fIvalue\fP] -Compare packets per second. -.TP -[\fB!\fP] \fB\-\-rateest\-lt\fP -Match if rate is less than given rate/estimator. -.TP -[\fB!\fP] \fB\-\-rateest\-gt\fP -Match if rate is greater than given rate/estimator. -.TP -[\fB!\fP] \fB\-\-rateest\-eq\fP -Match if rate is equal to given rate/estimator. +Compare the estimator(s) by bytes or packets per second, and compare against +the chosen value. See the above bullet list for which option is to be used in +which case. A unit suffix may be used - available ones are: bit, [kmgt]bit, +[KMGT]ibit, Bps, [KMGT]Bps, [KMGT]iBps. .PP Example: This is what can be used to route outgoing data connections from an FTP server over two lines based on the available bandwidth at the time the data -- cgit v1.2.3 From 10345ca36786592aa176036f11dd186b24ba1c76 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 21 May 2011 00:58:44 +0200 Subject: doc: clarify that -p all is a special keyword only Signed-off-by: Jan Engelhardt --- ip6tables.8.in | 5 ++--- iptables.8.in | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ip6tables.8.in b/ip6tables.8.in index 61d6667e..48ba18e1 100644 --- a/ip6tables.8.in +++ b/ip6tables.8.in @@ -243,15 +243,14 @@ add, delete, insert, replace and append commands). [\fB!\fP] \fB\-p\fP, \fB\-\-protocol\fP \fIprotocol\fP The protocol of the rule or of the packet to check. The specified protocol can be one of \fBtcp\fP, \fBudp\fP, \fBudplite\fP, -\fBicmpv6\fP, \fBesp\fP, \fBmh\fP or \fBall\fP, +\fBicmpv6\fP, \fBesp\fP, \fBmh\fP or the special keyword "\fBall\fP", or it can be a numeric value, representing one of these protocols or a different one. A protocol name from /etc/protocols is also allowed. But IPv6 extension headers except \fBesp\fP are not allowed. \fBesp\fP and \fBipv6\-nonext\fP can be used with Kernel version 2.6.11 or later. A "!" argument before the protocol inverts the -test. The number zero is equivalent to \fBall\fP. -Protocol \fBall\fP +test. The number zero is equivalent to \fBall\fP. "\fBall\fP" will match with all protocols and is taken as default when this option is omitted. .TP diff --git a/iptables.8.in b/iptables.8.in index 110c5994..d09bf7aa 100644 --- a/iptables.8.in +++ b/iptables.8.in @@ -246,12 +246,11 @@ add, delete, insert, replace and append commands). [\fB!\fP] \fB\-p\fP, \fB\-\-protocol\fP \fIprotocol\fP The protocol of the rule or of the packet to check. The specified protocol can be one of \fBtcp\fP, \fBudp\fP, \fBudplite\fP, -\fBicmp\fP, \fBesp\fP, \fBah\fP, \fBsctp\fP or \fBall\fP, +\fBicmp\fP, \fBesp\fP, \fBah\fP, \fBsctp\fP or the special keyword "\fBall\fP", or it can be a numeric value, representing one of these protocols or a different one. A protocol name from /etc/protocols is also allowed. A "!" argument before the protocol inverts the -test. The number zero is equivalent to \fBall\fP. -Protocol \fBall\fP +test. The number zero is equivalent to \fBall\fP. "\fBall\fP" will match with all protocols and is taken as default when this option is omitted. .TP -- cgit v1.2.3 From 4f0d5a7fd4cb1452493921446603c837316e0179 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 23 May 2011 17:54:38 +0200 Subject: doc: use .IP list for TCPMSS Signed-off-by: Jan Engelhardt --- extensions/libxt_TCPMSS.man | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/extensions/libxt_TCPMSS.man b/extensions/libxt_TCPMSS.man index ac8fb4e8..8da8e761 100644 --- a/extensions/libxt_TCPMSS.man +++ b/extensions/libxt_TCPMSS.man @@ -11,19 +11,13 @@ packets. The symptoms of this problem are that everything works fine from your Linux firewall/router, but machines behind it can never exchange large packets: -.PD 0 -.RS 0.1i -.TP 0.3i -1) +.IP 1. 4 Web browsers connect, then hang with no data received. -.TP -2) +.IP 2. 4 Small mail works fine, but large emails hang. -.TP -3) +.IP 3. 4 ssh works fine, but scp hangs after initial handshaking. -.RE -.PD +.PP Workaround: activate this option and add a rule to your firewall configuration like: .IP -- cgit v1.2.3 From 9039600d2a50970274b5a13f6f616e38cc9c3e6d Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 23 May 2011 17:55:29 +0200 Subject: doc: remove redundant .IP calls in libxt_time Signed-off-by: Jan Engelhardt --- extensions/libxt_time.man | 6 ------ 1 file changed, 6 deletions(-) diff --git a/extensions/libxt_time.man b/extensions/libxt_time.man index 2bceaf66..4aff7ff5 100644 --- a/extensions/libxt_time.man +++ b/extensions/libxt_time.man @@ -4,7 +4,6 @@ options are optional, but are ANDed when specified. \fB\-\-datestart\fP \fIYYYY\fP[\fB\-\fP\fIMM\fP[\fB\-\fP\fIDD\fP[\fBT\fP\fIhh\fP[\fB:\fP\fImm\fP[\fB:\fP\fIss\fP]]]]] .TP \fB\-\-datestop\fP \fIYYYY\fP[\fB\-\fP\fIMM\fP[\fB\-\fP\fIDD\fP[\fBT\fP\fIhh\fP[\fB:\fP\fImm\fP[\fB:\fP\fIss\fP]]]]] -.IP Only match during the given time, which must be in ISO 8601 "T" notation. The possible time range is 1970-01-01T00:00:00 to 2038-01-19T04:17:07. .IP @@ -14,32 +13,27 @@ and 2038-01-19, respectively. \fB\-\-timestart\fP \fIhh\fP\fB:\fP\fImm\fP[\fB:\fP\fIss\fP] .TP \fB\-\-timestop\fP \fIhh\fP\fB:\fP\fImm\fP[\fB:\fP\fIss\fP] -.IP Only match during the given daytime. The possible time range is 00:00:00 to 23:59:59. Leading zeroes are allowed (e.g. "06:03") and correctly interpreted as base-10. .TP [\fB!\fP] \fB\-\-monthdays\fP \fIday\fP[\fB,\fP\fIday\fP...] -.IP Only match on the given days of the month. Possible values are \fB1\fP to \fB31\fP. Note that specifying \fB31\fP will of course not match on months which do not have a 31st day; the same goes for 28- or 29-day February. .TP [\fB!\fP] \fB\-\-weekdays\fP \fIday\fP[\fB,\fP\fIday\fP...] -.IP Only match on the given weekdays. Possible values are \fBMon\fP, \fBTue\fP, \fBWed\fP, \fBThu\fP, \fBFri\fP, \fBSat\fP, \fBSun\fP, or values from \fB1\fP to \fB7\fP, respectively. You may also use two-character variants (\fBMo\fP, \fBTu\fP, etc.). .TP \fB\-\-utc\fP -.IP Interpret the times given for \fB\-\-datestart\fP, \fB\-\-datestop\fP, \fB\-\-timestart\fP and \fB\-\-timestop\fP to be UTC. .TP \fB\-\-localtz\fP -.IP Interpret the times given for \fB\-\-datestart\fP, \fB\-\-datestop\fP, \fB\-\-timestart\fP and \fB\-\-timestop\fP to be local kernel time. (Default) .PP -- cgit v1.2.3 From c52f7aa866ee3cdc0e0dc67f3eae629055a126dc Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 23 May 2011 00:22:27 +0200 Subject: libxt_ipvs: restore network-byte order Signed-off-by: Jan Engelhardt --- extensions/libxt_ipvs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/libxt_ipvs.c b/extensions/libxt_ipvs.c index 88d235f6..46727660 100644 --- a/extensions/libxt_ipvs.c +++ b/extensions/libxt_ipvs.c @@ -32,12 +32,14 @@ static const struct xt_option_entry ipvs_mt_opts[] = { {.name = "vaddr", .id = O_VADDR, .type = XTTYPE_HOSTMASK, .flags = XTOPT_INVERT}, {.name = "vport", .id = O_VPORT, .type = XTTYPE_PORT, - .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, vport)}, + .flags = XTOPT_NBO | XTOPT_INVERT | XTOPT_PUT, + XTOPT_POINTER(s, vport)}, {.name = "vdir", .id = O_VDIR, .type = XTTYPE_STRING}, {.name = "vmethod", .id = O_VMETHOD, .type = XTTYPE_STRING, .flags = XTOPT_INVERT}, {.name = "vportctl", .id = O_VPORTCTL, .type = XTTYPE_PORT, - .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, vportctl)}, + .flags = XTOPT_NBO | XTOPT_INVERT | XTOPT_PUT, + XTOPT_POINTER(s, vportctl)}, XTOPT_TABLEEND, }; #undef s -- cgit v1.2.3 From 5a66f40d2f64e8792e1360906d3d6a1c829ba2b7 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 00:35:00 +0200 Subject: libxt_u32: --u32 option is required Signed-off-by: Jan Engelhardt --- extensions/libxt_u32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/libxt_u32.c b/extensions/libxt_u32.c index 9198edca..774d5eac 100644 --- a/extensions/libxt_u32.c +++ b/extensions/libxt_u32.c @@ -23,7 +23,8 @@ enum { }; static const struct xt_option_entry u32_opts[] = { - {.name = "u32", .id = O_U32, .type = XTTYPE_STRING}, + {.name = "u32", .id = O_U32, .type = XTTYPE_STRING, + .flags = XTOPT_MAND}, XTOPT_TABLEEND, }; -- cgit v1.2.3 From 319046c3f96f810f81a5a2e6189ba87527e882f1 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 00:45:08 +0200 Subject: libip6t_rt: restore --rt-type storing Signed-off-by: Jan Engelhardt --- extensions/libip6t_rt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/libip6t_rt.c b/extensions/libip6t_rt.c index eb308204..9e6868de 100644 --- a/extensions/libip6t_rt.c +++ b/extensions/libip6t_rt.c @@ -31,8 +31,8 @@ IP6T_RT_HOPS); #define s struct ip6t_rt static const struct xt_option_entry rt_opts[] = { - {.name = "rt-type", .id = O_RT_TYPE, .type = XTTYPE_UINT32RC, - .flags = XTOPT_INVERT}, + {.name = "rt-type", .id = O_RT_TYPE, .type = XTTYPE_UINT32, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, rt_type)}, {.name = "rt-segsleft", .id = O_RT_SEGSLEFT, .type = XTTYPE_UINT32RC, .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segsleft)}, {.name = "rt-len", .id = O_RT_LEN, .type = XTTYPE_UINT32, -- cgit v1.2.3 From 5e35b7d435c5bc1b3641f76a6601a55d32d63ac8 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 02:03:00 +0200 Subject: libxtables: more detailed error message on multi-int parsing Now shows where exactly the error is. Signed-off-by: Jan Engelhardt --- xtoptions.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/xtoptions.c b/xtoptions.c index ec2269b2..9884b7df 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -206,13 +206,14 @@ static void xtopt_parse_mint(struct xt_option_call *cb) cb->ext_name, entry->name, maxiter); if (!xtables_strtoui(arg, &end, &value, 0, UINT32_MAX)) xt_params->exit_err(PARAMETER_PROBLEM, - "%s: bad value for option \"--%s\", " - "or out of range (0-%u).\n", - cb->ext_name, entry->name, UINT32_MAX); + "%s: bad value for option \"--%s\" near " + "\"%s\", or out of range (0-%u).\n", + cb->ext_name, entry->name, arg, UINT32_MAX); if (*end != '\0' && *end != sep) xt_params->exit_err(PARAMETER_PROBLEM, "%s: Argument to \"--%s\" has unexpected " - "characters.\n", cb->ext_name, entry->name); + "characters near \"%s\".\n", + cb->ext_name, entry->name, end); if (cb->nvals < ARRAY_SIZE(cb->val.u32_range)) { if (entry->type == XTTYPE_UINT8RC) cb->val.u8_range[cb->nvals] = value; -- cgit v1.2.3 From 0b7a140944738d67b9c4e6f09992c8407eefb18a Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 02:30:23 +0200 Subject: libxtables: use uintmax for xtables_strtoul Addendum to 2305d5fb42fc059f38fc1bdf53411dbeecdb310b. I noticed that unsigned long long is not consistently used, for example, min/max are still just unsigned long, and strtoul is being called. Instead of changing it to unsigned long long, just use uintmax functions right away so this does not need size-related changing in the future. Cc: JP Abgrall Signed-off-by: Jan Engelhardt --- include/xtables.h.in | 4 ++-- xtables.c | 11 ++++++----- xtoptions.c | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/xtables.h.in b/include/xtables.h.in index 90eb1b2b..2565dd23 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -408,8 +408,8 @@ extern void xtables_register_matches(struct xtables_match *, unsigned int); extern void xtables_register_target(struct xtables_target *me); extern void xtables_register_targets(struct xtables_target *, unsigned int); -extern bool xtables_strtoul(const char *, char **, unsigned long long *, - unsigned long, unsigned long); +extern bool xtables_strtoul(const char *, char **, uintmax_t *, + uintmax_t, uintmax_t); extern bool xtables_strtoui(const char *, char **, unsigned int *, unsigned int, unsigned int); extern int xtables_service_to_port(const char *name, const char *proto); diff --git a/xtables.c b/xtables.c index e11a77ee..acfcf8bd 100644 --- a/xtables.c +++ b/xtables.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -426,10 +427,10 @@ int xtables_load_ko(const char *modprobe, bool quiet) * Returns true/false whether number was accepted. On failure, *value has * undefined contents. */ -bool xtables_strtoul(const char *s, char **end, unsigned long long *value, - unsigned long min, unsigned long max) +bool xtables_strtoul(const char *s, char **end, uintmax_t *value, + uintmax_t min, uintmax_t max) { - unsigned long v; + uintmax_t v; const char *p; char *my_end; @@ -439,7 +440,7 @@ bool xtables_strtoul(const char *s, char **end, unsigned long long *value, ; if (*p == '-') return false; - v = strtoul(s, &my_end, 0); + v = strtoumax(s, &my_end, 0); if (my_end == s) return false; if (end != NULL) @@ -459,7 +460,7 @@ bool xtables_strtoul(const char *s, char **end, unsigned long long *value, bool xtables_strtoui(const char *s, char **end, unsigned int *value, unsigned int min, unsigned int max) { - unsigned long long v; + uintmax_t v; bool ret; ret = xtables_strtoul(s, end, &v, min, max); diff --git a/xtoptions.c b/xtoptions.c index 9884b7df..e9736a44 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -104,8 +104,8 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts, static void xtopt_parse_int(struct xt_option_call *cb) { const struct xt_option_entry *entry = cb->entry; - unsigned long long lmin = 0, lmax = UINT32_MAX; - unsigned long long value; + uintmax_t lmin = 0, lmax = UINT32_MAX; + uintmax_t value; if (entry->type == XTTYPE_UINT8) lmax = UINT8_MAX; @@ -121,7 +121,7 @@ static void xtopt_parse_int(struct xt_option_call *cb) if (!xtables_strtoul(cb->arg, NULL, &value, lmin, lmax)) xt_params->exit_err(PARAMETER_PROBLEM, "%s: bad value for option \"--%s\", " - "or out of range (%llu-%llu).\n", + "or out of range (%ju-%ju).\n", cb->ext_name, entry->name, lmin, lmax); if (entry->type == XTTYPE_UINT8) { -- cgit v1.2.3 From 57e2e37ebe5319cf84381bdb319ea94143b1bf97 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 02:45:50 +0200 Subject: libxtables: make multiint parser have greater range Since parse_mint can handle XTTYPE_UINT64RC, it must allow numbers larger than UINT32_MAX. Cc: JP Abgrall Signed-off-by: Jan Engelhardt --- xtoptions.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/xtoptions.c b/xtoptions.c index e9736a44..1fc90ee8 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -98,21 +98,35 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts, return merge; } +static uintmax_t xtopt_max_by_type(enum xt_option_type type) +{ + switch (type) { + case XTTYPE_UINT8: + case XTTYPE_UINT8RC: + return UINT8_MAX; + case XTTYPE_UINT16: + case XTTYPE_UINT16RC: + return UINT16_MAX; + case XTTYPE_UINT32: + case XTTYPE_UINT32RC: + return UINT32_MAX; + case XTTYPE_UINT64: + case XTTYPE_UINT64RC: + return UINT64_MAX; + default: + return 0; + } +} + /** * Require a simple integer. */ static void xtopt_parse_int(struct xt_option_call *cb) { const struct xt_option_entry *entry = cb->entry; - uintmax_t lmin = 0, lmax = UINT32_MAX; + uintmax_t lmin = 0, lmax = xtopt_max_by_type(entry->type); uintmax_t value; - if (entry->type == XTTYPE_UINT8) - lmax = UINT8_MAX; - else if (entry->type == XTTYPE_UINT16) - lmax = UINT16_MAX; - else if (entry->type == XTTYPE_UINT64) - lmax = UINT64_MAX; if (cb->entry->min != 0) lmin = cb->entry->min; if (cb->entry->max != 0) @@ -180,8 +194,10 @@ static void xtopt_parse_mint(struct xt_option_call *cb) const struct xt_option_entry *entry = cb->entry; const char *arg = cb->arg; size_t esize = sizeof(uint32_t); + uintmax_t lmax = xtopt_max_by_type(entry->type); char *put = XTOPT_MKPTR(cb); - unsigned int maxiter, value; + unsigned int maxiter; + uintmax_t value; char *end = ""; char sep = ':'; @@ -204,11 +220,11 @@ static void xtopt_parse_mint(struct xt_option_call *cb) xt_params->exit_err(PARAMETER_PROBLEM, "%s: Too many " "components for option \"--%s\" (max: %u)\n", cb->ext_name, entry->name, maxiter); - if (!xtables_strtoui(arg, &end, &value, 0, UINT32_MAX)) + if (!xtables_strtoul(arg, &end, &value, 0, lmax)) xt_params->exit_err(PARAMETER_PROBLEM, "%s: bad value for option \"--%s\" near " - "\"%s\", or out of range (0-%u).\n", - cb->ext_name, entry->name, arg, UINT32_MAX); + "\"%s\", or out of range (0-%ju).\n", + cb->ext_name, entry->name, arg, lmax); if (*end != '\0' && *end != sep) xt_params->exit_err(PARAMETER_PROBLEM, "%s: Argument to \"--%s\" has unexpected " -- cgit v1.2.3 From 1b6c7632e5e35ecce91f87a4ae36eca3103cfee2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 14:49:15 +0200 Subject: libxtables: unclutter xtopt_parse_mint ..by moving type-based actions into their own function. Signed-off-by: Jan Engelhardt --- xtoptions.c | 148 ++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 54 deletions(-) diff --git a/xtoptions.c b/xtoptions.c index 1fc90ee8..30d70b0c 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -41,6 +41,31 @@ struct tos_value_mask { uint8_t value, mask; }; +static const size_t xtopt_psize[] = { + /* + * All types not listed here, and thus essentially being initialized to + * zero have zero on purpose. + */ + [XTTYPE_UINT8] = sizeof(uint8_t), + [XTTYPE_UINT16] = sizeof(uint16_t), + [XTTYPE_UINT32] = sizeof(uint32_t), + [XTTYPE_UINT64] = sizeof(uint64_t), + [XTTYPE_UINT8RC] = sizeof(uint8_t[2]), + [XTTYPE_UINT16RC] = sizeof(uint16_t[2]), + [XTTYPE_UINT32RC] = sizeof(uint32_t[2]), + [XTTYPE_UINT64RC] = sizeof(uint64_t[2]), + [XTTYPE_DOUBLE] = sizeof(double), + [XTTYPE_STRING] = -1, + [XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t), + [XTTYPE_HOST] = sizeof(union nf_inet_addr), + [XTTYPE_HOSTMASK] = sizeof(union nf_inet_addr), + [XTTYPE_PROTOCOL] = sizeof(uint8_t), + [XTTYPE_PORT] = sizeof(uint16_t), + [XTTYPE_PORTRC] = sizeof(uint16_t[2]), + [XTTYPE_PLENMASK] = sizeof(union nf_inet_addr), + [XTTYPE_ETHERMAC] = sizeof(uint8_t[6]), +}; + /** * Creates getopt options from the x6-style option map, and assigns each a * getopt id. @@ -98,6 +123,9 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts, return merge; } +/** + * Give the upper limit for a certain type. + */ static uintmax_t xtopt_max_by_type(enum xt_option_type type) { switch (type) { @@ -118,6 +146,26 @@ static uintmax_t xtopt_max_by_type(enum xt_option_type type) } } +/** + * Return the size of a single entity based upon a type - predominantly an + * XTTYPE_UINT*RC type. + */ +static size_t xtopt_esize_by_type(enum xt_option_type type) +{ + switch (type) { + case XTTYPE_UINT8RC: + return xtopt_psize[XTTYPE_UINT8]; + case XTTYPE_UINT16RC: + return xtopt_psize[XTTYPE_UINT16]; + case XTTYPE_UINT32RC: + return xtopt_psize[XTTYPE_UINT32]; + case XTTYPE_UINT64RC: + return xtopt_psize[XTTYPE_UINT64]; + default: + return xtopt_psize[type]; + } +} + /** * Require a simple integer. */ @@ -180,6 +228,48 @@ static void xtopt_parse_float(struct xt_option_call *cb) *(double *)XTOPT_MKPTR(cb) = cb->val.dbl; } +/** + * Copy the parsed value to the appropriate entry in cb->val. + */ +static void xtopt_mint_value_to_cb(struct xt_option_call *cb, uintmax_t value) +{ + const struct xt_option_entry *entry = cb->entry; + + if (cb->nvals >= ARRAY_SIZE(cb->val.u32_range)) + return; + if (entry->type == XTTYPE_UINT8RC) + cb->val.u8_range[cb->nvals] = value; + else if (entry->type == XTTYPE_UINT16RC) + cb->val.u16_range[cb->nvals] = value; + else if (entry->type == XTTYPE_UINT32RC) + cb->val.u32_range[cb->nvals] = value; + else if (entry->type == XTTYPE_UINT64RC) + cb->val.u64_range[cb->nvals] = value; +} + +/** + * Copy the parsed value to the data area, using appropriate type access. + */ +static void xtopt_mint_value_to_ptr(struct xt_option_call *cb, void **datap, + uintmax_t value) +{ + const struct xt_option_entry *entry = cb->entry; + void *data = *datap; + + if (!(entry->flags & XTOPT_PUT)) + return; + if (entry->type == XTTYPE_UINT8RC) + *(uint8_t *)data = value; + else if (entry->type == XTTYPE_UINT16RC) + *(uint16_t *)data = value; + else if (entry->type == XTTYPE_UINT32RC) + *(uint32_t *)data = value; + else if (entry->type == XTTYPE_UINT64RC) + *(uint64_t *)data = value; + data += xtopt_esize_by_type(entry->type); + *datap = data; +} + /** * Multiple integer parse routine. * @@ -193,20 +283,14 @@ static void xtopt_parse_mint(struct xt_option_call *cb) { const struct xt_option_entry *entry = cb->entry; const char *arg = cb->arg; - size_t esize = sizeof(uint32_t); + size_t esize = xtopt_esize_by_type(entry->type); uintmax_t lmax = xtopt_max_by_type(entry->type); - char *put = XTOPT_MKPTR(cb); + void *put = XTOPT_MKPTR(cb); unsigned int maxiter; uintmax_t value; char *end = ""; char sep = ':'; - if (entry->type == XTTYPE_UINT8RC) - esize = sizeof(uint8_t); - else if (entry->type == XTTYPE_UINT16RC) - esize = sizeof(uint16_t); - else if (entry->type == XTTYPE_UINT64RC) - esize = sizeof(uint64_t); maxiter = entry->size / esize; if (maxiter == 0) maxiter = 2; /* ARRAY_SIZE(cb->val.uXX_range) */ @@ -230,28 +314,9 @@ static void xtopt_parse_mint(struct xt_option_call *cb) "%s: Argument to \"--%s\" has unexpected " "characters near \"%s\".\n", cb->ext_name, entry->name, end); - if (cb->nvals < ARRAY_SIZE(cb->val.u32_range)) { - if (entry->type == XTTYPE_UINT8RC) - cb->val.u8_range[cb->nvals] = value; - else if (entry->type == XTTYPE_UINT16RC) - cb->val.u16_range[cb->nvals] = value; - else if (entry->type == XTTYPE_UINT32RC) - cb->val.u32_range[cb->nvals] = value; - else if (entry->type == XTTYPE_UINT64RC) - cb->val.u64_range[cb->nvals] = value; - } + xtopt_mint_value_to_cb(cb, value); ++cb->nvals; - if (entry->flags & XTOPT_PUT) { - if (entry->type == XTTYPE_UINT8RC) - *(uint8_t *)put = value; - else if (entry->type == XTTYPE_UINT16RC) - *(uint16_t *)put = value; - else if (entry->type == XTTYPE_UINT32RC) - *(uint32_t *)put = value; - else if (entry->type == XTTYPE_UINT64RC) - *(uint64_t *)put = value; - put += esize; - } + xtopt_mint_value_to_ptr(cb, &put, value); if (*end == '\0') break; } @@ -726,31 +791,6 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = { [XTTYPE_ETHERMAC] = xtopt_parse_ethermac, }; -static const size_t xtopt_psize[] = { - /* - * All types not listed here, and thus essentially being initialized to - * zero have zero on purpose. - */ - [XTTYPE_UINT8] = sizeof(uint8_t), - [XTTYPE_UINT16] = sizeof(uint16_t), - [XTTYPE_UINT32] = sizeof(uint32_t), - [XTTYPE_UINT64] = sizeof(uint64_t), - [XTTYPE_UINT8RC] = sizeof(uint8_t[2]), - [XTTYPE_UINT16RC] = sizeof(uint16_t[2]), - [XTTYPE_UINT32RC] = sizeof(uint32_t[2]), - [XTTYPE_UINT64RC] = sizeof(uint64_t[2]), - [XTTYPE_DOUBLE] = sizeof(double), - [XTTYPE_STRING] = -1, - [XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t), - [XTTYPE_HOST] = sizeof(union nf_inet_addr), - [XTTYPE_HOSTMASK] = sizeof(union nf_inet_addr), - [XTTYPE_PROTOCOL] = sizeof(uint8_t), - [XTTYPE_PORT] = sizeof(uint16_t), - [XTTYPE_PORTRC] = sizeof(uint16_t[2]), - [XTTYPE_PLENMASK] = sizeof(union nf_inet_addr), - [XTTYPE_ETHERMAC] = sizeof(uint8_t[6]), -}; - /** * The master option parsing routine. May be used for the ".x6_parse" * function pointer in extensions if fully automatic parsing is desired. -- cgit v1.2.3 From 6944f2c8190f1c4319aeac748470c71b0ba45025 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 23:50:29 +0200 Subject: libxtables: have xtopt_parse_mint interpret partially-spec'd ranges When ":n" or "n:" is specified, it will now be interpreted as "0:n" and "n:", respecitvely. nvals will always reflect the number of (expanded) components. This restores the functionality of options that take such partially-unspecified ranges. This makes it possible to nuke the per-matchdata init functions of some extensions and simply the extensions postparsing to the point where it only needs to check for nvals==1 or ==2. Signed-off-by: Jan Engelhardt --- extensions/libip6t_ah.c | 10 ++---- extensions/libip6t_frag.c | 12 +++----- extensions/libip6t_rt.c | 10 ++---- extensions/libipt_ah.c | 10 ++---- extensions/libxt_conntrack.c | 73 +++++--------------------------------------- extensions/libxt_esp.c | 10 ++---- extensions/libxt_length.c | 4 ++- xtoptions.c | 32 +++++++++++-------- 8 files changed, 42 insertions(+), 119 deletions(-) diff --git a/extensions/libip6t_ah.c b/extensions/libip6t_ah.c index d30ddfa4..26f81408 100644 --- a/extensions/libip6t_ah.c +++ b/extensions/libip6t_ah.c @@ -28,13 +28,6 @@ static const struct xt_option_entry ah_opts[] = { }; #undef s -static void ah_init(struct xt_entry_match *m) -{ - struct ip6t_ah *ahinfo = (struct ip6t_ah *)m->data; - - ahinfo->spis[1] = 0xFFFFFFFF; -} - static void ah_parse(struct xt_option_call *cb) { struct ip6t_ah *ahinfo = cb->data; @@ -42,6 +35,8 @@ static void ah_parse(struct xt_option_call *cb) xtables_option_parse(cb); switch (cb->entry->id) { case O_AHSPI: + if (cb->nvals == 1) + ahinfo->spis[1] = ahinfo->spis[0]; if (cb->invert) ahinfo->invflags |= IP6T_AH_INV_SPI; break; @@ -132,7 +127,6 @@ static struct xtables_match ah_mt6_reg = { .size = XT_ALIGN(sizeof(struct ip6t_ah)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)), .help = ah_help, - .init = ah_init, .print = ah_print, .save = ah_save, .x6_parse = ah_parse, diff --git a/extensions/libip6t_frag.c b/extensions/libip6t_frag.c index 12794e42..47793860 100644 --- a/extensions/libip6t_frag.c +++ b/extensions/libip6t_frag.c @@ -41,19 +41,16 @@ static const struct xt_option_entry frag_opts[] = { }; #undef s -static void frag_init(struct xt_entry_match *m) -{ - struct ip6t_frag *fraginfo = (struct ip6t_frag *)m->data; - - fraginfo->ids[1] = 0xFFFFFFFF; -} - static void frag_parse(struct xt_option_call *cb) { struct ip6t_frag *fraginfo = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { + case O_FRAGID: + if (cb->nvals == 1) + fraginfo->ids[1] = fraginfo->ids[0]; + break; case O_FRAGRES: fraginfo->flags |= IP6T_FRAG_RES; break; @@ -160,7 +157,6 @@ static struct xtables_match frag_mt6_reg = { .size = XT_ALIGN(sizeof(struct ip6t_frag)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_frag)), .help = frag_help, - .init = frag_init, .print = frag_print, .save = frag_save, .x6_parse = frag_parse, diff --git a/extensions/libip6t_rt.c b/extensions/libip6t_rt.c index 9e6868de..d470488d 100644 --- a/extensions/libip6t_rt.c +++ b/extensions/libip6t_rt.c @@ -99,13 +99,6 @@ parse_addresses(const char *addrstr, struct in6_addr *addrp) return i; } -static void rt_init(struct xt_entry_match *m) -{ - struct ip6t_rt *rtinfo = (struct ip6t_rt *)m->data; - - rtinfo->segsleft[1] = 0xFFFFFFFF; -} - static void rt_parse(struct xt_option_call *cb) { struct ip6t_rt *rtinfo = cb->data; @@ -118,6 +111,8 @@ static void rt_parse(struct xt_option_call *cb) rtinfo->flags |= IP6T_RT_TYP; break; case O_RT_SEGSLEFT: + if (cb->nvals == 1) + rtinfo->segsleft[1] = rtinfo->segsleft[0]; if (cb->invert) rtinfo->invflags |= IP6T_RT_INV_SGS; rtinfo->flags |= IP6T_RT_SGS; @@ -250,7 +245,6 @@ static struct xtables_match rt_mt6_reg = { .size = XT_ALIGN(sizeof(struct ip6t_rt)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_rt)), .help = rt_help, - .init = rt_init, .x6_parse = rt_parse, .print = rt_print, .save = rt_save, diff --git a/extensions/libipt_ah.c b/extensions/libipt_ah.c index 53adfd87..8cf167c4 100644 --- a/extensions/libipt_ah.c +++ b/extensions/libipt_ah.c @@ -21,18 +21,13 @@ static const struct xt_option_entry ah_opts[] = { XTOPT_TABLEEND, }; -static void ah_init(struct xt_entry_match *m) -{ - struct ipt_ah *ahinfo = (struct ipt_ah *)m->data; - - ahinfo->spis[1] = 0xFFFFFFFF; -} - static void ah_parse(struct xt_option_call *cb) { struct ipt_ah *ahinfo = cb->data; xtables_option_parse(cb); + if (cb->nvals == 1) + ahinfo->spis[1] = ahinfo->spis[0]; if (cb->invert) ahinfo->invflags |= IPT_AH_INV_SPI; } @@ -97,7 +92,6 @@ static struct xtables_match ah_mt_reg = { .size = XT_ALIGN(sizeof(struct ipt_ah)), .userspacesize = XT_ALIGN(sizeof(struct ipt_ah)), .help = ah_help, - .init = ah_init, .print = ah_print, .save = ah_save, .x6_parse = ah_parse, diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c index ed0bd939..e1d85755 100644 --- a/extensions/libxt_conntrack.c +++ b/extensions/libxt_conntrack.c @@ -291,69 +291,6 @@ conntrack_ps_statuses(struct xt_conntrack_mtinfo3 *info, const char *arg) xtables_error(PARAMETER_PROBLEM, "Bad ctstatus \"%s\"", arg); } -static unsigned long -parse_expire(const char *s) -{ - unsigned int len; - - if (!xtables_strtoui(s, NULL, &len, 0, UINT32_MAX)) - xtables_error(PARAMETER_PROBLEM, "expire value invalid: \"%s\"\n", s); - else - return len; -} - -/* If a single value is provided, min and max are both set to the value */ -static void -parse_expires(const char *s, struct xt_conntrack_info *sinfo) -{ - char *buffer; - char *cp; - - buffer = strdup(s); - if ((cp = strchr(buffer, ':')) == NULL) - sinfo->expires_min = sinfo->expires_max = - parse_expire(buffer); - else { - *cp = '\0'; - cp++; - - sinfo->expires_min = buffer[0] ? parse_expire(buffer) : 0; - sinfo->expires_max = cp[0] - ? parse_expire(cp) - : (unsigned long)-1; - } - free(buffer); - - if (sinfo->expires_min > sinfo->expires_max) - xtables_error(PARAMETER_PROBLEM, - "expire min. range value `%lu' greater than max. " - "range value `%lu'", sinfo->expires_min, sinfo->expires_max); -} - -static void -conntrack_ps_expires(struct xt_conntrack_mtinfo3 *info, const char *s) -{ - unsigned int min, max; - char *end; - - if (!xtables_strtoui(s, &end, &min, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "conntrack", "--expires", s); - max = min; - if (*end == ':') - if (!xtables_strtoui(end + 1, &end, &max, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "conntrack", "--expires", s); - if (*end != '\0') - xtables_param_act(XTF_BAD_VALUE, "conntrack", "--expires", s); - - if (min > max) - xtables_error(PARAMETER_PROBLEM, - "expire min. range value \"%u\" greater than max. " - "range value \"%u\"", min, max); - - info->expires_min = min; - info->expires_max = max; -} - static void conntrack_parse(struct xt_option_call *cb) { struct xt_conntrack_info *sinfo = cb->data; @@ -408,7 +345,10 @@ static void conntrack_parse(struct xt_option_call *cb) sinfo->flags |= XT_CONNTRACK_STATUS; break; case O_CTEXPIRE: - parse_expires(cb->arg, sinfo); + sinfo->expires_min = cb->val.u32_range[0]; + sinfo->expires_max = cb->val.u32_range[0]; + if (cb->nvals >= 2) + sinfo->expires_max = cb->val.u32_range[1]; if (cb->invert) sinfo->invflags |= XT_CONNTRACK_EXPIRES; sinfo->flags |= XT_CONNTRACK_EXPIRES; @@ -473,7 +413,10 @@ static void conntrack_mt_parse(struct xt_option_call *cb, uint8_t rev) info->invert_flags |= XT_CONNTRACK_STATUS; break; case O_CTEXPIRE: - conntrack_ps_expires(info, cb->arg); + info->expires_min = cb->val.u32_range[0]; + info->expires_max = cb->val.u32_range[0]; + if (cb->nvals >= 2) + info->expires_max = cb->val.u32_range[1]; info->match_flags |= XT_CONNTRACK_EXPIRES; if (cb->invert) info->invert_flags |= XT_CONNTRACK_EXPIRES; diff --git a/extensions/libxt_esp.c b/extensions/libxt_esp.c index e9d7990e..294338b4 100644 --- a/extensions/libxt_esp.c +++ b/extensions/libxt_esp.c @@ -21,18 +21,13 @@ static const struct xt_option_entry esp_opts[] = { XTOPT_TABLEEND, }; -static void esp_init(struct xt_entry_match *m) -{ - struct xt_esp *espinfo = (struct xt_esp *)m->data; - - espinfo->spis[1] = 0xFFFFFFFF; -} - static void esp_parse(struct xt_option_call *cb) { struct xt_esp *espinfo = cb->data; xtables_option_parse(cb); + if (cb->nvals == 1) + espinfo->spis[1] = espinfo->spis[0]; if (cb->invert) espinfo->invflags |= XT_ESP_INV_SPI; } @@ -91,7 +86,6 @@ static struct xtables_match esp_match = { .size = XT_ALIGN(sizeof(struct xt_esp)), .userspacesize = XT_ALIGN(sizeof(struct xt_esp)), .help = esp_help, - .init = esp_init, .print = esp_print, .save = esp_save, .x6_parse = esp_parse, diff --git a/extensions/libxt_length.c b/extensions/libxt_length.c index 4f3a3318..6ea76465 100644 --- a/extensions/libxt_length.c +++ b/extensions/libxt_length.c @@ -26,7 +26,9 @@ static void length_parse(struct xt_option_call *cb) xtables_option_parse(cb); info->min = cb->val.u16_range[0]; - info->max = (cb->nvals == 2) ? cb->val.u16_range[1] : UINT16_MAX; + info->max = cb->val.u16_range[0]; + if (cb->nvals >= 2) + info->max = cb->val.u16_range[1]; if (cb->invert) info->invert = 1; } diff --git a/xtoptions.c b/xtoptions.c index 30d70b0c..ac0601f2 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -284,7 +284,7 @@ static void xtopt_parse_mint(struct xt_option_call *cb) const struct xt_option_entry *entry = cb->entry; const char *arg = cb->arg; size_t esize = xtopt_esize_by_type(entry->type); - uintmax_t lmax = xtopt_max_by_type(entry->type); + const uintmax_t lmax = xtopt_max_by_type(entry->type); void *put = XTOPT_MKPTR(cb); unsigned int maxiter; uintmax_t value; @@ -293,27 +293,33 @@ static void xtopt_parse_mint(struct xt_option_call *cb) maxiter = entry->size / esize; if (maxiter == 0) - maxiter = 2; /* ARRAY_SIZE(cb->val.uXX_range) */ + maxiter = ARRAY_SIZE(cb->val.u32_range); if (entry->size % esize != 0) xt_params->exit_err(OTHER_PROBLEM, "%s: memory block does " "not have proper size\n", __func__); cb->nvals = 0; - for (arg = cb->arg; ; arg = end + 1) { + for (arg = cb->arg, end = (char *)arg; ; arg = end + 1) { if (cb->nvals == maxiter) xt_params->exit_err(PARAMETER_PROBLEM, "%s: Too many " "components for option \"--%s\" (max: %u)\n", cb->ext_name, entry->name, maxiter); - if (!xtables_strtoul(arg, &end, &value, 0, lmax)) - xt_params->exit_err(PARAMETER_PROBLEM, - "%s: bad value for option \"--%s\" near " - "\"%s\", or out of range (0-%ju).\n", - cb->ext_name, entry->name, arg, lmax); - if (*end != '\0' && *end != sep) - xt_params->exit_err(PARAMETER_PROBLEM, - "%s: Argument to \"--%s\" has unexpected " - "characters near \"%s\".\n", - cb->ext_name, entry->name, end); + if (*arg == '\0' || *arg == sep) { + /* Default range components when field not spec'd. */ + end = (char *)arg; + value = (cb->nvals == 1) ? lmax : 0; + } else { + if (!xtables_strtoul(arg, &end, &value, 0, lmax)) + xt_params->exit_err(PARAMETER_PROBLEM, + "%s: bad value for option \"--%s\" near " + "\"%s\", or out of range (0-%ju).\n", + cb->ext_name, entry->name, arg, lmax); + if (*end != '\0' && *end != sep) + xt_params->exit_err(PARAMETER_PROBLEM, + "%s: Argument to \"--%s\" has " + "unexpected characters near \"%s\".\n", + cb->ext_name, entry->name, end); + } xtopt_mint_value_to_cb(cb, value); ++cb->nvals; xtopt_mint_value_to_ptr(cb, &put, value); -- cgit v1.2.3 From 089585f14fda80508e26ea019703add07cb72f64 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 25 May 2011 00:11:48 +0200 Subject: libxt_NFQUEUE: avoid double attempt at parsing Fixes this error: NFQUEUE: option "--queue-num" can only be used once. Signed-off-by: Jan Engelhardt --- extensions/libxt_NFQUEUE.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/extensions/libxt_NFQUEUE.c b/extensions/libxt_NFQUEUE.c index a86c88a3..71ead8d6 100644 --- a/extensions/libxt_NFQUEUE.c +++ b/extensions/libxt_NFQUEUE.c @@ -81,14 +81,11 @@ static void NFQUEUE_parse_v2(struct xt_option_call *cb) { struct xt_NFQ_info_v2 *info = cb->data; - xtables_option_parse(cb); + NFQUEUE_parse_v1(cb); switch (cb->entry->id) { case O_QUEUE_BYPASS: info->bypass = 1; break; - default: - NFQUEUE_parse_v1(cb); - break; } } -- cgit v1.2.3 From d8784613a5be2821ff910cd4c2bfe889a9b306c5 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 25 May 2011 00:26:01 +0200 Subject: libxt_NFQUEUE: add mutual exclusion between qnum and qbal Only one is printed on save operation, which leads me to believe that only one is meant to be used. The manpage seems to corroborate. Signed-off-by: Jan Engelhardt --- extensions/libxt_NFQUEUE.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/libxt_NFQUEUE.c b/extensions/libxt_NFQUEUE.c index 71ead8d6..e47b586c 100644 --- a/extensions/libxt_NFQUEUE.c +++ b/extensions/libxt_NFQUEUE.c @@ -13,6 +13,8 @@ enum { O_QUEUE_NUM = 0, O_QUEUE_BALANCE, O_QUEUE_BYPASS, + F_QUEUE_NUM = 1 << O_QUEUE_NUM, + F_QUEUE_BALANCE = 1 << O_QUEUE_BALANCE, }; static void NFQUEUE_help(void) @@ -41,9 +43,10 @@ static void NFQUEUE_help_v2(void) #define s struct xt_NFQ_info static const struct xt_option_entry NFQUEUE_opts[] = { {.name = "queue-num", .id = O_QUEUE_NUM, .type = XTTYPE_UINT16, - .flags = XTOPT_PUT, XTOPT_POINTER(s, queuenum)}, + .flags = XTOPT_PUT, XTOPT_POINTER(s, queuenum), + .excl = F_QUEUE_BALANCE}, {.name = "queue-balance", .id = O_QUEUE_BALANCE, - .type = XTTYPE_UINT16RC}, + .type = XTTYPE_UINT16RC, .excl = F_QUEUE_NUM}, {.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE}, XTOPT_TABLEEND, }; -- cgit v1.2.3 From b1319cc083de658c0007da93f25d19874f75d55f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 23 May 2011 17:42:37 +0200 Subject: libxt_time: always ignore libc timezone Since xt_time is meant to work across many months, libc doing automatic conversion from local time to UTC (during parse) is unwanted, especially when --utc is specified. The same goes for dumping. Signed-off-by: Jan Engelhardt --- extensions/libxt_time.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c index b538476c..67b7f45d 100644 --- a/extensions/libxt_time.c +++ b/extensions/libxt_time.c @@ -136,6 +136,12 @@ static time_t time_parse_date(const char *s, bool end) tm.tm_min = minute; tm.tm_sec = second; tm.tm_isdst = 0; + /* + * Offsetting, if any, is done by xt_time.ko, + * so we have to disable it here in userspace. + */ + setenv("TZ", "UTC", true); + tzset(); ret = mktime(&tm); if (ret >= 0) return ret; @@ -289,7 +295,7 @@ static void time_print_date(time_t date, const char *command) if (date == 0 || date == LONG_MAX) return; - t = localtime(&date); + t = gmtime(&date); if (command != NULL) /* * Need a contiguous string (no whitespaces), hence using -- cgit v1.2.3 From 1201871343223d9781253283a64686be4e63ad52 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 23 May 2011 17:48:20 +0200 Subject: libxt_time: --utc and --localtz are mutually exclusive Signed-off-by: Jan Engelhardt --- extensions/libxt_time.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c index 67b7f45d..dfb0d5b7 100644 --- a/extensions/libxt_time.c +++ b/extensions/libxt_time.c @@ -26,6 +26,8 @@ enum { O_WEEKDAYS, O_LOCAL_TZ, O_UTC, + F_LOCAL_TZ = 1 << O_LOCAL_TZ, + F_UTC = 1 << O_UTC, }; static const char *const week_days[] = { @@ -41,8 +43,10 @@ static const struct xt_option_entry time_opts[] = { .flags = XTOPT_INVERT}, {.name = "monthdays", .id = O_MONTHDAYS, .type = XTTYPE_STRING, .flags = XTOPT_INVERT}, - {.name = "localtz", .id = O_LOCAL_TZ, .type = XTTYPE_NONE}, - {.name = "utc", .id = O_UTC, .type = XTTYPE_NONE}, + {.name = "localtz", .id = O_LOCAL_TZ, .type = XTTYPE_NONE, + .excl = F_UTC}, + {.name = "utc", .id = O_UTC, .type = XTTYPE_NONE, + .excl = F_LOCAL_TZ}, XTOPT_TABLEEND, }; -- cgit v1.2.3 From db50b83bc3cd634beb71f38978ad7d035c88ff11 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 23 May 2011 18:38:09 +0200 Subject: libxt_time: deprecate --localtz option, document kernel TZ caveats Comparing against the kernel time zone has significant caveats. This patch adds documentation about the issue, and makes --utc the default setting for libxt_time. Furthremore, throw a warning on using the "--localtz" option, to avoid confusion with one's shell TZ environment variable, and rename it to "--kerneltz" to be explicit about whose timezone will be used. Signed-off-by: Jan Engelhardt --- extensions/libxt_time.c | 24 ++++++++++++++---------- extensions/libxt_time.man | 39 +++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c index dfb0d5b7..44c05b8f 100644 --- a/extensions/libxt_time.c +++ b/extensions/libxt_time.c @@ -26,8 +26,10 @@ enum { O_WEEKDAYS, O_LOCAL_TZ, O_UTC, + O_KERNEL_TZ, F_LOCAL_TZ = 1 << O_LOCAL_TZ, F_UTC = 1 << O_UTC, + F_KERNEL_TZ = 1 << O_KERNEL_TZ, }; static const char *const week_days[] = { @@ -46,7 +48,9 @@ static const struct xt_option_entry time_opts[] = { {.name = "localtz", .id = O_LOCAL_TZ, .type = XTTYPE_NONE, .excl = F_UTC}, {.name = "utc", .id = O_UTC, .type = XTTYPE_NONE, - .excl = F_LOCAL_TZ}, + .excl = F_LOCAL_TZ | F_KERNEL_TZ}, + {.name = "kerneltz", .id = O_KERNEL_TZ, .type = XTTYPE_NONE, + .excl = F_UTC}, XTOPT_TABLEEND, }; @@ -63,7 +67,7 @@ static void time_help(void) "[!] --weekdays value List of weekdays on which to match, sep. by comma\n" " (Possible days: Mon,Tue,Wed,Thu,Fri,Sat,Sun or 1 to 7\n" " Defaults to all weekdays.)\n" -" --localtz/--utc Time is interpreted as UTC/local time\n"); +" --kerneltz Work with the kernel timezone instead of UTC\n"); } static void time_init(struct xt_entry_match *m) @@ -79,9 +83,6 @@ static void time_init(struct xt_entry_match *m) /* ...and have no date-begin or date-end boundary */ info->date_start = 0; info->date_stop = INT_MAX; - - /* local time is default */ - info->flags |= XT_TIME_LOCAL_TZ; } static time_t time_parse_date(const char *s, bool end) @@ -273,6 +274,12 @@ static void time_parse(struct xt_option_call *cb) info->daytime_stop = time_parse_minutes(cb->arg); break; case O_LOCAL_TZ: + fprintf(stderr, "WARNING: --localtz is being replaced by " + "--kerneltz, since \"local\" is ambiguous. Note the " + "kernel timezone has caveats - " + "see manpage for details.\n"); + /* fallthrough */ + case O_KERNEL_TZ: info->flags |= XT_TIME_LOCAL_TZ; break; case O_MONTHDAYS: @@ -285,9 +292,6 @@ static void time_parse(struct xt_option_call *cb) if (cb->invert) info->weekdays_match ^= XT_TIME_ALL_WEEKDAYS; break; - case O_UTC: - info->flags &= ~XT_TIME_LOCAL_TZ; - break; } } @@ -423,8 +427,8 @@ static void time_save(const void *ip, const struct xt_entry_match *match) } time_print_date(info->date_start, "--datestart"); time_print_date(info->date_stop, "--datestop"); - if (!(info->flags & XT_TIME_LOCAL_TZ)) - printf(" --utc"); + if (info->flags & XT_TIME_LOCAL_TZ) + printf(" --kerneltz"); } static struct xtables_match time_match = { diff --git a/extensions/libxt_time.man b/extensions/libxt_time.man index 4aff7ff5..1d677b94 100644 --- a/extensions/libxt_time.man +++ b/extensions/libxt_time.man @@ -1,5 +1,6 @@ This matches if the packet arrival time/date is within a given range. All -options are optional, but are ANDed when specified. +options are optional, but are ANDed when specified. All times are interpreted +as UTC by default. .TP \fB\-\-datestart\fP \fIYYYY\fP[\fB\-\fP\fIMM\fP[\fB\-\fP\fIDD\fP[\fBT\fP\fIhh\fP[\fB:\fP\fImm\fP[\fB:\fP\fIss\fP]]]]] .TP @@ -29,13 +30,35 @@ Only match on the given weekdays. Possible values are \fBMon\fP, \fBTue\fP, to \fB7\fP, respectively. You may also use two-character variants (\fBMo\fP, \fBTu\fP, etc.). .TP -\fB\-\-utc\fP -Interpret the times given for \fB\-\-datestart\fP, \fB\-\-datestop\fP, -\fB\-\-timestart\fP and \fB\-\-timestop\fP to be UTC. -.TP -\fB\-\-localtz\fP -Interpret the times given for \fB\-\-datestart\fP, \fB\-\-datestop\fP, -\fB\-\-timestart\fP and \fB\-\-timestop\fP to be local kernel time. (Default) +\fB\-\-kerneltz\fP +Use the kernel timezone instead of UTC to determine whether a packet meets the +time regulations. +.PP +About kernel timezones: Linux keeps the system time in UTC, and always does so. +On boot, system time is initialized from a referential time source. Where this +time source has no timezone information, such as the x86 CMOS RTC, UTC will be +assumed. If the time source is however not in UTC, userspace should provide the +correct system time and timezone to the kernel once it has the information. +.PP +Local time is a feature on top of the (timezone independent) system time. Each +process has its own idea of local time, specified via the TZ environment +variable. The kernel also has its own timezone offset variable. The TZ +userspace environment variable specifies how the UTC-based system time is +displayed, e.g. when you run date(1), or what you see on your desktop clock. +The TZ string may resolve to different offsets at different dates, which is +what enables the automatic time-jumping in userspace. when DST changes. The +kernel's timezone offset variable is used when it has to convert between +non-UTC sources, such as FAT filesystems, to UTC (since the latter is what the +rest of the system uses). +.PP +The caveat with the kernel timezone is that Linux distributions may ignore to +set the kernel timezone, and instead only set the system time. Even if a +particular distribution does set the timezone at boot, it is usually does not +keep the kernel timezone offset - which is what changes on DST - up to date. +ntpd will not touch the kernel timezone, so running it will not resolve the +issue. As such, one may encounter a timezone that is always +0000, or one that +is wrong half of the time of the year. As such, \fBusing \-\-kerneltz is highly +discouraged.\fP .PP EXAMPLES. To match on weekends, use: .IP -- cgit v1.2.3