]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxt_TPROXY: use guided option parser
authorJan Engelhardt <jengelh@medozas.de>
Wed, 9 Feb 2011 01:15:22 +0000 (02:15 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Wed, 13 Apr 2011 16:09:27 +0000 (18:09 +0200)
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

index 890dd866a612fb49f7707156576b28b87750ddca..5264ea7d39f8bfca361ae821280cd9d746e6ea0f 100644 (file)
@@ -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,
        },
 };