From 86a5d1878d33a974289d61bcab5fc5d8d05c9c42 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 10 Nov 2011 09:29:22 +0100 Subject: Add support for older kernel and iptables versions --- ip6t_DNPTV6.c | 6 +++--- ip6t_NPTV6_common.h | 10 ++++++++++ ip6t_SNPTV6.c | 6 +++--- libip6t_DNPTV6.c | 30 +++++++++++++++++++++++++----- libip6t_NPTV6.c | 14 +------------- libip6t_NPTV6.h | 2 +- libip6t_SNPTV6.c | 30 +++++++++++++++++++++++++----- 7 files changed, 68 insertions(+), 30 deletions(-) diff --git a/ip6t_DNPTV6.c b/ip6t_DNPTV6.c index 506d0a5..ea09835 100644 --- a/ip6t_DNPTV6.c +++ b/ip6t_DNPTV6.c @@ -48,16 +48,16 @@ static unsigned int dnptv6_tg6(struct sk_buff *skb, const struct xt_action_param return NF_ACCEPT; } -static int dnptv6_tg6_check(const struct xt_tgchk_param *par) +static CHECKENTRY_RET dnptv6_tg6_check(const struct xt_tgchk_param *par) { const struct ip6t_nptv6_info *info = par->targinfo; if (info->nptv6_prefix_len > 64) { printk("DNPTV6: Prefix length longer than 64 given\n"); - return -EINVAL; + return CHECKENTRY_RET_EINVAL; } - return 0; + return CHECKENTRY_RET_SUCCESS; } static struct xt_target dnptv6_tg6_reg __read_mostly = { diff --git a/ip6t_NPTV6_common.h b/ip6t_NPTV6_common.h index 4a0c807..1bbcc03 100644 --- a/ip6t_NPTV6_common.h +++ b/ip6t_NPTV6_common.h @@ -33,6 +33,16 @@ ntohs((addr).s6_addr16[7]) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) +# define xt_action_param xt_target_param +# define CHECKENTRY_RET bool +# define CHECKENTRY_RET_SUCCESS true +# define CHECKENTRY_RET_EINVAL false +#else +# define CHECKENTRY_RET int +# define CHECKENTRY_RET_SUCCESS 0 +# define CHECKENTRY_RET_EINVAL (-EINVAL) +#endif /* Ones' complement add */ static inline u_int16_t add16(u_int16_t a, u_int16_t b) diff --git a/ip6t_SNPTV6.c b/ip6t_SNPTV6.c index 79747ae..97f8e04 100644 --- a/ip6t_SNPTV6.c +++ b/ip6t_SNPTV6.c @@ -48,16 +48,16 @@ static unsigned int snptv6_tg6(struct sk_buff *skb, const struct xt_action_param return NF_ACCEPT; } -static int snptv6_tg6_check(const struct xt_tgchk_param *par) +static CHECKENTRY_RET snptv6_tg6_check(const struct xt_tgchk_param *par) { const struct ip6t_nptv6_info *info = par->targinfo; if (info->nptv6_prefix_len > 64) { printk("SNPTV6: Prefix length longer than 64 given\n"); - return -EINVAL; + return CHECKENTRY_RET_EINVAL; } - return 0; + return CHECKENTRY_RET_SUCCESS; } static struct xt_target snptv6_tg6_reg __read_mostly = { diff --git a/libip6t_DNPTV6.c b/libip6t_DNPTV6.c index ad937ae..c12ca4d 100644 --- a/libip6t_DNPTV6.c +++ b/libip6t_DNPTV6.c @@ -16,15 +16,35 @@ static void DNPTV6_help(void) NPTV6_help_note(); } +static int DNPTV6_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) +{ + struct ip6t_nptv6_info* info = (struct ip6t_nptv6_info*)(*target)->data; + + switch(c) { + case 0: + if (!optarg) { + xtables_error(PARAMETER_PROBLEM, "--to-destination: No prefix given"); + } + if (invert) { + xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-destination"); + } + + NPTV6_parse_to(optarg, info); + return 1; + } + + return 0; +} + static void DNPTV6_save(const void *ip, const struct xt_entry_target *target) { const struct ip6t_nptv6_info* info = (struct ip6t_nptv6_info*)target->data; printf(" --to-destination %s/%d ", xtables_ip6addr_to_numeric(&info->nptv6_prefix), info->nptv6_prefix_len); } -static const struct xt_option_entry DNPTV6_opts[] = { - {.name = "to-destination", .id = 0, .type = XTTYPE_STRING, .flags = XTOPT_MAND}, - XTOPT_TABLEEND, +static const struct option DNPTV6_opts[] = { + {.name = "to-destination", .has_arg = required_argument, .flag = NULL, .val = 0}, + {.name = NULL}, }; static struct xtables_target DNPTV6_tg6_reg = { @@ -34,10 +54,10 @@ static struct xtables_target DNPTV6_tg6_reg = { .size = XT_ALIGN(sizeof(struct ip6t_nptv6_info)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_nptv6_info)), .help = DNPTV6_help, - .x6_parse = NPTV6_parse, + .parse = DNPTV6_parse, .print = NPTV6_print, .save = DNPTV6_save, - .x6_options = DNPTV6_opts, + .extra_opts = DNPTV6_opts, }; void _init(void) diff --git a/libip6t_NPTV6.c b/libip6t_NPTV6.c index 4c7aae7..3b75434 100644 --- a/libip6t_NPTV6.c +++ b/libip6t_NPTV6.c @@ -21,7 +21,7 @@ void NPTV6_help_note(void) "ip6tables -t mangle -I POSTROUTING -o eth0 -s FD01:0203:0405::/48 -j SNPTV6 --to-source 2001:0DB8:0001::/48\n"); } -static void parse_to(const char *orig_arg, struct ip6t_nptv6_info *info) +void NPTV6_parse_to(const char *orig_arg, struct ip6t_nptv6_info *info) { char *arg, *slash; @@ -43,18 +43,6 @@ static void parse_to(const char *orig_arg, struct ip6t_nptv6_info *info) free(arg); } -void NPTV6_parse(struct xt_option_call *cb) -{ - struct ip6t_nptv6_info* info = (struct ip6t_nptv6_info*)cb->data; - - xtables_option_parse(cb); - switch(cb->entry->id) { - case 0: - parse_to(cb->arg, info); - break; - } -} - void NPTV6_print(const void *ip, const struct xt_entry_target *target, int numeric) { const struct ip6t_nptv6_info* info = (struct ip6t_nptv6_info*)target->data; diff --git a/libip6t_NPTV6.h b/libip6t_NPTV6.h index d091de6..17b003b 100644 --- a/libip6t_NPTV6.h +++ b/libip6t_NPTV6.h @@ -21,7 +21,7 @@ void NPTV6_help_note(void); -void NPTV6_parse(struct xt_option_call *cb); +void NPTV6_parse_to(const char *orig_arg, struct ip6t_nptv6_info *info); void NPTV6_print(const void *ip, const struct xt_entry_target *target, int numeric); void _init(void); diff --git a/libip6t_SNPTV6.c b/libip6t_SNPTV6.c index 3bcc66e..267a27a 100644 --- a/libip6t_SNPTV6.c +++ b/libip6t_SNPTV6.c @@ -16,15 +16,35 @@ static void SNPTV6_help(void) NPTV6_help_note(); } +static int SNPTV6_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) +{ + struct ip6t_nptv6_info* info = (struct ip6t_nptv6_info*)(*target)->data; + + switch(c) { + case 0: + if (!optarg) { + xtables_error(PARAMETER_PROBLEM, "--to-source: No prefix given"); + } + if (invert) { + xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --to-source"); + } + + NPTV6_parse_to(optarg, info); + return 1; + } + + return 0; +} + static void SNPTV6_save(const void *ip, const struct xt_entry_target *target) { const struct ip6t_nptv6_info* info = (struct ip6t_nptv6_info*)target->data; printf(" --to-source %s/%d ", xtables_ip6addr_to_numeric(&info->nptv6_prefix), info->nptv6_prefix_len); } -static const struct xt_option_entry SNPTV6_opts[] = { - {.name = "to-source", .id = 0, .type = XTTYPE_STRING, .flags = XTOPT_MAND}, - XTOPT_TABLEEND, +static const struct option SNPTV6_opts[] = { + {.name = "to-source", .has_arg = required_argument, .flag = NULL, .val = 0}, + {.name = NULL}, }; static struct xtables_target SNPTV6_tg6_reg = { @@ -34,10 +54,10 @@ static struct xtables_target SNPTV6_tg6_reg = { .size = XT_ALIGN(sizeof(struct ip6t_nptv6_info)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_nptv6_info)), .help = SNPTV6_help, - .x6_parse = NPTV6_parse, + .parse = SNPTV6_parse, .print = NPTV6_print, .save = SNPTV6_save, - .x6_options = SNPTV6_opts, + .extra_opts = SNPTV6_opts, }; void _init(void) -- cgit v1.2.3