From ff587205009a0d49e2d086765de87dc619b028bb Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Tue, 8 Feb 2005 20:02:28 +0000 Subject: general cleanup + add -C and -c --- extensions/ebt_vlan.c | 286 ++++++++++++++------------------------------------ 1 file changed, 76 insertions(+), 210 deletions(-) (limited to 'extensions/ebt_vlan.c') diff --git a/extensions/ebt_vlan.c b/extensions/ebt_vlan.c index 0c94a66..21f2e22 100644 --- a/extensions/ebt_vlan.c +++ b/extensions/ebt_vlan.c @@ -1,33 +1,10 @@ -/* - * Summary: ebt_vlan - IEEE 802.1Q extension module for userspace - * - * Description: 802.1Q Virtual LAN match support module for ebtables project. - * Enables to match 802.1Q: - * 1) VLAN-tagged frames by VLAN numeric identifier (12 - bits field) - * 2) Priority-tagged frames by user_priority (3 bits field) - * 3) Encapsulated Frame by ethernet protocol type/length +/* ebt_vlan * * Authors: - * Bart De Schuymer + * Bart De Schuymer * Nick Fedchik - * June, 2002 - * - * License: GNU GPL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * June, 2002 */ #include @@ -40,30 +17,19 @@ #include #include - -#define GET_BITMASK(_MASK_) vlaninfo->bitmask & _MASK_ -#define SET_BITMASK(_MASK_) vlaninfo->bitmask |= _MASK_ -#define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "! " : "" -#define CHECK_IF_MISSING_VALUE if (optind > argc) ebt_print_error ("Missing %s value", opts[c].name); -#define CHECK_INV_FLAG(_INDEX_) if (ebt_check_inverse (optarg)) vlaninfo->invflags |= _INDEX_; -#define CHECK_RANGE(_RANGE_) if (_RANGE_) ebt_print_error ("Invalid %s range", opts[c].name); - #define NAME_VLAN_ID "id" #define NAME_VLAN_PRIO "prio" #define NAME_VLAN_ENCAP "encap" -#define VLAN_ID 0 -#define VLAN_PRIO 1 -#define VLAN_ENCAP 2 +#define VLAN_ID '1' +#define VLAN_PRIO '2' +#define VLAN_ENCAP '3' static struct option opts[] = { - {EBT_VLAN_MATCH "-" NAME_VLAN_ID, required_argument, NULL, - VLAN_ID}, - {EBT_VLAN_MATCH "-" NAME_VLAN_PRIO, required_argument, NULL, - VLAN_PRIO}, - {EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP, required_argument, NULL, - VLAN_ENCAP}, - {NULL} + {"vlan-id" , required_argument, NULL, VLAN_ID}, + {"vlan-prio" , required_argument, NULL, VLAN_PRIO}, + {"vlan-encap", required_argument, NULL, VLAN_ENCAP}, + { 0 } }; /* @@ -76,104 +42,67 @@ static struct option opts[] = { struct ethertypeent *ethent; -/* - * Print out local help by "ebtables -h " - */ - static void print_help() { -#define HELP_TITLE "802.1Q VLAN extension" - - printf(HELP_TITLE " options:\n"); - printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_ID " %s" NAME_VLAN_ID - " : VLAN-tagged frame identifier, 0,1-4096 (integer), default 1\n", - OPT_VLAN_FLAGS & OPT_VLAN_ID ? "[!] " : ""); - printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_PRIO " %s" NAME_VLAN_PRIO - " : Priority-tagged frame user_priority, 0-7 (integer), default 0\n", - OPT_VLAN_FLAGS & OPT_VLAN_PRIO ? "[!] " : ""); - printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP " %s" - NAME_VLAN_ENCAP - " : Encapsulated frame type (hexadecimal), default IP (0800)\n", - OPT_VLAN_FLAGS & OPT_VLAN_ENCAP ? "[!] " : ""); + printf( +"vlan options:\n" +"--vlan-id [!] id : vlan-tagged frame identifier, 0,1-4096 (integer)\n" +"--vlan-prio [!] prio : Priority-tagged frame's user priority, 0-7 (integer)\n" +"--vlan-encap [!] encap : Encapsulated frame protocol (hexadecimal or name)\n"); } -/* - * Initialization function - */ static void init(struct ebt_entry_match *match) { - struct ebt_vlan_info *vlaninfo = - (struct ebt_vlan_info *) match->data; - /* - * Set initial values - */ - vlaninfo->id = 1; /* Default VID for VLAN-tagged 802.1Q frames */ - vlaninfo->prio = 0; - vlaninfo->encap = 0; + struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data; vlaninfo->invflags = 0; vlaninfo->bitmask = 0; } -/* - * Parse passed arguments values (ranges, flags, etc...) - * int c - parameter number from static struct option opts[] - * int argc - total amout of arguments (std argc value) - * int argv - arguments (std argv value) - * const struct ebt_u_entry *entry - default ebtables entry set - * unsigned int *flags - - * struct ebt_entry_match **match - - */ -static int -parse(int c, - char **argv, - int argc, - const struct ebt_u_entry *entry, - unsigned int *flags, struct ebt_entry_match **match) +static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + unsigned int *flags, struct ebt_entry_match **match) { - struct ebt_vlan_info *vlaninfo = - (struct ebt_vlan_info *) (*match)->data; + struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) (*match)->data; char *end; struct ebt_vlan_info local; switch (c) { case VLAN_ID: - ebt_check_option(flags, OPT_VLAN_ID); - CHECK_INV_FLAG(EBT_VLAN_ID); - CHECK_IF_MISSING_VALUE; - local.id = strtoul(argv[optind - 1], &end, 10); - CHECK_RANGE(local.id > 4094 || *end != '\0'); + ebt_check_option2(flags, OPT_VLAN_ID); + if (ebt_check_inverse2(optarg)) + vlaninfo->invflags |= EBT_VLAN_ID; + local.id = strtoul(optarg, &end, 10); + if (local.id > 4094 || *end != '\0') + ebt_print_error2("Invalid --vlan-id range ('%s')", optarg); vlaninfo->id = local.id; - SET_BITMASK(EBT_VLAN_ID); + vlaninfo->bitmask |= EBT_VLAN_ID; break; - case VLAN_PRIO: - ebt_check_option(flags, OPT_VLAN_PRIO); - CHECK_INV_FLAG(EBT_VLAN_PRIO); - CHECK_IF_MISSING_VALUE; - local.prio = strtoul(argv[optind - 1], &end, 10); - CHECK_RANGE(local.prio >= 8 || *end != '\0'); + ebt_check_option2(flags, OPT_VLAN_PRIO); + if (ebt_check_inverse2(optarg)) + vlaninfo->invflags |= EBT_VLAN_PRIO; + local.prio = strtoul(optarg, &end, 10); + if (local.prio >= 8 || *end != '\0') + ebt_print_error2("Invalid --vlan-prio range ('%s')", optarg); vlaninfo->prio = local.prio; - SET_BITMASK(EBT_VLAN_PRIO); + vlaninfo->bitmask |= EBT_VLAN_PRIO; break; - case VLAN_ENCAP: - ebt_check_option(flags, OPT_VLAN_ENCAP); - CHECK_INV_FLAG(EBT_VLAN_ENCAP); - CHECK_IF_MISSING_VALUE; - local.encap = strtoul(argv[optind - 1], &end, 16); + ebt_check_option2(flags, OPT_VLAN_ENCAP); + if (ebt_check_inverse2(optarg)) + vlaninfo->invflags |= EBT_VLAN_ENCAP; + local.encap = strtoul(optarg, &end, 16); if (*end != '\0') { - ethent = getethertypebyname(argv[optind - 1]); + ethent = getethertypebyname(optarg); if (ethent == NULL) - ebt_print_error("Unknown %s encap", - opts[c].name); + ebt_print_error("Unknown --vlan-encap value ('%s')", optarg); local.encap = ethent->e_ethertype; } - CHECK_RANGE(local.encap < ETH_ZLEN); + if (local.encap < ETH_ZLEN) + ebt_print_error2("Invalid --vlan-encap range ('%s')", optarg); vlaninfo->encap = htons(local.encap); - SET_BITMASK(EBT_VLAN_ENCAP); + vlaninfo->bitmask |= EBT_VLAN_ENCAP; break; - default: return 0; @@ -181,75 +110,34 @@ parse(int c, return 1; } -/* - * Final check - logical conditions - */ -static void -final_check(const struct ebt_u_entry *entry, - const struct ebt_entry_match *match, - const char *name, unsigned int hookmask, unsigned int time) +static void final_check(const struct ebt_u_entry *entry, + const struct ebt_entry_match *match, + const char *name, unsigned int hookmask, unsigned int time) { - - struct ebt_vlan_info *vlaninfo = - (struct ebt_vlan_info *) match->data; - /* - * Specified proto isn't 802.1Q? - */ if (entry->ethproto != ETH_P_8021Q || entry->invflags & EBT_IPROTO) - ebt_print_error("For use 802.1Q extension the protocol " - "must be specified as 802_1Q"); - /* - * Check if specified vlan-encap=0x8100 (802.1Q Frame) - * when vlan-encap specified. - */ - if (GET_BITMASK(EBT_VLAN_ENCAP)) { - if (vlaninfo->encap == htons(0x8100)) - ebt_print_error("Encapsulated frame type can not be " - "802.1Q (0x8100)"); - } - - /* - * Check if specified vlan-id=0 (priority-tagged frame condition) - * when vlan-prio was specified. - */ - if (GET_BITMASK(EBT_VLAN_PRIO)) { - if (vlaninfo->id && GET_BITMASK(EBT_VLAN_ID)) - ebt_print_error("For use user_priority the specified " - "vlan-id must be 0"); - } + ebt_print_error("For vlan filtering the protocol must be specified as 802_1Q"); + + /* Check if specified vlan-id=0 (priority-tagged frame condition) + * when vlan-prio was specified. */ + /* I see no reason why a user should be prohibited to match on a perhaps impossible situation + if (vlaninfo->bitmask & EBT_VLAN_PRIO && + vlaninfo->id && vlaninfo->bitmask & EBT_VLAN_ID) + ebt_print_error("When setting --vlan-prio the specified --vlan-id must be 0");*/ } -/* - * Print line when listing rules by ebtables -L - */ -static void -print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match) +static void print(const struct ebt_u_entry *entry, + const struct ebt_entry_match *match) { - struct ebt_vlan_info *vlaninfo = - (struct ebt_vlan_info *) match->data; + struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data; - /* - * Print VLAN ID if they are specified - */ - if (GET_BITMASK(EBT_VLAN_ID)) { - printf("--%s %s%d ", - opts[VLAN_ID].name, - INV_FLAG(EBT_VLAN_ID), vlaninfo->id); + if (vlaninfo->bitmask & EBT_VLAN_ID) { + printf("--vlan-id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "", vlaninfo->id); } - /* - * Print user priority if they are specified - */ - if (GET_BITMASK(EBT_VLAN_PRIO)) { - printf("--%s %s%d ", - opts[VLAN_PRIO].name, - INV_FLAG(EBT_VLAN_PRIO), vlaninfo->prio); + if (vlaninfo->bitmask & EBT_VLAN_PRIO) { + printf("--vlan-prio %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "", vlaninfo->prio); } - /* - * Print encapsulated frame type if they are specified - */ - if (GET_BITMASK(EBT_VLAN_ENCAP)) { - printf("--%s %s", - opts[VLAN_ENCAP].name, INV_FLAG(EBT_VLAN_ENCAP)); + if (vlaninfo->bitmask & EBT_VLAN_ENCAP) { + printf("--vlan-encap %s", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : ""); ethent = getethertypebynumber(ntohs(vlaninfo->encap)); if (ethent != NULL) { printf("%s ", ethent->e_name); @@ -259,47 +147,25 @@ print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match) } } - -static int -compare(const struct ebt_entry_match *vlan1, - const struct ebt_entry_match *vlan2) +static int compare(const struct ebt_entry_match *vlan1, + const struct ebt_entry_match *vlan2) { - struct ebt_vlan_info *vlaninfo1 = - (struct ebt_vlan_info *) vlan1->data; - struct ebt_vlan_info *vlaninfo2 = - (struct ebt_vlan_info *) vlan2->data; - /* - * Compare argc - */ + struct ebt_vlan_info *vlaninfo1 = (struct ebt_vlan_info *) vlan1->data; + struct ebt_vlan_info *vlaninfo2 = (struct ebt_vlan_info *) vlan2->data; + if (vlaninfo1->bitmask != vlaninfo2->bitmask) return 0; - /* - * Compare inv flags - */ if (vlaninfo1->invflags != vlaninfo2->invflags) return 0; - /* - * Compare VLAN ID if they are present - */ - if (vlaninfo1->bitmask & EBT_VLAN_ID) { - if (vlaninfo1->id != vlaninfo2->id) - return 0; - }; - /* - * Compare VLAN Prio if they are present - */ - if (vlaninfo1->bitmask & EBT_VLAN_PRIO) { - if (vlaninfo1->prio != vlaninfo2->prio) - return 0; - }; - /* - * Compare VLAN Encap if they are present - */ - if (vlaninfo1->bitmask & EBT_VLAN_ENCAP) { - if (vlaninfo1->encap != vlaninfo2->encap) - return 0; - }; - + if (vlaninfo1->bitmask & EBT_VLAN_ID && + vlaninfo1->id != vlaninfo2->id) + return 0; + if (vlaninfo1->bitmask & EBT_VLAN_PRIO && + vlaninfo1->prio != vlaninfo2->prio) + return 0; + if (vlaninfo1->bitmask & EBT_VLAN_ENCAP && + vlaninfo1->encap != vlaninfo2->encap) + return 0; return 1; } -- cgit v1.2.3