summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/ebt_vlan.c162
1 files changed, 102 insertions, 60 deletions
diff --git a/extensions/ebt_vlan.c b/extensions/ebt_vlan.c
index f74b26f..5c8504d 100644
--- a/extensions/ebt_vlan.c
+++ b/extensions/ebt_vlan.c
@@ -1,16 +1,32 @@
/*
- * Summary: ebt_vlan - 802.1 Q match extension module for userspace
+ * Summary: ebt_vlan - IEEE 802.1Q extension module for userspace
*
- * Description:802.1 Q Virtual LAN match support module for ebtables project.
- * Enable to match 802.1 Q VLAN tagged frames by VLAN numeric
- * identifier (12 - bits field) and user_priority (3 bits field)
+ * 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
*
* Authors:
* Bart De Schuymer <bart.de.schuymer@pandora.be>
* Nick Fedchik <nick@fedchik.org.ua>
* June, 2002
*
- * License: GPL
+ * 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
*
*/
@@ -23,26 +39,30 @@
#include "../include/ebtables_u.h"
#include <linux/netfilter_bridge/ebt_vlan.h>
-#define VLAN_ID '1'
-#define VLAN_PRIO '2'
-#define VLAN_ENCAP '3'
+#define GET_BITMASK(_MASK_) vlaninfo->bitmask & _MASK_
+#define SET_BITMASK(_MASK_) vlaninfo->bitmask |= _MASK_
+#define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "!" : ""
+#define VLAN_ID 0
+#define VLAN_PRIO 1
+#define VLAN_ENCAP 2
static struct option opts[] = {
- {"vlan-id", required_argument, 0, VLAN_ID},
- {"vlan-prio", required_argument, 0, VLAN_PRIO},
- {"vlan-encap", required_argument, 0, VLAN_ENCAP},
- {0}
+ {"vlan-id", required_argument, NULL, VLAN_ID},
+ {"vlan-prio", required_argument, NULL, VLAN_PRIO},
+ {"vlan-encap", required_argument, NULL, VLAN_ENCAP},
+ {NULL}
};
+
/*
- * Print out local help by ebtables -h vlan
+ * Print out local help by "ebtables -h vlan"
*/
static void print_help ()
{
- printf ("802.1Q VLAN options:\n"
- "--vlan-id [!] id : VLAN ID 1-4094 (integer)\n"
- "--vlan-prio [!] prio : VLAN Priority 0-7 (integer)\n"
- "--vlan-encap [!] proto : VLAN Encapsulated Protocol (integer or string as in /etc/ethertypes)\n");
+ printf ("802.1Q VLAN extension options:\n"
+ "--vlan-id [!]id : VLAN-tagged frame identifier, 0,1-4094 (integer)\n"
+ "--vlan-prio [!]prio : Priority-tagged frame user_priority, 0-7 (integer)\n"
+ "--vlan-encap [!]proto : Encapsulated protocol (hexadecimal)\n");
}
/*
@@ -53,9 +73,9 @@ static void init (struct ebt_entry_match *match)
struct ebt_vlan_info *vlaninfo =
(struct ebt_vlan_info *) match->data;
/*
- * Just clean initial values
+ * Set initial values
*/
- vlaninfo->id = 0;
+ vlaninfo->id = 1; /* Default VID for VLAN-tagged 802.1Q frames */
vlaninfo->prio = 0;
vlaninfo->encap = 0;
vlaninfo->invflags = 0;
@@ -69,16 +89,23 @@ static void init (struct ebt_entry_match *match)
#define OPT_VLAN_PRIO 0x02
#define OPT_VLAN_ENCAP 0x04
+/*
+ * 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)
+ *
+ */
static int
-parse (int c, char **argv, int argc,
- const struct ebt_u_entry *entry, unsigned int *flags,
- struct ebt_entry_match **match)
+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;
unsigned long i;
char *end;
-
switch (c) {
case VLAN_ID:
/*
@@ -96,7 +123,7 @@ parse (int c, char **argv, int argc,
* Check arg value presence
*/
if (optind > argc)
- print_error ("Missing VLAN ID argument\n");
+ print_error ("Missing VLAN ID argument value\n");
/*
* Convert argv to long int,
* set *end to end of argv string,
@@ -106,19 +133,17 @@ parse (int c, char **argv, int argc,
/*
* Check arg val range
*/
- if (i < 1 || i >= 4094 || *end != '\0') {
- i = 0;
+ if (i > 4094 || *end != '\0')
print_error
- ("Problem with specified VLAN ID range\n");
- }
+ ("Specified VLAN ID is out of range (0-4094)\n");
/*
- * Set up parameter value
+ * Set up parameter value
*/
vlaninfo->id = i;
/*
* Set up parameter presence flag
*/
- vlaninfo->bitmask |= EBT_VLAN_ID;
+ SET_BITMASK (EBT_VLAN_ID);
break;
case VLAN_PRIO:
@@ -127,7 +152,7 @@ parse (int c, char **argv, int argc,
vlaninfo->invflags |= EBT_VLAN_PRIO;
if (optind > argc)
print_error
- ("Missing VLAN Priority level argument\n");
+ ("Missing user_priority argument value\n");
/*
* Convert argv to long int,
* set *end to end of argv string,
@@ -137,11 +162,9 @@ parse (int c, char **argv, int argc,
/*
* Check arg val range
*/
- if (i >= 8 || *end != '\0') {
- i = 0;
+ if (i >= 8 || *end != '\0')
print_error
- ("Problem with specified VLAN Priority range\n");
- }
+ ("Specified user_priority is out of range (0-7)\n");
/*
* Set up parameter value
*/
@@ -149,7 +172,7 @@ parse (int c, char **argv, int argc,
/*
* Set up parameter presence flag
*/
- vlaninfo->bitmask |= EBT_VLAN_PRIO;
+ SET_BITMASK (EBT_VLAN_PRIO);
break;
case VLAN_ENCAP:
@@ -158,20 +181,20 @@ parse (int c, char **argv, int argc,
vlaninfo->invflags |= EBT_VLAN_ENCAP;
if (optind > argc)
print_error
- ("Missing VLAN Encapsulated Protocol argument\n");
+ ("Missing encapsulated frame type argument value\n");
/*
* Parameter can be decimal, hexadecimal, or string.
- * Check arg val range
+ * Check arg val range (still raw area)
*/
(unsigned short) i = strtol (argv[optind - 1], &end, 16);
- if (*end == '\0' && (i < 0 || i > 0xFFFF))
+ if (*end == '\0' && (i < ETH_ZLEN || i > 0xFFFF))
print_error
- ("Problem with the specified encapsulated protocol");
+ ("Specified encapsulated frame type is out of range\n");
if (*end != '\0')
if (name_to_protocol (argv[optind - 1]) == -1)
print_error
("Problem with the specified encapsulated"
- "protocol");
+ "protocol\n");
/*
* Set up parameter value (network notation)
*/
@@ -179,7 +202,7 @@ parse (int c, char **argv, int argc,
/*
* Set up parameter presence flag
*/
- vlaninfo->bitmask |= EBT_VLAN_ENCAP;
+ SET_BITMASK (EBT_VLAN_ENCAP);
break;
default:
return 0;
@@ -188,19 +211,31 @@ parse (int c, char **argv, int argc,
}
/*
- * Final check
+ * 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 hook_mask, unsigned int time)
+ const char *name, unsigned int hook, unsigned int time)
{
+
+ struct ebt_vlan_info *vlaninfo =
+ (struct ebt_vlan_info *) match->data;
/*
- * Is any proto supplied there? Or specified proto isn't 802.1Q?
+ * Is any proto param specified there? Or specified proto isn't 802.1Q?
*/
if (entry->bitmask & EBT_NOPROTO || entry->ethproto != ETH_P_8021Q)
print_error
- ("For matching 802.1Q VLAN the protocol must be specified as 802_1Q\n");
+ ("For use 802.1Q extension the protocol must be specified as 802_1Q\n");
+ /*
+ * 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))
+ print_error
+ ("For use user_priority the specified vlan-id must be 0\n");
+ }
}
/*
@@ -213,29 +248,36 @@ print (const struct ebt_u_entry *entry,
struct ebt_vlan_info *vlaninfo =
(struct ebt_vlan_info *) match->data;
+ char ethertype_name[21];
/*
* Print VLAN ID if they are specified
*/
- if (vlaninfo->bitmask & EBT_VLAN_ID) {
- printf ("--vlan-id %s %d ",
- vlaninfo->invflags & EBT_VLAN_ID ? "!" : "",
- vlaninfo->id);
+ if (GET_BITMASK (EBT_VLAN_ID)) {
+ printf ("--%s %s%d ",
+ opts[VLAN_ID].name,
+ INV_FLAG (EBT_VLAN_ID), vlaninfo->id);
}
/*
- * Print VLAN priority if they are specified
+ * Print user priority if they are specified
*/
- if (vlaninfo->bitmask & EBT_VLAN_PRIO) {
- printf ("--vlan-prio %s %d ",
- vlaninfo->invflags & EBT_VLAN_PRIO ? "!" : "",
- vlaninfo->prio);
+ if (GET_BITMASK (EBT_VLAN_PRIO)) {
+ printf ("--%s %s%d ",
+ opts[VLAN_PRIO].name,
+ INV_FLAG (EBT_VLAN_PRIO), vlaninfo->prio);
}
/*
- * Print VLAN encapsulated protocol if they are specified
+ * Print encapsulated frame type if they are specified
*/
- if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
- printf ("--vlan-encap %s %2.4X ",
- vlaninfo->invflags & EBT_VLAN_ENCAP ? "!" : "",
- ntohs (vlaninfo->encap));
+ if (GET_BITMASK (EBT_VLAN_ENCAP)) {
+ printf ("--%s %s",
+ opts[VLAN_ENCAP].name, INV_FLAG (EBT_VLAN_ENCAP));
+ bzero (ethertype_name, 21);
+ if (!number_to_name
+ (ntohs (vlaninfo->encap), ethertype_name)) {
+ printf ("%s ", ethertype_name);
+ } else {
+ printf ("%2.4X ", ntohs (vlaninfo->encap));
+ }
}
}