summaryrefslogtreecommitdiffstats
path: root/extensions/ebt_vlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/ebt_vlan.c')
-rw-r--r--extensions/ebt_vlan.c119
1 files changed, 95 insertions, 24 deletions
diff --git a/extensions/ebt_vlan.c b/extensions/ebt_vlan.c
index ad3e6f7..580fa71 100644
--- a/extensions/ebt_vlan.c
+++ b/extensions/ebt_vlan.c
@@ -1,44 +1,49 @@
/*
- * Summary: ebt_vlan userspace module
- *
- * Description: 802.1Q Virtual LAN match support module for ebtables project.
- * Enable to match 802.1Q VLAN tagged frames by VLAN numeric
- * identifier (12-bites field) and frame priority (3-bites field)
+ * Summary: ebt_vlan - 802.1 Q match 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)
*
* Authors:
* Bart De Schuymer <bart.de.schuymer@pandora.be>
- * Nick Fedchik <nick@fedchik.org.ua>
- *
- * May, 2002
+ * Nick Fedchik <nick@fedchik.org.ua>
+ * June, 2002
+ *
+ * License: GPL
+ *
*/
-
+
+#include <getopt.h>
+#include <netinet/in.h>
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
-#include <netinet/in.h>
+
#include <linux/netfilter_bridge/ebtables.h>
-#include <getopt.h>
#include "../include/ebtables_u.h"
-#include <linux/netfilter_bridge/ebt_vlan.h>
#define VLAN_ID '1'
#define VLAN_PRIO '2'
+#define VLAN_ENCAP '3'
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}
};
/*
- * Print out help for 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-4095 (integer)\n"
- "--vlan-prio [!] prio : VLAN Priority 0-7 (integer)\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");
}
/*
@@ -53,12 +58,18 @@ static void init (struct ebt_entry_match *match)
*/
vlaninfo->id = 0;
vlaninfo->prio = 0;
+ vlaninfo->encap = 0;
vlaninfo->invflags = 0;
vlaninfo->bitmask = 0;
}
+/*
+ * option flags definition
+ */
#define OPT_VLAN_ID 0x01
#define OPT_VLAN_PRIO 0x02
+#define OPT_VLAN_ENCAP 0x04
+
static int
parse (int c, char **argv, int argc,
const struct ebt_u_entry *entry, unsigned int *flags,
@@ -66,20 +77,24 @@ parse (int c, char **argv, int argc,
{
struct ebt_vlan_info *vlaninfo =
(struct ebt_vlan_info *) (*match)->data;
- unsigned short i;
+ unsigned long i;
char *end;
switch (c) {
case VLAN_ID:
+ /*
+ * ebtables.c:check_option(unsigned int *flags, unsigned int mask)
+ * checking for multiple usage of same option
+ */
check_option (flags, OPT_VLAN_ID);
/*
- * Check If we got inversed arg for VID,
+ * Check If we got inversed arg for vlan-id option,
* otherwise unset inversion flag
*/
if (check_inverse (optarg))
vlaninfo->invflags |= EBT_VLAN_ID;
/*
- * Check arg value presense
+ * Check arg value presence
*/
if (optind > argc)
print_error ("Missing VLAN ID argument\n");
@@ -90,15 +105,21 @@ parse (int c, char **argv, int argc,
*/
(unsigned short) i = strtol (argv[optind - 1], &end, 10);
/*
- * Check arg val range
+ * Check arg val range
*/
- if (i < 1 || i >= 4096 || *end != '\0') {
+ if (i < 1 || i >= 4094 || *end != '\0') {
i = 0;
print_error
("Problem with specified VLAN ID range\n");
}
+ /*
+ * Set up parameter value
+ */
vlaninfo->id = i;
- vlaninfo->bitmask|=EBT_VLAN_ID;
+ /*
+ * Set up parameter presence flag
+ */
+ vlaninfo->bitmask |= EBT_VLAN_ID;
break;
case VLAN_PRIO:
@@ -113,7 +134,7 @@ parse (int c, char **argv, int argc,
* set *end to end of argv string,
* base set 10 for decimal only
*/
- (unsigned short) i = strtol (argv[optind - 1], &end, 10);
+ (unsigned char) i = strtol (argv[optind - 1], &end, 10);
/*
* Check arg val range
*/
@@ -122,10 +143,45 @@ parse (int c, char **argv, int argc,
print_error
("Problem with specified VLAN Priority range\n");
}
+ /*
+ * Set up parameter value
+ */
vlaninfo->prio = i;
- vlaninfo->bitmask|=EBT_VLAN_PRIO;
+ /*
+ * Set up parameter presence flag
+ */
+ vlaninfo->bitmask |= EBT_VLAN_PRIO;
break;
+ case VLAN_ENCAP:
+ check_option (flags, OPT_VLAN_ENCAP);
+ if (check_inverse (optarg))
+ vlaninfo->invflags |= EBT_VLAN_ENCAP;
+ if (optind > argc)
+ print_error
+ ("Missing VLAN Encapsulated Protocol argument\n");
+ /*
+ * Parameter can be decimal, hexadecimal, or string.
+ * Check arg val range
+ */
+ (unsigned short) i = strtol (argv[optind - 1], &end, 16);
+ if (*end == '\0' && (i < 0 || i > 0xFFFF))
+ print_error
+ ("Problem with the specified encapsulated protocol");
+ if (*end != '\0')
+ if (name_to_protocol (argv[optind - 1]) == -1)
+ print_error
+ ("Problem with the specified encapsulated"
+ "protocol");
+ /*
+ * Set up parameter value (network notation)
+ */
+ vlaninfo->encap = htons (i);
+ /*
+ * Set up parameter presence flag
+ */
+ vlaninfo->bitmask |= EBT_VLAN_ENCAP;
+ break;
default:
return 0;
}
@@ -174,6 +230,14 @@ print (const struct ebt_u_entry *entry,
vlaninfo->invflags & EBT_VLAN_PRIO ? "!" : "",
vlaninfo->prio);
}
+ /*
+ * Print VLAN encapsulated protocol if they are specified
+ */
+ if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
+ printf ("vlan encap: %s%2.4X, ",
+ vlaninfo->invflags & EBT_VLAN_ENCAP ? "!" : "",
+ ntohs (vlaninfo->encap));
+ }
}
@@ -209,6 +273,13 @@ compare (const struct ebt_entry_match *vlan1,
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;
+ };
return 1;
}