diff options
Diffstat (limited to 'extensions/libip6t_hbh.c')
-rw-r--r-- | extensions/libip6t_hbh.c | 164 |
1 files changed, 65 insertions, 99 deletions
diff --git a/extensions/libip6t_hbh.c b/extensions/libip6t_hbh.c index bdcbf9b..520ec9e 100644 --- a/extensions/libip6t_hbh.c +++ b/extensions/libip6t_hbh.c @@ -1,49 +1,35 @@ -/* Shared library add-on to ip6tables to add Hop-by-Hop and Dst headers support. */ +/* Shared library add-on to ip6tables to add Hop-by-Hop header support. */ #include <stdio.h> #include <netdb.h> #include <string.h> #include <stdlib.h> #include <getopt.h> #include <errno.h> -#include <ip6tables.h> +#include <xtables.h> /*#include <linux/in6.h>*/ #include <linux/netfilter_ipv6/ip6t_opts.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> - + #define DEBUG 0 -#define HOPBYHOP 1 -#define UNAME (HOPBYHOP ? "HBH" : "DST") -#define LNAME (HOPBYHOP ? "hbh" : "dst") -/* Function which prints out usage message. */ -static void -help(void) +static void hbh_help(void) { printf( -"%s v%s options:\n" -" --%s-len [!] length total length of this header\n" -" --%s-opts TYPE[:LEN][,TYPE[:LEN]...] \n" -" Options and its length (list, max: %d)\n", -UNAME , IPTABLES_VERSION, LNAME, LNAME, IP6T_OPTS_OPTSNR); +"hbh match options:\n" +"[!] --hbh-len length total length of this header\n" +" --hbh-opts TYPE[:LEN][,TYPE[:LEN]...] \n" +" Options and its length (list, max: %d)\n", +IP6T_OPTS_OPTSNR); } -#if HOPBYHOP -static struct option opts[] = { - { "hbh-len", 1, 0, '1' }, - { "hbh-opts", 1, 0, '2' }, - { "hbh-not-strict", 1, 0, '3' }, - {0} +static const struct option hbh_opts[] = { + { "hbh-len", 1, NULL, '1' }, + { "hbh-opts", 1, NULL, '2' }, + { "hbh-not-strict", 1, NULL, '3' }, + { .name = NULL } }; -#else -static struct option opts[] = { - { "dst-len", 1, 0, '1' }, - { "dst-opts", 1, 0, '2' }, - { "dst-not-strict", 1, 0, '3' }, - {0} -}; -#endif static u_int32_t parse_opts_num(const char *idstr, const char *typestr) @@ -54,19 +40,19 @@ parse_opts_num(const char *idstr, const char *typestr) id = strtoul(idstr,&ep,0) ; if ( idstr == ep ) { - exit_error(PARAMETER_PROBLEM, - "%s no valid digits in %s `%s'", UNAME, typestr, idstr); + xtables_error(PARAMETER_PROBLEM, + "hbh: no valid digits in %s `%s'", typestr, idstr); } if ( id == ULONG_MAX && errno == ERANGE ) { - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "%s `%s' specified too big: would overflow", typestr, idstr); } if ( *idstr != '\0' && *ep != '\0' ) { - exit_error(PARAMETER_PROBLEM, - "%s error parsing %s `%s'", UNAME, typestr, idstr); + xtables_error(PARAMETER_PROBLEM, + "hbh: error parsing %s `%s'", typestr, idstr); } - return (u_int32_t) id; + return id; } static int @@ -76,7 +62,7 @@ parse_options(const char *optsstr, u_int16_t *opts) unsigned int i; buffer = strdup(optsstr); - if (!buffer) exit_error(OTHER_PROBLEM, "strdup failed"); + if (!buffer) xtables_error(OTHER_PROBLEM, "strdup failed"); for (cp=buffer, i=0; cp && i<IP6T_OPTS_OPTSNR; cp=next,i++) { @@ -85,16 +71,15 @@ parse_options(const char *optsstr, u_int16_t *opts) range = strchr(cp, ':'); if (range) { if (i == IP6T_OPTS_OPTSNR-1) - exit_error(PARAMETER_PROBLEM, + xtables_error(PARAMETER_PROBLEM, "too many ports specified"); *range++ = '\0'; } - opts[i] = (u_int16_t)((parse_opts_num(cp,"opt") & 0x000000FF)<<8); + opts[i] = (parse_opts_num(cp, "opt") & 0xFF) << 8; if (range) { if (opts[i] == 0) - exit_error(PARAMETER_PROBLEM, "PAD0 hasn't got length"); - opts[i] |= (u_int16_t)(parse_opts_num(range,"length") & - 0x000000FF); + xtables_error(PARAMETER_PROBLEM, "PAD0 has not got length"); + opts[i] |= parse_opts_num(range, "length") & 0xFF; } else { opts[i] |= (0x00FF); } @@ -104,7 +89,7 @@ parse_options(const char *optsstr, u_int16_t *opts) printf("opts opt: %04X\n", opts[i]); #endif } - if (cp) exit_error(PARAMETER_PROBLEM, "too many addresses specified"); + if (cp) xtables_error(PARAMETER_PROBLEM, "too many addresses specified"); free(buffer); @@ -115,9 +100,7 @@ parse_options(const char *optsstr, u_int16_t *opts) return i; } -/* Initialize the match. */ -static void -init(struct ip6t_entry_match *m, unsigned int *nfcache) +static void hbh_init(struct xt_entry_match *m) { struct ip6t_opts *optinfo = (struct ip6t_opts *)m->data; @@ -127,23 +110,18 @@ init(struct ip6t_entry_match *m, unsigned int *nfcache) optinfo->optsnr = 0; } -/* Function which parses command options; returns true if it - ate an option */ -static int -parse(int c, char **argv, int invert, unsigned int *flags, - const struct ip6t_entry *entry, - unsigned int *nfcache, - struct ip6t_entry_match **match) +static int hbh_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) { struct ip6t_opts *optinfo = (struct ip6t_opts *)(*match)->data; switch (c) { case '1': if (*flags & IP6T_OPTS_LEN) - exit_error(PARAMETER_PROBLEM, - "Only one `--%s-len' allowed", LNAME); - check_inverse(optarg, &invert, &optind, 0); - optinfo->hdrlen = parse_opts_num(argv[optind-1], "length"); + xtables_error(PARAMETER_PROBLEM, + "Only one `--hbh-len' allowed"); + xtables_check_inverse(optarg, &invert, &optind, 0, argv); + optinfo->hdrlen = parse_opts_num(optarg, "length"); if (invert) optinfo->invflags |= IP6T_OPTS_INV_LEN; optinfo->flags |= IP6T_OPTS_LEN; @@ -151,23 +129,23 @@ parse(int c, char **argv, int invert, unsigned int *flags, break; case '2': if (*flags & IP6T_OPTS_OPTS) - exit_error(PARAMETER_PROBLEM, - "Only one `--%s-opts' allowed", LNAME); - check_inverse(optarg, &invert, &optind, 0); + xtables_error(PARAMETER_PROBLEM, + "Only one `--hbh-opts' allowed"); + xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) - exit_error(PARAMETER_PROBLEM, - " '!' not allowed with `--%s-opts'", LNAME); - optinfo->optsnr = parse_options(argv[optind-1], optinfo->opts); + xtables_error(PARAMETER_PROBLEM, + " '!' not allowed with `--hbh-opts'"); + optinfo->optsnr = parse_options(optarg, optinfo->opts); optinfo->flags |= IP6T_OPTS_OPTS; *flags |= IP6T_OPTS_OPTS; break; case '3': if (*flags & IP6T_OPTS_NSTRICT) - exit_error(PARAMETER_PROBLEM, - "Only one `--%s-not-strict' allowed", LNAME); + xtables_error(PARAMETER_PROBLEM, + "Only one `--hbh-not-strict' allowed"); if ( !(*flags & IP6T_OPTS_OPTS) ) - exit_error(PARAMETER_PROBLEM, - "`--%s-opts ...' required before `--%s-not-strict'", LNAME, LNAME); + xtables_error(PARAMETER_PROBLEM, + "`--hbh-opts ...' required before `--hbh-not-strict'"); optinfo->flags |= IP6T_OPTS_NSTRICT; *flags |= IP6T_OPTS_NSTRICT; break; @@ -178,14 +156,8 @@ parse(int c, char **argv, int invert, unsigned int *flags, return 1; } -/* Final check; we don't care. */ static void -final_check(unsigned int flags) -{ -} - -static void -print_options(int optsnr, u_int16_t *optsp) +print_options(unsigned int optsnr, u_int16_t *optsp) { unsigned int i; @@ -198,14 +170,12 @@ print_options(int optsnr, u_int16_t *optsp) } } -/* Prints out the union ip6t_matchinfo. */ -static void -print(const struct ip6t_ip6 *ip, - const struct ip6t_entry_match *match, int numeric) +static void hbh_print(const void *ip, const struct xt_entry_match *match, + int numeric) { const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data; - printf("%s ", LNAME); + printf("hbh "); if (optinfo->flags & IP6T_OPTS_LEN) { printf("length"); printf(":%s", optinfo->invflags & IP6T_OPTS_INV_LEN ? "!" : ""); @@ -220,43 +190,39 @@ print(const struct ip6t_ip6 *ip, optinfo->invflags & ~IP6T_OPTS_INV_MASK); } -/* Saves the union ip6t_matchinfo in parsable form to stdout. */ -static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match) +static void hbh_save(const void *ip, const struct xt_entry_match *match) { const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data; if (optinfo->flags & IP6T_OPTS_LEN) { - printf("--%s-len %s%u ", LNAME, + printf("%s--hbh-len %u ", (optinfo->invflags & IP6T_OPTS_INV_LEN) ? "! " : "", optinfo->hdrlen); } - if (optinfo->flags & IP6T_OPTS_OPTS) printf("--%s-opts ", LNAME); + if (optinfo->flags & IP6T_OPTS_OPTS) + printf("--hbh-opts "); print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts); - if (optinfo->flags & IP6T_OPTS_NSTRICT) printf("--%s-not-strict ", LNAME); - + if (optinfo->flags & IP6T_OPTS_NSTRICT) + printf("--hbh-not-strict "); } -static struct ip6tables_match optstruct = { -#if HOPBYHOP +static struct xtables_match hbh_mt6_reg = { .name = "hbh", -#else - .name = "dst", -#endif - .version = IPTABLES_VERSION, - .size = IP6T_ALIGN(sizeof(struct ip6t_opts)), - .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_opts)), - .help = &help, - .init = &init, - .parse = &parse, - .final_check = &final_check, - .print = &print, - .save = &save, - .extra_opts = opts, + .version = XTABLES_VERSION, + .family = NFPROTO_IPV6, + .size = XT_ALIGN(sizeof(struct ip6t_opts)), + .userspacesize = XT_ALIGN(sizeof(struct ip6t_opts)), + .help = hbh_help, + .init = hbh_init, + .parse = hbh_parse, + .print = hbh_print, + .save = hbh_save, + .extra_opts = hbh_opts, }; void _init(void) { - register_match6(&optstruct); + xtables_register_match(&hbh_mt6_reg); } |