diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2009-06-01 11:46:12 +0200 |
---|---|---|
committer | Jan Engelhardt <jengelh@medozas.de> | 2009-06-01 11:46:12 +0200 |
commit | 67cf1a928952f1d1ca32f529d78036cebc1b8800 (patch) | |
tree | a4800406c1813082bb2dab8ca172acc836b0a75d /extensions/libip6t_policy.c | |
parent | cd30054544021bad206efb6b98df640528e1cba1 (diff) |
policy: merge ipv6 and ipv4 variant
The files duplicate most of their code, and struct ipt_policy_info
being defined to xt_policy_info makes them actually have even more in
common.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'extensions/libip6t_policy.c')
-rw-r--r-- | extensions/libip6t_policy.c | 432 |
1 files changed, 0 insertions, 432 deletions
diff --git a/extensions/libip6t_policy.c b/extensions/libip6t_policy.c deleted file mode 100644 index daeff893..00000000 --- a/extensions/libip6t_policy.c +++ /dev/null @@ -1,432 +0,0 @@ -/* Shared library add-on to ip6tables to add policy support. */ -#include <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <syslog.h> -#include <getopt.h> -#include <netdb.h> -#include <errno.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <xtables.h> -#include <libiptc/libip6tc.h> -#include <linux/netfilter/xt_policy.h> - -/* - * HACK: global pointer to current matchinfo for making - * final checks and adjustments in final_check. - */ -static struct xt_policy_info *policy_info; - -static void policy_help(void) -{ - printf( -"policy match options:\n" -" --dir in|out match policy applied during decapsulation/\n" -" policy to be applied during encapsulation\n" -" --pol none|ipsec match policy\n" -" --strict match entire policy instead of single element\n" -" at any position\n" -"[!] --reqid reqid match reqid\n" -"[!] --spi spi match SPI\n" -"[!] --proto proto match protocol (ah/esp/ipcomp)\n" -"[!] --mode mode match mode (transport/tunnel)\n" -"[!] --tunnel-src addr/masklen match tunnel source\n" -"[!] --tunnel-dst addr/masklen match tunnel destination\n" -" --next begin next element in policy\n"); -} - -static const struct option policy_opts[] = -{ - { - .name = "dir", - .has_arg = 1, - .val = '1', - }, - { - .name = "pol", - .has_arg = 1, - .val = '2', - }, - { - .name = "strict", - .val = '3' - }, - { - .name = "reqid", - .has_arg = 1, - .val = '4', - }, - { - .name = "spi", - .has_arg = 1, - .val = '5' - }, - { - .name = "tunnel-src", - .has_arg = 1, - .val = '6' - }, - { - .name = "tunnel-dst", - .has_arg = 1, - .val = '7' - }, - { - .name = "proto", - .has_arg = 1, - .val = '8' - }, - { - .name = "mode", - .has_arg = 1, - .val = '9' - }, - { - .name = "next", - .val = 'a' - }, - { .name = NULL } -}; - -static int parse_direction(char *s) -{ - if (strcmp(s, "in") == 0) - return XT_POLICY_MATCH_IN; - if (strcmp(s, "out") == 0) - return XT_POLICY_MATCH_OUT; - xtables_error(PARAMETER_PROBLEM, "policy_match: invalid dir \"%s\"", s); -} - -static int parse_policy(char *s) -{ - if (strcmp(s, "none") == 0) - return XT_POLICY_MATCH_NONE; - if (strcmp(s, "ipsec") == 0) - return 0; - xtables_error(PARAMETER_PROBLEM, "policy match: invalid policy \"%s\"", s); -} - -static int parse_mode(char *s) -{ - if (strcmp(s, "transport") == 0) - return XT_POLICY_MODE_TRANSPORT; - if (strcmp(s, "tunnel") == 0) - return XT_POLICY_MODE_TUNNEL; - xtables_error(PARAMETER_PROBLEM, "policy match: invalid mode \"%s\"", s); -} - -static int policy_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct xt_policy_info *info = (void *)(*match)->data; - struct xt_policy_elem *e = &info->pol[info->len]; - struct in6_addr *addr = NULL, mask; - unsigned int naddr = 0, num; - int mode; - - xtables_check_inverse(optarg, &invert, &optind, 0); - - switch (c) { - case '1': - if (info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT)) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --dir option"); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "policy match: can't invert --dir option"); - - info->flags |= parse_direction(argv[optind-1]); - break; - case '2': - if (invert) - xtables_error(PARAMETER_PROBLEM, - "policy match: can't invert --policy option"); - - info->flags |= parse_policy(argv[optind-1]); - break; - case '3': - if (info->flags & XT_POLICY_MATCH_STRICT) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --strict option"); - - if (invert) - xtables_error(PARAMETER_PROBLEM, - "policy match: can't invert --strict option"); - - info->flags |= XT_POLICY_MATCH_STRICT; - break; - case '4': - if (e->match.reqid) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --reqid option"); - - e->match.reqid = 1; - e->invert.reqid = invert; - if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "policy", "--reqid", optarg); - e->reqid = num; - break; - case '5': - if (e->match.spi) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --spi option"); - - e->match.spi = 1; - e->invert.spi = invert; - if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg); - e->spi = num; - break; - case '6': - if (e->match.saddr) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --tunnel-src option"); - - xtables_ip6parse_any(argv[optind-1], &addr, &mask, &naddr); - if (naddr > 1) - xtables_error(PARAMETER_PROBLEM, - "policy match: name resolves to multiple IPs"); - - e->match.saddr = 1; - e->invert.saddr = invert; - memcpy(&e->saddr.a6, addr, sizeof(*addr)); - memcpy(&e->smask.a6, &mask, sizeof(mask)); - break; - case '7': - if (e->match.daddr) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --tunnel-dst option"); - - xtables_ip6parse_any(argv[optind-1], &addr, &mask, &naddr); - if (naddr > 1) - xtables_error(PARAMETER_PROBLEM, - "policy match: name resolves to multiple IPs"); - - e->match.daddr = 1; - e->invert.daddr = invert; - memcpy(&e->daddr.a6, addr, sizeof(*addr)); - memcpy(&e->dmask.a6, &mask, sizeof(mask)); - break; - case '8': - if (e->match.proto) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --proto option"); - - e->proto = xtables_parse_protocol(argv[optind-1]); - if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP && - e->proto != IPPROTO_COMP) - xtables_error(PARAMETER_PROBLEM, - "policy match: protocol must ah/esp/ipcomp"); - e->match.proto = 1; - e->invert.proto = invert; - break; - case '9': - if (e->match.mode) - xtables_error(PARAMETER_PROBLEM, - "policy match: double --mode option"); - - mode = parse_mode(argv[optind-1]); - e->match.mode = 1; - e->invert.mode = invert; - e->mode = mode; - break; - case 'a': - if (invert) - xtables_error(PARAMETER_PROBLEM, - "policy match: can't invert --next option"); - - if (++info->len == XT_POLICY_MAX_ELEM) - xtables_error(PARAMETER_PROBLEM, - "policy match: maximum policy depth reached"); - break; - default: - return 0; - } - - policy_info = info; - return 1; -} - -static void policy_check(unsigned int flags) -{ - struct xt_policy_info *info = policy_info; - struct xt_policy_elem *e; - int i; - - if (info == NULL) - xtables_error(PARAMETER_PROBLEM, - "policy match: no parameters given"); - - if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) - xtables_error(PARAMETER_PROBLEM, - "policy match: neither --in nor --out specified"); - - if (info->flags & XT_POLICY_MATCH_NONE) { - if (info->flags & XT_POLICY_MATCH_STRICT) - xtables_error(PARAMETER_PROBLEM, - "policy match: policy none but --strict given"); - - if (info->len != 0) - xtables_error(PARAMETER_PROBLEM, - "policy match: policy none but policy given"); - } else - info->len++; /* increase len by 1, no --next after last element */ - - if (!(info->flags & XT_POLICY_MATCH_STRICT) && info->len > 1) - xtables_error(PARAMETER_PROBLEM, - "policy match: multiple elements but no --strict"); - - for (i = 0; i < info->len; i++) { - e = &info->pol[i]; - - if (info->flags & XT_POLICY_MATCH_STRICT && - !(e->match.reqid || e->match.spi || e->match.saddr || - e->match.daddr || e->match.proto || e->match.mode)) - xtables_error(PARAMETER_PROBLEM, - "policy match: empty policy element"); - - if ((e->match.saddr || e->match.daddr) - && ((e->mode == XT_POLICY_MODE_TUNNEL && e->invert.mode) || - (e->mode == XT_POLICY_MODE_TRANSPORT && !e->invert.mode))) - xtables_error(PARAMETER_PROBLEM, - "policy match: --tunnel-src/--tunnel-dst " - "is only valid in tunnel mode"); - } -} - -static void print_mode(char *prefix, u_int8_t mode, int numeric) -{ - printf("%smode ", prefix); - - switch (mode) { - case XT_POLICY_MODE_TRANSPORT: - printf("transport "); - break; - case XT_POLICY_MODE_TUNNEL: - printf("tunnel "); - break; - default: - printf("??? "); - break; - } -} - -static void print_proto(char *prefix, u_int8_t proto, int numeric) -{ - struct protoent *p = NULL; - - printf("%sproto ", prefix); - if (!numeric) - p = getprotobynumber(proto); - if (p != NULL) - printf("%s ", p->p_name); - else - printf("%u ", proto); -} - -#define PRINT_INVERT(x) \ -do { \ - if (x) \ - printf("! "); \ -} while(0) - -static void print_entry(char *prefix, const struct xt_policy_elem *e, - int numeric) -{ - if (e->match.reqid) { - PRINT_INVERT(e->invert.reqid); - printf("%sreqid %u ", prefix, e->reqid); - } - if (e->match.spi) { - PRINT_INVERT(e->invert.spi); - printf("%sspi 0x%x ", prefix, e->spi); - } - if (e->match.proto) { - PRINT_INVERT(e->invert.proto); - print_proto(prefix, e->proto, numeric); - } - if (e->match.mode) { - PRINT_INVERT(e->invert.mode); - print_mode(prefix, e->mode, numeric); - } - if (e->match.daddr) { - PRINT_INVERT(e->invert.daddr); - printf("%stunnel-dst %s%s ", prefix, - xtables_ip6addr_to_numeric(&e->daddr.a6), - xtables_ip6mask_to_numeric(&e->dmask.a6)); - } - if (e->match.saddr) { - PRINT_INVERT(e->invert.saddr); - printf("%stunnel-src %s%s ", prefix, - xtables_ip6addr_to_numeric(&e->saddr.a6), - xtables_ip6mask_to_numeric(&e->smask.a6)); - } -} - -static void print_flags(char *prefix, const struct xt_policy_info *info) -{ - if (info->flags & XT_POLICY_MATCH_IN) - printf("%sdir in ", prefix); - else - printf("%sdir out ", prefix); - - if (info->flags & XT_POLICY_MATCH_NONE) - printf("%spol none ", prefix); - else - printf("%spol ipsec ", prefix); - - if (info->flags & XT_POLICY_MATCH_STRICT) - printf("%sstrict ", prefix); -} - -static void policy_print(const void *ip, const struct xt_entry_match *match, - int numeric) -{ - const struct xt_policy_info *info = (void *)match->data; - unsigned int i; - - printf("policy match "); - print_flags("", info); - for (i = 0; i < info->len; i++) { - if (info->len > 1) - printf("[%u] ", i); - print_entry("", &info->pol[i], numeric); - } - - printf("\n"); -} - -static void policy_save(const void *ip, const struct xt_entry_match *match) -{ - const struct xt_policy_info *info = (void *)match->data; - unsigned int i; - - print_flags("--", info); - for (i = 0; i < info->len; i++) { - print_entry("--", &info->pol[i], 0); - if (i + 1 < info->len) - printf("--next "); - } -} - -static struct xtables_match policy_mt6_reg = { - .name = "policy", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV6, - .size = XT_ALIGN(sizeof(struct xt_policy_info)), - .userspacesize = XT_ALIGN(sizeof(struct xt_policy_info)), - .help = policy_help, - .parse = policy_parse, - .final_check = policy_check, - .print = policy_print, - .save = policy_save, - .extra_opts = policy_opts, -}; - -void _init(void) -{ - xtables_register_match(&policy_mt6_reg); -} |