Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: iptables: Devel

Re: u32 extension

 

 

iptables devel RSS feed   Index | Next | Previous | View Threaded


jengelh at computergmbh

Sep 10, 2007, 3:28 AM

Post #1 of 5 (7081 views)
Permalink
Re: u32 extension

On Sep 10 2007 11:18, Patrick McHardy wrote:
>Hi Jan,
>
>I just noticed the u32 extension is missing from iptables.
>Could you send me your latest version please.
>


Adds u32 to iptables.

Signed-off-by: Jan Engelhardt <jengelh [at] gmx>

---

symlink extensions/libip6t_u32.man -> extensions/libipt_u32.man

extensions/Makefile | 2
extensions/libipt_u32.man | 129 ++++++++++++++++
extensions/libxt_u32.c | 307 +++++++++++++++++++++++++++++++++++++++
include/linux/netfilter/xt_u32.h | 40 +++++
4 files changed, 477 insertions(+), 1 deletion(-)

Index: iptables/extensions/Makefile
===================================================================
--- iptables.orig/extensions/Makefile
+++ iptables/extensions/Makefile
@@ -7,7 +7,7 @@
#
PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE

PF_EXT_SELINUX_SLIB:=
PF6_EXT_SELINUX_SLIB:=
Index: iptables/extensions/libipt_u32.man
===================================================================
--- /dev/null
+++ iptables/extensions/libipt_u32.man
@@ -0,0 +1,129 @@
+U32 tests whether quantities of up to 4 bytes extracted from a packet have
+specified values. The specification of what to extract is general enough to
+find data at given offsets from tcp headers or payloads.
+.TP
+[\fB!\fR]\fB --u32 \fItests\fR
+The argument amounts to a program in a small language described below.
+.IP
+tests := location "=" value | tests "&&" location "=" value
+.IP
+value := range | value "," range
+.IP
+range := number | number ":" number
+.PP
+a single number, \fIn\fR, is interpreted the same as \fIn:n\fR. \fIn:m\fR is
+interpreted as the range of numbers \fB>=n\fR and \fB<=m\fR.
+.IP "" 4
+location := number | location operator number
+.IP "" 4
+operator := "&" | "<<" | ">>" | "@"
+.PP
+The operators \fB&\fR, \fB<<\fR, \fB>>\fR and \fB&&\fR mean the same as in C.
+The \fB=\fR is really a set membership operator and the value syntax describes
+a set. The \fB@\fR operator is what allows moving to the next header and is
+described further below.
+.PP
+There are currently some artificial implementation limits on the size of the
+tests:
+.IP " *"
+no more than 10 of "\fB=\fR" (and 9 "\fB&&\fR"s) in the u32 argument
+.IP " *"
+no more than 10 ranges (and 9 commas) per value
+.IP " *"
+no more than 10 numbers (and 9 operators) per location
+.PP
+To describe the meaning of location, imagine the following machine that
+interprets it. There are three registers:
+.IP
+A is of type \fBchar *\fR, initially the address of the IP header
+.IP
+B and C are unsigned 32 bit integers, initially zero
+.PP
+The instructions are:
+.IP
+number B = number;
+.IP
+C = (*(A+B)<<24) + (*(A+B+1)<<16) + (*(A+B+2)<<8) + *(A+B+3)
+.IP
+&number C = C & number
+.IP
+<< number C = C << number
+.IP
+>> number C = C >> number
+.IP
+@number A = A + C; then do the instruction number
+.PP
+Any access of memory outside [skb->data,skb->end] causes the match to fail.
+Otherwise the result of the computation is the final value of C.
+.PP
+Whitespace is allowed but not required in the tests. However, the characters
+that do occur there are likely to require shell quoting, so it is a good idea
+to enclose the arguments in quotes.
+.PP
+Example:
+.IP
+match IP packets with total length >= 256
+.IP
+The IP header contains a total length field in bytes 2-3.
+.IP
+--u32 "\fB0 & 0xFFFF = 0x100:0xFFFF\fR"
+.IP
+read bytes 0-3
+.IP
+AND that with 0xFFFF (giving bytes 2-3), and test whether that is in the range
+[0x100:0xFFFF]
+.PP
+Example: (more realistic, hence more complicated)
+.IP
+match ICMP packets with icmp type 0
+.IP
+First test that it is an ICMP packet, true iff byte 9 (protocol) = 1
+.IP
+--u32 "\fB6 & 0xFF = 1 &&\fR ...
+.IP
+read bytes 6-9, use \fB&\fR to throw away bytes 6-8 and compare the result to
+1. Next test that it is not a fragment. (If so, it might be part of such a
+packet but we cannot always tell.) N.B.: This test is generally needed if you
+want to match anything beyond the IP header. The last 6 bits of byte 6 and all
+of byte 7 are 0 iff this is a complete packet (not a fragment). Alternatively,
+you can allow first fragments by only testing the last 5 bits of byte 6.
+.IP
+ ... \fB4 & 0x3FFF = 0 &&\fR ...
+.IP
+Last test: the first byte past the IP header (the type) is 0. This is where we
+have to use the @syntax. The length of the IP header (IHL) in 32 bit words is
+stored in the right half of byte 0 of the IP header itself.
+.IP
+ ... \fB0 >> 22 & 0x3C @ 0 >> 24 = 0\fR"
+.IP
+The first 0 means read bytes 0-3, \fB>>22\fR means shift that 22 bits to the
+right. Shifting 24 bits would give the first byte, so only 22 bits is four
+times that plus a few more bits. \fB&3C\fR then eliminates the two extra bits
+on the right and the first four bits of the first byte. For instance, if IHL=5,
+then the IP header is 20 (4 x 5) bytes long. In this case, bytes 0-1 are (in
+binary) xxxx0101 yyzzzzzz, \fB>>22\fR gives the 10 bit value xxxx0101yy and
+\fB&3C\fR gives 010100. \fB@\fR means to use this number as a new offset into
+the packet, and read four bytes starting from there. This is the first 4 bytes
+of the ICMP payload, of which byte 0 is the ICMP type. Therefore, we simply
+shift the value 24 to the right to throw out all but the first byte and compare
+the result with 0.
+.PP
+Example:
+.IP
+TCP payload bytes 8-12 is any of 1, 2, 5 or 8
+.IP
+First we test that the packet is a tcp packet (similar to ICMP).
+.IP
+--u32 "\fB6 & 0xFF = 6 &&\fR ...
+.IP
+Next, test that it is not a fragment (same as above).
+.IP
+ ... \fB0 >> 22 & 0x3C @ 12 >> 26 & 0x3C @ 8 = 1,2,5,8\fR"
+.IP
+\fB0>>22&3C\fR as above computes the number of bytes in the IP header. \fB@\fR
+makes this the new offset into the packet, which is the start of the TCP
+header. The length of the TCP header (again in 32 bit words) is the left half
+of byte 12 of the TCP header. The \fB12>>26&3C\fR computes this length in bytes
+(similar to the IP header before). "@" makes this the new offset, which is the
+start of the TCP payload. Finally, 8 reads bytes 8-12 of the payload and
+\fB=\fR checks whether the result is any of 1, 2, 5 or 8.
Index: iptables/extensions/libxt_u32.c
===================================================================
--- /dev/null
+++ iptables/extensions/libxt_u32.c
@@ -0,0 +1,307 @@
+/* Shared library add-on to iptables to add u32 matching,
+ * generalized matching on values found at packet offsets
+ *
+ * Detailed doc is in the kernel module source
+ * net/netfilter/xt_u32.c
+ *
+ * (C) 2002 by Don Cohen <don-netf [at] isis>
+ * Copyright © Jan Engelhardt <jengelh [at] gmx>, 2007
+ * Released under the terms of GNU GPL v2
+ */
+#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <xtables.h>
+#include "../include/linux/netfilter/xt_u32.h"
+
+static const struct option u32_opts[] = {
+ {"u32", 1, NULL, 'u'},
+ {NULL},
+};
+
+static void u32_help(void)
+{
+ printf(
+ "u32 v%s options:\n"
+ "[!] --u32 tests\n"
+ "\t\t""tests := location \"=\" value | tests \"&&\" location \"=\" value\n"
+ "\t\t""value := range | value \",\" range\n"
+ "\t\t""range := number | number \":\" number\n"
+ "\t\t""location := number | location operator number\n"
+ "\t\t""operator := \"&\" | \"<<\" | \">>\" | \"@\"\n",
+ IPTABLES_VERSION);
+ return;
+}
+
+static void u32_dump(const struct xt_u32 *data)
+{
+ const struct xt_u32_test *ct;
+ unsigned int testind, i;
+
+ for (testind = 0; testind < data->ntests; ++testind) {
+ ct = &data->tests[testind];
+
+ if (testind > 0)
+ printf("&&");
+
+ printf("0x%x", ct->location[0].number);
+ for (i = 1; i < ct->nnums; ++i) {
+ switch (ct->location[i].nextop) {
+ case XT_U32_AND:
+ printf("&");
+ break;
+ case XT_U32_LEFTSH:
+ printf("<<");
+ break;
+ case XT_U32_RIGHTSH:
+ printf(">>");
+ break;
+ case XT_U32_AT:
+ printf("@");
+ break;
+ }
+ printf("0x%x", ct->location[i].number);
+ }
+
+ printf("=");
+ for (i = 0; i < ct->nvalues; ++i) {
+ if (i > 0)
+ printf(",");
+ if (ct->value[i].min == ct->value[i].max)
+ printf("0x%x", ct->value[i].min);
+ else
+ printf("0x%x:0x%x", ct->value[i].min,
+ ct->value[i].max);
+ }
+ }
+ printf(" ");
+}
+
+/* string_to_number() is not quite what we need here ... */
+static u_int32_t parse_number(char **s, int pos)
+{
+ u_int32_t number;
+ char *end;
+
+ errno = 0;
+ number = strtoul(*s, &end, 0);
+ if (end == *s)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %d: expected number", pos);
+ if (errno != 0)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %d: error reading number", pos);
+ *s = end;
+ return number;
+}
+
+/* Function which parses command options; returns true if it ate an option */
+static int u32_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct xt_u32 *data = (void *)(*match)->data;
+ unsigned int testind = 0, locind = 0, valind = 0;
+ struct xt_u32_test *ct = &data->tests[testind]; /* current test */
+ char *arg = argv[optind-1]; /* the argument string */
+ char *start = arg;
+ int state = 0;
+
+ if (c != 'u')
+ return 0;
+
+ data->invert = invert;
+
+ /*
+ * states:
+ * 0 = looking for numbers and operations,
+ * 1 = looking for ranges
+ */
+ while (1) {
+ /* read next operand/number or range */
+ while (isspace(*arg))
+ ++arg;
+
+ if (*arg == '\0') {
+ /* end of argument found */
+ if (state == 0)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: abrupt end of input after location specifier");
+ if (valind == 0)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: test ended with no value specified");
+
+ ct->nnums = locind;
+ ct->nvalues = valind;
+ data->ntests = ++testind;
+
+ if (testind > XT_U32_MAXSIZE)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: too many \"&&\"s",
+ arg - start);
+ return 1;
+ }
+
+ if (state == 0) {
+ /*
+ * reading location: read a number if nothing read yet,
+ * otherwise either op number or = to end location spec
+ */
+ if (*arg == '=') {
+ if (locind == 0) {
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: "
+ "location spec missing",
+ arg - start);
+ } else {
+ ++arg;
+ state = 1;
+ }
+ } else {
+ if (locind != 0) {
+ /* need op before number */
+ if (*arg == '&') {
+ ct->location[locind].nextop = XT_U32_AND;
+ } else if (*arg == '<') {
+ if (*++arg != '<')
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: a second < expected", arg - start);
+ ct->location[locind].nextop = XT_U32_LEFTSH;
+ } else if (*arg == '>') {
+ if (*++arg != '>')
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: a second > expected", arg - start);
+ ct->location[locind].nextop = XT_U32_RIGHTSH;
+ } else if (*arg == '@') {
+ ct->location[locind].nextop = XT_U32_AT;
+ } else {
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: operator expected", arg - start);
+ }
+ ++arg;
+ }
+ /* now a number; string_to_number skips white space? */
+ ct->location[locind].number =
+ parse_number(&arg, arg - start);
+ if (++locind > XT_U32_MAXSIZE)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: too many operators", arg - start);
+ }
+ } else {
+ /*
+ * state 1 - reading values: read a range if nothing
+ * read yet, otherwise either ,range or && to end
+ * test spec
+ */
+ if (*arg == '&') {
+ if (*++arg != '&')
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: a second & was expected", arg - start);
+ if (valind == 0) {
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: value spec missing", arg - start);
+ } else {
+ ct->nnums = locind;
+ ct->nvalues = valind;
+ ct = &data->tests[++testind];
+ if (testind > XT_U32_MAXSIZE)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: too many \"&&\"s", arg - start);
+ ++arg;
+ state = 0;
+ locind = 0;
+ valind = 0;
+ }
+ } else { /* read value range */
+ if (valind > 0) { /* need , before number */
+ if (*arg != ',')
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: expected , or &&", arg - start);
+ ++arg;
+ }
+ ct->value[valind].min =
+ parse_number(&arg, arg - start);
+
+ while (isspace(*arg))
+ ++arg;
+
+ if (*arg == ':') {
+ ++arg;
+ ct->value[valind].max =
+ parse_number(&arg, arg-start);
+ } else {
+ ct->value[valind].max =
+ ct->value[valind].min;
+ }
+
+ if (++valind > XT_U32_MAXSIZE)
+ exit_error(PARAMETER_PROBLEM,
+ "u32: at char %u: too many \",\"s", arg - start);
+ }
+ }
+ }
+}
+
+static void u32_check(unsigned int flags)
+{
+}
+
+static void u32_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ const struct xt_u32 *data = (const void *)match->data;
+ printf("u32 ");
+ if (data->invert)
+ printf("! ");
+ u32_dump(data);
+ return;
+}
+
+static void u32_save(const void *ip, const struct xt_entry_match *match)
+{
+ const struct xt_u32 *data = (const void *)match->data;
+ if (data->invert)
+ printf("! ");
+ printf("--u32 ");
+ u32_dump(data);
+ return;
+}
+
+static struct xtables_match u32_reg = {
+ .name = "u32",
+ .version = IPTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_u32)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_u32)),
+ .help = u32_help,
+ .parse = u32_parse,
+ .final_check = u32_check,
+ .print = u32_print,
+ .save = u32_save,
+ .extra_opts = u32_opts,
+};
+
+static struct xtables_match u32_reg6 = {
+ .name = "u32",
+ .family = AF_INET6,
+ .version = IPTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_u32)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_u32)),
+ .help = u32_help,
+ .parse = u32_parse,
+ .final_check = u32_check,
+ .print = u32_print,
+ .save = u32_save,
+ .extra_opts = u32_opts,
+};
+
+void _init(void)
+{
+ xtables_register_match(&u32_reg);
+ xtables_register_match(&u32_reg6);
+ return;
+}
Index: iptables/include/linux/netfilter/xt_u32.h
===================================================================
--- /dev/null
+++ iptables/include/linux/netfilter/xt_u32.h
@@ -0,0 +1,40 @@
+#ifndef _XT_U32_H
+#define _XT_U32_H 1
+
+enum xt_u32_ops {
+ XT_U32_AND,
+ XT_U32_LEFTSH,
+ XT_U32_RIGHTSH,
+ XT_U32_AT,
+};
+
+struct xt_u32_location_element {
+ u_int32_t number;
+ u_int8_t nextop;
+};
+
+struct xt_u32_value_element {
+ u_int32_t min;
+ u_int32_t max;
+};
+
+/*
+ * Any way to allow for an arbitrary number of elements?
+ * For now, I settle with a limit of 10 each.
+ */
+#define XT_U32_MAXSIZE 10
+
+struct xt_u32_test {
+ struct xt_u32_location_element location[XT_U32_MAXSIZE+1];
+ struct xt_u32_value_element value[XT_U32_MAXSIZE+1];
+ u_int8_t nnums;
+ u_int8_t nvalues;
+};
+
+struct xt_u32 {
+ struct xt_u32_test tests[XT_U32_MAXSIZE+1];
+ u_int8_t ntests;
+ u_int8_t invert;
+};
+
+#endif /* _XT_U32_H */


kaber at trash

Sep 10, 2007, 3:33 AM

Post #2 of 5 (6774 views)
Permalink
Re: u32 extension [In reply to]

Jan Engelhardt wrote:
> On Sep 10 2007 11:18, Patrick McHardy wrote:
>
>>Hi Jan,
>>
>>I just noticed the u32 extension is missing from iptables.
>>Could you send me your latest version please.
>>
>
>
>
> Adds u32 to iptables.


Applied, thanks Jan.

> symlink extensions/libip6t_u32.man -> extensions/libipt_u32.man


I copied it and fixed a bunch of warnings on 64 bit:

extensions/libxt_u32.c: In function 'u32_parse':
extensions/libxt_u32.c:146: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:160: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:173: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:178: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:184: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:193: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:204: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:207: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:214: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:224: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'
extensions/libxt_u32.c:244: warning: format '%u' expects type 'unsigned
int', but argument 3 has type 'long int'


jengelh at computergmbh

Sep 10, 2007, 3:39 AM

Post #3 of 5 (6773 views)
Permalink
Re: u32 extension [In reply to]

On Sep 10 2007 12:33, Patrick McHardy wrote:
>Jan Engelhardt wrote:
>> On Sep 10 2007 11:18, Patrick McHardy wrote:
>>>
>>>I just noticed the u32 extension is missing from iptables.
>>>Could you send me your latest version please.
>>
>> Adds u32 to iptables.
>
>Applied, thanks Jan.
>
>> symlink extensions/libip6t_u32.man -> extensions/libipt_u32.man
>
>I copied it and fixed a bunch of warnings on 64 bit:
>
>extensions/libxt_u32.c: In function 'u32_parse':
>extensions/libxt_u32.c:146: warning: format '%u' expects type 'unsigned
>int', but argument 3 has type 'long int'

argument 3 is actually of type ptrdiff_t, but whatever :)
Yeah should be %lu.


Jan
--


jengelh at computergmbh

Sep 15, 2007, 8:28 AM

Post #4 of 5 (6931 views)
Permalink
Re: u32 extension [In reply to]

On Sep 10 2007 12:39, Jan Engelhardt wrote:
>On Sep 10 2007 12:33, Patrick McHardy wrote:
>>Jan Engelhardt wrote:
>>> On Sep 10 2007 11:18, Patrick McHardy wrote:
>>>>
>>>>I just noticed the u32 extension is missing from iptables.
>>>>Could you send me your latest version please.
>>>
>>> Adds u32 to iptables.
>>
>>Applied, thanks Jan.
>>
>>> symlink extensions/libip6t_u32.man -> extensions/libipt_u32.man
>>
>>I copied it and fixed a bunch of warnings on 64 bit:
>>
>>extensions/libxt_u32.c: In function 'u32_parse':
>>extensions/libxt_u32.c:146: warning: format '%u' expects type 'unsigned
>>int', but argument 3 has type 'long int'
>
>argument 3 is actually of type ptrdiff_t, but whatever :)
>Yeah should be %lu.

Ha, not! On i586 (iptables-svn7047) I now get:

warning: format '%ld' expects type 'long int', but argument 3 has type 'int'.

Oh well, oh well. Patch below.
===


With %u alone, you would get "but arg-start is long" warnings on x64.
With %lu, you would get "but arg-start is int" on x86.
Fix it up by explicitly deciding for one (%u and cast to unsigned int)
and using that.

---
extensions/libxt_u32.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)

Index: iptables/extensions/libxt_u32.c
===================================================================
--- iptables.orig/extensions/libxt_u32.c
+++ iptables/extensions/libxt_u32.c
@@ -142,8 +142,8 @@ static int u32_parse(int c, char **argv,

if (testind > XT_U32_MAXSIZE)
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: too many \"&&\"s",
- arg - start);
+ "u32: at char %u: too many \"&&\"s",
+ (unsigned int)(arg - start));
return 1;
}

@@ -155,9 +155,9 @@ static int u32_parse(int c, char **argv,
if (*arg == '=') {
if (locind == 0) {
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: "
+ "u32: at char %u: "
"location spec missing",
- arg - start);
+ (unsigned int)(arg - start));
} else {
++arg;
state = 1;
@@ -170,18 +170,18 @@ static int u32_parse(int c, char **argv,
} else if (*arg == '<') {
if (*++arg != '<')
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: a second < expected", arg - start);
+ "u32: at char %u: a second '<' was expected", (unsigned int)(arg - start));
ct->location[locind].nextop = XT_U32_LEFTSH;
} else if (*arg == '>') {
if (*++arg != '>')
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: a second > expected", arg - start);
+ "u32: at char %u: a second '>' was expected", (unsigned int)(arg - start));
ct->location[locind].nextop = XT_U32_RIGHTSH;
} else if (*arg == '@') {
ct->location[locind].nextop = XT_U32_AT;
} else {
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: operator expected", arg - start);
+ "u32: at char %u: operator expected", (unsigned int)(arg - start));
}
++arg;
}
@@ -190,7 +190,7 @@ static int u32_parse(int c, char **argv,
parse_number(&arg, arg - start);
if (++locind > XT_U32_MAXSIZE)
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: too many operators", arg - start);
+ "u32: at char %u: too many operators", (unsigned int)(arg - start));
}
} else {
/*
@@ -201,17 +201,17 @@ static int u32_parse(int c, char **argv,
if (*arg == '&') {
if (*++arg != '&')
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: a second & was expected", arg - start);
+ "u32: at char %u: a second '&' was expected", (unsigned int)(arg - start));
if (valind == 0) {
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: value spec missing", arg - start);
+ "u32: at char %u: value spec missing", (unsigned int)(arg - start));
} else {
ct->nnums = locind;
ct->nvalues = valind;
ct = &data->tests[++testind];
if (testind > XT_U32_MAXSIZE)
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: too many \"&&\"s", arg - start);
+ "u32: at char %u: too many \"&&\"s", (unsigned int)(arg - start));
++arg;
state = 0;
locind = 0;
@@ -221,7 +221,7 @@ static int u32_parse(int c, char **argv,
if (valind > 0) { /* need , before number */
if (*arg != ',')
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: expected , or &&", arg - start);
+ "u32: at char %u: expected \",\" or \"&&\"", (unsigned int)(arg - start));
++arg;
}
ct->value[valind].min =
@@ -241,7 +241,7 @@ static int u32_parse(int c, char **argv,

if (++valind > XT_U32_MAXSIZE)
exit_error(PARAMETER_PROBLEM,
- "u32: at char %ld: too many \",\"s", arg - start);
+ "u32: at char %u: too many \",\"s", (unsigned int)(arg - start));
}
}
}


kaber at trash

Sep 19, 2007, 5:52 AM

Post #5 of 5 (6767 views)
Permalink
Re: u32 extension [In reply to]

Jan Engelhardt wrote:
> warning: format '%ld' expects type 'long int', but argument 3 has type 'int'.
>
> Oh well, oh well. Patch below.
> ===
>
>
> With %u alone, you would get "but arg-start is long" warnings on x64.
> With %lu, you would get "but arg-start is int" on x86.
> Fix it up by explicitly deciding for one (%u and cast to unsigned int)
> and using that.


Applied, thanks Jan.

iptables devel RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.