summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2011-05-07 00:15:49 +0200
committerJan Engelhardt <jengelh@medozas.de>2011-05-09 00:49:03 +0200
commit87a34d7aef2cba833f4f36536575dee304bbece5 (patch)
treeadd81c554a93e5d2fcb9b5a8507dd47d2ba92c51 /extensions
parent94cd683a969e024ec870df258fafd790b8a1abf1 (diff)
libxt_multiport: use guided option parser
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'extensions')
-rw-r--r--extensions/libxt_multiport.c178
1 files changed, 73 insertions, 105 deletions
diff --git a/extensions/libxt_multiport.c b/extensions/libxt_multiport.c
index 7fa537e0..03af5a96 100644
--- a/extensions/libxt_multiport.c
+++ b/extensions/libxt_multiport.c
@@ -1,19 +1,23 @@
-/* Shared library add-on to iptables to add multiple TCP port support. */
-#include <stdbool.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
-#include <getopt.h>
-
#include <xtables.h>
-#include <libiptc/libiptc.h>
-#include <libiptc/libip6tc.h>
#include <limits.h> /* INT_MAX in ip_tables.h/ip6_tables.h */
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter/xt_multiport.h>
+enum {
+ O_SOURCE_PORTS = 0,
+ O_DEST_PORTS,
+ O_SD_PORTS,
+ F_SOURCE_PORTS = 1 << O_SOURCE_PORTS,
+ F_DEST_PORTS = 1 << O_DEST_PORTS,
+ F_SD_PORTS = 1 << O_SD_PORTS,
+ F_ANY = F_SOURCE_PORTS | F_DEST_PORTS | F_SD_PORTS,
+};
+
/* Function which prints out usage message. */
static void multiport_help(void)
{
@@ -44,13 +48,18 @@ static void multiport_help_v1(void)
" match both source and destination port(s)\n");
}
-static const struct option multiport_opts[] = {
- {.name = "source-ports", .has_arg = true, .val = '1'},
- {.name = "sports", .has_arg = true, .val = '1'}, /* synonym */
- {.name = "destination-ports", .has_arg = true, .val = '2'},
- {.name = "dports", .has_arg = true, .val = '2'}, /* synonym */
- {.name = "ports", .has_arg = true, .val = '3'},
- XT_GETOPT_TABLEEND,
+static const struct xt_option_entry multiport_opts[] = {
+ {.name = "source-ports", .id = O_SOURCE_PORTS, .type = XTTYPE_STRING,
+ .excl = F_ANY, .flags = XTOPT_INVERT},
+ {.name = "sports", .id = O_SOURCE_PORTS, .type = XTTYPE_STRING,
+ .excl = F_ANY, .flags = XTOPT_INVERT},
+ {.name = "destination-ports", .id = O_DEST_PORTS,
+ .type = XTTYPE_STRING, .excl = F_ANY, .flags = XTOPT_INVERT},
+ {.name = "dports", .id = O_DEST_PORTS, .type = XTTYPE_STRING,
+ .excl = F_ANY, .flags = XTOPT_INVERT},
+ {.name = "ports", .id = O_SD_PORTS, .type = XTTYPE_STRING,
+ .excl = F_ANY, .flags = XTOPT_INVERT},
+ XTOPT_TABLEEND,
};
static const char *
@@ -152,136 +161,97 @@ check_proto(uint16_t pnum, uint8_t invflags)
"multiport only works with TCP, UDP, UDPLITE, SCTP and DCCP");
}
-/* Function which parses command options; returns true if it
- ate an option */
-static int
-__multiport_parse(int c, char **argv, int invert, unsigned int *flags,
- struct xt_entry_match **match, uint16_t pnum,
- uint8_t invflags)
+static void __multiport_parse(struct xt_option_call *cb, uint16_t pnum,
+ uint8_t invflags)
{
const char *proto;
- struct xt_multiport *multiinfo
- = (struct xt_multiport *)(*match)->data;
+ struct xt_multiport *multiinfo = cb->data;
- switch (c) {
- case '1':
- xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+ xtables_option_parse(cb);
+ switch (cb->entry->id) {
+ case O_SOURCE_PORTS:
proto = check_proto(pnum, invflags);
- multiinfo->count = parse_multi_ports(optarg,
+ multiinfo->count = parse_multi_ports(cb->arg,
multiinfo->ports, proto);
multiinfo->flags = XT_MULTIPORT_SOURCE;
break;
-
- case '2':
- xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+ case O_DEST_PORTS:
proto = check_proto(pnum, invflags);
- multiinfo->count = parse_multi_ports(optarg,
+ multiinfo->count = parse_multi_ports(cb->arg,
multiinfo->ports, proto);
multiinfo->flags = XT_MULTIPORT_DESTINATION;
break;
-
- case '3':
- xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+ case O_SD_PORTS:
proto = check_proto(pnum, invflags);
- multiinfo->count = parse_multi_ports(optarg,
+ multiinfo->count = parse_multi_ports(cb->arg,
multiinfo->ports, proto);
multiinfo->flags = XT_MULTIPORT_EITHER;
break;
}
-
- if (invert)
+ if (cb->invert)
xtables_error(PARAMETER_PROBLEM,
- "multiport does not support invert");
-
- if (*flags)
- xtables_error(PARAMETER_PROBLEM,
- "multiport can only have one option");
- *flags = 1;
- return 1;
+ "multiport.0 does not support invert");
}
-static int
-multiport_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *e, struct xt_entry_match **match)
+static void multiport_parse(struct xt_option_call *cb)
{
- const struct ipt_entry *entry = e;
- return __multiport_parse(c, argv, invert, flags, match,
+ const struct ipt_entry *entry = cb->xt_entry;
+ return __multiport_parse(cb,
entry->ip.proto, entry->ip.invflags);
}
-static int
-multiport_parse6(int c, char **argv, int invert, unsigned int *flags,
- const void *e, struct xt_entry_match **match)
+static void multiport_parse6(struct xt_option_call *cb)
{
- const struct ip6t_entry *entry = e;
- return __multiport_parse(c, argv, invert, flags, match,
+ const struct ip6t_entry *entry = cb->xt_entry;
+ return __multiport_parse(cb,
entry->ipv6.proto, entry->ipv6.invflags);
}
-static int
-__multiport_parse_v1(int c, char **argv, int invert, unsigned int *flags,
- struct xt_entry_match **match, uint16_t pnum,
- uint8_t invflags)
+static void __multiport_parse_v1(struct xt_option_call *cb, uint16_t pnum,
+ uint8_t invflags)
{
const char *proto;
- struct xt_multiport_v1 *multiinfo
- = (struct xt_multiport_v1 *)(*match)->data;
+ struct xt_multiport_v1 *multiinfo = cb->data;
- switch (c) {
- case '1':
- xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+ xtables_option_parse(cb);
+ switch (cb->entry->id) {
+ case O_SOURCE_PORTS:
proto = check_proto(pnum, invflags);
- parse_multi_ports_v1(optarg, multiinfo, proto);
+ parse_multi_ports_v1(cb->arg, multiinfo, proto);
multiinfo->flags = XT_MULTIPORT_SOURCE;
break;
-
- case '2':
- xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+ case O_DEST_PORTS:
proto = check_proto(pnum, invflags);
- parse_multi_ports_v1(optarg, multiinfo, proto);
+ parse_multi_ports_v1(cb->arg, multiinfo, proto);
multiinfo->flags = XT_MULTIPORT_DESTINATION;
break;
-
- case '3':
- xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+ case O_SD_PORTS:
proto = check_proto(pnum, invflags);
- parse_multi_ports_v1(optarg, multiinfo, proto);
+ parse_multi_ports_v1(cb->arg, multiinfo, proto);
multiinfo->flags = XT_MULTIPORT_EITHER;
break;
}
-
- if (invert)
+ if (cb->invert)
multiinfo->invert = 1;
-
- if (*flags)
- xtables_error(PARAMETER_PROBLEM,
- "multiport can only have one option");
- *flags = 1;
- return 1;
}
-static int
-multiport_parse_v1(int c, char **argv, int invert, unsigned int *flags,
- const void *e, struct xt_entry_match **match)
+static void multiport_parse_v1(struct xt_option_call *cb)
{
- const struct ipt_entry *entry = e;
- return __multiport_parse_v1(c, argv, invert, flags, match,
+ const struct ipt_entry *entry = cb->xt_entry;
+ return __multiport_parse_v1(cb,
entry->ip.proto, entry->ip.invflags);
}
-static int
-multiport_parse6_v1(int c, char **argv, int invert, unsigned int *flags,
- const void *e, struct xt_entry_match **match)
+static void multiport_parse6_v1(struct xt_option_call *cb)
{
- const struct ip6t_entry *entry = e;
- return __multiport_parse_v1(c, argv, invert, flags, match,
+ const struct ip6t_entry *entry = cb->xt_entry;
+ return __multiport_parse_v1(cb,
entry->ipv6.proto, entry->ipv6.invflags);
}
-/* Final check; must specify something. */
-static void multiport_check(unsigned int flags)
+static void multiport_check(struct xt_fcheck_call *cb)
{
- if (!flags)
+ if (cb->xflags == 0)
xtables_error(PARAMETER_PROBLEM, "multiport expection an option");
}
@@ -307,7 +277,6 @@ print_port(uint16_t port, uint8_t protocol, int numeric)
printf("%s", service);
}
-/* Prints out the matchinfo. */
static void
__multiport_print(const struct xt_entry_match *match, int numeric,
uint16_t proto)
@@ -410,7 +379,6 @@ static void multiport_print6_v1(const void *ip_void,
__multiport_print_v1(match, numeric, ip->proto);
}
-/* Saves the union ipt_matchinfo in parsable form to stdout. */
static void __multiport_save(const struct xt_entry_match *match,
uint16_t proto)
{
@@ -509,11 +477,11 @@ static struct xtables_match multiport_mt_reg[] = {
.size = XT_ALIGN(sizeof(struct xt_multiport)),
.userspacesize = XT_ALIGN(sizeof(struct xt_multiport)),
.help = multiport_help,
- .parse = multiport_parse,
- .final_check = multiport_check,
+ .x6_parse = multiport_parse,
+ .x6_fcheck = multiport_check,
.print = multiport_print,
.save = multiport_save,
- .extra_opts = multiport_opts,
+ .x6_options = multiport_opts,
},
{
.family = NFPROTO_IPV6,
@@ -523,11 +491,11 @@ static struct xtables_match multiport_mt_reg[] = {
.size = XT_ALIGN(sizeof(struct xt_multiport)),
.userspacesize = XT_ALIGN(sizeof(struct xt_multiport)),
.help = multiport_help,
- .parse = multiport_parse6,
- .final_check = multiport_check,
+ .x6_parse = multiport_parse6,
+ .x6_fcheck = multiport_check,
.print = multiport_print6,
.save = multiport_save6,
- .extra_opts = multiport_opts,
+ .x6_options = multiport_opts,
},
{
.family = NFPROTO_IPV4,
@@ -537,11 +505,11 @@ static struct xtables_match multiport_mt_reg[] = {
.size = XT_ALIGN(sizeof(struct xt_multiport_v1)),
.userspacesize = XT_ALIGN(sizeof(struct xt_multiport_v1)),
.help = multiport_help_v1,
- .parse = multiport_parse_v1,
- .final_check = multiport_check,
+ .x6_parse = multiport_parse_v1,
+ .x6_fcheck = multiport_check,
.print = multiport_print_v1,
.save = multiport_save_v1,
- .extra_opts = multiport_opts,
+ .x6_options = multiport_opts,
},
{
.family = NFPROTO_IPV6,
@@ -551,11 +519,11 @@ static struct xtables_match multiport_mt_reg[] = {
.size = XT_ALIGN(sizeof(struct xt_multiport_v1)),
.userspacesize = XT_ALIGN(sizeof(struct xt_multiport_v1)),
.help = multiport_help_v1,
- .parse = multiport_parse6_v1,
- .final_check = multiport_check,
+ .x6_parse = multiport_parse6_v1,
+ .x6_fcheck = multiport_check,
.print = multiport_print6_v1,
.save = multiport_save6_v1,
- .extra_opts = multiport_opts,
+ .x6_options = multiport_opts,
},
};