diff options
Diffstat (limited to 'extensions/libebt_stp.c')
-rw-r--r-- | extensions/libebt_stp.c | 274 |
1 files changed, 98 insertions, 176 deletions
diff --git a/extensions/libebt_stp.c b/extensions/libebt_stp.c index 3e9e2447..189e36a5 100644 --- a/extensions/libebt_stp.c +++ b/extensions/libebt_stp.c @@ -9,7 +9,6 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <getopt.h> #include <netinet/ether.h> #include <linux/netfilter_bridge/ebt_stp.h> #include <xtables.h> @@ -17,35 +16,37 @@ #include "iptables/nft.h" #include "iptables/nft-bridge.h" -#define STP_TYPE 'a' -#define STP_FLAGS 'b' -#define STP_ROOTPRIO 'c' -#define STP_ROOTADDR 'd' -#define STP_ROOTCOST 'e' -#define STP_SENDERPRIO 'f' -#define STP_SENDERADDR 'g' -#define STP_PORT 'h' -#define STP_MSGAGE 'i' -#define STP_MAXAGE 'j' -#define STP_HELLOTIME 'k' -#define STP_FWDD 'l' -#define STP_NUMOPS 12 +/* These must correspond to the bit position in EBT_STP_* defines */ +enum { + O_TYPE = 0, + O_FLAGS, + O_RPRIO, + O_RADDR, + O_RCOST, + O_SPRIO, + O_SADDR, + O_PORT, + O_MSGAGE, + O_MAXAGE, + O_HTIME, + O_FWDD, +}; -static const struct option brstp_opts[] = -{ - { "stp-type" , required_argument, 0, STP_TYPE}, - { "stp-flags" , required_argument, 0, STP_FLAGS}, - { "stp-root-prio" , required_argument, 0, STP_ROOTPRIO}, - { "stp-root-addr" , required_argument, 0, STP_ROOTADDR}, - { "stp-root-cost" , required_argument, 0, STP_ROOTCOST}, - { "stp-sender-prio" , required_argument, 0, STP_SENDERPRIO}, - { "stp-sender-addr" , required_argument, 0, STP_SENDERADDR}, - { "stp-port" , required_argument, 0, STP_PORT}, - { "stp-msg-age" , required_argument, 0, STP_MSGAGE}, - { "stp-max-age" , required_argument, 0, STP_MAXAGE}, - { "stp-hello-time" , required_argument, 0, STP_HELLOTIME}, - { "stp-forward-delay", required_argument, 0, STP_FWDD}, - { 0 } +static const struct xt_option_entry brstp_opts[] = { +#define ENTRY(n, i, t) { .name = n, .id = i, .type = t, .flags = XTOPT_INVERT } + ENTRY("stp-type", O_TYPE, XTTYPE_STRING), + ENTRY("stp-flags", O_FLAGS, XTTYPE_STRING), + ENTRY("stp-root-prio", O_RPRIO, XTTYPE_UINT16RC), + ENTRY("stp-root-addr", O_RADDR, XTTYPE_ETHERMACMASK), + ENTRY("stp-root-cost", O_RCOST, XTTYPE_UINT32RC), + ENTRY("stp-sender-prio", O_SPRIO, XTTYPE_UINT16RC), + ENTRY("stp-sender-addr", O_SADDR, XTTYPE_ETHERMACMASK), + ENTRY("stp-port", O_PORT, XTTYPE_UINT16RC), + ENTRY("stp-msg-age", O_MSGAGE, XTTYPE_UINT16RC), + ENTRY("stp-max-age", O_MAXAGE, XTTYPE_UINT16RC), + ENTRY("stp-hello-time", O_HTIME, XTTYPE_UINT16RC), + ENTRY("stp-forward-delay", O_FWDD, XTTYPE_UINT16RC), + XTOPT_TABLEEND, }; #define BPDU_TYPE_CONFIG 0 @@ -62,18 +63,18 @@ static void brstp_print_help(void) { printf( "stp options:\n" -"--stp-type type : BPDU type\n" -"--stp-flags flag : control flag\n" -"--stp-root-prio prio[:prio] : root priority (16-bit) range\n" -"--stp-root-addr address[/mask] : MAC address of root\n" -"--stp-root-cost cost[:cost] : root cost (32-bit) range\n" -"--stp-sender-prio prio[:prio] : sender priority (16-bit) range\n" -"--stp-sender-addr address[/mask] : MAC address of sender\n" -"--stp-port port[:port] : port id (16-bit) range\n" -"--stp-msg-age age[:age] : message age timer (16-bit) range\n" -"--stp-max-age age[:age] : maximum age timer (16-bit) range\n" -"--stp-hello-time time[:time] : hello time timer (16-bit) range\n" -"--stp-forward-delay delay[:delay]: forward delay timer (16-bit) range\n" +"[!] --stp-type type : BPDU type\n" +"[!] --stp-flags flag : control flag\n" +"[!] --stp-root-prio prio[:prio] : root priority (16-bit) range\n" +"[!] --stp-root-addr address[/mask] : MAC address of root\n" +"[!] --stp-root-cost cost[:cost] : root cost (32-bit) range\n" +"[!] --stp-sender-prio prio[:prio] : sender priority (16-bit) range\n" +"[!] --stp-sender-addr address[/mask] : MAC address of sender\n" +"[!] --stp-port port[:port] : port id (16-bit) range\n" +"[!] --stp-msg-age age[:age] : message age timer (16-bit) range\n" +"[!] --stp-max-age age[:age] : maximum age timer (16-bit) range\n" +"[!] --stp-hello-time time[:time] : hello time timer (16-bit) range\n" +"[!] --stp-forward-delay delay[:delay]: forward delay timer (16-bit) range\n" " Recognized BPDU type strings:\n" " \"config\": configuration BPDU (=0)\n" " \"tcn\" : topology change notification BPDU (=0x80)\n" @@ -82,172 +83,92 @@ static void brstp_print_help(void) " \"topology-change-ack\": topology change acknowledgement flag (0x80)"); } -static int parse_range(const char *portstring, void *lower, void *upper, - int bits, uint32_t min, uint32_t max) -{ - char *buffer; - char *cp, *end; - uint32_t low_nr, upp_nr; - int ret = 0; - - buffer = xtables_strdup(portstring); - - if ((cp = strchr(buffer, ':')) == NULL) { - low_nr = strtoul(buffer, &end, 10); - if (*end || low_nr < min || low_nr > max) { - ret = -1; - goto out; - } - if (bits == 2) { - *(uint16_t *)lower = low_nr; - *(uint16_t *)upper = low_nr; - } else { - *(uint32_t *)lower = low_nr; - *(uint32_t *)upper = low_nr; - } - } else { - *cp = '\0'; - cp++; - if (!*buffer) - low_nr = min; - else { - low_nr = strtoul(buffer, &end, 10); - if (*end || low_nr < min) { - ret = -1; - goto out; - } - } - if (!*cp) - upp_nr = max; - else { - upp_nr = strtoul(cp, &end, 10); - if (*end || upp_nr > max) { - ret = -1; - goto out; - } - } - if (upp_nr < low_nr) { - ret = -1; - goto out; - } - if (bits == 2) { - *(uint16_t *)lower = low_nr; - *(uint16_t *)upper = upp_nr; - } else { - *(uint32_t *)lower = low_nr; - *(uint32_t *)upper = upp_nr; - } - } -out: - free(buffer); - return ret; -} - static void print_range(unsigned int l, unsigned int u) { if (l == u) - printf("%u ", l); + printf("%u", l); else - printf("%u:%u ", l, u); + printf("%u:%u", l, u); } -static int -brstp_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void brstp_parse(struct xt_option_call *cb) { - struct ebt_stp_info *stpinfo = (struct ebt_stp_info *)(*match)->data; - unsigned int flag; - long int i; + struct ebt_stp_info *stpinfo = cb->data; char *end = NULL; + long int i; + + xtables_option_parse(cb); - if (c < 'a' || c > ('a' + STP_NUMOPS - 1)) - return 0; - flag = 1 << (c - 'a'); - EBT_CHECK_OPTION(flags, flag); - if (invert) - stpinfo->invflags |= flag; - stpinfo->bitmask |= flag; - switch (flag) { - case EBT_STP_TYPE: - i = strtol(optarg, &end, 0); + stpinfo->bitmask |= 1 << cb->entry->id; + if (cb->invert) + stpinfo->invflags |= 1 << cb->entry->id; + + switch (cb->entry->id) { + case O_TYPE: + i = strtol(cb->arg, &end, 0); if (i < 0 || i > 255 || *end != '\0') { - if (!strcasecmp(optarg, BPDU_TYPE_CONFIG_STRING)) + if (!strcasecmp(cb->arg, BPDU_TYPE_CONFIG_STRING)) stpinfo->type = BPDU_TYPE_CONFIG; - else if (!strcasecmp(optarg, BPDU_TYPE_TCN_STRING)) + else if (!strcasecmp(cb->arg, BPDU_TYPE_TCN_STRING)) stpinfo->type = BPDU_TYPE_TCN; else xtables_error(PARAMETER_PROBLEM, "Bad --stp-type argument"); } else stpinfo->type = i; break; - case EBT_STP_FLAGS: - i = strtol(optarg, &end, 0); + case O_FLAGS: + i = strtol(cb->arg, &end, 0); if (i < 0 || i > 255 || *end != '\0') { - if (!strcasecmp(optarg, FLAG_TC_STRING)) + if (!strcasecmp(cb->arg, FLAG_TC_STRING)) stpinfo->config.flags = FLAG_TC; - else if (!strcasecmp(optarg, FLAG_TC_ACK_STRING)) + else if (!strcasecmp(cb->arg, FLAG_TC_ACK_STRING)) stpinfo->config.flags = FLAG_TC_ACK; else xtables_error(PARAMETER_PROBLEM, "Bad --stp-flags argument"); } else stpinfo->config.flags = i; break; - case EBT_STP_ROOTPRIO: - if (parse_range(argv[optind-1], &(stpinfo->config.root_priol), - &(stpinfo->config.root_priou), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-prio range"); + case O_RADDR: + memcpy(stpinfo->config.root_addr, cb->val.ethermac, ETH_ALEN); + memcpy(stpinfo->config.root_addrmsk, + cb->val.ethermacmask, ETH_ALEN); break; - case EBT_STP_ROOTCOST: - if (parse_range(argv[optind-1], &(stpinfo->config.root_costl), - &(stpinfo->config.root_costu), 4, 0, 0xffffffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-cost range"); + case O_SADDR: + memcpy(stpinfo->config.sender_addr, cb->val.ethermac, ETH_ALEN); + memcpy(stpinfo->config.sender_addrmsk, + cb->val.ethermacmask, ETH_ALEN); break; - case EBT_STP_SENDERPRIO: - if (parse_range(argv[optind-1], &(stpinfo->config.sender_priol), - &(stpinfo->config.sender_priou), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-prio range"); + +#define RANGE_ASSIGN(fname, val) { \ + stpinfo->config.fname##l = val[0]; \ + stpinfo->config.fname##u = cb->nvals > 1 ? val[1] : val[0]; \ +} + case O_RPRIO: + RANGE_ASSIGN(root_prio, cb->val.u16_range); break; - case EBT_STP_PORT: - if (parse_range(argv[optind-1], &(stpinfo->config.portl), - &(stpinfo->config.portu), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-port-range"); + case O_RCOST: + RANGE_ASSIGN(root_cost, cb->val.u32_range); break; - case EBT_STP_MSGAGE: - if (parse_range(argv[optind-1], &(stpinfo->config.msg_agel), - &(stpinfo->config.msg_ageu), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-msg-age range"); + case O_SPRIO: + RANGE_ASSIGN(sender_prio, cb->val.u16_range); break; - case EBT_STP_MAXAGE: - if (parse_range(argv[optind-1], &(stpinfo->config.max_agel), - &(stpinfo->config.max_ageu), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-max-age range"); + case O_PORT: + RANGE_ASSIGN(port, cb->val.u16_range); break; - case EBT_STP_HELLOTIME: - if (parse_range(argv[optind-1], &(stpinfo->config.hello_timel), - &(stpinfo->config.hello_timeu), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-hello-time range"); + case O_MSGAGE: + RANGE_ASSIGN(msg_age, cb->val.u16_range); break; - case EBT_STP_FWDD: - if (parse_range(argv[optind-1], &(stpinfo->config.forward_delayl), - &(stpinfo->config.forward_delayu), 2, 0, 0xffff)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range"); + case O_MAXAGE: + RANGE_ASSIGN(max_age, cb->val.u16_range); break; - case EBT_STP_ROOTADDR: - if (xtables_parse_mac_and_mask(argv[optind-1], - stpinfo->config.root_addr, - stpinfo->config.root_addrmsk)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address"); + case O_HTIME: + RANGE_ASSIGN(hello_time, cb->val.u16_range); break; - case EBT_STP_SENDERADDR: - if (xtables_parse_mac_and_mask(argv[optind-1], - stpinfo->config.sender_addr, - stpinfo->config.sender_addrmsk)) - xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address"); + case O_FWDD: + RANGE_ASSIGN(forward_delay, cb->val.u16_range); break; - default: - xtables_error(PARAMETER_PROBLEM, "Unknown stp option"); +#undef RANGE_ASSIGN } - return 1; } static void brstp_print(const void *ip, const struct xt_entry_match *match, @@ -257,11 +178,12 @@ static void brstp_print(const void *ip, const struct xt_entry_match *match, const struct ebt_stp_config_info *c = &(stpinfo->config); int i; - for (i = 0; i < STP_NUMOPS; i++) { + for (i = 0; (1 << i) < EBT_STP_MASK; i++) { if (!(stpinfo->bitmask & (1 << i))) continue; - printf("--%s %s", brstp_opts[i].name, - (stpinfo->invflags & (1 << i)) ? "! " : ""); + printf("%s--%s ", + (stpinfo->invflags & (1 << i)) ? "! " : "", + brstp_opts[i].name); if (EBT_STP_TYPE == (1 << i)) { if (stpinfo->type == BPDU_TYPE_CONFIG) printf("%s", BPDU_TYPE_CONFIG_STRING); @@ -308,9 +230,9 @@ static struct xtables_match brstp_match = { .family = NFPROTO_BRIDGE, .size = sizeof(struct ebt_stp_info), .help = brstp_print_help, - .parse = brstp_parse, + .x6_parse = brstp_parse, .print = brstp_print, - .extra_opts = brstp_opts, + .x6_options = brstp_opts }; void _init(void) |