summaryrefslogtreecommitdiffstats
path: root/extensions/ebt_vlan.c
diff options
context:
space:
mode:
authorBart De Schuymer <bdschuym@pandora.be>2005-02-08 20:02:28 +0000
committerBart De Schuymer <bdschuym@pandora.be>2005-02-08 20:02:28 +0000
commitff587205009a0d49e2d086765de87dc619b028bb (patch)
treed1d7fd0768212c24f2adcfd9c720975394f85694 /extensions/ebt_vlan.c
parent96ce8685fe4011ef08b0f4fe2778b523c3740766 (diff)
general cleanup + add -C and -c
Diffstat (limited to 'extensions/ebt_vlan.c')
-rw-r--r--extensions/ebt_vlan.c286
1 files changed, 76 insertions, 210 deletions
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@pandora.be>
+ * Bart De Schuymer <bdschuym@pandora.be>
* Nick Fedchik <nick@fedchik.org.ua>
- * 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 <stdio.h>
@@ -40,30 +17,19 @@
#include <linux/netfilter_bridge/ebt_vlan.h>
#include <linux/if_ether.h>
-
-#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 <match name>"
- */
-
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 <BDS>
+ 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;
}