Minor logic changes, comments, minor fixes
authorfnm3 <fnm3>
Tue, 25 Jun 2002 16:37:52 +0000 (16:37 +0000)
committerfnm3 <fnm3>
Tue, 25 Jun 2002 16:37:52 +0000 (16:37 +0000)
extensions/ebt_vlan.c

index f74b26f..5c8504d 100644 (file)
@@ -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
  *
  */
 
 #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));
+               }
        }
 }