[OpenWrt-Devel] [PATCH] iptables: correctly parse non-options arguments with musl libc

Gianluca Anzolin gianluca at sottospazio.it
Mon Nov 17 02:03:07 EST 2014


musl libc doesn't support the GNU getopt extensions to parse non-options
arguments when the optstring starts with '-'.

Therefore perfectly valid iptables invocations like:

$ iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

don't work because getopt_long() returns -1 when it first finds the '!'
negation clause.

The patch adds a xgetopt_long() function which wraps around
getopt_long() taking care of the required behaviour and has no effect
when the getopt() implementation already knows how to handle the case.

The wrapper is used in iptables.c and ip6tables.c to parse their
options.

Signed-off-by: Gianluca Anzolin <gianluca at sottospazio.it>
---
 .../iptables/patches/310-musl_getopt_fixes.patch   | 63 ++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 package/network/utils/iptables/patches/310-musl_getopt_fixes.patch

diff --git a/package/network/utils/iptables/patches/310-musl_getopt_fixes.patch b/package/network/utils/iptables/patches/310-musl_getopt_fixes.patch
new file mode 100644
index 0000000..d656233
--- /dev/null
+++ b/package/network/utils/iptables/patches/310-musl_getopt_fixes.patch
@@ -0,0 +1,63 @@
+--- a/iptables/ip6tables.c
++++ b/iptables/ip6tables.c
+@@ -1357,7 +1357,7 @@ int do_command6(int argc, char *argv[],
+ 	opterr = 0;
+ 
+ 	opts = xt_params->orig_opts;
+-	while ((cs.c = getopt_long(argc, argv,
++	while ((cs.c = xgetopt_long(argc, argv,
+ 	   "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvwnt:m:xc:g:46",
+ 					   opts, NULL)) != -1) {
+ 		switch (cs.c) {
+--- a/iptables/iptables.c
++++ b/iptables/iptables.c
+@@ -1353,7 +1353,7 @@ int do_command4(int argc, char *argv[],
+ 	opterr = 0;
+ 
+ 	opts = xt_params->orig_opts;
+-	while ((cs.c = getopt_long(argc, argv,
++	while ((cs.c = xgetopt_long(argc, argv,
+ 	   "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvwnt:m:xc:g:46",
+ 					   opts, NULL)) != -1) {
+ 		switch (cs.c) {
+--- a/iptables/xshared.c
++++ b/iptables/xshared.c
+@@ -16,6 +16,26 @@
+ #define XT_SOCKET_LEN 8
+ 
+ /*
++ * simulate the behaviour of glibc when optstring starts with '-'
++ */
++int xgetopt_long(int argc, char * const argv[],
++		 const char *optstring,
++		 const struct option *longopts, int *longindex)
++{
++	int c = getopt_long(argc, argv, optstring, longopts, longindex);
++	if (c != -1)
++		return c;
++
++	if (optind < argc && optstring[0] == '-') {
++		optarg = argv[optind];
++		optind++;
++		return 1;
++	}
++
++	return 0;
++}
++
++/*
+  * Print out any special helps. A user might like to be able to add a --help
+  * to the commandline, and see expected results. So we call help for all
+  * specified matches and targets.
+--- a/iptables/xshared.h
++++ b/iptables/xshared.h
+@@ -75,6 +75,9 @@ enum {
+ 	XT_OPTION_OFFSET_SCALE = 256,
+ };
+ 
++extern int xgetopt_long(int argc, char * const argv[],
++			const char *optstring,
++			const struct option *longopts, int *longindex);
+ extern void print_extension_helps(const struct xtables_target *,
+ 	const struct xtables_rule_match *);
+ extern const char *proto_to_name(uint8_t, int);
-- 
2.1.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list