Fix 'iptables -p !' bug (segfault when `!' used without argument)
diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c
index 39d938a..529720f 100644
--- a/extensions/libip6t_LOG.c
+++ b/extensions/libip6t_LOG.c
@@ -114,7 +114,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --log-level twice");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --log-level");
 
@@ -127,7 +127,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --log-prefix twice");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --log-prefix");
 
diff --git a/extensions/libip6t_REJECT.c b/extensions/libip6t_REJECT.c
index ab8595d..a145f44 100644
--- a/extensions/libip6t_REJECT.c
+++ b/extensions/libip6t_REJECT.c
@@ -97,7 +97,7 @@
 
 	switch(c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --reject-with");
 		for (i = 0; i < limit; i++) {
diff --git a/extensions/libip6t_icmpv6.c b/extensions/libip6t_icmpv6.c
index 4185cad..97027da 100644
--- a/extensions/libip6t_icmpv6.c
+++ b/extensions/libip6t_icmpv6.c
@@ -168,8 +168,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		*nfcache |= parse_icmpv6(argv[optind-1],
 				       &icmpv6info->type,
 				       icmpv6info->code);
diff --git a/extensions/libip6t_ipv6header.c b/extensions/libip6t_ipv6header.c
index b1fcc04..6e4986d 100644
--- a/extensions/libip6t_ipv6header.c
+++ b/extensions/libip6t_ipv6header.c
@@ -200,8 +200,7 @@
 				exit_error(PARAMETER_PROBLEM,
 					"Only one `--header' allowed");
 
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 
 			if (! (info->matchflags = parse_header(argv[optind-1])) )
 				exit_error(PARAMETER_PROBLEM, "ip6t_ipv6header: cannot parse header names");
diff --git a/extensions/libip6t_length.c b/extensions/libip6t_length.c
index 71075ca..fe65115 100644
--- a/extensions/libip6t_length.c
+++ b/extensions/libip6t_length.c
@@ -87,8 +87,7 @@
 				exit_error(PARAMETER_PROBLEM,
 				           "length: `--length' may only be "
 				           "specified once");
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			parse_lengths(argv[optind-1], info);
 			if (invert)
 				info->invert = 1;
diff --git a/extensions/libip6t_limit.c b/extensions/libip6t_limit.c
index 837b0fe..4a0dc08 100644
--- a/extensions/libip6t_limit.c
+++ b/extensions/libip6t_limit.c
@@ -1,8 +1,9 @@
 /* Shared library add-on to iptables to add limit support.
  *
  * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
- * Hervé Eychenne   <eychenne@info.enserb.u-bordeaux.fr>
+ * Hervé Eychenne    <rv@wallfire.org>
  */
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -102,7 +103,7 @@
 
 	switch(c) {
 	case '%':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --limit");
 		if (!parse_rate(optarg, &r->avg))
@@ -111,7 +112,7 @@
 		break;
 
 	case '$':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --limit-burst");
 
diff --git a/extensions/libip6t_mac.c b/extensions/libip6t_mac.c
index e4c4345..64c62f2 100644
--- a/extensions/libip6t_mac.c
+++ b/extensions/libip6t_mac.c
@@ -72,8 +72,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_mac(argv[optind-1], macinfo);
 		if (invert)
 			macinfo->invert = 1;
diff --git a/extensions/libip6t_mark.c b/extensions/libip6t_mark.c
index b344bb6..7a05d03 100644
--- a/extensions/libip6t_mark.c
+++ b/extensions/libip6t_mark.c
@@ -45,8 +45,7 @@
 	switch (c) {
 		char *end;
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		markinfo->mark = strtoul(optarg, &end, 0);
 		if (*end == '/') {
 			markinfo->mask = strtoul(end+1, &end, 0);
diff --git a/extensions/libip6t_owner.c b/extensions/libip6t_owner.c
index 4eed251..8b511d9 100644
--- a/extensions/libip6t_owner.c
+++ b/extensions/libip6t_owner.c
@@ -55,8 +55,7 @@
 		struct passwd *pwd;
 		struct group *grp;
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		if ((pwd = getpwnam(optarg)))
 			ownerinfo->uid = pwd->pw_uid;
@@ -72,8 +71,7 @@
 		break;
 
 	case '2':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		if ((grp = getgrnam(optarg)))
 			ownerinfo->gid = grp->gr_gid;
 		else {
@@ -88,8 +86,7 @@
 		break;
 
 	case '3':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		ownerinfo->pid = strtoul(optarg, &end, 0);
 		if (*end != '\0' || end == optarg)
 			exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
@@ -100,8 +97,7 @@
 		break;
 
 	case '4':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		ownerinfo->sid = strtoul(optarg, &end, 0);
 		if (*end != '\0' || end == optarg)
 			exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
diff --git a/extensions/libip6t_tcp.c b/extensions/libip6t_tcp.c
index f03f072..d158a8c 100644
--- a/extensions/libip6t_tcp.c
+++ b/extensions/libip6t_tcp.c
@@ -178,8 +178,7 @@
 		if (*flags & TCP_SRC_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--source-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_ports(argv[optind-1], tcpinfo->spts);
 		if (invert)
 			tcpinfo->invflags |= IP6T_TCP_INV_SRCPT;
@@ -191,8 +190,7 @@
 		if (*flags & TCP_DST_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--destination-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_ports(argv[optind-1], tcpinfo->dpts);
 		if (invert)
 			tcpinfo->invflags |= IP6T_TCP_INV_DSTPT;
@@ -215,8 +213,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one of `--syn' or `--tcp-flags' "
 				   " allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		if (!argv[optind]
 		    || argv[optind][0] == '-' || argv[optind][0] == '!')
@@ -232,8 +229,7 @@
 		if (*flags & TCP_OPTION)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--tcp-option' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_option(argv[optind-1], &tcpinfo->option);
 		if (invert)
 			tcpinfo->invflags |= IP6T_TCP_INV_OPTION;
diff --git a/extensions/libip6t_udp.c b/extensions/libip6t_udp.c
index 441c814..5378e59 100644
--- a/extensions/libip6t_udp.c
+++ b/extensions/libip6t_udp.c
@@ -100,8 +100,7 @@
 		if (*flags & UDP_SRC_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--source-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_udp_ports(argv[optind-1], udpinfo->spts);
 		if (invert)
 			udpinfo->invflags |= IP6T_UDP_INV_SRCPT;
@@ -113,8 +112,7 @@
 		if (*flags & UDP_DST_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--destination-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_udp_ports(argv[optind-1], udpinfo->dpts);
 		if (invert)
 			udpinfo->invflags |= IP6T_UDP_INV_DSTPT;
diff --git a/extensions/libipt_BALANCE.c b/extensions/libipt_BALANCE.c
index 75f4cda..78d5d2d 100644
--- a/extensions/libipt_BALANCE.c
+++ b/extensions/libipt_BALANCE.c
@@ -77,7 +77,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-destination");
 
diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c
index 3e466ae..279f76e 100644
--- a/extensions/libipt_DNAT.c
+++ b/extensions/libipt_DNAT.c
@@ -153,7 +153,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-destination");
 
diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c
index 68a9f65..1445f08 100644
--- a/extensions/libipt_LOG.c
+++ b/extensions/libipt_LOG.c
@@ -114,7 +114,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --log-level twice");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --log-level");
 
@@ -127,7 +127,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --log-prefix twice");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --log-prefix");
 
diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c
index 0eecba5..a45285a 100644
--- a/extensions/libipt_MASQUERADE.c
+++ b/extensions/libipt_MASQUERADE.c
@@ -94,7 +94,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Need TCP or UDP with port specification");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-ports");
 
diff --git a/extensions/libipt_NETLINK.c b/extensions/libipt_NETLINK.c
index 104e642..7855d99 100644
--- a/extensions/libipt_NETLINK.c
+++ b/extensions/libipt_NETLINK.c
@@ -48,7 +48,7 @@
 				exit_error(PARAMETER_PROBLEM,
 				"Can't specify --nldrop twice");
 
-			if ( check_inverse(optarg, &invert) ) {
+			if ( check_inverse(optarg, &invert, NULL, 0) ) {
 				MASK_UNSET(nld->flags, USE_DROP);
 			} else {
 				MASK_SET(nld->flags, USE_DROP);
@@ -62,7 +62,7 @@
 				exit_error(PARAMETER_PROBLEM,
 				"Can't specify --nlmark twice");
 
-			if (check_inverse(optarg, &invert)) {
+			if (check_inverse(optarg, &invert, NULL, 0)) {
 				MASK_UNSET(nld->flags, USE_MARK);
 			}else{
 				MASK_SET(nld->flags, USE_MARK);
@@ -81,7 +81,7 @@
 				"--nlsize must be larger than zero");
 			
 
-			if (check_inverse(optarg, &invert)) {
+			if (check_inverse(optarg, &invert, NULL, 0)) {
 				MASK_UNSET(nld->flags, USE_SIZE);
 			}else{
 				MASK_SET(nld->flags, USE_SIZE);
diff --git a/extensions/libipt_NETMAP.c b/extensions/libipt_NETMAP.c
index 947ca8d..9124157 100644
--- a/extensions/libipt_NETMAP.c
+++ b/extensions/libipt_NETMAP.c
@@ -128,7 +128,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --%s", opts[0].name);
 
diff --git a/extensions/libipt_REDIRECT.c b/extensions/libipt_REDIRECT.c
index 02afacf..ca029c8 100644
--- a/extensions/libipt_REDIRECT.c
+++ b/extensions/libipt_REDIRECT.c
@@ -94,7 +94,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Need TCP or UDP with port specification");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-ports");
 
diff --git a/extensions/libipt_REJECT.c b/extensions/libipt_REJECT.c
index 4316958..2403bef 100644
--- a/extensions/libipt_REJECT.c
+++ b/extensions/libipt_REJECT.c
@@ -97,7 +97,7 @@
 
 	switch(c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --reject-with");
 		for (i = 0; i < limit; i++) {
diff --git a/extensions/libipt_SAME.c b/extensions/libipt_SAME.c
index 59ef604..37c75d8 100644
--- a/extensions/libipt_SAME.c
+++ b/extensions/libipt_SAME.c
@@ -98,7 +98,7 @@
 				   "Too many ranges specified, maximum "
 				   "is %i ranges.\n",
 				   IPT_SAME_MAX_RANGE);
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to");
 
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
index 1af0d5e..9493a14 100644
--- a/extensions/libipt_SNAT.c
+++ b/extensions/libipt_SNAT.c
@@ -153,7 +153,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-source");
 
diff --git a/extensions/libipt_TTL.c b/extensions/libipt_TTL.c
index 0dc7351..e4d56b3 100644
--- a/extensions/libipt_TTL.c
+++ b/extensions/libipt_TTL.c
@@ -1,7 +1,7 @@
 /* Shared library add-on to iptables for the TTL target
  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
  *
- * $Id: libipt_TTL.c,v 1.3 2000/11/13 11:16:08 laforge Exp $
+ * $Id: libipt_TTL.c,v 1.4 2002/02/25 11:25:41 laforge Exp $
  *
  * This program is distributed under the terms of GNU GPL
  */
@@ -46,7 +46,7 @@
 		exit_error(PARAMETER_PROBLEM, 
 				"TTL: You must specify a value");
 
-	if (check_inverse(optarg, &invert))
+	if (check_inverse(optarg, &invert, NULL, 0))
 		exit_error(PARAMETER_PROBLEM,
 				"TTL: unexpected `!'");
 	
diff --git a/extensions/libipt_ULOG.c b/extensions/libipt_ULOG.c
index 5de8ee0..6a9c342 100644
--- a/extensions/libipt_ULOG.c
+++ b/extensions/libipt_ULOG.c
@@ -87,7 +87,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --ulog-nlgroup twice");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --ulog-nlgroup");
 		group_d = atoi(optarg);
@@ -105,7 +105,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --ulog-prefix twice");
 
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --ulog-prefix");
 
diff --git a/extensions/libipt_ah.c b/extensions/libipt_ah.c
index 0473760..8686326 100644
--- a/extensions/libipt_ah.c
+++ b/extensions/libipt_ah.c
@@ -92,8 +92,7 @@
 		if (*flags & AH_SPI)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--spi' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_ah_spis(argv[optind-1], ahinfo->spis);
 		if (invert)
 			ahinfo->invflags |= IPT_AH_INV_SPI;
diff --git a/extensions/libipt_connlimit.c b/extensions/libipt_connlimit.c
index 19928ac..a9a0f37 100644
--- a/extensions/libipt_connlimit.c
+++ b/extensions/libipt_connlimit.c
@@ -51,8 +51,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		info->limit = atoi(argv[optind-1]);
 		info->inverse = invert;
 		*flags |= 1;
diff --git a/extensions/libipt_connmark.c b/extensions/libipt_connmark.c
index e71d962..005050f 100644
--- a/extensions/libipt_connmark.c
+++ b/extensions/libipt_connmark.c
@@ -45,8 +45,7 @@
 	switch (c) {
 		char *end;
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		markinfo->mark = strtoul(optarg, &end, 0);
 		if (*end == '/') {
 			markinfo->mask = strtoul(end+1, &end, 0);
diff --git a/extensions/libipt_conntrack.c b/extensions/libipt_conntrack.c
index 9b63939..b15ade0 100644
--- a/extensions/libipt_conntrack.c
+++ b/extensions/libipt_conntrack.c
@@ -179,8 +179,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		parse_states(argv[optind-1], sinfo);
 		if (invert) {
@@ -190,8 +189,7 @@
 		break;
 
 	case '2':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optdind, 0);
 
 		if(invert)
 			sinfo->invflags |= IPT_CONNTRACK_PROTO;
@@ -212,8 +210,7 @@
 		break;
 
 	case '3':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 9);
 
 		if (invert)
 			sinfo->invflags |= IPT_CONNTRACK_ORIGSRC;
@@ -233,8 +230,7 @@
 		break;
 
 	case '4':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		if (invert)
 			sinfo->invflags |= IPT_CONNTRACK_ORIGDST;
@@ -254,8 +250,7 @@
 		break;
 
 	case '5':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		if (invert)
 			sinfo->invflags |= IPT_CONNTRACK_REPLSRC;
@@ -275,8 +270,7 @@
 		break;
 
 	case '6':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		if (invert)
 			sinfo->invflags |= IPT_CONNTRACK_REPLDST;
@@ -296,8 +290,7 @@
 		break;
 
 	case '7':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		parse_statuses(argv[optind-1], sinfo);
 		if (invert) {
@@ -307,8 +300,7 @@
 		break;
 
 	case '8':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		parse_expires(argv[optind-1], sinfo);
 		if (invert) {
diff --git a/extensions/libipt_esp.c b/extensions/libipt_esp.c
index 07d2515..8890ff7 100644
--- a/extensions/libipt_esp.c
+++ b/extensions/libipt_esp.c
@@ -92,8 +92,7 @@
 		if (*flags & ESP_SPI)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--spi' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_esp_spis(argv[optind-1], espinfo->spis);
 		if (invert)
 			espinfo->invflags |= IPT_ESP_INV_SPI;
diff --git a/extensions/libipt_helper.c b/extensions/libipt_helper.c
index ddb42ee..92ade93 100644
--- a/extensions/libipt_helper.c
+++ b/extensions/libipt_helper.c
@@ -44,8 +44,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &invert, 0);
 		strncpy(info->name, optarg, 29);
 		if (invert)
 			info->invert = 1;
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index 8d2d85d..98098fa 100644
--- a/extensions/libipt_icmp.c
+++ b/extensions/libipt_icmp.c
@@ -183,8 +183,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		*nfcache |= parse_icmp(argv[optind-1],
 				       &icmpinfo->type,
 				       icmpinfo->code);
diff --git a/extensions/libipt_length.c b/extensions/libipt_length.c
index 00326c4..cd5a6a8 100644
--- a/extensions/libipt_length.c
+++ b/extensions/libipt_length.c
@@ -85,8 +85,7 @@
 				exit_error(PARAMETER_PROBLEM,
 				           "length: `--length' may only be "
 				           "specified once");
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			parse_lengths(argv[optind-1], info);
 			if (invert)
 				info->invert = 1;
diff --git a/extensions/libipt_limit.c b/extensions/libipt_limit.c
index 73f9b37..2839547 100644
--- a/extensions/libipt_limit.c
+++ b/extensions/libipt_limit.c
@@ -1,8 +1,9 @@
 /* Shared library add-on to iptables to add limit support.
  *
  * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
- * Hervé Eychenne   <eychenne@info.enserb.u-bordeaux.fr>
+ * Hervé Eychenne    <rv@wallfire.org>
  */
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -102,7 +103,7 @@
 
 	switch(c) {
 	case '%':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --limit");
 		if (!parse_rate(optarg, &r->avg))
@@ -111,7 +112,7 @@
 		break;
 
 	case '$':
-		if (check_inverse(optarg, &invert))
+		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --limit-burst");
 
diff --git a/extensions/libipt_mac.c b/extensions/libipt_mac.c
index 1b088a8..5779e8b 100644
--- a/extensions/libipt_mac.c
+++ b/extensions/libipt_mac.c
@@ -72,8 +72,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_mac(argv[optind-1], macinfo);
 		if (invert)
 			macinfo->invert = 1;
diff --git a/extensions/libipt_mark.c b/extensions/libipt_mark.c
index 001635a..1c86fd7 100644
--- a/extensions/libipt_mark.c
+++ b/extensions/libipt_mark.c
@@ -45,8 +45,7 @@
 	switch (c) {
 		char *end;
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		markinfo->mark = strtoul(optarg, &end, 0);
 		if (*end == '/') {
 			markinfo->mask = strtoul(end+1, &end, 0);
diff --git a/extensions/libipt_owner.c b/extensions/libipt_owner.c
index 30ee0c1..9663122 100644
--- a/extensions/libipt_owner.c
+++ b/extensions/libipt_owner.c
@@ -61,9 +61,7 @@
 		struct passwd *pwd;
 		struct group *grp;
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
-
+		check_inverse(optarg, &invert, &optind, 0);
 		if ((pwd = getpwnam(optarg)))
 			ownerinfo->uid = pwd->pw_uid;
 		else {
@@ -78,8 +76,7 @@
 		break;
 
 	case '2':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		if ((grp = getgrnam(optarg)))
 			ownerinfo->gid = grp->gr_gid;
 		else {
@@ -94,8 +91,7 @@
 		break;
 
 	case '3':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		ownerinfo->pid = strtoul(optarg, &end, 0);
 		if (*end != '\0' || end == optarg)
 			exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
@@ -106,8 +102,7 @@
 		break;
 
 	case '4':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		ownerinfo->sid = strtoul(optarg, &end, 0);
 		if (*end != '\0' || end == optarg)
 			exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
@@ -119,8 +114,7 @@
 
 #ifdef IPT_OWNER_COMM
 	case '5':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		if(strlen(optarg) > sizeof(ownerinfo->comm))
 			exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %d characters", optarg, sizeof(ownerinfo->comm));
 
diff --git a/extensions/libipt_pkttype.c b/extensions/libipt_pkttype.c
index 04a43db..a0c74b8 100644
--- a/extensions/libipt_pkttype.c
+++ b/extensions/libipt_pkttype.c
@@ -100,8 +100,7 @@
 	switch(c)
 	{
 		case '1':
-			if(check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			parse_pkttype(argv[optind-1], info);
 			if(invert)
 				info->invert=1;
diff --git a/extensions/libipt_pool.c b/extensions/libipt_pool.c
index 3fec463..4e54f45 100644
--- a/extensions/libipt_pool.c
+++ b/extensions/libipt_pool.c
@@ -59,13 +59,13 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert)) optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		info->src = ip_pool_get_index(argv[optind-1]);
 		if (invert) info->flags |= IPT_POOL_INV_SRC;
 		*flags = 1;
 		break;
 	case '2':
-		if (check_inverse(optarg, &invert)) optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		info->dst = ip_pool_get_index(argv[optind-1]);
 		if (invert) info->flags |= IPT_POOL_INV_DST;
 		*flags = 1;
diff --git a/extensions/libipt_quota.c b/extensions/libipt_quota.c
index 28e16e6..d95b8a1 100644
--- a/extensions/libipt_quota.c
+++ b/extensions/libipt_quota.c
@@ -74,7 +74,7 @@
 
         switch (c) {
         case '1':
-                if (check_inverse(optarg, &invert))
+                if (check_inverse(optarg, &invert, NULL, 0))
                         exit_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
                 if (!parse_quota(optarg, &info->quota))
                         exit_error(PARAMETER_PROBLEM,
diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c
index f0dea00..77e6a3e 100644
--- a/extensions/libipt_realm.c
+++ b/extensions/libipt_realm.c
@@ -49,8 +49,7 @@
 	switch (c) {
 		char *end;
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		realminfo->id = strtoul(optarg, &end, 0);
 		if (*end == '/') {
 			realminfo->mask = strtoul(end+1, &end, 0);
diff --git a/extensions/libipt_recent.c b/extensions/libipt_recent.c
index 48cc814..d796d56 100644
--- a/extensions/libipt_recent.c
+++ b/extensions/libipt_recent.c
@@ -70,7 +70,7 @@
 			if (*flags) exit_error(PARAMETER_PROBLEM,
 					"recent: only one of `--set', `--check' "
 					"`--update' or `--remove' may be set");
-			if (check_inverse(optarg, &invert)) optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			info->check_set |= IPT_RECENT_SET;
 			if (invert) info->invert = 1;
 			*flags = 1;
@@ -80,7 +80,7 @@
 			if (*flags) exit_error(PARAMETER_PROBLEM,
 					"recent: only one of `--set', `--check' "
 					"`--update' or `--remove' may be set");
-			if (check_inverse(optarg, &invert)) optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			info->check_set |= IPT_RECENT_CHECK;
 			if(invert) info->invert = 1;
 			*flags = 1;
@@ -90,7 +90,7 @@
 			if (*flags) exit_error(PARAMETER_PROBLEM,
 					"recent: only one of `--set', `--check' "
 					"`--update' or `--remove' may be set");
-			if (check_inverse(optarg, &invert)) optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			info->check_set |= IPT_RECENT_UPDATE;
 			if (invert) info->invert = 1;
 			*flags = 1;
@@ -100,7 +100,7 @@
 			if (*flags) exit_error(PARAMETER_PROBLEM,
 					"recent: only one of `--set', `--check' "
 					"`--update' or `--remove' may be set");
-			if (check_inverse(optarg, &invert)) optind++;
+			check_inverse(optarg, &invert, &optind, 0);
 			info->check_set |= IPT_RECENT_REMOVE;
 			if (invert) info->invert = 1;
 			*flags = 1;
diff --git a/extensions/libipt_state.c b/extensions/libipt_state.c
index 25bc2a2..0c2b4f8 100644
--- a/extensions/libipt_state.c
+++ b/extensions/libipt_state.c
@@ -75,8 +75,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		parse_states(argv[optind-1], sinfo);
 		if (invert)
diff --git a/extensions/libipt_string.c b/extensions/libipt_string.c
index b9f38d7..96801b3 100644
--- a/extensions/libipt_string.c
+++ b/extensions/libipt_string.c
@@ -60,8 +60,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_string(argv[optind-1], stringinfo);
 		if (invert)
 			stringinfo->invert = 1;
diff --git a/extensions/libipt_tcp.c b/extensions/libipt_tcp.c
index 7f17252..85f6d78 100644
--- a/extensions/libipt_tcp.c
+++ b/extensions/libipt_tcp.c
@@ -178,8 +178,7 @@
 		if (*flags & TCP_SRC_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--source-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_ports(argv[optind-1], tcpinfo->spts);
 		if (invert)
 			tcpinfo->invflags |= IPT_TCP_INV_SRCPT;
@@ -191,8 +190,7 @@
 		if (*flags & TCP_DST_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--destination-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_ports(argv[optind-1], tcpinfo->dpts);
 		if (invert)
 			tcpinfo->invflags |= IPT_TCP_INV_DSTPT;
@@ -215,8 +213,7 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one of `--syn' or `--tcp-flags' "
 				   " allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 
 		if (!argv[optind]
 		    || argv[optind][0] == '-' || argv[optind][0] == '!')
@@ -234,8 +231,7 @@
 		if (*flags & TCP_OPTION)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--tcp-option' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_option(argv[optind-1], &tcpinfo->option);
 		if (invert)
 			tcpinfo->invflags |= IPT_TCP_INV_OPTION;
diff --git a/extensions/libipt_tcpmss.c b/extensions/libipt_tcpmss.c
index 92e0539..87353bf 100644
--- a/extensions/libipt_tcpmss.c
+++ b/extensions/libipt_tcpmss.c
@@ -79,8 +79,7 @@
 		if (*flags)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--mss' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tcp_mssvalues(argv[optind-1],
 				    &mssinfo->mss_min, &mssinfo->mss_max);
 		if (invert)
diff --git a/extensions/libipt_tos.c b/extensions/libipt_tos.c
index a1ef4e6..3d4616f 100644
--- a/extensions/libipt_tos.c
+++ b/extensions/libipt_tos.c
@@ -91,8 +91,7 @@
 
 	switch (c) {
 	case '1':
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_tos(argv[optind-1], tosinfo);
 		if (invert)
 			tosinfo->invert = 1;
diff --git a/extensions/libipt_ttl.c b/extensions/libipt_ttl.c
index 61635f7..4ef9764 100644
--- a/extensions/libipt_ttl.c
+++ b/extensions/libipt_ttl.c
@@ -1,7 +1,7 @@
 /* Shared library add-on to iptables to add TTL matching support 
  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
  *
- * $Id: libipt_ttl.c,v 1.4 2000/11/13 11:16:08 laforge Exp $
+ * $Id: libipt_ttl.c,v 1.4 2002/02/25 11:25:41 laforge Exp $
  *
  * This program is released under the terms of GNU GPL */
 
@@ -37,8 +37,7 @@
 	struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
 	u_int8_t value;
 
-	if (check_inverse(optarg, &invert))
-		optind++;
+	check_inverse(optarg, &invert, &optind, 0);
 	value = atoi(argv[optind-1]);
 
 	if (*flags) 
diff --git a/extensions/libipt_udp.c b/extensions/libipt_udp.c
index 3db35b1..6b6b996 100644
--- a/extensions/libipt_udp.c
+++ b/extensions/libipt_udp.c
@@ -100,8 +100,7 @@
 		if (*flags & UDP_SRC_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--source-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_udp_ports(argv[optind-1], udpinfo->spts);
 		if (invert)
 			udpinfo->invflags |= IPT_UDP_INV_SRCPT;
@@ -113,8 +112,7 @@
 		if (*flags & UDP_DST_PORTS)
 			exit_error(PARAMETER_PROBLEM,
 				   "Only one `--destination-port' allowed");
-		if (check_inverse(optarg, &invert))
-			optind++;
+		check_inverse(optarg, &invert, &optind, 0);
 		parse_udp_ports(argv[optind-1], udpinfo->dpts);
 		if (invert)
 			udpinfo->invflags |= IPT_UDP_INV_DSTPT;
diff --git a/include/iptables_common.h b/include/iptables_common.h
index 12b5797..25f23c3 100644
--- a/include/iptables_common.h
+++ b/include/iptables_common.h
@@ -9,7 +9,7 @@
 };
 extern void exit_printhelp() __attribute__((noreturn));
 extern void exit_tryhelp(int) __attribute__((noreturn));
-int check_inverse(const char option[], int *invert);
+int check_inverse(const char option[], int *invert, int *optind, int argc);
 extern int string_to_number(const char *, 
 			    unsigned int, 
 			    unsigned int,
diff --git a/ip6tables.c b/ip6tables.c
index 22d636e..b4d6ea5 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -424,14 +424,20 @@
 }
 
 int
-check_inverse(const char option[], int *invert)
+check_inverse(const char option[], int *invert, int *optind, int argc)
 {
 	if (option && strcmp(option, "!") == 0) {
 		if (*invert)
 			exit_error(PARAMETER_PROBLEM,
 				   "Multiple `!' flags not allowed");
-
 		*invert = TRUE;
+		if (optind) {
+			*optind = *optind+1;
+			if (argc && *optind > argc)
+				exit_error(PARAMETER_PROBLEM,
+					   "no argument following `!'");
+		}
+
 		return TRUE;
 	}
 	return FALSE;
@@ -1838,8 +1844,7 @@
 			 * Option selection
 			 */
 		case 'p':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_PROTOCOL, &fw.ipv6.invflags,
 				   invert);
 
@@ -1861,8 +1866,7 @@
 			break;
 
 		case 's':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_SOURCE, &fw.ipv6.invflags,
 				   invert);
 			shostnetworkmask = argv[optind-1];
@@ -1870,8 +1874,7 @@
 			break;
 
 		case 'd':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_DESTINATION, &fw.ipv6.invflags,
 				   invert);
 			dhostnetworkmask = argv[optind-1];
@@ -1901,8 +1904,7 @@
 
 
 		case 'i':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_VIANAMEIN, &fw.ipv6.invflags,
 				   invert);
 			parse_interface(argv[optind-1],
@@ -1912,8 +1914,7 @@
 			break;
 
 		case 'o':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_VIANAMEOUT, &fw.ipv6.invflags,
 				   invert);
 			parse_interface(argv[optind-1],
diff --git a/iptables.c b/iptables.c
index 25e6d9f..8e4c13a 100644
--- a/iptables.c
+++ b/iptables.c
@@ -476,14 +476,20 @@
 }
 
 int
-check_inverse(const char option[], int *invert)
+check_inverse(const char option[], int *invert, int *optind, int argc)
 {
 	if (option && strcmp(option, "!") == 0) {
 		if (*invert)
 			exit_error(PARAMETER_PROBLEM,
 				   "Multiple `!' flags not allowed");
-
 		*invert = TRUE;
+		if (optind) {
+			*optind = *optind+1;
+			if (argc && *optind > argc)
+				exit_error(PARAMETER_PROBLEM,
+					   "no argument following `!'");
+		}
+
 		return TRUE;
 	}
 	return FALSE;
@@ -1834,8 +1840,7 @@
 			 * Option selection
 			 */
 		case 'p':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_PROTOCOL, &fw.ip.invflags,
 				   invert);
 
@@ -1854,8 +1859,7 @@
 			break;
 
 		case 's':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_SOURCE, &fw.ip.invflags,
 				   invert);
 			shostnetworkmask = argv[optind-1];
@@ -1863,8 +1867,7 @@
 			break;
 
 		case 'd':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_DESTINATION, &fw.ip.invflags,
 				   invert);
 			dhostnetworkmask = argv[optind-1];
@@ -1894,8 +1897,7 @@
 
 
 		case 'i':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_VIANAMEIN, &fw.ip.invflags,
 				   invert);
 			parse_interface(argv[optind-1],
@@ -1905,8 +1907,7 @@
 			break;
 
 		case 'o':
-			if (check_inverse(optarg, &invert))
-				optind++;
+			check_inverse(optarg, &invert, &optind, argc);
 			set_option(&options, OPT_VIANAMEOUT, &fw.ip.invflags,
 				   invert);
 			parse_interface(argv[optind-1],