static int parse_options(const char *optsstr, u_int16_t *opts) { char *buffer, *cp, *next, *range; unsigned int i; buffer = strdup(optsstr); if (!buffer) exit_error(OTHER_PROBLEM, "strdup failed"); for (cp = buffer, i = 0; cp && i < IP6T_OPTS_OPTSNR; cp = next, i++) { next = strchr(cp, ','); if (next) *next++='\0'; range = strchr(cp, ':'); if (range) { if (i == IP6T_OPTS_OPTSNR-1) exit_error(PARAMETER_PROBLEM, "too many ports specified"); *range++ = '\0'; } opts[i] = (u_int16_t)((parse_opts_num(cp,"opt") & 0x000000FF)<<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); } else opts[i] |= (0x00FF); #ifdef DEBUG printf("opts str: %s %s\n", cp, range); printf("opts opt: %04X\n", opts[i]); #endif } if (cp) exit_error(PARAMETER_PROBLEM, "too many addresses specified"); free(buffer); #ifdef DEBUG printf("addr nr: %d\n", i); #endif return i; }
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) 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; *flags |= IP6T_OPTS_LEN; break; case '2': if (*flags & IP6T_OPTS_OPTS) xtables_error(PARAMETER_PROBLEM, "Only one `--hbh-opts' allowed"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) 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; } return 1; }
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) { struct ip6t_opts *optinfo = (struct ip6t_opts *)(*match)->data; switch (c) { case '1': if (*flags & IP6T_OPTS_LEN) exit_error(PARAMETER_PROBLEM, "Only one `--" LNAME "-len' allowed"); check_inverse(optarg, &invert, &optind, 0); optinfo->hdrlen = parse_opts_num(argv[optind-1], "length"); if (invert) optinfo->invflags |= IP6T_OPTS_INV_LEN; optinfo->flags |= IP6T_OPTS_LEN; *flags |= IP6T_OPTS_LEN; break; case '2': if (*flags & IP6T_OPTS_OPTS) exit_error(PARAMETER_PROBLEM, "Only one `--" LNAME "-opts' allowed"); check_inverse(optarg, &invert, &optind, 0); if (invert) exit_error(PARAMETER_PROBLEM, " '!' not allowed with `--" LNAME "-opts'"); optinfo->optsnr = parse_options(argv[optind-1], 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 `--" LNAME "-not-strict' allowed"); if ( !(*flags & IP6T_OPTS_OPTS) ) exit_error(PARAMETER_PROBLEM, "`--" LNAME "-opts ...' required before `--" LNAME "-not-strict'"); optinfo->flags |= IP6T_OPTS_NSTRICT; *flags |= IP6T_OPTS_NSTRICT; break; default: return 0; } return 1; }