netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* guided option parser, run 3
@ 2011-04-13 16:13 Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 01/26] libxtables: XTTYPE_MARKMASK32 support Jan Engelhardt
                   ` (26 more replies)
  0 siblings, 27 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel


The following changes since commit 316ae9d2f1996caea4cf221201accb8c2087a154:

  Merge branch 'opts' of git://dev.medozas.de/iptables (2011-04-13 13:38:20 +0200)

are available in the git repository at:

  git://dev.medozas.de/iptables floating/opts

Jan Engelhardt (26):
      libxtables: XTTYPE_MARKMASK32 support
      libxt_MARK: use guided option parser
      libxt_CONNMARK: use guided option parser
      libxtables: XTTYPE_UINT64 support
      libxt_quota: use guided option parser
      libxtables: linked-list name<->id map
      libxt_devgroup: use guided option parser
      libipt_realm: use guided option parser
      libxtables: XTTYPE_UINT16RC support
      libxt_length: use guided option parser
      libxt_tcpmss: use guided option parser
      libxtables: XTTYPE_UINT8RC support
      libxtables: XTTYPE_UINT64RC support
      libxt_connbytes: use guided option parser
      libxtables: XTTYPE_UINT16 support
      libxt_CT: use guided option parser
      libxt_NFQUEUE: use guided option parser
      libxt_TCPMSS: use guided option parser
      libxtables: pass struct xt_entry_{match,target} to x6 parser
      libxt_string: use guided option parser
      libxtables: XTTYPE_SYSLOGLEVEL support
      libip[6]t_LOG: use guided option parser
      libxtables: XTTYPE_ONEHOST support
      libxtables: XTTYPE_PORT support
      libxt_TPROXY: use guided option parser
      libipt_ULOG: use guided option parser

 extensions/libip6t_LOG.c     |  174 +++++----------------
 extensions/libipt_LOG.c      |  174 +++++----------------
 extensions/libipt_ULOG.c     |  137 ++++------------
 extensions/libipt_realm.c    |  202 +++++-------------------
 extensions/libxt_CONNMARK.c  |  271 +++++++++++++-------------------
 extensions/libxt_CT.c        |   74 ++++------
 extensions/libxt_MARK.c      |  202 ++++++++++---------------
 extensions/libxt_NFQUEUE.c   |  139 ++++++-----------
 extensions/libxt_TCPMSS.c    |   96 ++++--------
 extensions/libxt_TPROXY.c    |  216 ++++++++------------------
 extensions/libxt_connbytes.c |  107 +++++--------
 extensions/libxt_connmark.c  |   98 +++---------
 extensions/libxt_devgroup.c  |  201 +++++-------------------
 extensions/libxt_length.c    |   92 ++---------
 extensions/libxt_mark.c      |   95 +++---------
 extensions/libxt_quota.c     |   67 ++------
 extensions/libxt_string.c    |  138 ++++++-----------
 extensions/libxt_tcpmss.c    |   92 +++---------
 include/xtables.h.in         |   42 +++++-
 xtoptions.c                  |  352 ++++++++++++++++++++++++++++++++++++++++-
 20 files changed, 1127 insertions(+), 1842 deletions(-)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/26] libxtables: XTTYPE_MARKMASK32 support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 02/26] libxt_MARK: use guided option parser Jan Engelhardt
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    5 +++++
 xtoptions.c          |   29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index c3c8da9..2fa5977 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -50,6 +50,7 @@ struct in_addr;
  * %XTTYPE_UINT*:	standard integer
  * %XTTYPE_UINT*RC:	colon-separated range of standard integers
  * %XTTYPE_STRING:	arbitrary string
+ * %XTTYPE_MARKMASK32:	32-bit mark with optional mask
  */
 enum xt_option_type {
 	XTTYPE_NONE,
@@ -57,6 +58,7 @@ enum xt_option_type {
 	XTTYPE_UINT32,
 	XTTYPE_UINT32RC,
 	XTTYPE_STRING,
+	XTTYPE_MARKMASK32,
 };
 
 /**
@@ -113,6 +115,9 @@ struct xt_option_call {
 	union {
 		uint8_t u8;
 		uint32_t u32, u32_range[2];
+		struct {
+			uint32_t mark, mask;
+		};
 	} val;
 };
 
diff --git a/xtoptions.c b/xtoptions.c
index 631e7a3..e9bcaa8 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -186,11 +186,40 @@ static void xtopt_parse_string(struct xt_option_call *cb)
 	p[z] = '\0';
 }
 
+/**
+ * Validate the input for being conformant to "mark[/mask]".
+ */
+static void xtopt_parse_markmask(struct xt_option_call *cb)
+{
+	unsigned int mark = 0, mask = ~0U;
+	char *end;
+
+	if (!xtables_strtoui(cb->arg, &end, &mark, 0, UINT32_MAX))
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"%s: bad mark value for option \"--%s\", "
+			"or out of range.\n",
+			cb->ext_name, cb->entry->name);
+	if (*end == '/' &&
+	    !xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"%s: bad mask value for option \"--%s\", "
+			"or out of range.\n",
+			cb->ext_name, cb->entry->name);
+	if (*end != '\0')
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"%s: trailing garbage after value "
+			"for option \"--%s\".\n",
+			cb->ext_name, cb->entry->name);
+	cb->val.mark = mark;
+	cb->val.mask = mask;
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT32]      = xtopt_parse_int,
 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
+	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
 };
 
 static const size_t xtopt_psize[] = {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/26] libxt_MARK: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 01/26] libxtables: XTTYPE_MARKMASK32 support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 03/26] libxt_CONNMARK: " Jan Engelhardt
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_MARK.c |  202 ++++++++++++++++++----------------------------
 extensions/libxt_mark.c |   95 ++++++----------------
 2 files changed, 104 insertions(+), 193 deletions(-)

diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c
index 885cf2f..556dbde 100644
--- a/extensions/libxt_MARK.c
+++ b/extensions/libxt_MARK.c
@@ -1,12 +1,6 @@
-/* Shared library add-on to iptables to add MARK target support. */
 #include <stdbool.h>
 #include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
-#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_MARK.h>
 
 /* Version 0 */
@@ -27,7 +21,18 @@ struct xt_mark_target_info_v1 {
 };
 
 enum {
-	F_MARK = 1 << 0,
+	O_SET_MARK = 0,
+	O_AND_MARK,
+	O_OR_MARK,
+	O_XOR_MARK,
+	O_SET_XMARK,
+	F_SET_MARK  = 1 << O_SET_MARK,
+	F_AND_MARK  = 1 << O_AND_MARK,
+	F_OR_MARK   = 1 << O_OR_MARK,
+	F_XOR_MARK  = 1 << O_XOR_MARK,
+	F_SET_XMARK = 1 << O_SET_XMARK,
+	F_ANY       = F_SET_MARK | F_AND_MARK | F_OR_MARK |
+	              F_XOR_MARK | F_SET_XMARK,
 };
 
 static void MARK_help(void)
@@ -39,20 +44,28 @@ static void MARK_help(void)
 "  --or-mark  value                   Binary OR  the nfmark with value\n");
 }
 
-static const struct option MARK_opts[] = {
-	{.name = "set-mark", .has_arg = true, .val = '1'},
-	{.name = "and-mark", .has_arg = true, .val = '2'},
-	{.name = "or-mark",  .has_arg = true, .val = '3'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry MARK_opts[] = {
+	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_ANY},
+	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_ANY},
+	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_ANY},
+	XTOPT_TABLEEND,
 };
 
-static const struct option mark_tg_opts[] = {
-	{.name = "set-xmark", .has_arg = true, .val = 'X'},
-	{.name = "set-mark",  .has_arg = true, .val = '='},
-	{.name = "and-mark",  .has_arg = true, .val = '&'},
-	{.name = "or-mark",   .has_arg = true, .val = '|'},
-	{.name = "xor-mark",  .has_arg = true, .val = '^'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry mark_tg_opts[] = {
+	{.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
+	 .excl = F_ANY},
+	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
+	 .excl = F_ANY},
+	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_ANY},
+	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_ANY},
+	{.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_ANY},
+	XTOPT_TABLEEND,
 };
 
 static void mark_tg_help(void)
@@ -67,137 +80,80 @@ static void mark_tg_help(void)
 "\n");
 }
 
-/* Function which parses command options; returns true if it
-   ate an option */
-static int
-MARK_parse_v0(int c, char **argv, int invert, unsigned int *flags,
-              const void *entry, struct xt_entry_target **target)
+static void MARK_parse_v0(struct xt_option_call *cb)
 {
-	struct xt_mark_target_info *markinfo
-		= (struct xt_mark_target_info *)(*target)->data;
-	unsigned int mark = 0;
+	struct xt_mark_target_info *markinfo = cb->data;
 
-	switch (c) {
-	case '1':
-		if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX))
-			xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
-		markinfo->mark = mark;
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "MARK target: Can't specify --set-mark twice");
-		*flags = 1;
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SET_MARK:
+		markinfo->mark = cb->val.mark;
 		break;
-	case '2':
-		xtables_error(PARAMETER_PROBLEM,
-			   "MARK target: kernel too old for --and-mark");
-	case '3':
+	default:
 		xtables_error(PARAMETER_PROBLEM,
-			   "MARK target: kernel too old for --or-mark");
+			   "MARK target: kernel too old for --%s",
+			   cb->entry->name);
 	}
-
-	return 1;
 }
 
-static void MARK_check(unsigned int flags)
+static void MARK_check(struct xt_fcheck_call *cb)
 {
-	if (!flags)
+	if (cb->xflags == 0)
 		xtables_error(PARAMETER_PROBLEM,
 		           "MARK target: Parameter --set/and/or-mark"
 			   " is required");
 }
 
-static int
-MARK_parse_v1(int c, char **argv, int invert, unsigned int *flags,
-              const void *entry, struct xt_entry_target **target)
+static void MARK_parse_v1(struct xt_option_call *cb)
 {
-	struct xt_mark_target_info_v1 *markinfo
-		= (struct xt_mark_target_info_v1 *)(*target)->data;
-	unsigned int mark = 0;
+	struct xt_mark_target_info_v1 *markinfo = cb->data;
 
-	switch (c) {
-	case '1':
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SET_MARK:
 	        markinfo->mode = XT_MARK_SET;
 		break;
-	case '2':
+	case O_AND_MARK:
 	        markinfo->mode = XT_MARK_AND;
 		break;
-	case '3':
+	case O_OR_MARK:
 	        markinfo->mode = XT_MARK_OR;
 		break;
 	}
-
-	if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX))
-		xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
-	markinfo->mark = mark;
-	if (*flags)
-		xtables_error(PARAMETER_PROBLEM,
-			   "MARK target: Can't specify --set-mark twice");
-
-	*flags = 1;
-	return 1;
+	markinfo->mark = cb->val.u32;
 }
 
-static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
-                         const void *entry, struct xt_entry_target **target)
+static void mark_tg_parse(struct xt_option_call *cb)
 {
-	struct xt_mark_tginfo2 *info = (void *)(*target)->data;
-	unsigned int value, mask = UINT32_MAX;
-	char *end;
+	struct xt_mark_tginfo2 *info = cb->data;
 
-	switch (c) {
-	case 'X': /* --set-xmark */
-	case '=': /* --set-mark */
-		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
-		xtables_param_act(XTF_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert);
-		if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
-		if (*end == '/')
-			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
-				xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
-		if (*end != '\0')
-			xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
-		info->mark = value;
-		info->mask = mask;
-
-		if (c == '=')
-			info->mask = value | mask;
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SET_XMARK:
+		info->mark = cb->val.mark;
+		info->mask = cb->val.mask;
 		break;
-
-	case '&': /* --and-mark */
-		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
-		xtables_param_act(XTF_NO_INVERT, "MARK", "--and-mark", invert);
-		if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "MARK", "--and-mark", optarg);
+	case O_SET_MARK:
+		info->mark = cb->val.mark;
+		info->mask = cb->val.mark | cb->val.mask;
+		break;
+	case O_AND_MARK:
 		info->mark = 0;
-		info->mask = ~mask;
+		info->mask = ~cb->val.u32;
 		break;
-
-	case '|': /* --or-mark */
-		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
-		xtables_param_act(XTF_NO_INVERT, "MARK", "--or-mark", invert);
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "MARK", "--or-mark", optarg);
-		info->mark = value;
-		info->mask = value;
+	case O_OR_MARK:
+		info->mark = info->mask = cb->val.u32;
 		break;
-
-	case '^': /* --xor-mark */
-		xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
-		xtables_param_act(XTF_NO_INVERT, "MARK", "--xor-mark", invert);
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "MARK", "--xor-mark", optarg);
-		info->mark = value;
+	case O_XOR_MARK:
+		info->mark = cb->val.u32;
 		info->mask = 0;
 		break;
 	}
-
-	*flags |= F_MARK;
-	return true;
 }
 
-static void mark_tg_check(unsigned int flags)
+static void mark_tg_check(struct xt_fcheck_call *cb)
 {
-	if (flags == 0)
+	if (cb->xflags == 0)
 		xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, "
 		           "--{and,or,xor,set}-mark options is required");
 }
@@ -298,11 +254,11 @@ static struct xtables_target mark_tg_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_mark_target_info)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
 		.help          = MARK_help,
-		.parse         = MARK_parse_v0,
-		.final_check   = MARK_check,
 		.print         = MARK_print_v0,
 		.save          = MARK_save_v0,
-		.extra_opts    = MARK_opts,
+		.x6_parse      = MARK_parse_v0,
+		.x6_fcheck     = MARK_check,
+		.x6_options    = MARK_opts,
 	},
 	{
 		.family        = NFPROTO_IPV4,
@@ -312,11 +268,11 @@ static struct xtables_target mark_tg_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
 		.help          = MARK_help,
-		.parse         = MARK_parse_v1,
-		.final_check   = MARK_check,
 		.print         = MARK_print_v1,
 		.save          = MARK_save_v1,
-		.extra_opts    = MARK_opts,
+		.x6_parse      = MARK_parse_v1,
+		.x6_fcheck     = MARK_check,
+		.x6_options    = MARK_opts,
 	},
 	{
 		.version       = XTABLES_VERSION,
@@ -326,11 +282,11 @@ static struct xtables_target mark_tg_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
 		.help          = mark_tg_help,
-		.parse         = mark_tg_parse,
-		.final_check   = mark_tg_check,
 		.print         = mark_tg_print,
 		.save          = mark_tg_save,
-		.extra_opts    = mark_tg_opts,
+		.x6_parse      = mark_tg_parse,
+		.x6_fcheck     = mark_tg_check,
+		.x6_options    = mark_tg_opts,
 	},
 };
 
diff --git a/extensions/libxt_mark.c b/extensions/libxt_mark.c
index d3c1727..7f8c995 100644
--- a/extensions/libxt_mark.c
+++ b/extensions/libxt_mark.c
@@ -1,11 +1,5 @@
-/* Shared library add-on to iptables to add NFMARK matching support. */
 #include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
 #include <linux/netfilter/xt_mark.h>
 
@@ -15,7 +9,7 @@ struct xt_mark_info {
 };
 
 enum {
-	F_MARK = 1 << 0,
+	O_MARK = 0,
 };
 
 static void mark_mt_help(void)
@@ -25,62 +19,32 @@ static void mark_mt_help(void)
 "[!] --mark value[/mask]    Match nfmark value with optional mask\n");
 }
 
-static const struct option mark_mt_opts[] = {
-	{.name = "mark", .has_arg = true, .val = '1'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry mark_mt_opts[] = {
+	{.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
-static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
-                         const void *entry, struct xt_entry_match **match)
+static void mark_mt_parse(struct xt_option_call *cb)
 {
-	struct xt_mark_mtinfo1 *info = (void *)(*match)->data;
-	unsigned int mark, mask = UINT32_MAX;
-	char *end;
-
-	switch (c) {
-	case '1': /* --mark */
-		xtables_param_act(XTF_ONLY_ONCE, "mark", "--mark", *flags & F_MARK);
-		if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
-		if (*end == '/')
-			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
-				xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
-		if (*end != '\0')
-			xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
-
-		if (invert)
-			info->invert = true;
-		info->mark = mark;
-		info->mask = mask;
-		*flags    |= F_MARK;
-		return true;
-	}
-	return false;
+	struct xt_mark_mtinfo1 *info = cb->data;
+
+	xtables_option_parse(cb);
+	if (cb->invert)
+		info->invert = true;
+	info->mark = cb->val.mark;
+	info->mask = cb->val.mask;
 }
 
-static int
-mark_parse(int c, char **argv, int invert, unsigned int *flags,
-           const void *entry, struct xt_entry_match **match)
+static void mark_parse(struct xt_option_call *cb)
 {
-	struct xt_mark_info *markinfo = (struct xt_mark_info *)(*match)->data;
-
-	switch (c) {
-		char *end;
-	case '1':
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		markinfo->mark = strtoul(optarg, &end, 0);
-		if (*end == '/') {
-			markinfo->mask = strtoul(end+1, &end, 0);
-		} else
-			markinfo->mask = 0xffffffff;
-		if (*end != '\0' || end == optarg)
-			xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
-		if (invert)
-			markinfo->invert = 1;
-		*flags = 1;
-		break;
-	}
-	return 1;
+	struct xt_mark_info *markinfo = cb->data;
+
+	xtables_option_parse(cb);
+	if (cb->invert)
+		markinfo->invert = 1;
+	markinfo->mark = cb->val.mark;
+	markinfo->mask = cb->val.mask;
 }
 
 static void print_mark(unsigned int mark, unsigned int mask)
@@ -91,13 +55,6 @@ static void print_mark(unsigned int mark, unsigned int mask)
 		printf(" 0x%x", mark);
 }
 
-static void mark_mt_check(unsigned int flags)
-{
-	if (flags == 0)
-		xtables_error(PARAMETER_PROBLEM,
-			   "mark match: The --mark option is required");
-}
-
 static void
 mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
 {
@@ -154,11 +111,10 @@ static struct xtables_match mark_mt_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_mark_info)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)),
 		.help          = mark_mt_help,
-		.parse         = mark_parse,
-		.final_check   = mark_mt_check,
 		.print         = mark_print,
 		.save          = mark_save,
-		.extra_opts    = mark_mt_opts,
+		.x6_parse      = mark_parse,
+		.x6_options    = mark_mt_opts,
 	},
 	{
 		.version       = XTABLES_VERSION,
@@ -168,11 +124,10 @@ static struct xtables_match mark_mt_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
 		.help          = mark_mt_help,
-		.parse         = mark_mt_parse,
-		.final_check   = mark_mt_check,
 		.print         = mark_mt_print,
 		.save          = mark_mt_save,
-		.extra_opts    = mark_mt_opts,
+		.x6_parse      = mark_mt_parse,
+		.x6_options    = mark_mt_opts,
 	},
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/26] libxt_CONNMARK: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 01/26] libxtables: XTTYPE_MARKMASK32 support Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 02/26] libxt_MARK: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 04/26] libxtables: XTTYPE_UINT64 support Jan Engelhardt
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_CONNMARK.c |  271 +++++++++++++++++--------------------------
 extensions/libxt_connmark.c |   98 ++++------------
 2 files changed, 134 insertions(+), 235 deletions(-)

diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c
index dbb9dc5..5d5351e 100644
--- a/extensions/libxt_CONNMARK.c
+++ b/extensions/libxt_CONNMARK.c
@@ -20,13 +20,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
-#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_CONNMARK.h>
 
 struct xt_connmark_target_info {
@@ -36,8 +32,28 @@ struct xt_connmark_target_info {
 };
 
 enum {
-	F_MARK    = 1 << 0,
-	F_SR_MARK = 1 << 1,
+	O_SET_MARK = 0,
+	O_SAVE_MARK,
+	O_RESTORE_MARK,
+	O_AND_MARK,
+	O_OR_MARK,
+	O_XOR_MARK,
+	O_SET_XMARK,
+	O_CTMASK,
+	O_NFMASK,
+	O_MASK,
+	F_SET_MARK     = 1 << O_SET_MARK,
+	F_SAVE_MARK    = 1 << O_SAVE_MARK,
+	F_RESTORE_MARK = 1 << O_RESTORE_MARK,
+	F_AND_MARK     = 1 << O_AND_MARK,
+	F_OR_MARK      = 1 << O_OR_MARK,
+	F_XOR_MARK     = 1 << O_XOR_MARK,
+	F_SET_XMARK    = 1 << O_SET_XMARK,
+	F_CTMASK       = 1 << O_CTMASK,
+	F_NFMASK       = 1 << O_NFMASK,
+	F_MASK         = 1 << O_MASK,
+	F_OP_ANY       = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
+	                 F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
 };
 
 static void CONNMARK_help(void)
@@ -49,27 +65,44 @@ static void CONNMARK_help(void)
 "  --restore-mark [--mask mask]  Restore saved nfmark value\n");
 }
 
-static const struct option CONNMARK_opts[] = {
-	{.name = "set-mark",     .has_arg = true,  .val = '1'},
-	{.name = "save-mark",    .has_arg = false, .val = '2'},
-	{.name = "restore-mark", .has_arg = false, .val = '3'},
-	{.name = "mask",         .has_arg = true,  .val = '4'},
-	XT_GETOPT_TABLEEND,
+#define s struct xt_connmark_target_info
+static const struct xt_option_entry CONNMARK_opts[] = {
+	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
+	 .excl = F_OP_ANY},
+	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
+	 .excl = F_OP_ANY},
+	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
+	 .excl = F_OP_ANY},
+	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32},
+	XTOPT_TABLEEND,
 };
-
-static const struct option connmark_tg_opts[] = {
-	{.name = "set-xmark",     .has_arg = true,  .val = '='},
-	{.name = "set-mark",      .has_arg = true,  .val = '-'},
-	{.name = "and-mark",      .has_arg = true,  .val = '&'},
-	{.name = "or-mark",       .has_arg = true,  .val = '|'},
-	{.name = "xor-mark",      .has_arg = true,  .val = '^'},
-	{.name = "save-mark",     .has_arg = false, .val = 'S'},
-	{.name = "restore-mark",  .has_arg = false, .val = 'R'},
-	{.name = "ctmask",        .has_arg = true,  .val = 'c'},
-	{.name = "nfmask",        .has_arg = true,  .val = 'n'},
-	{.name = "mask",          .has_arg = true,  .val = 'm'},
-	XT_GETOPT_TABLEEND,
+#undef s
+
+#define s struct xt_connmark_tginfo1
+static const struct xt_option_entry connmark_tg_opts[] = {
+	{.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
+	 .excl = F_OP_ANY},
+	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
+	 .excl = F_OP_ANY},
+	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_OP_ANY},
+	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_OP_ANY},
+	{.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
+	 .excl = F_OP_ANY},
+	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
+	 .excl = F_OP_ANY},
+	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
+	 .excl = F_OP_ANY},
+	{.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
+	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
+	{.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
+	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
+	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
+	 .excl = F_CTMASK | F_NFMASK},
+	XTOPT_TABLEEND,
 };
+#undef s
 
 static void connmark_tg_help(void)
 {
@@ -101,163 +134,75 @@ static void connmark_tg_init(struct xt_entry_target *target)
 	info->nfmask = UINT32_MAX;
 }
 
-static int
-CONNMARK_parse(int c, char **argv, int invert, unsigned int *flags,
-               const void *entry, struct xt_entry_target **target)
+static void CONNMARK_parse(struct xt_option_call *cb)
 {
-	struct xt_connmark_target_info *markinfo
-		= (struct xt_connmark_target_info *)(*target)->data;
+	struct xt_connmark_target_info *markinfo = cb->data;
 
-	switch (c) {
-		char *end;
-	case '1':
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SET_MARK:
 		markinfo->mode = XT_CONNMARK_SET;
-
-		markinfo->mark = strtoul(optarg, &end, 0);
-		if (*end == '/' && end[1] != '\0')
-		    markinfo->mask = strtoul(end+1, &end, 0);
-
-		if (*end != '\0' || end == optarg)
-			xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "CONNMARK target: Can't specify --set-mark twice");
-		*flags = 1;
+		markinfo->mark = cb->val.mark;
+		markinfo->mask = cb->val.mask;
 		break;
-	case '2':
+	case O_SAVE_MARK:
 		markinfo->mode = XT_CONNMARK_SAVE;
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "CONNMARK target: Can't specify --save-mark twice");
-		*flags = 1;
 		break;
-	case '3':
+	case O_RESTORE_MARK:
 		markinfo->mode = XT_CONNMARK_RESTORE;
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "CONNMARK target: Can't specify --restore-mark twice");
-		*flags = 1;
 		break;
-	case '4':
-		if (!*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "CONNMARK target: Can't specify --mask without a operation");
-		markinfo->mask = strtoul(optarg, &end, 0);
-
-		if (*end != '\0' || end == optarg)
-			xtables_error(PARAMETER_PROBLEM, "Bad MASK value \"%s\"", optarg);
+	case O_MASK:
+		markinfo->mask = cb->val.u32;
 		break;
 	}
-
-	return 1;
 }
 
-static int connmark_tg_parse(int c, char **argv, int invert,
-                             unsigned int *flags, const void *entry,
-                             struct xt_entry_target **target)
+static void connmark_tg_parse(struct xt_option_call *cb)
 {
-	struct xt_connmark_tginfo1 *info = (void *)(*target)->data;
-	unsigned int value, mask = UINT32_MAX;
-	char *end;
+	struct xt_connmark_tginfo1 *info = cb->data;
 
-	switch (c) {
-	case '=': /* --set-xmark */
-	case '-': /* --set-mark */
-		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
-		if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
-		if (*end == '/')
-			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
-				xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
-		if (*end != '\0')
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SET_XMARK:
 		info->mode   = XT_CONNMARK_SET;
-		info->ctmark = value;
-		info->ctmask = mask;
-		if (c == '-')
-			info->ctmask |= value;
-		*flags |= F_MARK;
-		return true;
-
-	case '&': /* --and-mark */
-		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
-		if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--and-mark", optarg);
+		info->ctmark = cb->val.mark;
+		info->ctmask = cb->val.mask;
+		break;
+	case O_SET_MARK:
+		info->mode   = XT_CONNMARK_SET;
+		info->ctmark = cb->val.mark;
+		info->ctmask = cb->val.mark | cb->val.mask;
+		break;
+	case O_AND_MARK:
 		info->mode   = XT_CONNMARK_SET;
 		info->ctmark = 0;
-		info->ctmask = ~mask;
-		*flags      |= F_MARK;
-		return true;
-
-	case '|': /* --or-mark */
-		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--or-mark", optarg);
+		info->ctmask = ~cb->val.u32;
+		break;
+	case O_OR_MARK:
 		info->mode   = XT_CONNMARK_SET;
-		info->ctmark = value;
-		info->ctmask = value;
-		*flags      |= F_MARK;
-		return true;
-
-	case '^': /* --xor-mark */
-		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--xor-mark", optarg);
+		info->ctmark = cb->val.u32;
+		info->ctmask = cb->val.u32;
+		break;
+	case O_XOR_MARK:
 		info->mode   = XT_CONNMARK_SET;
-		info->ctmark = value;
+		info->ctmark = cb->val.u32;
 		info->ctmask = 0;
-		*flags      |= F_MARK;
-		return true;
-
-	case 'S': /* --save-mark */
-		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		break;
+	case O_SAVE_MARK:
 		info->mode = XT_CONNMARK_SAVE;
-		*flags |= F_MARK | F_SR_MARK;
-		return true;
-
-	case 'R': /* --restore-mark */
-		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		break;
+	case O_RESTORE_MARK:
 		info->mode = XT_CONNMARK_RESTORE;
-		*flags |= F_MARK | F_SR_MARK;
-		return true;
-
-	case 'n': /* --nfmask */
-		if (!(*flags & F_SR_MARK))
-			xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
-			           "or --restore-mark is required for "
-			           "--nfmask");
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--nfmask", optarg);
-		info->nfmask = value;
-		return true;
-
-	case 'c': /* --ctmask */
-		if (!(*flags & F_SR_MARK))
-			xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
-			           "or --restore-mark is required for "
-			           "--ctmask");
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--ctmask", optarg);
-		info->ctmask = value;
-		return true;
-
-	case 'm': /* --mask */
-		if (!(*flags & F_SR_MARK))
-			xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
-			           "or --restore-mark is required for "
-			           "--mask");
-		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--mask", optarg);
-		info->nfmask = info->ctmask = value;
-		return true;
+		break;
+	case O_MASK:
+		info->nfmask = info->ctmask = cb->val.u32;
+		break;
 	}
-
-	return false;
 }
 
-static void connmark_tg_check(unsigned int flags)
+static void connmark_tg_check(struct xt_fcheck_call *cb)
 {
-	if (!flags)
+	if (!(cb->xflags & F_OP_ANY))
 		xtables_error(PARAMETER_PROBLEM,
 		           "CONNMARK target: No operation specified");
 }
@@ -412,11 +357,11 @@ static struct xtables_target connmark_tg_reg[] = {
 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
 		.help          = CONNMARK_help,
 		.init          = CONNMARK_init,
-		.parse         = CONNMARK_parse,
-		.final_check   = connmark_tg_check,
 		.print         = CONNMARK_print,
 		.save          = CONNMARK_save,
-		.extra_opts    = CONNMARK_opts,
+		.x6_parse      = CONNMARK_parse,
+		.x6_fcheck     = connmark_tg_check,
+		.x6_options    = CONNMARK_opts,
 	},
 	{
 		.version       = XTABLES_VERSION,
@@ -427,11 +372,11 @@ static struct xtables_target connmark_tg_reg[] = {
 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
 		.help          = connmark_tg_help,
 		.init          = connmark_tg_init,
-		.parse         = connmark_tg_parse,
-		.final_check   = connmark_tg_check,
 		.print         = connmark_tg_print,
 		.save          = connmark_tg_save,
-		.extra_opts    = connmark_tg_opts,
+		.x6_parse      = connmark_tg_parse,
+		.x6_fcheck     = connmark_tg_check,
+		.x6_options    = connmark_tg_opts,
 	},
 };
 
diff --git a/extensions/libxt_connmark.c b/extensions/libxt_connmark.c
index a0e89fe..6f1d532 100644
--- a/extensions/libxt_connmark.c
+++ b/extensions/libxt_connmark.c
@@ -20,12 +20,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
 #include <linux/netfilter/xt_connmark.h>
 
@@ -35,7 +31,7 @@ struct xt_connmark_info {
 };
 
 enum {
-	F_MARK = 1 << 0,
+	O_MARK = 0,
 };
 
 static void connmark_mt_help(void)
@@ -45,65 +41,32 @@ static void connmark_mt_help(void)
 "[!] --mark value[/mask]    Match ctmark value with optional mask\n");
 }
 
-static const struct option connmark_mt_opts[] = {
-	{.name = "mark", .has_arg = true, .val = '1'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry connmark_mt_opts[] = {
+	{.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
-static int
-connmark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
-                  const void *entry, struct xt_entry_match **match)
+static void connmark_mt_parse(struct xt_option_call *cb)
 {
-	struct xt_connmark_mtinfo1 *info = (void *)(*match)->data;
-	unsigned int mark, mask = UINT32_MAX;
-	char *end;
-
-	switch (c) {
-	case '1': /* --mark */
-		xtables_param_act(XTF_ONLY_ONCE, "connmark", "--mark", *flags & F_MARK);
-		if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg);
-		if (*end == '/')
-			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
-				xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg);
-		if (*end != '\0')
-			xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg);
-
-		if (invert)
-			info->invert = true;
-		info->mark = mark;
-		info->mask = mask;
-		*flags    |= F_MARK;
-		return true;
-	}
-	return false;
+	struct xt_connmark_mtinfo1 *info = cb->data;
+
+	xtables_option_parse(cb);
+	if (cb->invert)
+		info->invert = true;
+	info->mark = cb->val.mark;
+	info->mask = cb->val.mask;
 }
 
-static int
-connmark_parse(int c, char **argv, int invert, unsigned int *flags,
-               const void *entry, struct xt_entry_match **match)
+static void connmark_parse(struct xt_option_call *cb)
 {
-	struct xt_connmark_info *markinfo = (struct xt_connmark_info *)(*match)->data;
-
-	switch (c) {
-		char *end;
-	case '1':
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-
-		markinfo->mark = strtoul(optarg, &end, 0);
-		markinfo->mask = 0xffffffffUL;
-		
-		if (*end == '/')
-			markinfo->mask = strtoul(end+1, &end, 0);
-
-		if (*end != '\0' || end == optarg)
-			xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
-		if (invert)
-			markinfo->invert = 1;
-		*flags = 1;
-		break;
-	}
-	return 1;
+	struct xt_connmark_info *markinfo = cb->data;
+
+	xtables_option_parse(cb);
+	markinfo->mark = cb->val.mark;
+	markinfo->mask = cb->val.mask;
+	if (cb->invert)
+		markinfo->invert = 1;
 }
 
 static void print_mark(unsigned int mark, unsigned int mask)
@@ -114,13 +77,6 @@ static void print_mark(unsigned int mark, unsigned int mask)
 		printf(" 0x%x", mark);
 }
 
-static void connmark_mt_check(unsigned int flags)
-{
-	if (flags == 0)
-		xtables_error(PARAMETER_PROBLEM,
-		           "connmark: The --mark option is required");
-}
-
 static void
 connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
 {
@@ -175,11 +131,10 @@ static struct xtables_match connmark_mt_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_connmark_info)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)),
 		.help          = connmark_mt_help,
-		.parse         = connmark_parse,
-		.final_check   = connmark_mt_check,
 		.print         = connmark_print,
 		.save          = connmark_save,
-		.extra_opts    = connmark_mt_opts,
+		.x6_parse      = connmark_parse,
+		.x6_options    = connmark_mt_opts,
 	},
 	{
 		.version       = XTABLES_VERSION,
@@ -189,11 +144,10 @@ static struct xtables_match connmark_mt_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
 		.help          = connmark_mt_help,
-		.parse         = connmark_mt_parse,
-		.final_check   = connmark_mt_check,
 		.print         = connmark_mt_print,
 		.save          = connmark_mt_save,
-		.extra_opts    = connmark_mt_opts,
+		.x6_parse      = connmark_mt_parse,
+		.x6_options    = connmark_mt_opts,
 	},
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/26] libxtables: XTTYPE_UINT64 support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (2 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 03/26] libxt_CONNMARK: " Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 05/26] libxt_quota: use guided option parser Jan Engelhardt
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    2 ++
 xtoptions.c          |   12 ++++++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index 2fa5977..c361bdb 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -56,6 +56,7 @@ enum xt_option_type {
 	XTTYPE_NONE,
 	XTTYPE_UINT8,
 	XTTYPE_UINT32,
+	XTTYPE_UINT64,
 	XTTYPE_UINT32RC,
 	XTTYPE_STRING,
 	XTTYPE_MARKMASK32,
@@ -115,6 +116,7 @@ struct xt_option_call {
 	union {
 		uint8_t u8;
 		uint32_t u32, u32_range[2];
+		uint64_t u64;
 		struct {
 			uint32_t mark, mask;
 		};
diff --git a/xtoptions.c b/xtoptions.c
index e9bcaa8..4206314 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -86,11 +86,13 @@ 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 int lmin = 0, lmax = UINT32_MAX;
+	unsigned long long lmin = 0, lmax = UINT32_MAX;
 	unsigned int value;
 
 	if (entry->type == XTTYPE_UINT8)
 		lmax = UINT8_MAX;
+	else if (entry->type == XTTYPE_UINT64)
+		lmax = UINT64_MAX;
 	if (cb->entry->min != 0)
 		lmin = cb->entry->min;
 	if (cb->entry->max != 0)
@@ -99,7 +101,7 @@ static void xtopt_parse_int(struct xt_option_call *cb)
 	if (!xtables_strtoui(cb->arg, NULL, &value, lmin, lmax))
 		xt_params->exit_err(PARAMETER_PROBLEM,
 			"%s: bad value for option \"--%s\", "
-			"or out of range (%u-%u).\n",
+			"or out of range (%llu-%llu).\n",
 			cb->ext_name, entry->name, lmin, lmax);
 
 	if (entry->type == XTTYPE_UINT8) {
@@ -110,6 +112,10 @@ static void xtopt_parse_int(struct xt_option_call *cb)
 		cb->val.u32 = value;
 		if (entry->flags & XTOPT_PUT)
 			*(uint32_t *)XTOPT_MKPTR(cb) = cb->val.u32;
+	} else if (entry->type == XTTYPE_UINT64) {
+		cb->val.u64 = value;
+		if (entry->flags & XTOPT_PUT)
+			*(uint64_t *)XTOPT_MKPTR(cb) = cb->val.u64;
 	}
 }
 
@@ -217,6 +223,7 @@ static void xtopt_parse_markmask(struct xt_option_call *cb)
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT32]      = xtopt_parse_int,
+	[XTTYPE_UINT64]      = xtopt_parse_int,
 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
@@ -225,6 +232,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 static const size_t xtopt_psize[] = {
 	[XTTYPE_UINT8]       = sizeof(uint8_t),
 	[XTTYPE_UINT32]      = sizeof(uint32_t),
+	[XTTYPE_UINT64]      = sizeof(uint64_t),
 	[XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
 	[XTTYPE_STRING]      = -1,
 };
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/26] libxt_quota: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (3 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 04/26] libxtables: XTTYPE_UINT64 support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 06/26] libxtables: linked-list name<->id map Jan Engelhardt
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_quota.c |   67 ++++++++++-----------------------------------
 1 files changed, 15 insertions(+), 52 deletions(-)

diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c
index e3699ad..988f404 100644
--- a/extensions/libxt_quota.c
+++ b/extensions/libxt_quota.c
@@ -3,18 +3,18 @@
  *
  * Sam Johnston <samj@samj.net>
  */
-#include <stdbool.h>
-#include <stddef.h>
 #include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
 #include <xtables.h>
-
 #include <linux/netfilter/xt_quota.h>
 
-static const struct option quota_opts[] = {
-	{.name = "quota", .has_arg = true, .val = '1'},
-	XT_GETOPT_TABLEEND,
+enum {
+	O_QUOTA = 0,
+};
+
+static const struct xt_option_entry quota_opts[] = {
+	{.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
 static void quota_help(void)
@@ -40,49 +40,13 @@ quota_save(const void *ip, const struct xt_entry_match *match)
 	printf(" --quota %llu", (unsigned long long) q->quota);
 }
 
-/* parse quota option */
-static int
-parse_quota(const char *s, uint64_t * quota)
-{
-	*quota = strtoull(s, NULL, 10);
-
-#ifdef DEBUG_XT_QUOTA
-	printf("Quota: %llu\n", *quota);
-#endif
-
-	if (*quota == UINT64_MAX)
-		xtables_error(PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
-	else
-		return 1;
-}
-
-static int
-quota_parse(int c, char **argv, int invert, unsigned int *flags,
-	    const void *entry, struct xt_entry_match **match)
+static void quota_parse(struct xt_option_call *cb)
 {
-	struct xt_quota_info *info = (struct xt_quota_info *) (*match)->data;
-
-	switch (c) {
-	case '1':
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
-		if (!parse_quota(optarg, &info->quota))
-			xtables_error(PARAMETER_PROBLEM,
-				   "bad quota: '%s'", optarg);
+	struct xt_quota_info *info = cb->data;
 
-		if (invert)
-			info->flags |= XT_QUOTA_INVERT;
-		*flags |= 1;
-		break;
-	}
-	return 1;
-}
-
-static void quota_check(unsigned int flags)
-{
-	if (flags == 0)
-		xtables_error(PARAMETER_PROBLEM,
-			"quota: the --quota argument must be specified\n");
+	xtables_option_parse(cb);
+	if (cb->invert)
+		info->flags |= XT_QUOTA_INVERT;
 }
 
 static struct xtables_match quota_match = {
@@ -92,11 +56,10 @@ static struct xtables_match quota_match = {
 	.size		= XT_ALIGN(sizeof (struct xt_quota_info)),
 	.userspacesize	= offsetof(struct xt_quota_info, master),
 	.help		= quota_help,
-	.parse		= quota_parse,
-	.final_check	= quota_check,
 	.print		= quota_print,
 	.save		= quota_save,
-	.extra_opts	= quota_opts,
+	.x6_parse	= quota_parse,
+	.x6_options	= quota_opts,
 };
 
 void
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/26] libxtables: linked-list name<->id map
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (4 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 05/26] libxt_quota: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 07/26] libxt_devgroup: use guided option parser Jan Engelhardt
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

This consolidates the maps from libxt_devgroup and libxt_realm.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |   15 ++++++++
 xtoptions.c          |   99 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index c361bdb..30d9e73 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -134,6 +134,16 @@ struct xt_fcheck_call {
 	unsigned int xflags;
 };
 
+/**
+ * A "linear"/linked-list based name<->id map, for files similar to
+ * /etc/iproute2/.
+ */
+struct xtables_lmap {
+	char *name;
+	int id;
+	struct xtables_lmap *next;
+};
+
 /* Include file for additions: new matches and targets. */
 struct xtables_match
 {
@@ -418,6 +428,11 @@ extern void xtables_option_mfcall(struct xtables_match *);
 extern void xtables_options_fcheck(const char *, unsigned int,
 				   const struct xt_option_entry *);
 
+extern struct xtables_lmap *xtables_lmap_init(const char *);
+extern void xtables_lmap_free(struct xtables_lmap *);
+extern int xtables_lmap_name2id(const struct xtables_lmap *, const char *);
+extern const char *xtables_lmap_id2name(const struct xtables_lmap *, int);
+
 #ifdef XTABLES_INTERNAL
 
 /* Shipped modules rely on this... */
diff --git a/xtoptions.c b/xtoptions.c
index 4206314..f48c011 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -7,6 +7,7 @@
  *	published by the Free Software Foundation; either version 2 of
  *	the License, or (at your option) any later version.
  */
+#include <ctype.h>
 #include <errno.h>
 #include <getopt.h>
 #include <limits.h>
@@ -487,3 +488,101 @@ void xtables_option_mfcall(struct xtables_match *m)
 	if (m->x6_options != NULL)
 		xtables_options_fcheck(m->name, m->mflags, m->x6_options);
 }
+
+struct xtables_lmap *xtables_lmap_init(const char *file)
+{
+	struct xtables_lmap *lmap_head = NULL, *lmap_prev = NULL, *lmap_this;
+	char buf[512];
+	FILE *fp;
+	char *cur, *nxt;
+	int id;
+
+	fp = fopen(file, "re");
+	if (fp == NULL)
+		return NULL;
+
+	while (fgets(buf, sizeof(buf), fp) != NULL) {
+		cur = buf;
+		while (isspace(*cur))
+			++cur;
+		if (*cur == '#' || *cur == '\n' || *cur == '\0')
+			continue;
+
+		/* iproute2 allows hex and dec format */
+		errno = 0;
+		id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) == 0 ? 16 : 10);
+		if (nxt == cur || errno != 0)
+			continue;
+
+		/* same boundaries as in iproute2 */
+		if (id < 0 || id > 255)
+			continue;
+		cur = nxt;
+
+		if (!isspace(*cur))
+			continue;
+		while (isspace(*cur))
+			++cur;
+		if (*cur == '#' || *cur == '\n' || *cur == '\0')
+			continue;
+		nxt = cur;
+		while (*nxt != '\0' && !isspace(*nxt))
+			++nxt;
+		if (nxt == cur)
+			continue;
+		*nxt = '\0';
+
+		/* found valid data */
+		lmap_this = malloc(sizeof(*lmap_this));
+		if (lmap_this == NULL) {
+			perror("malloc");
+			goto out;
+		}
+		lmap_this->id   = id;
+		lmap_this->name = strdup(cur);
+		if (lmap_this->name == NULL) {
+			free(lmap_this);
+			goto out;
+		}
+		lmap_this->next = NULL;
+
+		if (lmap_prev != NULL)
+			lmap_prev->next = lmap_this;
+		else
+			lmap_head = lmap_this;
+		lmap_prev = lmap_this;
+	}
+
+	fclose(fp);
+	return lmap_head;
+ out:
+	xtables_lmap_free(lmap_head);
+	return NULL;
+}
+
+void xtables_lmap_free(struct xtables_lmap *head)
+{
+	struct xtables_lmap *next;
+
+	for (; head != NULL; head = next) {
+		next = head->next;
+		free(head->name);
+		free(head);
+	}
+}
+
+int xtables_lmap_name2id(const struct xtables_lmap *head, const char *name)
+{
+	for (; head != NULL; head = head->next)
+		if (strcmp(head->name, name) == 0)
+			return head->id;
+	return -1;
+}
+
+const char *xtables_lmap_id2name(const struct xtables_lmap *head, int id)
+{
+	for (; head != NULL; head = head->next)
+		if (head->id == id)
+			return head->name;
+	return NULL;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/26] libxt_devgroup: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (5 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 06/26] libxtables: linked-list name<->id map Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 08/26] libipt_realm: " Jan Engelhardt
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_devgroup.c |  201 +++++++++----------------------------------
 1 files changed, 41 insertions(+), 160 deletions(-)

diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c
index 2624868..a925dd0 100644
--- a/extensions/libxt_devgroup.c
+++ b/extensions/libxt_devgroup.c
@@ -2,14 +2,10 @@
  *
  * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
  */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
-#include <ctype.h>
-#include <getopt.h>
 #include <xtables.h>
 #include <linux/netfilter/xt_devgroup.h>
 
@@ -23,200 +19,84 @@ static void devgroup_help(void)
 }
 
 enum {
-	XT_DEVGROUP_OPT_SRCGROUP = 1,
-	XT_DEVGROUP_OPT_DSTGROUP,
+	O_SRC_GROUP = 0,
+	O_DST_GROUP,
 };
 
-static const struct option devgroup_opts[] = {
-	{ .name = "src-group", .has_arg = true, .val = XT_DEVGROUP_OPT_SRCGROUP },
-	{ .name = "dst-group", .has_arg = true, .val = XT_DEVGROUP_OPT_DSTGROUP },
-	XT_GETOPT_TABLEEND,
-};
-
-struct devgroupname {
-	unsigned int		id;
-	char			*name;
-	int			len;
-	struct devgroupname	*next;
+static const struct xt_option_entry devgroup_opts[] = {
+	{.name = "src-group", .id = O_SRC_GROUP, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT},
+	{.name = "dst-group", .id = O_DST_GROUP, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
 /* array of devgroups from /etc/iproute2/group_map */
-static struct devgroupname *devgroups;
-/* 1 if loading failed */
-static int rdberr;
+static struct xtables_lmap *devgroups;
 
-static void load_devgroups(void)
+static void devgroup_init(struct xt_entry_match *match)
 {
-	const char* rfnm = "/etc/iproute2/group_map";
-	char buf[512];
-	FILE *fil;
-	char *cur, *nxt;
-	int id;
-	struct devgroupname *oldnm = NULL, *newnm = NULL;
-
-	fil = fopen(rfnm, "r");
-	if (!fil) {
-		rdberr = 1;
-		return;
-	}
-
-	while (fgets(buf, sizeof(buf), fil)) {
-		cur = buf;
-		while ((*cur == ' ') || (*cur == '\t'))
-			cur++;
-		if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
-			continue;
-
-		/* iproute2 allows hex and dec format */
-		errno = 0;
-		id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
-		if ((nxt == cur) || errno)
-			continue;
-
-		/* same boundaries as in iproute2 */
-		if (id < 0 || id > 255)
-			continue;
-		cur = nxt;
-
-		if (!isspace(*cur))
-			continue;
-		while ((*cur == ' ') || (*cur == '\t'))
-			cur++;
-		if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
-			continue;
-		nxt = cur;
-		while ((*nxt != 0) && !isspace(*nxt))
-			nxt++;
-		if (nxt == cur)
-			continue;
-
-		/* found valid data */
-		newnm = malloc(sizeof(struct devgroupname));
-		if (newnm == NULL) {
-			perror("libxt_devgroup: malloc failed");
-			exit(1);
-		}
-		newnm->id = id;
-		newnm->len = nxt - cur;
-		newnm->name = malloc(newnm->len + 1);
-		if (newnm->name == NULL) {
-			perror("libxt_devgroup: malloc failed");
-			exit(1);
-		}
-		strncpy(newnm->name, cur, newnm->len);
-		newnm->name[newnm->len] = 0;
-		newnm->next = NULL;
-
-		if (oldnm)
-			oldnm->next = newnm;
-		else
-			devgroups = newnm;
-		oldnm = newnm;
-	}
-
-	fclose(fil);
-}
-
-/* get devgroup id for name, -1 if error/not found */
-static int devgroup_name2id(const char* name)
-{
-	struct devgroupname* cur;
-
-	if ((devgroups == NULL) && (rdberr == 0))
-		load_devgroups();
-	cur = devgroups;
-	if (cur == NULL)
-		return -1;
-	while (cur) {
-		if (!strncmp(name, cur->name, cur->len + 1))
-			return cur->id;
-		cur = cur->next;
-	}
-	return -1;
-}
-
-/* get devgroup name for id, NULL if error/not found */
-static const char *devgroup_id2name(int id)
-{
-	struct devgroupname* cur;
-
-	if ((devgroups == NULL) && (rdberr == 0))
-		load_devgroups();
-	cur = devgroups;
-	if (cur == NULL)
-		return NULL;
-	while (cur) {
-		if (id == cur->id)
-			return cur->name;
-		cur = cur->next;
-	}
-	return NULL;
+	const char file[] = "/etc/iproute2/group_map";
+	devgroups = xtables_lmap_init(file);
+	if (devgroups == NULL && errno != ENOENT)
+		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
 }
 
-static int devgroup_parse(int c, char **argv, int invert, unsigned int *flags,
-                       const void *entry, struct xt_entry_match **match)
+static void devgroup_parse(struct xt_option_call *cb)
 {
-	struct xt_devgroup_info *info = (struct xt_devgroup_info *)(*match)->data;
+	struct xt_devgroup_info *info = cb->data;
 	unsigned int id;
 	char *end;
 
-	switch (c) {
-	case XT_DEVGROUP_OPT_SRCGROUP:
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		end = optarg;
-		info->src_group = strtoul(optarg, &end, 0);
-		if (end != optarg && (*end == '/' || *end == '\0')) {
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SRC_GROUP:
+		info->src_group = strtoul(cb->arg, &end, 0);
+		if (end != cb->arg && (*end == '/' || *end == '\0')) {
 			if (*end == '/')
 				info->src_mask = strtoul(end+1, &end, 0);
 			else
 				info->src_mask = 0xffffffff;
-			if (*end != '\0' || end == optarg)
+			if (*end != '\0' || end == cb->arg)
 				xtables_error(PARAMETER_PROBLEM,
 					      "Bad src-group value `%s'",
-					      optarg);
+					      cb->arg);
 		} else {
-			id = devgroup_name2id(optarg);
+			id = xtables_lmap_name2id(devgroups, cb->arg);
 			if (id == -1)
 				xtables_error(PARAMETER_PROBLEM,
 					      "Device group `%s' not found",
-					      optarg);
+					      cb->arg);
 			info->src_group = id;
 			info->src_mask  = 0xffffffff;
 		}
-		info->flags |= XT_DEVGROUP_MATCH_SRC;
-		if (invert)
+		if (cb->invert)
 			info->flags |= XT_DEVGROUP_INVERT_SRC;
-		*flags |= c;
 		break;
-	case XT_DEVGROUP_OPT_DSTGROUP:
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		end = optarg;
-		info->dst_group = strtoul(optarg, &end, 0);
-		if (end != optarg && (*end == '/' || *end == '\0')) {
+	case O_DST_GROUP:
+		info->dst_group = strtoul(cb->arg, &end, 0);
+		if (end != cb->arg && (*end == '/' || *end == '\0')) {
 			if (*end == '/')
 				info->dst_mask = strtoul(end+1, &end, 0);
 			else
 				info->dst_mask = 0xffffffff;
-			if (*end != '\0' || end == optarg)
+			if (*end != '\0' || end == cb->arg)
 				xtables_error(PARAMETER_PROBLEM,
 					      "Bad dst-group value `%s'",
-					      optarg);
+					      cb->arg);
 		} else {
-			id = devgroup_name2id(optarg);
+			id = xtables_lmap_name2id(devgroups, cb->arg);
 			if (id == -1)
 				xtables_error(PARAMETER_PROBLEM,
 					      "Device group `%s' not found",
-					      optarg);
+					      cb->arg);
 			info->dst_group = id;
 			info->dst_mask  = 0xffffffff;
 		}
-		info->flags |= XT_DEVGROUP_MATCH_DST;
-		if (invert)
+		if (cb->invert)
 			info->flags |= XT_DEVGROUP_INVERT_DST;
-		*flags |= c;
 		break;
 	}
-	return 1;
 }
 
 static void
@@ -228,7 +108,7 @@ print_devgroup(unsigned int id, unsigned int mask, int numeric)
 		printf("0x%x/0x%x", id, mask);
 	else {
 		if (numeric == 0)
-			name = devgroup_id2name(id);
+			name = xtables_lmap_id2name(devgroups, id);
 		if (name)
 			printf("%s", name);
 		else
@@ -269,9 +149,9 @@ static void devgroup_save(const void *ip, const struct xt_entry_match *match)
 	devgroup_show("--", info, 0);
 }
 
-static void devgroup_check(unsigned int flags)
+static void devgroup_check(struct xt_fcheck_call *cb)
 {
-	if (!flags)
+	if (cb->xflags == 0)
 		xtables_error(PARAMETER_PROBLEM,
 			      "devgroup match: You must specify either "
 			      "'--src-group' or '--dst-group'");
@@ -283,12 +163,13 @@ static struct xtables_match devgroup_mt_reg = {
 	.family		= NFPROTO_UNSPEC,
 	.size		= XT_ALIGN(sizeof(struct xt_devgroup_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_devgroup_info)),
+	.init		= devgroup_init,
 	.help		= devgroup_help,
-	.parse		= devgroup_parse,
-	.final_check	= devgroup_check,
 	.print		= devgroup_print,
 	.save		= devgroup_save,
-	.extra_opts	= devgroup_opts,
+	.x6_parse	= devgroup_parse,
+	.x6_fcheck	= devgroup_check,
+	.x6_options	= devgroup_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/26] libipt_realm: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (6 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 07/26] libxt_devgroup: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 09/26] libxtables: XTTYPE_UINT16RC support Jan Engelhardt
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libipt_realm.c |  202 +++++++++------------------------------------
 1 files changed, 39 insertions(+), 163 deletions(-)

diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c
index 17b1754..b60c57e 100644
--- a/extensions/libipt_realm.c
+++ b/extensions/libipt_realm.c
@@ -1,12 +1,7 @@
-/* Shared library add-on to iptables to add realm matching support. */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
-#include <ctype.h>
-#include <getopt.h>
 #if defined(__GLIBC__) && __GLIBC__ == 2
 #include <net/ethernet.h>
 #else
@@ -15,6 +10,10 @@
 #include <xtables.h>
 #include <linux/netfilter_ipv4/ipt_realm.h>
 
+enum {
+	O_REALM = 0,
+};
+
 static void realm_help(void)
 {
 	printf(
@@ -23,165 +22,49 @@ static void realm_help(void)
 "				Match realm\n");
 }
 
-static const struct option realm_opts[] = {
-	{.name = "realm", .has_arg = true, .val = '1'},
-	XT_GETOPT_TABLEEND,
-};
-
-struct realmname { 
-	int	id;
-	char*	name;
-	int	len;
-	struct realmname* next;
+static const struct xt_option_entry realm_opts[] = {
+	{.name = "realm", .id = O_REALM, .type = XTTYPE_STRING,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
 /* array of realms from /etc/iproute2/rt_realms */
-static struct realmname *realms;
-/* 1 if loading failed */
-static int rdberr;
+static struct xtables_lmap *realms;
 
-static void load_realms(void)
+static void realm_init(struct xt_entry_match *m)
 {
-	const char* rfnm = "/etc/iproute2/rt_realms";
-	char buf[512];
-	FILE *fil;
-	char *cur, *nxt;
-	int id;
-	struct realmname *oldnm = NULL, *newnm = NULL;
-
-	fil = fopen(rfnm, "re");
-	if (!fil) {
-		rdberr = 1;
-		return;
-	}
-
-	while (fgets(buf, sizeof(buf), fil)) {
-		cur = buf;
-		while ((*cur == ' ') || (*cur == '\t'))
-			cur++;
-		if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
-			continue;
-
-		/* iproute2 allows hex and dec format */
-		errno = 0;
-		id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
-		if ((nxt == cur) || errno)
-			continue;
-
-		/* same boundaries as in iproute2 */
-		if (id < 0 || id > 255)
-			continue;
-		cur = nxt;
-
-		if (!isspace(*cur))
-			continue;
-		while ((*cur == ' ') || (*cur == '\t'))
-			cur++;
-		if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
-			continue;
-		nxt = cur;
-		while ((*nxt != 0) && !isspace(*nxt))
-			nxt++;
-		if (nxt == cur)
-			continue;
-
-		/* found valid data */
-		newnm = malloc(sizeof(struct realmname));
-		if (newnm == NULL) {
-			perror("libipt_realm: malloc failed");
-			exit(1);
-		}
-		newnm->id = id;
-		newnm->len = nxt - cur;
-		newnm->name = malloc(newnm->len + 1);
-		if (newnm->name == NULL) {
-			perror("libipt_realm: malloc failed");
-			exit(1);
-		}
-		strncpy(newnm->name, cur, newnm->len);
-		newnm->name[newnm->len] = 0;
-		newnm->next = NULL;
-
-		if (oldnm)
-			oldnm->next = newnm;
-		else
-			realms = newnm;
-		oldnm = newnm;
-	}
-
-	fclose(fil);
+	const char file[] = "/etc/iproute2/rt_realms";
+	realms = xtables_lmap_init(file);
+	if (realms == NULL && errno != ENOENT)
+		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
 }
 
-/* get realm id for name, -1 if error/not found */
-static int realm_name2id(const char* name)
+static void realm_parse(struct xt_option_call *cb)
 {
-	struct realmname* cur;
-
-	if ((realms == NULL) && (rdberr == 0))
-		load_realms();
-	cur = realms;
-	if (cur == NULL)
-		return -1;
-	while (cur) {
-		if (!strncmp(name, cur->name, cur->len + 1))
-			return cur->id;
-		cur = cur->next;
-	}
-	return -1;
-}
-
-/* get realm name for id, NULL if error/not found */
-static const char *realm_id2name(int id)
-{
-	struct realmname* cur;
-
-	if ((realms == NULL) && (rdberr == 0))
-		load_realms();
-	cur = realms;
-	if (cur == NULL)
-		return NULL;
-	while (cur) {
-		if (id == cur->id)
-			return cur->name;
-		cur = cur->next;
-	}
-	return NULL;
-}
-
-static int realm_parse(int c, char **argv, int invert, unsigned int *flags,
-                       const void *entry, struct xt_entry_match **match)
-{
-	struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data;
+	struct ipt_realm_info *realminfo = cb->data;
 	int id;
+	char *end;
 
-	switch (c) {
-		char *end;
-	case '1':
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		end = optarg = optarg;
-		realminfo->id = strtoul(optarg, &end, 0);
-		if (end != optarg && (*end == '/' || *end == '\0')) {
-			if (*end == '/')
-				realminfo->mask = strtoul(end+1, &end, 0);
-			else
-				realminfo->mask = 0xffffffff;
-			if (*end != '\0' || end == optarg)
-				xtables_error(PARAMETER_PROBLEM,
-					   "Bad realm value `%s'", optarg);
-		} else {
-			id = realm_name2id(optarg);
-			if (id == -1)
-				xtables_error(PARAMETER_PROBLEM,
-					   "Realm `%s' not found", optarg);
-			realminfo->id = id;
+	xtables_option_parse(cb);
+	realminfo->id = strtoul(cb->arg, &end, 0);
+	if (end != cb->arg && (*end == '/' || *end == '\0')) {
+		if (*end == '/')
+			realminfo->mask = strtoul(end+1, &end, 0);
+		else
 			realminfo->mask = 0xffffffff;
-		}
-		if (invert)
-			realminfo->invert = 1;
-		*flags = 1;
-		break;
+		if (*end != '\0' || end == cb->arg)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Bad realm value \"%s\"", cb->arg);
+	} else {
+		id = xtables_lmap_name2id(realms, cb->arg);
+		if (id == -1)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Realm \"%s\" not found", cb->arg);
+		realminfo->id = id;
+		realminfo->mask = 0xffffffff;
 	}
-	return 1;
+	if (cb->invert)
+		realminfo->invert = 1;
 }
 
 static void
@@ -193,7 +76,7 @@ print_realm(unsigned long id, unsigned long mask, int numeric)
 		printf(" 0x%lx/0x%lx", id, mask);
 	else {
 		if (numeric == 0)
-			name = realm_id2name(id);
+			name = xtables_lmap_id2name(realms, id);
 		if (name)
 			printf(" %s", name);
 		else
@@ -224,13 +107,6 @@ static void realm_save(const void *ip, const struct xt_entry_match *match)
 	print_realm(ri->id, ri->mask, 0);
 }
 
-static void realm_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			   "realm match: You must specify `--realm'");
-}
-
 static struct xtables_match realm_mt_reg = {
 	.name		= "realm",
 	.version	= XTABLES_VERSION,
@@ -238,11 +114,11 @@ static struct xtables_match realm_mt_reg = {
 	.size		= XT_ALIGN(sizeof(struct ipt_realm_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct ipt_realm_info)),
 	.help		= realm_help,
-	.parse		= realm_parse,
-	.final_check	= realm_check,
+	.init		= realm_init,
 	.print		= realm_print,
 	.save		= realm_save,
-	.extra_opts	= realm_opts,
+	.x6_parse	= realm_parse,
+	.x6_options	= realm_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/26] libxtables: XTTYPE_UINT16RC support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (7 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 08/26] libipt_realm: " Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 10/26] libxt_length: use guided option parser Jan Engelhardt
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    2 ++
 xtoptions.c          |   28 +++++++++++++++++++++-------
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index 30d9e73..ae76bb6 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -57,6 +57,7 @@ enum xt_option_type {
 	XTTYPE_UINT8,
 	XTTYPE_UINT32,
 	XTTYPE_UINT64,
+	XTTYPE_UINT16RC,
 	XTTYPE_UINT32RC,
 	XTTYPE_STRING,
 	XTTYPE_MARKMASK32,
@@ -115,6 +116,7 @@ struct xt_option_call {
 	uint8_t nvals;
 	union {
 		uint8_t u8;
+		uint16_t u16_range[2];
 		uint32_t u32, u32_range[2];
 		uint64_t u64;
 		struct {
diff --git a/xtoptions.c b/xtoptions.c
index f48c011..ca5bffa 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -133,15 +133,18 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 {
 	const struct xt_option_entry *entry = cb->entry;
 	const char *arg = cb->arg;
-	uint32_t *put = XTOPT_MKPTR(cb);
+	size_t esize = sizeof(uint32_t);
+	char *put = XTOPT_MKPTR(cb);
 	unsigned int maxiter, value;
 	char *end = "";
 	char sep = ':';
 
-	maxiter = entry->size / sizeof(uint32_t);
+	if (entry->type == XTTYPE_UINT16RC)
+		esize = sizeof(uint16_t);
+	maxiter = entry->size / esize;
 	if (maxiter == 0)
 		maxiter = 2; /* ARRAY_SIZE(cb->val.uXX_range) */
-	if (entry->size % sizeof(uint32_t) != 0)
+	if (entry->size % esize != 0)
 		xt_params->exit_err(OTHER_PROBLEM, "%s: memory block does "
 			"not have proper size\n", __func__);
 
@@ -161,10 +164,19 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 				"%s: Argument to \"--%s\" has unexpected "
 				"characters.\n", cb->ext_name, entry->name);
 		++cb->nvals;
-		if (cb->nvals < ARRAY_SIZE(cb->val.u32_range))
-			cb->val.u32_range[cb->nvals] = value;
-		if (entry->flags & XTOPT_PUT)
-			*put++ = value;
+		if (cb->nvals < ARRAY_SIZE(cb->val.u32_range)) {
+			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;
+		}
+		if (entry->flags & XTOPT_PUT) {
+			if (entry->type == XTTYPE_UINT16RC)
+				*(uint16_t *)put = value;
+			else if (entry->type == XTTYPE_UINT32RC)
+				*(uint32_t *)put = value;
+			put += esize;
+		}
 		if (*end == '\0')
 			break;
 	}
@@ -225,6 +237,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT32]      = xtopt_parse_int,
 	[XTTYPE_UINT64]      = xtopt_parse_int,
+	[XTTYPE_UINT16RC]    = xtopt_parse_mint,
 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
@@ -234,6 +247,7 @@ static const size_t xtopt_psize[] = {
 	[XTTYPE_UINT8]       = sizeof(uint8_t),
 	[XTTYPE_UINT32]      = sizeof(uint32_t),
 	[XTTYPE_UINT64]      = sizeof(uint64_t),
+	[XTTYPE_UINT16RC]    = sizeof(uint16_t[2]),
 	[XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
 	[XTTYPE_STRING]      = -1,
 };
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/26] libxt_length: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (8 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 09/26] libxtables: XTTYPE_UINT16RC support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 11/26] libxt_tcpmss: " Jan Engelhardt
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_length.c |   92 ++++++++------------------------------------
 1 files changed, 17 insertions(+), 75 deletions(-)

diff --git a/extensions/libxt_length.c b/extensions/libxt_length.c
index a12aefe..4f3a331 100644
--- a/extensions/libxt_length.c
+++ b/extensions/libxt_length.c
@@ -1,14 +1,11 @@
-/* Shared library add-on to iptables to add packet length matching support. */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
 #include <linux/netfilter/xt_length.h>
 
+enum {
+	O_LENGTH = 0,
+};
+
 static void length_help(void)
 {
 	printf(
@@ -17,75 +14,21 @@ static void length_help(void)
 "                                of values (inclusive)\n");
 }
   
-static const struct option length_opts[] = {
-	{.name = "length", .has_arg = true, .val = '1'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry length_opts[] = {
+	{.name = "length", .id = O_LENGTH, .type = XTTYPE_UINT16RC,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
-static uint16_t
-parse_length(const char *s)
-{
-	unsigned int len;
-	
-	if (!xtables_strtoui(s, NULL, &len, 0, UINT32_MAX))
-		xtables_error(PARAMETER_PROBLEM, "length 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_lengths(const char *s, struct xt_length_info *info)
-{
-	char *buffer;
-	char *cp;
-
-	buffer = strdup(s);
-	if ((cp = strchr(buffer, ':')) == NULL)
-		info->min = info->max = parse_length(buffer);
-	else {
-		*cp = '\0';
-		cp++;
-
-		info->min = buffer[0] ? parse_length(buffer) : 0;
-		info->max = cp[0] ? parse_length(cp) : 0xFFFF;
-	}
-	free(buffer);
-	
-	if (info->min > info->max)
-		xtables_error(PARAMETER_PROBLEM,
-		           "length min. range value `%u' greater than max. "
-		           "range value `%u'", info->min, info->max);
-	
-}
-
-static int
-length_parse(int c, char **argv, int invert, unsigned int *flags,
-             const void *entry, struct xt_entry_match **match)
+static void length_parse(struct xt_option_call *cb)
 {
-	struct xt_length_info *info = (struct xt_length_info *)(*match)->data;
-
-	switch (c) {
-		case '1':
-			if (*flags)
-				xtables_error(PARAMETER_PROBLEM,
-				           "length: `--length' may only be "
-				           "specified once");
-			xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-			parse_lengths(optarg, info);
-			if (invert)
-				info->invert = 1;
-			*flags = 1;
-			break;
-	}
-	return 1;
-}
+	struct xt_length_info *info = cb->data;
 
-static void length_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			   "length: You must specify `--length'");
+	xtables_option_parse(cb);
+	info->min = cb->val.u16_range[0];
+	info->max = (cb->nvals == 2) ? cb->val.u16_range[1] : UINT16_MAX;
+	if (cb->invert)
+		info->invert = 1;
 }
 
 static void
@@ -118,11 +61,10 @@ static struct xtables_match length_match = {
 	.size		= XT_ALIGN(sizeof(struct xt_length_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_length_info)),
 	.help		= length_help,
-	.parse		= length_parse,
-	.final_check	= length_check,
 	.print		= length_print,
 	.save		= length_save,
-	.extra_opts	= length_opts,
+	.x6_parse	= length_parse,
+	.x6_options	= length_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 11/26] libxt_tcpmss: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (9 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 10/26] libxt_length: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 12/26] libxtables: XTTYPE_UINT8RC support Jan Engelhardt
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_tcpmss.c |   92 ++++++++++-----------------------------------
 1 files changed, 20 insertions(+), 72 deletions(-)

diff --git a/extensions/libxt_tcpmss.c b/extensions/libxt_tcpmss.c
index 3dc3528..c7c5971 100644
--- a/extensions/libxt_tcpmss.c
+++ b/extensions/libxt_tcpmss.c
@@ -1,14 +1,11 @@
-/* Shared library add-on to iptables to add tcp MSS matching support. */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
 #include <linux/netfilter/xt_tcpmss.h>
 
+enum {
+	O_TCPMSS = 0,
+};
+
 static void tcpmss_help(void)
 {
 	printf(
@@ -17,71 +14,23 @@ static void tcpmss_help(void)
 "				(only valid for TCP SYN or SYN/ACK packets)\n");
 }
 
-static const struct option tcpmss_opts[] = {
-	{.name = "mss", .has_arg = true, .val = '1'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry tcpmss_opts[] = {
+	{.name = "mss", .id = O_TCPMSS, .type = XTTYPE_UINT16RC,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	XTOPT_TABLEEND,
 };
 
-static uint16_t
-parse_tcp_mssvalue(const char *mssvalue)
-{
-	unsigned int mssvaluenum;
-
-	if (xtables_strtoui(mssvalue, NULL, &mssvaluenum, 0, UINT16_MAX))
-		return mssvaluenum;
-
-	xtables_error(PARAMETER_PROBLEM,
-		   "Invalid mss `%s' specified", mssvalue);
-}
-
-static void
-parse_tcp_mssvalues(const char *mssvaluestring,
-		    uint16_t *mss_min, uint16_t *mss_max)
-{
-	char *buffer;
-	char *cp;
-
-	buffer = strdup(mssvaluestring);
-	if ((cp = strchr(buffer, ':')) == NULL)
-		*mss_min = *mss_max = parse_tcp_mssvalue(buffer);
-	else {
-		*cp = '\0';
-		cp++;
-
-		*mss_min = buffer[0] ? parse_tcp_mssvalue(buffer) : 0;
-		*mss_max = cp[0] ? parse_tcp_mssvalue(cp) : 0xFFFF;
-	}
-	free(buffer);
-}
-
-static int
-tcpmss_parse(int c, char **argv, int invert, unsigned int *flags,
-             const void *entry, struct xt_entry_match **match)
-{
-	struct xt_tcpmss_match_info *mssinfo =
-		(struct xt_tcpmss_match_info *)(*match)->data;
-
-	switch (c) {
-	case '1':
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Only one `--mss' allowed");
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		parse_tcp_mssvalues(optarg,
-				    &mssinfo->mss_min, &mssinfo->mss_max);
-		if (invert)
-			mssinfo->invert = 1;
-		*flags = 1;
-		break;
-	}
-	return 1;
-}
-
-static void tcpmss_check(unsigned int flags)
+static void tcpmss_parse(struct xt_option_call *cb)
 {
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			   "tcpmss match: You must specify `--mss'");
+	struct xt_tcpmss_match_info *mssinfo = cb->data;
+
+	xtables_option_parse(cb);
+	mssinfo->mss_min = cb->val.u16_range[0];
+	mssinfo->mss_max = mssinfo->mss_min;
+	if (cb->nvals == 2)
+		mssinfo->mss_max = cb->val.u16_range[1];
+	if (cb->invert)
+		mssinfo->invert = 1;
 }
 
 static void
@@ -114,11 +63,10 @@ static struct xtables_match tcpmss_match = {
 	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_match_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_match_info)),
 	.help		= tcpmss_help,
-	.parse		= tcpmss_parse,
-	.final_check	= tcpmss_check,
 	.print		= tcpmss_print,
 	.save		= tcpmss_save,
-	.extra_opts	= tcpmss_opts,
+	.x6_parse	= tcpmss_parse,
+	.x6_options	= tcpmss_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 12/26] libxtables: XTTYPE_UINT8RC support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (10 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 11/26] libxt_tcpmss: " Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 13/26] libxtables: XTTYPE_UINT64RC support Jan Engelhardt
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    3 ++-
 xtoptions.c          |   14 +++++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index ae76bb6..8f65b05 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -57,6 +57,7 @@ enum xt_option_type {
 	XTTYPE_UINT8,
 	XTTYPE_UINT32,
 	XTTYPE_UINT64,
+	XTTYPE_UINT8RC,
 	XTTYPE_UINT16RC,
 	XTTYPE_UINT32RC,
 	XTTYPE_STRING,
@@ -115,7 +116,7 @@ struct xt_option_call {
 	bool invert;
 	uint8_t nvals;
 	union {
-		uint8_t u8;
+		uint8_t u8, u8_range[2];
 		uint16_t u16_range[2];
 		uint32_t u32, u32_range[2];
 		uint64_t u64;
diff --git a/xtoptions.c b/xtoptions.c
index ca5bffa..babc827 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -139,7 +139,9 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 	char *end = "";
 	char sep = ':';
 
-	if (entry->type == XTTYPE_UINT16RC)
+	if (entry->type == XTTYPE_UINT8RC)
+		esize = sizeof(uint8_t);
+	else if (entry->type == XTTYPE_UINT16RC)
 		esize = sizeof(uint16_t);
 	maxiter = entry->size / esize;
 	if (maxiter == 0)
@@ -165,13 +167,17 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 				"characters.\n", cb->ext_name, entry->name);
 		++cb->nvals;
 		if (cb->nvals < ARRAY_SIZE(cb->val.u32_range)) {
-			if (entry->type == XTTYPE_UINT16RC)
+			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;
 		}
 		if (entry->flags & XTOPT_PUT) {
-			if (entry->type == XTTYPE_UINT16RC)
+			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;
@@ -237,6 +243,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT32]      = xtopt_parse_int,
 	[XTTYPE_UINT64]      = xtopt_parse_int,
+	[XTTYPE_UINT8RC]     = xtopt_parse_mint,
 	[XTTYPE_UINT16RC]    = xtopt_parse_mint,
 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
@@ -247,6 +254,7 @@ static const size_t xtopt_psize[] = {
 	[XTTYPE_UINT8]       = sizeof(uint8_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_STRING]      = -1,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 13/26] libxtables: XTTYPE_UINT64RC support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (11 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 12/26] libxtables: XTTYPE_UINT8RC support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 14/26] libxt_connbytes: use guided option parser Jan Engelhardt
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    3 ++-
 xtoptions.c          |    8 ++++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index 8f65b05..325c04c 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -60,6 +60,7 @@ enum xt_option_type {
 	XTTYPE_UINT8RC,
 	XTTYPE_UINT16RC,
 	XTTYPE_UINT32RC,
+	XTTYPE_UINT64RC,
 	XTTYPE_STRING,
 	XTTYPE_MARKMASK32,
 };
@@ -119,7 +120,7 @@ struct xt_option_call {
 		uint8_t u8, u8_range[2];
 		uint16_t u16_range[2];
 		uint32_t u32, u32_range[2];
-		uint64_t u64;
+		uint64_t u64, u64_range[2];
 		struct {
 			uint32_t mark, mask;
 		};
diff --git a/xtoptions.c b/xtoptions.c
index babc827..a74938f 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -143,6 +143,8 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 		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) */
@@ -173,6 +175,8 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 				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;
 		}
 		if (entry->flags & XTOPT_PUT) {
 			if (entry->type == XTTYPE_UINT8RC)
@@ -181,6 +185,8 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 				*(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;
 		}
 		if (*end == '\0')
@@ -246,6 +252,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8RC]     = xtopt_parse_mint,
 	[XTTYPE_UINT16RC]    = xtopt_parse_mint,
 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
+	[XTTYPE_UINT64RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
 };
@@ -257,6 +264,7 @@ static const size_t xtopt_psize[] = {
 	[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_STRING]      = -1,
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 14/26] libxt_connbytes: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (12 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 13/26] libxtables: XTTYPE_UINT64RC support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 15/26] libxtables: XTTYPE_UINT16 support Jan Engelhardt
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_connbytes.c |  107 +++++++++++++++---------------------------
 1 files changed, 38 insertions(+), 69 deletions(-)

diff --git a/extensions/libxt_connbytes.c b/extensions/libxt_connbytes.c
index 1d3391a..46a7e4b 100644
--- a/extensions/libxt_connbytes.c
+++ b/extensions/libxt_connbytes.c
@@ -1,14 +1,14 @@
-/* Shared library add-on to iptables to add byte tracking support. */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
 #include <xtables.h>
-#include <linux/netfilter/nf_conntrack_common.h>
 #include <linux/netfilter/xt_connbytes.h>
 
+enum {
+	O_CONNBYTES = 0,
+	O_CONNBYTES_DIR,
+	O_CONNBYTES_MODE,
+};
+
 static void connbytes_help(void)
 {
 	printf(
@@ -18,87 +18,57 @@ static void connbytes_help(void)
 "     --connbytes-mode [packets, bytes, avgpkt]\n");
 }
 
-static const struct option connbytes_opts[] = {
-	{.name = "connbytes",      .has_arg = true, .val = '1'},
-	{.name = "connbytes-dir",  .has_arg = true, .val = '2'},
-	{.name = "connbytes-mode", .has_arg = true, .val = '3'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry connbytes_opts[] = {
+	{.name = "connbytes", .id = O_CONNBYTES, .type = XTTYPE_UINT64RC,
+	 .flags = XTOPT_MAND | XTOPT_INVERT},
+	{.name = "connbytes-dir", .id = O_CONNBYTES_DIR, .type = XTTYPE_STRING,
+	 .flags = XTOPT_MAND},
+	{.name = "connbytes-mode", .id = O_CONNBYTES_MODE,
+	 .type = XTTYPE_STRING, .flags = XTOPT_MAND},
+	XTOPT_TABLEEND,
 };
 
-static void
-parse_range(const char *arg, struct xt_connbytes_info *si)
-{
-	char *colon,*p;
-
-	si->count.from = strtoul(arg,&colon,10);
-	if (*colon != ':') 
-		xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", arg);
-	si->count.to = strtoul(colon+1,&p,10);
-	if (p == colon+1) {
-		/* second number omited */
-		si->count.to = 0xffffffff;
-	}
-	if (si->count.from > si->count.to)
-		xtables_error(PARAMETER_PROBLEM, "%llu should be less than %llu",
-			   (unsigned long long)si->count.from,
-			   (unsigned long long)si->count.to);
-}
-
-static int
-connbytes_parse(int c, char **argv, int invert, unsigned int *flags,
-                const void *entry, struct xt_entry_match **match)
+static void connbytes_parse(struct xt_option_call *cb)
 {
-	struct xt_connbytes_info *sinfo = (struct xt_connbytes_info *)(*match)->data;
-	unsigned long i;
-
-	switch (c) {
-	case '1':
-		if (xtables_check_inverse(optarg, &invert, &optind, 0, argv))
-			optind++;
-
-		parse_range(optarg, sinfo);
-		if (invert) {
+	struct xt_connbytes_info *sinfo = cb->data;
+	unsigned long long i;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_CONNBYTES:
+		sinfo->count.from = cb->val.u64_range[0];
+		sinfo->count.to   = cb->val.u64_range[0];
+		if (cb->nvals == 2)
+			sinfo->count.to = cb->val.u64_range[1];
+		if (cb->invert) {
 			i = sinfo->count.from;
 			sinfo->count.from = sinfo->count.to;
 			sinfo->count.to = i;
 		}
-		*flags |= 1;
 		break;
-	case '2':
-		if (!strcmp(optarg, "original"))
+	case O_CONNBYTES_DIR:
+		if (strcmp(cb->arg, "original") == 0)
 			sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL;
-		else if (!strcmp(optarg, "reply"))
+		else if (strcmp(cb->arg, "reply") == 0)
 			sinfo->direction = XT_CONNBYTES_DIR_REPLY;
-		else if (!strcmp(optarg, "both"))
+		else if (strcmp(cb->arg, "both") == 0)
 			sinfo->direction = XT_CONNBYTES_DIR_BOTH;
 		else
 			xtables_error(PARAMETER_PROBLEM,
-				   "Unknown --connbytes-dir `%s'", optarg);
-
-		*flags |= 2;
+				   "Unknown --connbytes-dir `%s'", cb->arg);
 		break;
-	case '3':
-		if (!strcmp(optarg, "packets"))
+	case O_CONNBYTES_MODE:
+		if (strcmp(cb->arg, "packets") == 0)
 			sinfo->what = XT_CONNBYTES_PKTS;
-		else if (!strcmp(optarg, "bytes"))
+		else if (strcmp(cb->arg, "bytes") == 0)
 			sinfo->what = XT_CONNBYTES_BYTES;
-		else if (!strcmp(optarg, "avgpkt"))
+		else if (strcmp(cb->arg, "avgpkt") == 0)
 			sinfo->what = XT_CONNBYTES_AVGPKT;
 		else
 			xtables_error(PARAMETER_PROBLEM,
-				   "Unknown --connbytes-mode `%s'", optarg);
-		*flags |= 4;
+				   "Unknown --connbytes-mode `%s'", cb->arg);
 		break;
 	}
-
-	return 1;
-}
-
-static void connbytes_check(unsigned int flags)
-{
-	if (flags != 7)
-		xtables_error(PARAMETER_PROBLEM, "You must specify `--connbytes'"
-			   "`--connbytes-dir' and `--connbytes-mode'");
 }
 
 static void print_mode(const struct xt_connbytes_info *sinfo)
@@ -185,11 +155,10 @@ static struct xtables_match connbytes_match = {
 	.size 		= XT_ALIGN(sizeof(struct xt_connbytes_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_connbytes_info)),
 	.help		= connbytes_help,
-	.parse		= connbytes_parse,
-	.final_check	= connbytes_check,
 	.print		= connbytes_print,
 	.save 		= connbytes_save,
-	.extra_opts	= connbytes_opts,
+	.x6_parse	= connbytes_parse,
+	.x6_options	= connbytes_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 15/26] libxtables: XTTYPE_UINT16 support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (13 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 14/26] libxt_connbytes: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 16/26] libxt_CT: use guided option parser Jan Engelhardt
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    3 ++-
 xtoptions.c          |    8 ++++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index 325c04c..6167f4d 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -55,6 +55,7 @@ struct in_addr;
 enum xt_option_type {
 	XTTYPE_NONE,
 	XTTYPE_UINT8,
+	XTTYPE_UINT16,
 	XTTYPE_UINT32,
 	XTTYPE_UINT64,
 	XTTYPE_UINT8RC,
@@ -118,7 +119,7 @@ struct xt_option_call {
 	uint8_t nvals;
 	union {
 		uint8_t u8, u8_range[2];
-		uint16_t u16_range[2];
+		uint16_t u16, u16_range[2];
 		uint32_t u32, u32_range[2];
 		uint64_t u64, u64_range[2];
 		struct {
diff --git a/xtoptions.c b/xtoptions.c
index a74938f..939e686 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -92,6 +92,8 @@ static void xtopt_parse_int(struct xt_option_call *cb)
 
 	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)
@@ -109,6 +111,10 @@ static void xtopt_parse_int(struct xt_option_call *cb)
 		cb->val.u8 = value;
 		if (entry->flags & XTOPT_PUT)
 			*(uint8_t *)XTOPT_MKPTR(cb) = cb->val.u8;
+	} else if (entry->type == XTTYPE_UINT16) {
+		cb->val.u16 = value;
+		if (entry->flags & XTOPT_PUT)
+			*(uint16_t *)XTOPT_MKPTR(cb) = cb->val.u16;
 	} else if (entry->type == XTTYPE_UINT32) {
 		cb->val.u32 = value;
 		if (entry->flags & XTOPT_PUT)
@@ -247,6 +253,7 @@ static void xtopt_parse_markmask(struct xt_option_call *cb)
 
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
+	[XTTYPE_UINT16]      = xtopt_parse_int,
 	[XTTYPE_UINT32]      = xtopt_parse_int,
 	[XTTYPE_UINT64]      = xtopt_parse_int,
 	[XTTYPE_UINT8RC]     = xtopt_parse_mint,
@@ -259,6 +266,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 
 static const size_t xtopt_psize[] = {
 	[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]),
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 16/26] libxt_CT: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (14 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 15/26] libxtables: XTTYPE_UINT16 support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 17/26] libxt_NFQUEUE: " Jan Engelhardt
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_CT.c |   74 ++++++++++++++++++------------------------------
 1 files changed, 28 insertions(+), 46 deletions(-)

diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
index 38ee17b..7b93bfa 100644
--- a/extensions/libxt_CT.c
+++ b/extensions/libxt_CT.c
@@ -1,9 +1,5 @@
-#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <getopt.h>
 #include <xtables.h>
 #include <linux/netfilter/nf_conntrack_common.h>
 #include <linux/netfilter/xt_CT.h>
@@ -20,22 +16,26 @@ static void ct_help(void)
 	);
 }
 
-enum ct_options {
-	CT_OPT_NOTRACK		= 0x1,
-	CT_OPT_HELPER		= 0x2,
-	CT_OPT_CTEVENTS		= 0x4,
-	CT_OPT_EXPEVENTS	= 0x8,
-	CT_OPT_ZONE		= 0x10,
+enum {
+	O_NOTRACK = 0,
+	O_HELPER,
+	O_CTEVENTS,
+	O_EXPEVENTS,
+	O_ZONE,
 };
 
-static const struct option ct_opts[] = {
-	{.name = "notrack",	.has_arg = false, .val = CT_OPT_NOTRACK},
-	{.name = "helper",	.has_arg = true,  .val = CT_OPT_HELPER},
-	{.name = "ctevents",	.has_arg = true,  .val = CT_OPT_CTEVENTS},
-	{.name = "expevents",	.has_arg = true,  .val = CT_OPT_EXPEVENTS},
-	{.name = "zone",	.has_arg = true,  .val = CT_OPT_ZONE},
-	XT_GETOPT_TABLEEND,
+#define s struct xt_ct_target_info
+static const struct xt_option_entry ct_opts[] = {
+	{.name = "notrack", .id = O_NOTRACK, .type = XTTYPE_NONE},
+	{.name = "helper", .id = O_HELPER, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, helper)},
+	{.name = "ctevents", .id = O_CTEVENTS, .type = XTTYPE_STRING},
+	{.name = "expevents", .id = O_EXPEVENTS, .type = XTTYPE_STRING},
+	{.name = "zone", .id = O_ZONE, .type = XTTYPE_UINT16,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, zone)},
+	XTOPT_TABLEEND,
 };
+#undef s
 
 struct event_tbl {
 	const char	*name;
@@ -96,40 +96,22 @@ static void ct_print_events(const char *pfx, const struct event_tbl *tbl,
 	}
 }
 
-static int ct_parse(int c, char **argv, int invert, unsigned int *flags,
-		    const void *entry, struct xt_entry_target **target)
+static void ct_parse(struct xt_option_call *cb)
 {
-	struct xt_ct_target_info *info = (struct xt_ct_target_info *)(*target)->data;
-	unsigned int zone;
+	struct xt_ct_target_info *info = cb->data;
 
-	switch (c) {
-	case CT_OPT_NOTRACK:
-		xtables_param_act(XTF_ONLY_ONCE, "CT", "--notrack", *flags & CT_OPT_NOTRACK);
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_NOTRACK:
 		info->flags |= XT_CT_NOTRACK;
 		break;
-	case CT_OPT_HELPER:
-		xtables_param_act(XTF_ONLY_ONCE, "CT", "--helper", *flags & CT_OPT_HELPER);
-		strncpy(info->helper, optarg, sizeof(info->helper));
-		info->helper[sizeof(info->helper) - 1] = '\0';
+	case O_CTEVENTS:
+		info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), cb->arg);
 		break;
-	case CT_OPT_CTEVENTS:
-		xtables_param_act(XTF_ONLY_ONCE, "CT", "--ctevents", *flags & CT_OPT_CTEVENTS);
-		info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), optarg);
-		break;
-	case CT_OPT_EXPEVENTS:
-		xtables_param_act(XTF_ONLY_ONCE, "CT", "--expevents", *flags & CT_OPT_EXPEVENTS);
-		info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), optarg);
-		break;
-	case CT_OPT_ZONE:
-		xtables_param_act(XTF_ONLY_ONCE, "CT", "--zone", *flags & CT_OPT_ZONE);
-		if (!xtables_strtoui(optarg, NULL, &zone, 0, UINT16_MAX))
-			xtables_error(PARAMETER_PROBLEM, "Bad zone value \"%s\"", optarg);
-		info->zone = zone;
+	case O_EXPEVENTS:
+		info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), cb->arg);
 		break;
 	}
-
-	*flags |= c;
-	return 1;
 }
 
 static void ct_print(const void *ip, const struct xt_entry_target *target, int numeric)
@@ -178,10 +160,10 @@ static struct xtables_target ct_target = {
 	.size		= XT_ALIGN(sizeof(struct xt_ct_target_info)),
 	.userspacesize	= offsetof(struct xt_ct_target_info, ct),
 	.help		= ct_help,
-	.parse		= ct_parse,
 	.print		= ct_print,
 	.save		= ct_save,
-	.extra_opts	= ct_opts,
+	.x6_parse	= ct_parse,
+	.x6_options	= ct_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 17/26] libxt_NFQUEUE: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (15 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 16/26] libxt_CT: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 18/26] libxt_TCPMSS: " Jan Engelhardt
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_NFQUEUE.c |  139 +++++++++++++++-----------------------------
 1 files changed, 47 insertions(+), 92 deletions(-)

diff --git a/extensions/libxt_NFQUEUE.c b/extensions/libxt_NFQUEUE.c
index 7f2aab1..a86c88a 100644
--- a/extensions/libxt_NFQUEUE.c
+++ b/extensions/libxt_NFQUEUE.c
@@ -5,16 +5,16 @@
  * This program is distributed under the terms of GNU GPL v2, 1991
  *
  */
-#include <stdbool.h>
 #include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
-#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_NFQUEUE.h>
 
+enum {
+	O_QUEUE_NUM = 0,
+	O_QUEUE_BALANCE,
+	O_QUEUE_BYPASS,
+};
+
 static void NFQUEUE_help(void)
 {
 	printf(
@@ -38,103 +38,58 @@ static void NFQUEUE_help_v2(void)
 "  --queue-bypass		Bypass Queueing if no queue instance exists.\n");
 }
 
-static const struct option NFQUEUE_opts[] = {
-	{.name = "queue-num",     .has_arg = true, .val = 'F'},
-	{.name = "queue-balance", .has_arg = true, .val = 'B'},
-	{.name = "queue-bypass",  .has_arg = false,.val = 'P'},
-	XT_GETOPT_TABLEEND,
+#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)},
+	{.name = "queue-balance", .id = O_QUEUE_BALANCE,
+	 .type = XTTYPE_UINT16RC},
+	{.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
 };
+#undef s
 
-static void exit_badqueue(const char *s)
-{
-	xtables_error(PARAMETER_PROBLEM, "Invalid queue number `%s'\n", s);
-}
-
-static void
-parse_num(const char *s, struct xt_NFQ_info *tinfo)
+static void NFQUEUE_parse(struct xt_option_call *cb)
 {
-	unsigned int num;
-
-	if (!xtables_strtoui(s, NULL, &num, 0, UINT16_MAX))
-		exit_badqueue(s);
-
-	tinfo->queuenum = num;
-}
-
-static int
-NFQUEUE_parse(int c, char **argv, int invert, unsigned int *flags,
-              const void *entry, struct xt_entry_target **target)
-{
-	struct xt_NFQ_info *tinfo
-		= (struct xt_NFQ_info *)(*target)->data;
-
-	switch (c) {
-	case 'F':
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
-				   "Only use --queue-num ONCE!");
-		parse_num(optarg, tinfo);
-		break;
-	case 'B':
+	xtables_option_parse(cb);
+	if (cb->entry->id == O_QUEUE_BALANCE)
 		xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
 				   "--queue-balance not supported (kernel too old?)");
-	}
-
-	return 1;
 }
 
-static int
-NFQUEUE_parse_v1(int c, char **argv, int invert, unsigned int *flags,
-                 const void *entry, struct xt_entry_target **target)
+static void NFQUEUE_parse_v1(struct xt_option_call *cb)
 {
-	struct xt_NFQ_info_v1 *info = (void *)(*target)->data;
-	char *colon;
-	unsigned int firstqueue, lastqueue;
-
-	switch (c) {
-	case 'F': /* fallthrough */
-	case 'B':
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
-				   "Only use --queue-num ONCE!");
-
-		if (!xtables_strtoui(optarg, &colon, &firstqueue, 0, UINT16_MAX))
-			exit_badqueue(optarg);
-
-		info->queuenum = firstqueue;
-
-		if (c == 'F') {
-			if (*colon)
-				exit_badqueue(optarg);
-			break;
-		}
+	struct xt_NFQ_info_v1 *info = cb->data;
+	const uint16_t *r = cb->val.u16_range;
 
-		if (*colon != ':')
-			xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", optarg);
-
-		if (!xtables_strtoui(colon + 1, NULL, &lastqueue, 1, UINT16_MAX))
-			exit_badqueue(optarg);
-
-		if (firstqueue >= lastqueue)
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_QUEUE_BALANCE:
+		if (cb->nvals != 2)
+			xtables_error(PARAMETER_PROBLEM,
+				"Bad range \"%s\"", cb->arg);
+		if (r[0] >= r[1])
 			xtables_error(PARAMETER_PROBLEM, "%u should be less than %u",
-							firstqueue, lastqueue);
-		info->queues_total = lastqueue - firstqueue + 1;
+				r[0], r[1]);
+		info->queuenum = r[0];
+		info->queues_total = r[1] - r[0] + 1;
 		break;
 	}
-
-	return 1;
 }
 
-static int
-NFQUEUE_parse_v2(int c, char **argv, int invert, unsigned int *flags,
-                 const void *entry, struct xt_entry_target **target)
+static void NFQUEUE_parse_v2(struct xt_option_call *cb)
 {
-	if (c == 'P') {
-		struct xt_NFQ_info_v2 *info = (void *)(*target)->data;
+	struct xt_NFQ_info_v2 *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_QUEUE_BYPASS:
 		info->bypass = 1;
-		return 1;
+		break;
+	default:
+		NFQUEUE_parse_v1(cb);
+		break;
 	}
-	return NFQUEUE_parse_v1(c, argv, invert, flags, entry, target);
 }
 
 static void NFQUEUE_print(const void *ip,
@@ -214,10 +169,10 @@ static struct xtables_target nfqueue_targets[] = {
 	.size		= XT_ALIGN(sizeof(struct xt_NFQ_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_NFQ_info)),
 	.help		= NFQUEUE_help,
-	.parse		= NFQUEUE_parse,
 	.print		= NFQUEUE_print,
 	.save		= NFQUEUE_save,
-	.extra_opts	= NFQUEUE_opts
+	.x6_parse	= NFQUEUE_parse,
+	.x6_options	= NFQUEUE_opts
 },{
 	.family		= NFPROTO_UNSPEC,
 	.revision	= 1,
@@ -227,10 +182,10 @@ static struct xtables_target nfqueue_targets[] = {
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
 	.help		= NFQUEUE_help_v1,
 	.init		= NFQUEUE_init_v1,
-	.parse		= NFQUEUE_parse_v1,
 	.print		= NFQUEUE_print_v1,
 	.save		= NFQUEUE_save_v1,
-	.extra_opts	= NFQUEUE_opts,
+	.x6_parse	= NFQUEUE_parse_v1,
+	.x6_options	= NFQUEUE_opts,
 },{
 	.family		= NFPROTO_UNSPEC,
 	.revision	= 2,
@@ -240,10 +195,10 @@ static struct xtables_target nfqueue_targets[] = {
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
 	.help		= NFQUEUE_help_v2,
 	.init		= NFQUEUE_init_v1,
-	.parse		= NFQUEUE_parse_v2,
 	.print		= NFQUEUE_print_v2,
 	.save		= NFQUEUE_save_v2,
-	.extra_opts	= NFQUEUE_opts,
+	.x6_parse	= NFQUEUE_parse_v2,
+	.x6_options	= NFQUEUE_opts,
 }
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 18/26] libxt_TCPMSS: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (16 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 17/26] libxt_NFQUEUE: " Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 19/26] libxtables: pass struct xt_entry_{match,target} to x6 parser Jan Engelhardt
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_TCPMSS.c |   96 ++++++++++++++++----------------------------
 1 files changed, 35 insertions(+), 61 deletions(-)

diff --git a/extensions/libxt_TCPMSS.c b/extensions/libxt_TCPMSS.c
index e15e87a..2266326 100644
--- a/extensions/libxt_TCPMSS.c
+++ b/extensions/libxt_TCPMSS.c
@@ -2,16 +2,17 @@
  *
  * Copyright (c) 2000 Marc Boucher
 */
-#include <stdbool.h>
 #include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
 #include <xtables.h>
-#include <linux/netfilter/x_tables.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
 #include <linux/netfilter/xt_TCPMSS.h>
 
+enum {
+	O_SET_MSS = 0,
+	O_CLAMP_MSS,
+};
+
 struct mssinfo {
 	struct xt_entry_target t;
 	struct xt_tcpmss_info mss;
@@ -28,69 +29,42 @@ hdrsize);
 
 static void TCPMSS_help(void)
 {
-	__TCPMSS_help(40);
+	__TCPMSS_help(sizeof(struct iphdr));
 }
 
 static void TCPMSS_help6(void)
 {
-	__TCPMSS_help(60);
+	__TCPMSS_help(sizeof(struct ip6_hdr));
 }
 
-static const struct option TCPMSS_opts[] = {
-	{.name = "set-mss",           .has_arg = true,  .val = '1'},
-	{.name = "clamp-mss-to-pmtu", .has_arg = false, .val = '2'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry TCPMSS4_opts[] = {
+	{.name = "set-mss", .id = O_SET_MSS, .type = XTTYPE_UINT16,
+	 .min = 0, .max = UINT16_MAX - sizeof(struct iphdr),
+	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_tcpmss_info, mss)},
+	{.name = "clamp-mss-to-pmtu", .id = O_CLAMP_MSS, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
 };
 
-static int __TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags,
-                          const void *entry, struct xt_entry_target **target,
-                          int hdrsize)
-{
-	struct xt_tcpmss_info *mssinfo
-		= (struct xt_tcpmss_info *)(*target)->data;
-
-	switch (c) {
-		unsigned int mssval;
-
-	case '1':
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "TCPMSS target: Only one option may be specified");
-		if (!xtables_strtoui(optarg, NULL, &mssval,
-		    0, UINT16_MAX - hdrsize))
-			xtables_error(PARAMETER_PROBLEM, "Bad TCPMSS value \"%s\"", optarg);
-		
-		mssinfo->mss = mssval;
-		*flags = 1;
-		break;
-
-	case '2':
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-			           "TCPMSS target: Only one option may be specified");
-		mssinfo->mss = XT_TCPMSS_CLAMP_PMTU;
-		*flags = 1;
-		break;
-	}
-
-	return 1;
-}
+static const struct xt_option_entry TCPMSS6_opts[] = {
+	{.name = "set-mss", .id = O_SET_MSS, .type = XTTYPE_UINT16,
+	 .min = 0, .max = UINT16_MAX - sizeof(struct ip6_hdr),
+	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_tcpmss_info, mss)},
+	{.name = "clamp-mss-to-pmtu", .id = O_CLAMP_MSS, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
 
-static int TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags,
-                        const void *entry, struct xt_entry_target **target)
+static void TCPMSS_parse(struct xt_option_call *cb)
 {
-	return __TCPMSS_parse(c, argv, invert, flags, entry, target, 40);
-}
+	struct xt_tcpmss_info *mssinfo = cb->data;
 
-static int TCPMSS_parse6(int c, char **argv, int invert, unsigned int *flags,
-                         const void *entry, struct xt_entry_target **target)
-{
-	return __TCPMSS_parse(c, argv, invert, flags, entry, target, 60);
+	xtables_option_parse(cb);
+	if (cb->entry->id == O_CLAMP_MSS)
+		mssinfo->mss = XT_TCPMSS_CLAMP_PMTU;
 }
 
-static void TCPMSS_check(unsigned int flags)
+static void TCPMSS_check(struct xt_fcheck_call *cb)
 {
-	if (!flags)
+	if (cb->xflags == 0)
 		xtables_error(PARAMETER_PROBLEM,
 		           "TCPMSS target: At least one parameter is required");
 }
@@ -124,11 +98,11 @@ static struct xtables_target tcpmss_target = {
 	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
 	.help		= TCPMSS_help,
-	.parse		= TCPMSS_parse,
-	.final_check	= TCPMSS_check,
 	.print		= TCPMSS_print,
 	.save		= TCPMSS_save,
-	.extra_opts	= TCPMSS_opts,
+	.x6_parse	= TCPMSS_parse,
+	.x6_fcheck	= TCPMSS_check,
+	.x6_options	= TCPMSS4_opts,
 };
 
 static struct xtables_target tcpmss_target6 = {
@@ -138,11 +112,11 @@ static struct xtables_target tcpmss_target6 = {
 	.size		= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
 	.userspacesize	= XT_ALIGN(sizeof(struct xt_tcpmss_info)),
 	.help		= TCPMSS_help6,
-	.parse		= TCPMSS_parse6,
-	.final_check	= TCPMSS_check,
 	.print		= TCPMSS_print,
 	.save		= TCPMSS_save,
-	.extra_opts	= TCPMSS_opts,
+	.x6_parse	= TCPMSS_parse,
+	.x6_fcheck	= TCPMSS_check,
+	.x6_options	= TCPMSS6_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 19/26] libxtables: pass struct xt_entry_{match,target} to x6 parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (17 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 18/26] libxt_TCPMSS: " Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 20/26] libxt_string: use guided option parser Jan Engelhardt
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    4 ++++
 xtoptions.c          |    2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index 6167f4d..afade14 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -126,6 +126,10 @@ struct xt_option_call {
 			uint32_t mark, mask;
 		};
 	} val;
+	union {
+		struct xt_entry_match **match;
+		struct xt_entry_target **target;
+	};
 };
 
 /**
diff --git a/xtoptions.c b/xtoptions.c
index 939e686..b3acff9 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -384,6 +384,7 @@ void xtables_option_tpcall(unsigned int c, char **argv, bool invert,
 	cb.ext_name = t->name;
 	cb.data     = t->t->data;
 	cb.xflags   = t->tflags;
+	cb.target   = &t->t;
 	t->x6_parse(&cb);
 	t->tflags = cb.xflags;
 }
@@ -417,6 +418,7 @@ void xtables_option_mpcall(unsigned int c, char **argv, bool invert,
 	cb.ext_name = m->name;
 	cb.data     = m->m->data;
 	cb.xflags   = m->mflags;
+	cb.match    = &m->m;
 	m->x6_parse(&cb);
 	m->mflags = cb.xflags;
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 20/26] libxt_string: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (18 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 19/26] libxtables: pass struct xt_entry_{match,target} to x6 parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 21/26] libxtables: XTTYPE_SYSLOGLEVEL support Jan Engelhardt
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_string.c |  138 +++++++++++++++-----------------------------
 1 files changed, 47 insertions(+), 91 deletions(-)

diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c
index 1030d2e..eef0b08 100644
--- a/extensions/libxt_string.c
+++ b/extensions/libxt_string.c
@@ -20,18 +20,25 @@
  *             updated to work with slightly modified
  *             ipt_string_info.
  */
-#define _GNU_SOURCE 1
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
 #include <stdlib.h>
-#include <getopt.h>
 #include <ctype.h>
 #include <xtables.h>
-#include <stddef.h>
 #include <linux/netfilter/xt_string.h>
 
+enum {
+	O_FROM = 0,
+	O_TO,
+	O_ALGO,
+	O_ICASE,
+	O_STRING,
+	O_HEX_STRING,
+	F_STRING     = 1 << O_STRING,
+	F_HEX_STRING = 1 << O_HEX_STRING,
+	F_OP_ANY     = F_STRING | F_HEX_STRING,
+};
+
 static void string_help(void)
 {
 	printf(
@@ -44,15 +51,22 @@ static void string_help(void)
 "[!] --hex-string string      Match a hex string in a packet\n");
 }
 
-static const struct option string_opts[] = {
-	{.name = "from",       .has_arg = true,  .val = '1'},
-	{.name = "to",         .has_arg = true,  .val = '2'},
-	{.name = "algo",       .has_arg = true,  .val = '3'},
-	{.name = "string",     .has_arg = true,  .val = '4'},
-	{.name = "hex-string", .has_arg = true,  .val = '5'},
-	{.name = "icase",      .has_arg = false, .val = '6'},
-	XT_GETOPT_TABLEEND,
+#define s struct xt_string_info
+static const struct xt_option_entry string_opts[] = {
+	{.name = "from", .id = O_FROM, .type = XTTYPE_UINT16,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, from_offset)},
+	{.name = "to", .id = O_TO, .type = XTTYPE_UINT16,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, to_offset)},
+	{.name = "algo", .id = O_ALGO, .type = XTTYPE_STRING,
+	 .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, algo)},
+	{.name = "string", .id = O_STRING, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT, .excl = F_HEX_STRING},
+	{.name = "hex-string", .id = O_HEX_STRING, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT, .excl = F_STRING},
+	{.name = "icase", .id = O_ICASE, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
 };
+#undef s
 
 static void string_init(struct xt_entry_match *m)
 {
@@ -74,17 +88,6 @@ parse_string(const char *s, struct xt_string_info *info)
 }
 
 static void
-parse_algo(const char *s, struct xt_string_info *info)
-{
-	/* xt_string needs \0 for algo name */
-	if (strlen(s) < XT_STRING_MAX_ALGO_NAME_SIZE) {
-		strncpy(info->algo, s, XT_STRING_MAX_ALGO_NAME_SIZE);
-		return;
-	}
-	xtables_error(PARAMETER_PROBLEM, "ALGO too long \"%s\"", s);
-}
-
-static void
 parse_hex_string(const char *s, struct xt_string_info *info)
 {
 	int i=0, slen, sindex=0, schar;
@@ -162,94 +165,47 @@ parse_hex_string(const char *s, struct xt_string_info *info)
 	info->patlen = sindex;
 }
 
-#define STRING 0x1
-#define ALGO   0x2
-#define FROM   0x4
-#define TO     0x8
-#define ICASE  0x10
-
-static int
-string_parse(int c, char **argv, int invert, unsigned int *flags,
-             const void *entry, struct xt_entry_match **match)
+static void string_parse(struct xt_option_call *cb)
 {
-	struct xt_string_info *stringinfo =
-	    (struct xt_string_info *)(*match)->data;
-	const int revision = (*match)->u.user.revision;
+	struct xt_string_info *stringinfo = cb->data;
+	const unsigned int revision = (*cb->match)->u.user.revision;
 
-	switch (c) {
-	case '1':
-		if (*flags & FROM)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify multiple --from");
-		stringinfo->from_offset = atoi(optarg);
-		*flags |= FROM;
-		break;
-	case '2':
-		if (*flags & TO)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify multiple --to");
-		stringinfo->to_offset = atoi(optarg);
-		*flags |= TO;
-		break;
-	case '3':
-		if (*flags & ALGO)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify multiple --algo");
-		parse_algo(optarg, stringinfo);
-		*flags |= ALGO;
-		break;
-	case '4':
-		if (*flags & STRING)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify multiple --string");
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		parse_string(optarg, stringinfo);
-		if (invert) {
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_STRING:
+		parse_string(cb->arg, stringinfo);
+		if (cb->invert) {
 			if (revision == 0)
 				stringinfo->u.v0.invert = 1;
 			else
 				stringinfo->u.v1.flags |= XT_STRING_FLAG_INVERT;
 		}
-		*flags |= STRING;
 		break;
-
-	case '5':
-		if (*flags & STRING)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify multiple --hex-string");
-
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		parse_hex_string(optarg, stringinfo);  /* sets length */
-		if (invert) {
+	case O_HEX_STRING:
+		parse_hex_string(cb->arg, stringinfo);  /* sets length */
+		if (cb->invert) {
 			if (revision == 0)
 				stringinfo->u.v0.invert = 1;
 			else
 				stringinfo->u.v1.flags |= XT_STRING_FLAG_INVERT;
 		}
-		*flags |= STRING;
 		break;
-
-	case '6':
+	case O_ICASE:
 		if (revision == 0)
 			xtables_error(VERSION_PROBLEM,
 				   "Kernel doesn't support --icase");
 
 		stringinfo->u.v1.flags |= XT_STRING_FLAG_IGNORECASE;
-		*flags |= ICASE;
 		break;
 	}
-	return 1;
 }
 
-static void string_check(unsigned int flags)
+static void string_check(struct xt_fcheck_call *cb)
 {
-	if (!(flags & STRING))
+	if (!(cb->xflags & F_OP_ANY))
 		xtables_error(PARAMETER_PROBLEM,
 			   "STRING match: You must specify `--string' or "
 			   "`--hex-string'");
-	if (!(flags & ALGO))
-		xtables_error(PARAMETER_PROBLEM,
-			   "STRING match: You must specify `--algo'");
 }
 
 /* Test to see if the string contains non-printable chars or quotes */
@@ -357,11 +313,11 @@ static struct xtables_match string_mt_reg[] = {
 		.userspacesize = offsetof(struct xt_string_info, config),
 		.help          = string_help,
 		.init          = string_init,
-		.parse         = string_parse,
-		.final_check   = string_check,
 		.print         = string_print,
 		.save          = string_save,
-		.extra_opts    = string_opts,
+		.x6_parse      = string_parse,
+		.x6_fcheck     = string_check,
+		.x6_options    = string_opts,
 	},
 	{
 		.name          = "string",
@@ -372,11 +328,11 @@ static struct xtables_match string_mt_reg[] = {
 		.userspacesize = offsetof(struct xt_string_info, config),
 		.help          = string_help,
 		.init          = string_init,
-		.parse         = string_parse,
-		.final_check   = string_check,
 		.print         = string_print,
 		.save          = string_save,
-		.extra_opts    = string_opts,
+		.x6_parse      = string_parse,
+		.x6_fcheck     = string_check,
+		.x6_options    = string_opts,
 	},
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 21/26] libxtables: XTTYPE_SYSLOGLEVEL support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (19 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 20/26] libxt_string: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 22/26] libip[6]t_LOG: use guided option parser Jan Engelhardt
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    4 +++-
 xtoptions.c          |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index afade14..afdac36 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -51,6 +51,7 @@ struct in_addr;
  * %XTTYPE_UINT*RC:	colon-separated range of standard integers
  * %XTTYPE_STRING:	arbitrary string
  * %XTTYPE_MARKMASK32:	32-bit mark with optional mask
+ * %XTTYPE_SYSLOGLEVEL:	syslog level by name or number
  */
 enum xt_option_type {
 	XTTYPE_NONE,
@@ -64,6 +65,7 @@ enum xt_option_type {
 	XTTYPE_UINT64RC,
 	XTTYPE_STRING,
 	XTTYPE_MARKMASK32,
+	XTTYPE_SYSLOGLEVEL,
 };
 
 /**
@@ -118,7 +120,7 @@ struct xt_option_call {
 	bool invert;
 	uint8_t nvals;
 	union {
-		uint8_t u8, u8_range[2];
+		uint8_t u8, u8_range[2], syslog_level;
 		uint16_t u16, u16_range[2];
 		uint32_t u32, u32_range[2];
 		uint64_t u64, u64_range[2];
diff --git a/xtoptions.c b/xtoptions.c
index b3acff9..a6738c1 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -17,6 +17,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <arpa/inet.h>
 #include "xtables.h"
 #include "xshared.h"
@@ -25,6 +26,14 @@
 	((void *)((char *)(cb)->data + (cb)->entry->ptroff))
 
 /**
+ * Simple key-value pairs for syslog levels
+ */
+struct syslog_level {
+	char name[8];
+	uint8_t level;
+};
+
+/**
  * Creates getopt options from the x6-style option map, and assigns each a
  * getopt id.
  */
@@ -251,6 +260,43 @@ static void xtopt_parse_markmask(struct xt_option_call *cb)
 	cb->val.mask = mask;
 }
 
+static int xtopt_sysloglvl_compare(const void *a, const void *b)
+{
+	const char *name = a;
+	const struct syslog_level *entry = b;
+
+	return strcmp(name, entry->name);
+}
+
+static void xtopt_parse_sysloglevel(struct xt_option_call *cb)
+{
+	static const struct syslog_level log_names[] = { /* must be sorted */
+		{"alert",   LOG_ALERT},
+		{"crit",    LOG_CRIT},
+		{"debug",   LOG_DEBUG},
+		{"emerg",   LOG_EMERG},
+		{"error",   LOG_ERR}, /* deprecated */
+		{"info",    LOG_INFO},
+		{"notice",  LOG_NOTICE},
+		{"panic",   LOG_EMERG}, /* deprecated */
+		{"warning", LOG_WARNING},
+	};
+	const struct syslog_level *e;
+	unsigned int num = 0;
+
+	if (!xtables_strtoui(cb->arg, NULL, &num, 0, 7)) {
+		e = bsearch(cb->arg, log_names, ARRAY_SIZE(log_names),
+			    sizeof(*log_names), xtopt_sysloglvl_compare);
+		if (e == NULL)
+			xt_params->exit_err(PARAMETER_PROBLEM,
+				"log level \"%s\" unknown\n", cb->arg);
+		num = e->level;
+	}
+	cb->val.syslog_level = num;
+	if (cb->entry->flags & XTOPT_PUT)
+		*(uint8_t *)XTOPT_MKPTR(cb) = num;
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT16]      = xtopt_parse_int,
@@ -262,6 +308,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT64RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
+	[XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel,
 };
 
 static const size_t xtopt_psize[] = {
@@ -274,6 +321,7 @@ static const size_t xtopt_psize[] = {
 	[XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
 	[XTTYPE_UINT64RC]    = sizeof(uint64_t[2]),
 	[XTTYPE_STRING]      = -1,
+	[XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
 };
 
 /**
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 22/26] libip[6]t_LOG: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (20 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 21/26] libxtables: XTTYPE_SYSLOGLEVEL support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 23/26] libxtables: XTTYPE_ONEHOST support Jan Engelhardt
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libip6t_LOG.c |  174 +++++++++++-----------------------------------
 extensions/libipt_LOG.c  |  174 +++++++++++-----------------------------------
 2 files changed, 82 insertions(+), 266 deletions(-)

diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c
index e9c738f..a419ec9 100644
--- a/extensions/libip6t_LOG.c
+++ b/extensions/libip6t_LOG.c
@@ -1,11 +1,6 @@
-/* Shared library add-on to ip6tables to add LOG support. */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
-#include <stdlib.h>
 #include <syslog.h>
-#include <getopt.h>
 #include <xtables.h>
 #include <linux/netfilter_ipv6/ip6t_LOG.h>
 
@@ -17,6 +12,16 @@
 
 #define LOG_DEFAULT_LEVEL LOG_WARNING
 
+enum {
+	O_LOG_LEVEL = 0,
+	O_LOG_PREFIX,
+	O_LOG_TCPSEQ,
+	O_LOG_TCPOPTS,
+	O_LOG_IPOPTS,
+	O_LOG_UID,
+	O_LOG_MAC,
+};
+
 static void LOG_help(void)
 {
 	printf(
@@ -30,16 +35,20 @@ static void LOG_help(void)
 " --log-macdecode		Decode MAC addresses and protocol.\n");
 }
 
-static const struct option LOG_opts[] = {
-	{.name = "log-level",        .has_arg = true,  .val = '!'},
-	{.name = "log-prefix",       .has_arg = true,  .val = '#'},
-	{.name = "log-tcp-sequence", .has_arg = false, .val = '1'},
-	{.name = "log-tcp-options",  .has_arg = false, .val = '2'},
-	{.name = "log-ip-options",   .has_arg = false, .val = '3'},
-	{.name = "log-uid",          .has_arg = false, .val = '4'},
-	{.name = "log-macdecode",    .has_arg = false, .val = '5'},
-	XT_GETOPT_TABLEEND,
+#define s struct ip6t_log_info
+static const struct xt_option_entry LOG_opts[] = {
+	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
+	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
+	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
+	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
+	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
 };
+#undef s
 
 static void LOG_init(struct xt_entry_target *t)
 {
@@ -66,134 +75,33 @@ static const struct ip6t_log_names ip6t_log_names[]
     { .name = "warning", .level = LOG_WARNING }
 };
 
-static uint8_t
-parse_level(const char *level)
+static void LOG_parse(struct xt_option_call *cb)
 {
-	unsigned int lev = -1;
-	unsigned int set = 0;
-
-	if (!xtables_strtoui(level, NULL, &lev, 0, 7)) {
-		unsigned int i = 0;
-
-		for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i)
-			if (strncasecmp(level, ip6t_log_names[i].name,
-					strlen(level)) == 0) {
-				if (set++)
-					xtables_error(PARAMETER_PROBLEM,
-						   "log-level `%s' ambiguous",
-						   level);
-				lev = ip6t_log_names[i].level;
-			}
+	struct ip6t_log_info *info = cb->data;
 
-		if (!set)
-			xtables_error(PARAMETER_PROBLEM,
-				   "log-level `%s' unknown", level);
-	}
-
-	return lev;
-}
-
-#define IP6T_LOG_OPT_LEVEL 0x01
-#define IP6T_LOG_OPT_PREFIX 0x02
-#define IP6T_LOG_OPT_TCPSEQ 0x04
-#define IP6T_LOG_OPT_TCPOPT 0x08
-#define IP6T_LOG_OPT_IPOPT 0x10
-#define IP6T_LOG_OPT_UID 0x20
-#define IP6T_LOG_OPT_MACDECODE 0x40
-
-static int LOG_parse(int c, char **argv, int invert, unsigned int *flags,
-                     const void *entry, struct xt_entry_target **target)
-{
-	struct ip6t_log_info *loginfo = (struct ip6t_log_info *)(*target)->data;
-
-	switch (c) {
-	case '!':
-		if (*flags & IP6T_LOG_OPT_LEVEL)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-level twice");
-
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Unexpected `!' after --log-level");
-
-		loginfo->level = parse_level(optarg);
-		*flags |= IP6T_LOG_OPT_LEVEL;
-		break;
-
-	case '#':
-		if (*flags & IP6T_LOG_OPT_PREFIX)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-prefix twice");
-
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Unexpected `!' after --log-prefix");
-
-		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Maximum prefix length %u for --log-prefix",
-				   (unsigned int)sizeof(loginfo->prefix) - 1);
-
-		if (strlen(optarg) == 0)
-			xtables_error(PARAMETER_PROBLEM,
-				   "No prefix specified for --log-prefix");
-
-		if (strlen(optarg) != strlen(strtok(optarg, "\n")))
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_LOG_PREFIX:
+		if (strchr(cb->arg, '\n') != NULL)
 			xtables_error(PARAMETER_PROBLEM,
 				   "Newlines not allowed in --log-prefix");
-
-		strcpy(loginfo->prefix, optarg);
-		*flags |= IP6T_LOG_OPT_PREFIX;
 		break;
-
-	case '1':
-		if (*flags & IP6T_LOG_OPT_TCPSEQ)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-tcp-sequence "
-				   "twice");
-
-		loginfo->logflags |= IP6T_LOG_TCPSEQ;
-		*flags |= IP6T_LOG_OPT_TCPSEQ;
+	case O_LOG_TCPSEQ:
+		info->logflags = IP6T_LOG_TCPSEQ;
 		break;
-
-	case '2':
-		if (*flags & IP6T_LOG_OPT_TCPOPT)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-tcp-options twice");
-
-		loginfo->logflags |= IP6T_LOG_TCPOPT;
-		*flags |= IP6T_LOG_OPT_TCPOPT;
+	case O_LOG_TCPOPTS:
+		info->logflags = IP6T_LOG_TCPOPT;
 		break;
-
-	case '3':
-		if (*flags & IP6T_LOG_OPT_IPOPT)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-ip-options twice");
-
-		loginfo->logflags |= IP6T_LOG_IPOPT;
-		*flags |= IP6T_LOG_OPT_IPOPT;
+	case O_LOG_IPOPTS:
+		info->logflags = IP6T_LOG_IPOPT;
 		break;
-
-	case '4':
-		if (*flags & IP6T_LOG_OPT_UID)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-uid twice");
-
-		loginfo->logflags |= IP6T_LOG_UID;
-		*flags |= IP6T_LOG_OPT_UID;
+	case O_LOG_UID:
+		info->logflags = IP6T_LOG_UID;
 		break;
-
-	case '5':
-		if (*flags & IP6T_LOG_OPT_MACDECODE)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Can't specify --log-macdecode twice");
-
-		loginfo->logflags |= IP6T_LOG_MACDECODE;
-		*flags |= IP6T_LOG_OPT_MACDECODE;
+	case O_LOG_MAC:
+		info->logflags = IP6T_LOG_MACDECODE;
 		break;
 	}
-
-	return 1;
 }
 
 static void LOG_print(const void *ip, const struct xt_entry_target *target,
@@ -264,10 +172,10 @@ static struct xtables_target log_tg6_reg = {
 	.userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)),
 	.help          = LOG_help,
 	.init          = LOG_init,
-	.parse         = LOG_parse,
 	.print         = LOG_print,
 	.save          = LOG_save,
-	.extra_opts    = LOG_opts,
+	.x6_parse      = LOG_parse,
+	.x6_options    = LOG_opts,
 };
 
 void _init(void)
diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c
index ba6af04..b270bcf 100644
--- a/extensions/libipt_LOG.c
+++ b/extensions/libipt_LOG.c
@@ -1,11 +1,6 @@
-/* Shared library add-on to iptables to add LOG support. */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
-#include <stdlib.h>
 #include <syslog.h>
-#include <getopt.h>
 #include <xtables.h>
 #include <linux/netfilter_ipv4/ipt_LOG.h>
 
@@ -17,6 +12,16 @@
 #define IPT_LOG_MASK	0x0f
 #endif
 
+enum {
+	O_LOG_LEVEL = 0,
+	O_LOG_PREFIX,
+	O_LOG_TCPSEQ,
+	O_LOG_TCPOPTS,
+	O_LOG_IPOPTS,
+	O_LOG_UID,
+	O_LOG_MAC,
+};
+
 static void LOG_help(void)
 {
 	printf(
@@ -30,16 +35,20 @@ static void LOG_help(void)
 " --log-macdecode		Decode MAC addresses and protocol.\n\n");
 }
 
-static const struct option LOG_opts[] = {
-	{.name = "log-level",        .has_arg = true,  .val = '!'},
-	{.name = "log-prefix",       .has_arg = true,  .val = '#'},
-	{.name = "log-tcp-sequence", .has_arg = false, .val = '1'},
-	{.name = "log-tcp-options",  .has_arg = false, .val = '2'},
-	{.name = "log-ip-options",   .has_arg = false, .val = '3'},
-	{.name = "log-uid",          .has_arg = false, .val = '4'},
-	{.name = "log-macdecode",    .has_arg = false, .val = '5'},
-	XT_GETOPT_TABLEEND,
+#define s struct ipt_log_info
+static const struct xt_option_entry LOG_opts[] = {
+	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
+	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
+	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
+	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
+	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
 };
+#undef s
 
 static void LOG_init(struct xt_entry_target *t)
 {
@@ -66,134 +75,33 @@ static const struct ipt_log_names ipt_log_names[]
     { .name = "warning", .level = LOG_WARNING }
 };
 
-static uint8_t
-parse_level(const char *level)
+static void LOG_parse(struct xt_option_call *cb)
 {
-	unsigned int lev = -1;
-	unsigned int set = 0;
-
-	if (!xtables_strtoui(level, NULL, &lev, 0, 7)) {
-		unsigned int i = 0;
-
-		for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
-			if (strncasecmp(level, ipt_log_names[i].name,
-					strlen(level)) == 0) {
-				if (set++)
-					xtables_error(PARAMETER_PROBLEM,
-						   "log-level `%s' ambiguous",
-						   level);
-				lev = ipt_log_names[i].level;
-			}
+	struct ipt_log_info *info = cb->data;
 
-		if (!set)
-			xtables_error(PARAMETER_PROBLEM,
-				   "log-level `%s' unknown", level);
-	}
-
-	return lev;
-}
-
-#define IPT_LOG_OPT_LEVEL 0x01
-#define IPT_LOG_OPT_PREFIX 0x02
-#define IPT_LOG_OPT_TCPSEQ 0x04
-#define IPT_LOG_OPT_TCPOPT 0x08
-#define IPT_LOG_OPT_IPOPT 0x10
-#define IPT_LOG_OPT_UID 0x20
-#define IPT_LOG_OPT_MACDECODE 0x40
-
-static int LOG_parse(int c, char **argv, int invert, unsigned int *flags,
-                     const void *entry, struct xt_entry_target **target)
-{
-	struct ipt_log_info *loginfo = (struct ipt_log_info *)(*target)->data;
-
-	switch (c) {
-	case '!':
-		if (*flags & IPT_LOG_OPT_LEVEL)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-level twice");
-
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Unexpected `!' after --log-level");
-
-		loginfo->level = parse_level(optarg);
-		*flags |= IPT_LOG_OPT_LEVEL;
-		break;
-
-	case '#':
-		if (*flags & IPT_LOG_OPT_PREFIX)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-prefix twice");
-
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Unexpected `!' after --log-prefix");
-
-		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Maximum prefix length %u for --log-prefix",
-				   (unsigned int)sizeof(loginfo->prefix) - 1);
-
-		if (strlen(optarg) == 0)
-			xtables_error(PARAMETER_PROBLEM,
-				   "No prefix specified for --log-prefix");
-
-		if (strlen(optarg) != strlen(strtok(optarg, "\n")))
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_LOG_PREFIX:
+		if (strchr(cb->arg, '\n') != NULL)
 			xtables_error(PARAMETER_PROBLEM,
 				   "Newlines not allowed in --log-prefix");
-
-		strcpy(loginfo->prefix, optarg);
-		*flags |= IPT_LOG_OPT_PREFIX;
 		break;
-
-	case '1':
-		if (*flags & IPT_LOG_OPT_TCPSEQ)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-tcp-sequence "
-				   "twice");
-
-		loginfo->logflags |= IPT_LOG_TCPSEQ;
-		*flags |= IPT_LOG_OPT_TCPSEQ;
+	case O_LOG_TCPSEQ:
+		info->logflags = IPT_LOG_TCPSEQ;
 		break;
-
-	case '2':
-		if (*flags & IPT_LOG_OPT_TCPOPT)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-tcp-options twice");
-
-		loginfo->logflags |= IPT_LOG_TCPOPT;
-		*flags |= IPT_LOG_OPT_TCPOPT;
+	case O_LOG_TCPOPTS:
+		info->logflags = IPT_LOG_TCPOPT;
 		break;
-
-	case '3':
-		if (*flags & IPT_LOG_OPT_IPOPT)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-ip-options twice");
-
-		loginfo->logflags |= IPT_LOG_IPOPT;
-		*flags |= IPT_LOG_OPT_IPOPT;
+	case O_LOG_IPOPTS:
+		info->logflags = IPT_LOG_IPOPT;
 		break;
-
-	case '4':
-		if (*flags & IPT_LOG_OPT_UID)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --log-uid twice");
-
-		loginfo->logflags |= IPT_LOG_UID;
-		*flags |= IPT_LOG_OPT_UID;
+	case O_LOG_UID:
+		info->logflags = IPT_LOG_UID;
 		break;
-
-	case '5':
-		if (*flags & IPT_LOG_OPT_MACDECODE)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Can't specifiy --log-macdecode twice");
-
-		loginfo->logflags |= IPT_LOG_MACDECODE;
-		*flags |= IPT_LOG_OPT_MACDECODE;
+	case O_LOG_MAC:
+		info->logflags = IPT_LOG_MACDECODE;
 		break;
 	}
-
-	return 1;
 }
 
 static void LOG_print(const void *ip, const struct xt_entry_target *target,
@@ -266,10 +174,10 @@ static struct xtables_target log_tg_reg = {
 	.userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)),
 	.help          = LOG_help,
 	.init          = LOG_init,
-	.parse         = LOG_parse,
 	.print         = LOG_print,
 	.save          = LOG_save,
-	.extra_opts    = LOG_opts,
+	.x6_parse      = LOG_parse,
+	.x6_options    = LOG_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 23/26] libxtables: XTTYPE_ONEHOST support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (21 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 22/26] libip[6]t_LOG: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 24/26] libxtables: XTTYPE_PORT support Jan Engelhardt
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

The bonus of the POSIX socket API is that it is almost protocol-agnostic
and that there are ready-made functions to take over the gist of address
parsing and packing.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    3 ++
 xtoptions.c          |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index afdac36..d8a3124 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -52,6 +52,7 @@ struct in_addr;
  * %XTTYPE_STRING:	arbitrary string
  * %XTTYPE_MARKMASK32:	32-bit mark with optional mask
  * %XTTYPE_SYSLOGLEVEL:	syslog level by name or number
+ * %XTTYPE_ONEHOST:	one host or address (union nf_inet_addr)
  */
 enum xt_option_type {
 	XTTYPE_NONE,
@@ -66,6 +67,7 @@ enum xt_option_type {
 	XTTYPE_STRING,
 	XTTYPE_MARKMASK32,
 	XTTYPE_SYSLOGLEVEL,
+	XTTYPE_ONEHOST,
 };
 
 /**
@@ -124,6 +126,7 @@ struct xt_option_call {
 		uint16_t u16, u16_range[2];
 		uint32_t u32, u32_range[2];
 		uint64_t u64, u64_range[2];
+		union nf_inet_addr inetaddr;
 		struct {
 			uint32_t mark, mask;
 		};
diff --git a/xtoptions.c b/xtoptions.c
index a6738c1..e0c3213 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -297,6 +297,63 @@ static void xtopt_parse_sysloglevel(struct xt_option_call *cb)
 		*(uint8_t *)XTOPT_MKPTR(cb) = num;
 }
 
+static void *xtables_sa_host(const void *sa, unsigned int afproto)
+{
+	if (afproto == AF_INET6)
+		return &((struct sockaddr_in6 *)sa)->sin6_addr;
+	else if (afproto == AF_INET)
+		return &((struct sockaddr_in *)sa)->sin_addr;
+	return (void *)sa;
+}
+
+static socklen_t xtables_sa_hostlen(unsigned int afproto)
+{
+	if (afproto == AF_INET6)
+		return sizeof(struct in6_addr);
+	else if (afproto == AF_INET)
+		return sizeof(struct in_addr);
+	return 0;
+}
+
+/**
+ * Accepts: a hostname (DNS), or a single inetaddr.
+ */
+static void xtopt_parse_onehost(struct xt_option_call *cb)
+{
+	struct addrinfo hints = {.ai_family = afinfo->family};
+	unsigned int adcount = 0;
+	struct addrinfo *res, *p;
+	int ret;
+
+	ret = getaddrinfo(cb->arg, NULL, &hints, &res);
+	if (ret < 0)
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"getaddrinfo: %s\n", gai_strerror(ret));
+
+	for (p = res; p != NULL; p = p->ai_next) {
+		if (adcount == 0) {
+			memset(&cb->val.inetaddr, 0, sizeof(cb->val.inetaddr));
+			memcpy(&cb->val.inetaddr,
+			       xtables_sa_host(p->ai_addr, p->ai_family),
+			       xtables_sa_hostlen(p->ai_family));
+			++adcount;
+			continue;
+		}
+		if (memcmp(&cb->val.inetaddr,
+		    xtables_sa_host(p->ai_addr, p->ai_family),
+		    xtables_sa_hostlen(p->ai_family)) != 0)
+			xt_params->exit_err(PARAMETER_PROBLEM,
+				"%s resolves to more than one address\n",
+				cb->arg);
+	}
+
+	freeaddrinfo(res);
+	if (cb->entry->flags & XTOPT_PUT)
+		/* Validation in xtables_option_metavalidate */
+		memcpy(XTOPT_MKPTR(cb), &cb->val.inetaddr,
+		       sizeof(cb->val.inetaddr));
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT16]      = xtopt_parse_int,
@@ -309,6 +366,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_STRING]      = xtopt_parse_string,
 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
 	[XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel,
+	[XTTYPE_ONEHOST]     = xtopt_parse_onehost,
 };
 
 static const size_t xtopt_psize[] = {
@@ -322,6 +380,7 @@ static const size_t xtopt_psize[] = {
 	[XTTYPE_UINT64RC]    = sizeof(uint64_t[2]),
 	[XTTYPE_STRING]      = -1,
 	[XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
+	[XTTYPE_ONEHOST]     = sizeof(union nf_inet_addr),
 };
 
 /**
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 24/26] libxtables: XTTYPE_PORT support
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (22 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 23/26] libxtables: XTTYPE_ONEHOST support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 25/26] libxt_TPROXY: use guided option parser Jan Engelhardt
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 include/xtables.h.in |    6 ++++-
 xtoptions.c          |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletions(-)

diff --git a/include/xtables.h.in b/include/xtables.h.in
index d8a3124..a9a9ffa 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -53,6 +53,8 @@ struct in_addr;
  * %XTTYPE_MARKMASK32:	32-bit mark with optional mask
  * %XTTYPE_SYSLOGLEVEL:	syslog level by name or number
  * %XTTYPE_ONEHOST:	one host or address (union nf_inet_addr)
+ * %XTTYPE_PORT:	16-bit port name or number
+ * %XTTYPE_PORT_NE:	16-bit port name or number, stored as network-endian
  */
 enum xt_option_type {
 	XTTYPE_NONE,
@@ -68,6 +70,8 @@ enum xt_option_type {
 	XTTYPE_MARKMASK32,
 	XTTYPE_SYSLOGLEVEL,
 	XTTYPE_ONEHOST,
+	XTTYPE_PORT,
+	XTTYPE_PORT_NE,
 };
 
 /**
@@ -123,7 +127,7 @@ struct xt_option_call {
 	uint8_t nvals;
 	union {
 		uint8_t u8, u8_range[2], syslog_level;
-		uint16_t u16, u16_range[2];
+		uint16_t u16, u16_range[2], port;
 		uint32_t u32, u32_range[2];
 		uint64_t u64, u64_range[2];
 		union nf_inet_addr inetaddr;
diff --git a/xtoptions.c b/xtoptions.c
index e0c3213..c3cc40e 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -354,6 +354,53 @@ static void xtopt_parse_onehost(struct xt_option_call *cb)
 		       sizeof(cb->val.inetaddr));
 }
 
+/**
+ * @name:	port name, or number as a string (e.g. "http" or "80")
+ *
+ * Resolve a port name to a number. Returns the port number in integral
+ * form on success, or <0 on error. (errno will not be set.)
+ */
+static int xtables_getportbyname(const char *name)
+{
+	struct addrinfo *res = NULL, *p;
+	int ret;
+
+	ret = getaddrinfo(NULL, name, NULL, &res);
+	if (ret < 0)
+		return -1;
+	ret = -1;
+	for (p = res; p != NULL; p = p->ai_next) {
+		if (p->ai_family == AF_INET6) {
+			ret = ((struct sockaddr_in6 *)p->ai_addr)->sin6_port;
+			break;
+		} else if (p->ai_family == AF_INET) {
+			ret = ((struct sockaddr_in *)p->ai_addr)->sin_port;
+			break;
+		}
+	}
+	freeaddrinfo(res);
+	return ntohs(ret);
+}
+
+/**
+ * Validate and parse a port specification and put the result into @cb.
+ */
+static void xtopt_parse_port(struct xt_option_call *cb)
+{
+	int ret;
+
+	ret = xtables_getportbyname(cb->arg);
+	if (ret < 0)
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"Port \"%s\" does not resolve to anything.\n",
+			cb->arg);
+	cb->val.port = ret;
+	if (cb->entry->type == XTTYPE_PORT_NE)
+		cb->val.port = htons(cb->val.port);
+	if (cb->entry->flags & XTOPT_PUT)
+		*(uint16_t *)XTOPT_MKPTR(cb) = cb->val.port;
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT16]      = xtopt_parse_int,
@@ -367,6 +414,8 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
 	[XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel,
 	[XTTYPE_ONEHOST]     = xtopt_parse_onehost,
+	[XTTYPE_PORT]        = xtopt_parse_port,
+	[XTTYPE_PORT_NE]     = xtopt_parse_port,
 };
 
 static const size_t xtopt_psize[] = {
@@ -381,6 +430,8 @@ static const size_t xtopt_psize[] = {
 	[XTTYPE_STRING]      = -1,
 	[XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
 	[XTTYPE_ONEHOST]     = sizeof(union nf_inet_addr),
+	[XTTYPE_PORT]        = sizeof(uint16_t),
+	[XTTYPE_PORT_NE]     = sizeof(uint16_t),
 };
 
 /**
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 25/26] libxt_TPROXY: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (23 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 24/26] libxtables: XTTYPE_PORT support Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-13 16:13 ` [PATCH 26/26] libipt_ULOG: " Jan Engelhardt
  2011-04-18 13:05 ` guided option parser, run 3 Patrick McHardy
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

I am starting with a simple module here that does not require a
final_check function.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libxt_TPROXY.c |  216 +++++++++++++--------------------------------
 1 files changed, 62 insertions(+), 154 deletions(-)

diff --git a/extensions/libxt_TPROXY.c b/extensions/libxt_TPROXY.c
index 890dd86..5264ea7 100644
--- a/extensions/libxt_TPROXY.c
+++ b/extensions/libxt_TPROXY.c
@@ -1,32 +1,42 @@
 /*
- * Shared library add-on to iptables to add TPROXY target support.
+ * shared library add-on to iptables to add TPROXY target support.
  *
  * Copyright (C) 2002-2008 BalaBit IT Ltd.
  */
-#include <getopt.h>
-#include <stdbool.h>
-#include <stdint.h>
 #include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include <limits.h>
-
 #include <xtables.h>
-#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_TPROXY.h>
+#include <arpa/inet.h>
 
-static const struct option tproxy_tg_opts[] = {
-	{.name = "on-port",     .has_arg = true, .val = '1'},
-	{.name = "on-ip",       .has_arg = true, .val = '2'},
-	{.name = "tproxy-mark", .has_arg = true, .val = '3'},
-	XT_GETOPT_TABLEEND,
+enum {
+	P_PORT = 0,
+	P_ADDR,
+	P_MARK,
+	F_PORT = 1 << P_PORT,
+	F_ADDR = 1 << P_ADDR,
+	F_MARK = 1 << P_MARK,
 };
 
-enum {
-	PARAM_ONPORT = 1 << 0,
-	PARAM_ONIP = 1 << 1,
-	PARAM_MARK = 1 << 2,
+#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-ip", .id = P_ADDR, .type = XTTYPE_ONEHOST},
+	{.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32},
+	XTOPT_TABLEEND,
 };
+#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-ip", .id = P_ADDR, .type = XTTYPE_ONEHOST,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, laddr)},
+	{.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32},
+	XTOPT_TABLEEND,
+};
+#undef s
 
 static void tproxy_tg_help(void)
 {
@@ -37,134 +47,6 @@ static void tproxy_tg_help(void)
 "  --tproxy-mark value[/mask]	    Mark packets with the given value/mask\n\n");
 }
 
-static void parse_tproxy_lport(const char *s, uint16_t *portp)
-{
-	unsigned int lport;
-
-	if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX))
-		*portp = htons(lport);
-	else
-		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s);
-}
-
-static void parse_tproxy_laddr(const char *s, union nf_inet_addr *addrp,
-			       unsigned int nfproto)
-{
-	struct in6_addr *laddr6 = NULL;
-	struct in_addr *laddr4 = NULL;
-
-	if (nfproto == NFPROTO_IPV6) {
-		laddr6 = xtables_numeric_to_ip6addr(s);
-		if (laddr6 == NULL)
-			goto out;
-		addrp->in6 = *laddr6;
-	} else if (nfproto == NFPROTO_IPV4) {
-		laddr4 = xtables_numeric_to_ipaddr(s);
-		if (laddr4 == NULL)
-			goto out;
-		addrp->in = *laddr4;
-	}
-	return;
- out:
-	xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s);
-}
-
-static void parse_tproxy_mark(char *s, uint32_t *markp, uint32_t *maskp)
-{
-	unsigned int value, mask = UINT32_MAX;
-	char *end;
-
-	if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX))
-		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
-	if (*end == '/')
-		if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
-			xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
-	if (*end != '\0')
-		xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
-
-	*markp = value;
-	*maskp = mask;
-}
-
-static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags,
-			const void *entry, struct xt_entry_target **target)
-{
-	struct xt_tproxy_target_info *info = (void *)(*target)->data;
-
-	switch (c) {
-	case '1':
-		xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT);
-		xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert);
-		parse_tproxy_lport(optarg, &info->lport);
-		*flags |= PARAM_ONPORT;
-		return 1;
-	case '2':
-		xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP);
-		xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert);
-		parse_tproxy_laddr(optarg, (void *)&info->laddr, NFPROTO_IPV4);
-		*flags |= PARAM_ONIP;
-		return 1;
-	case '3':
-		xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK);
-		xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert);
-		parse_tproxy_mark(optarg, &info->mark_value, &info->mark_mask);
-		*flags |= PARAM_MARK;
-		return 1;
-	}
-
-	return 0;
-}
-
-static int
-tproxy_tg_parse1(int c, char **argv, int invert, unsigned int *flags,
-		 struct xt_tproxy_target_info_v1 *info, unsigned int nfproto)
-{
-	switch (c) {
-	case '1':
-		xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT);
-		xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert);
-		parse_tproxy_lport(optarg, &info->lport);
-		*flags |= PARAM_ONPORT;
-		return true;
-	case '2':
-		xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP);
-		xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert);
-		parse_tproxy_laddr(optarg, (void *)&info->laddr, nfproto);
-		*flags |= PARAM_ONIP;
-		return true;
-	case '3':
-		xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK);
-		xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert);
-		parse_tproxy_mark(optarg, &info->mark_value, &info->mark_mask);
-		*flags |= PARAM_MARK;
-		return true;
-	}
-	return false;
-}
-
-static int
-tproxy_tg_parse4(int c, char **argv, int invert, unsigned int *flags,
-		 const void *entry, struct xt_entry_target **target)
-{
-	struct xt_tproxy_target_info_v1 *info = (void *)(*target)->data;
-	return tproxy_tg_parse1(c, argv, invert, flags, info, NFPROTO_IPV4);
-}
-
-static int
-tproxy_tg_parse6(int c, char **argv, int invert, unsigned int *flags,
-		 const void *entry, struct xt_entry_target **target)
-{
-	struct xt_tproxy_target_info_v1 *info = (void *)(*target)->data;
-	return tproxy_tg_parse1(c, argv, invert, flags, info, NFPROTO_IPV6);
-}
-
-static void tproxy_tg_check(unsigned int flags)
-{
-	if (!(flags & PARAM_ONPORT))
-		xtables_error(PARAMETER_PROBLEM,
-			   "TPROXY target: Parameter --on-port is required");
-}
-
 static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target,
 			 int numeric)
 {
@@ -236,6 +118,35 @@ tproxy_tg_save6(const void *ip, const struct xt_entry_target *target)
 	       (unsigned int)info->mark_value, (unsigned int)info->mark_mask);
 }
 
+static void tproxy_tg0_parse(struct xt_option_call *cb)
+{
+	struct xt_tproxy_target_info *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case P_MARK:
+		info->mark_value = cb->val.mark;
+		info->mark_mask  = cb->val.mask;
+		break;
+	case P_ADDR:
+		info->laddr = cb->val.inetaddr.ip;
+		break;
+	}
+}
+
+static void tproxy_tg1_parse(struct xt_option_call *cb)
+{
+	struct xt_tproxy_target_info_v1 *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case P_MARK:
+		info->mark_value = cb->val.mark;
+		info->mark_mask  = cb->val.mask;
+		break;
+	}
+}
+
 static struct xtables_target tproxy_tg_reg[] = {
 	{
 		.name          = "TPROXY",
@@ -245,11 +156,10 @@ static struct xtables_target tproxy_tg_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
 		.help          = tproxy_tg_help,
-		.parse         = tproxy_tg_parse,
-		.final_check   = tproxy_tg_check,
 		.print         = tproxy_tg_print,
 		.save          = tproxy_tg_save,
-		.extra_opts    = tproxy_tg_opts,
+		.x6_options    = tproxy_tg0_opts,
+		.x6_parse      = tproxy_tg0_parse,
 	},
 	{
 		.name          = "TPROXY",
@@ -259,11 +169,10 @@ static struct xtables_target tproxy_tg_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
 		.help          = tproxy_tg_help,
-		.parse         = tproxy_tg_parse4,
-		.final_check   = tproxy_tg_check,
 		.print         = tproxy_tg_print4,
 		.save          = tproxy_tg_save4,
-		.extra_opts    = tproxy_tg_opts,
+		.x6_options    = tproxy_tg1_opts,
+		.x6_parse      = tproxy_tg1_parse,
 	},
 	{
 		.name          = "TPROXY",
@@ -273,11 +182,10 @@ static struct xtables_target tproxy_tg_reg[] = {
 		.size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
 		.userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
 		.help          = tproxy_tg_help,
-		.parse         = tproxy_tg_parse6,
-		.final_check   = tproxy_tg_check,
 		.print         = tproxy_tg_print6,
 		.save          = tproxy_tg_save6,
-		.extra_opts    = tproxy_tg_opts,
+		.x6_options    = tproxy_tg1_opts,
+		.x6_parse      = tproxy_tg1_parse,
 	},
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 26/26] libipt_ULOG: use guided option parser
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (24 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 25/26] libxt_TPROXY: use guided option parser Jan Engelhardt
@ 2011-04-13 16:13 ` Jan Engelhardt
  2011-04-18 13:05 ` guided option parser, run 3 Patrick McHardy
  26 siblings, 0 replies; 28+ messages in thread
From: Jan Engelhardt @ 2011-04-13 16:13 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
 extensions/libipt_ULOG.c |  137 +++++++++++----------------------------------
 1 files changed, 34 insertions(+), 103 deletions(-)

diff --git a/extensions/libipt_ULOG.c b/extensions/libipt_ULOG.c
index 8eeccf0..e08ae05 100644
--- a/extensions/libipt_ULOG.c
+++ b/extensions/libipt_ULOG.c
@@ -9,29 +9,18 @@
  * 
  * libipt_ULOG.c,v 1.7 2001/01/30 11:55:02 laforge Exp
  */
-#include <stdbool.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <string.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <getopt.h>
 #include <xtables.h>
 /* For 64bit kernel / 32bit userspace */
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
 
-
-static void print_groups(unsigned int gmask)
-{
-	int b;
-	unsigned int test;
-
-	for (b = 31; b >= 0; b--) {
-		test = (1 << b);
-		if (gmask & test)
-			printf(" %d", b + 1);
-	}
-}
+enum {
+	O_ULOG_NLGROUP = 0,
+	O_ULOG_PREFIX,
+	O_ULOG_CPRANGE,
+	O_ULOG_QTHR,
+};
 
 static void ULOG_help(void)
 {
@@ -42,12 +31,16 @@ static void ULOG_help(void)
 	       " --ulog-prefix prefix		Prefix log messages with this prefix.\n");
 }
 
-static const struct option ULOG_opts[] = {
-	{.name = "ulog-nlgroup",    .has_arg = true, .val = '!'},
-	{.name = "ulog-prefix",     .has_arg = true, .val = '#'},
-	{.name = "ulog-cprange",    .has_arg = true, .val = 'A'},
-	{.name = "ulog-qthreshold", .has_arg = true, .val = 'B'},
-	XT_GETOPT_TABLEEND,
+static const struct xt_option_entry ULOG_opts[] = {
+	{.name = "ulog-nlgroup", .id = O_ULOG_NLGROUP, .type = XTTYPE_UINT8,
+	 .min = 1, .max = 32},
+	{.name = "ulog-prefix", .id = O_ULOG_PREFIX, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(struct ipt_ulog_info, prefix),
+	 .min = 1},
+	{.name = "ulog-cprange", .id = O_ULOG_CPRANGE, .type = XTTYPE_UINT64,
+	 .min = 1, .max = ULOG_MAX_QLEN},
+	{.name = "ulog-qthreshold", .id = O_ULOG_QTHR, .type = XTTYPE_UINT64},
+	XTOPT_TABLEEND,
 };
 
 static void ULOG_init(struct xt_entry_target *t)
@@ -59,87 +52,27 @@ static void ULOG_init(struct xt_entry_target *t)
 
 }
 
-#define IPT_LOG_OPT_NLGROUP 0x01
-#define IPT_LOG_OPT_PREFIX 0x02
-#define IPT_LOG_OPT_CPRANGE 0x04
-#define IPT_LOG_OPT_QTHRESHOLD 0x08
-
-static int ULOG_parse(int c, char **argv, int invert, unsigned int *flags,
-                      const void *entry, struct xt_entry_target **target)
+static void ULOG_parse(struct xt_option_call *cb)
 {
-	struct ipt_ulog_info *loginfo =
-	    (struct ipt_ulog_info *) (*target)->data;
-	int group_d;
+	struct ipt_ulog_info *loginfo = cb->data;
 
-	switch (c) {
-	case '!':
-		if (*flags & IPT_LOG_OPT_NLGROUP)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --ulog-nlgroup twice");
-
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Unexpected `!' after --ulog-nlgroup");
-		group_d = atoi(optarg);
-		if (group_d > 32 || group_d < 1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "--ulog-nlgroup has to be between 1 and 32");
-
-		loginfo->nl_group = (1 << (group_d - 1));
-
-		*flags |= IPT_LOG_OPT_NLGROUP;
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_ULOG_NLGROUP:
+		loginfo->nl_group = 1 << (cb->val.u8 - 1);
 		break;
-
-	case '#':
-		if (*flags & IPT_LOG_OPT_PREFIX)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --ulog-prefix twice");
-
-		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Unexpected `!' after --ulog-prefix");
-
-		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Maximum prefix length %u for --ulog-prefix",
-				   (unsigned int)sizeof(loginfo->prefix) - 1);
-
-		if (strlen(optarg) == 0)
-			xtables_error(PARAMETER_PROBLEM,
-				   "No prefix specified for --ulog-prefix");
-
-		if (strlen(optarg) != strlen(strtok(optarg, "\n")))
+	case O_ULOG_PREFIX:
+		if (strchr(cb->arg, '\n') != NULL)
 			xtables_error(PARAMETER_PROBLEM,
 				   "Newlines not allowed in --ulog-prefix");
-
-		strcpy(loginfo->prefix, optarg);
-		*flags |= IPT_LOG_OPT_PREFIX;
 		break;
-	case 'A':
-		if (*flags & IPT_LOG_OPT_CPRANGE)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --ulog-cprange twice");
-		if (atoi(optarg) < 0)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Negative copy range?");
-		loginfo->copy_range = atoi(optarg);
-		*flags |= IPT_LOG_OPT_CPRANGE;
+	case O_ULOG_CPRANGE:
+		loginfo->copy_range = cb->val.u64;
 		break;
-	case 'B':
-		if (*flags & IPT_LOG_OPT_QTHRESHOLD)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Can't specify --ulog-qthreshold twice");
-		if (atoi(optarg) < 1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Negative or zero queue threshold ?");
-		if (atoi(optarg) > ULOG_MAX_QLEN)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Maximum queue length exceeded");
-		loginfo->qthreshold = atoi(optarg);
-		*flags |= IPT_LOG_OPT_QTHRESHOLD;
+	case O_ULOG_QTHR:
+		loginfo->qthreshold = cb->val.u64;
 		break;
 	}
-	return 1;
 }
 
 static void ULOG_save(const void *ip, const struct xt_entry_target *target)
@@ -152,10 +85,8 @@ static void ULOG_save(const void *ip, const struct xt_entry_target *target)
 		xtables_save_string(loginfo->prefix);
 	}
 
-	if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) {
-		printf(" --ulog-nlgroup");
-		print_groups(loginfo->nl_group);
-	}
+	if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP)
+		printf(" --ulog-nlgroup %d", ffs(loginfo->nl_group));
 	if (loginfo->copy_range)
 		printf(" --ulog-cprange %u", (unsigned int)loginfo->copy_range);
 
@@ -170,8 +101,8 @@ static void ULOG_print(const void *ip, const struct xt_entry_target *target,
 	    = (const struct ipt_ulog_info *) target->data;
 
 	printf(" ULOG ");
-	printf("copy_range %u nlgroup", (unsigned int)loginfo->copy_range);
-	print_groups(loginfo->nl_group);
+	printf("copy_range %u nlgroup %d", (unsigned int)loginfo->copy_range,
+	       ffs(loginfo->nl_group));
 	if (strcmp(loginfo->prefix, "") != 0)
 		printf(" prefix \"%s\"", loginfo->prefix);
 	printf(" queue_threshold %u", (unsigned int)loginfo->qthreshold);
@@ -185,10 +116,10 @@ static struct xtables_target ulog_tg_reg = {
 	.userspacesize	= XT_ALIGN(sizeof(struct ipt_ulog_info)),
 	.help		= ULOG_help,
 	.init		= ULOG_init,
-	.parse		= ULOG_parse,
 	.print		= ULOG_print,
 	.save		= ULOG_save,
-	.extra_opts	= ULOG_opts,
+	.x6_parse	= ULOG_parse,
+	.x6_options	= ULOG_opts,
 };
 
 void _init(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: guided option parser, run 3
  2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
                   ` (25 preceding siblings ...)
  2011-04-13 16:13 ` [PATCH 26/26] libipt_ULOG: " Jan Engelhardt
@ 2011-04-18 13:05 ` Patrick McHardy
  26 siblings, 0 replies; 28+ messages in thread
From: Patrick McHardy @ 2011-04-18 13:05 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

Am 13.04.2011 18:13, schrieb Jan Engelhardt:
> The following changes since commit 316ae9d2f1996caea4cf221201accb8c2087a154:
> 
>   Merge branch 'opts' of git://dev.medozas.de/iptables (2011-04-13 13:38:20 +0200)
> 
> are available in the git repository at:
> 
>   git://dev.medozas.de/iptables floating/opts
> 
> Jan Engelhardt (26):
>       libxtables: XTTYPE_MARKMASK32 support
>       libxt_MARK: use guided option parser
>       libxt_CONNMARK: use guided option parser
>       libxtables: XTTYPE_UINT64 support
>       libxt_quota: use guided option parser
>       libxtables: linked-list name<->id map
>       libxt_devgroup: use guided option parser
>       libipt_realm: use guided option parser
>       libxtables: XTTYPE_UINT16RC support
>       libxt_length: use guided option parser
>       libxt_tcpmss: use guided option parser
>       libxtables: XTTYPE_UINT8RC support
>       libxtables: XTTYPE_UINT64RC support
>       libxt_connbytes: use guided option parser
>       libxtables: XTTYPE_UINT16 support
>       libxt_CT: use guided option parser
>       libxt_NFQUEUE: use guided option parser
>       libxt_TCPMSS: use guided option parser
>       libxtables: pass struct xt_entry_{match,target} to x6 parser
>       libxt_string: use guided option parser
>       libxtables: XTTYPE_SYSLOGLEVEL support
>       libip[6]t_LOG: use guided option parser
>       libxtables: XTTYPE_ONEHOST support
>       libxtables: XTTYPE_PORT support
>       libxt_TPROXY: use guided option parser
>       libipt_ULOG: use guided option parser

Pulled, thanks Jan.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2011-04-18 13:05 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-13 16:13 guided option parser, run 3 Jan Engelhardt
2011-04-13 16:13 ` [PATCH 01/26] libxtables: XTTYPE_MARKMASK32 support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 02/26] libxt_MARK: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 03/26] libxt_CONNMARK: " Jan Engelhardt
2011-04-13 16:13 ` [PATCH 04/26] libxtables: XTTYPE_UINT64 support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 05/26] libxt_quota: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 06/26] libxtables: linked-list name<->id map Jan Engelhardt
2011-04-13 16:13 ` [PATCH 07/26] libxt_devgroup: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 08/26] libipt_realm: " Jan Engelhardt
2011-04-13 16:13 ` [PATCH 09/26] libxtables: XTTYPE_UINT16RC support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 10/26] libxt_length: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 11/26] libxt_tcpmss: " Jan Engelhardt
2011-04-13 16:13 ` [PATCH 12/26] libxtables: XTTYPE_UINT8RC support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 13/26] libxtables: XTTYPE_UINT64RC support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 14/26] libxt_connbytes: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 15/26] libxtables: XTTYPE_UINT16 support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 16/26] libxt_CT: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 17/26] libxt_NFQUEUE: " Jan Engelhardt
2011-04-13 16:13 ` [PATCH 18/26] libxt_TCPMSS: " Jan Engelhardt
2011-04-13 16:13 ` [PATCH 19/26] libxtables: pass struct xt_entry_{match,target} to x6 parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 20/26] libxt_string: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 21/26] libxtables: XTTYPE_SYSLOGLEVEL support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 22/26] libip[6]t_LOG: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 23/26] libxtables: XTTYPE_ONEHOST support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 24/26] libxtables: XTTYPE_PORT support Jan Engelhardt
2011-04-13 16:13 ` [PATCH 25/26] libxt_TPROXY: use guided option parser Jan Engelhardt
2011-04-13 16:13 ` [PATCH 26/26] libipt_ULOG: " Jan Engelhardt
2011-04-18 13:05 ` guided option parser, run 3 Patrick McHardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).