Improved VLAN support, from Peter Jeremy - "vlan" filtering keyword,
letting you filter based on the VLAN to which a packet belongs, and an
improvement to the printing of VLAN packets (adding an extra space to
separate the VLAN priority and flags from the next stuff printed).
diff --git a/CREDITS b/CREDITS
index 4222d8a..a56b76d 100644
--- a/CREDITS
+++ b/CREDITS
@@ -20,6 +20,7 @@
 	Love Hörnquist-Åstrand		<lha@stacken.kth.se>
 	Rafal Maszkowski		<rzm@icm.edu.pl>
 	Rick Jones			<raj@cup.hp.com>
+	Peter Jeremy			<peter.jeremy@alcatel.com.au>
 
 The original LBL crew:
 	Steve McCanne
diff --git a/ethertype.h b/ethertype.h
index f5cb767..3af6f86 100644
--- a/ethertype.h
+++ b/ethertype.h
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.10 2000-09-23 07:26:27 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.11 2000-10-22 04:15:55 guy Exp $ (LBL)
  */
 
 /*
@@ -96,6 +96,9 @@
 #ifndef ETHERTYPE_IPV6
 #define ETHERTYPE_IPV6		0x86dd
 #endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q		0x8100
+#endif
 #ifndef	ETHERTYPE_LOOPBACK
 #define	ETHERTYPE_LOOPBACK	0x9000
 #endif
diff --git a/gencode.c b/gencode.c
index ea55dd1..af2218d 100644
--- a/gencode.c
+++ b/gencode.c
@@ -21,7 +21,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.122 2000-10-12 03:53:57 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.123 2000-10-22 04:15:55 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -2926,3 +2926,50 @@
 			  dir);
 	return (b0);
 }
+
+/*
+ * support IEEE 802.1Q VLAN trunk over ethernet
+ */
+struct block *
+gen_vlan(vlan_num)
+	int vlan_num;
+{
+	static u_int	orig_linktype = -1, orig_nl = -1;
+	struct	block	*b0;
+
+	/*
+	 * Change the offsets to point to the type and data fields within
+	 * the VLAN packet.  This is somewhat of a kludge.
+	 */
+	if (orig_nl == (u_int)-1) {
+		orig_linktype = off_linktype;	/* save original values */
+		orig_nl = off_nl;
+
+		switch (linktype) {
+
+		case DLT_EN10MB:
+			off_linktype = 16;
+			off_nl = 18;
+			break;
+
+		default:
+			bpf_error("no VLAN support for data link type %d",
+				  linktype);
+			/*NOTREACHED*/
+		}
+	}
+
+	/* check for VLAN */
+	b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_8021Q);
+
+	/* If a specific VLAN is requested, check VLAN id */
+	if (vlan_num >= 0) {
+		struct block *b1;
+
+		b1 = gen_cmp(orig_nl, BPF_H, (bpf_int32)vlan_num);
+		gen_and(b0, b1);
+		b0 = b1;
+	}
+
+	return (b0);
+}
diff --git a/gencode.h b/gencode.h
index 51c0e66..8feffb0 100644
--- a/gencode.h
+++ b/gencode.h
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.41 2000-07-13 06:51:56 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.42 2000-10-22 04:15:56 guy Exp $ (LBL)
  */
 
 /* Address qualifiers. */
@@ -173,6 +173,8 @@
 struct block *gen_multicast(int);
 struct block *gen_inbound(int);
 
+struct block *gen_vlan(int);
+
 void bpf_optimize(struct block **);
 void bpf_error(const char *, ...)
 #if HAVE___ATTRIBUTE__
diff --git a/grammar.y b/grammar.y
index fc8d6e5..9932f42 100644
--- a/grammar.y
+++ b/grammar.y
@@ -22,7 +22,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.60 2000-09-23 07:26:28 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.61 2000-10-22 04:15:56 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -116,6 +116,7 @@
 %token	LSH RSH
 %token  LEN
 %token  IPV6 ICMPV6 AH ESP
+%token	VLAN
 
 %type	<s> ID
 %type	<e> EID
@@ -162,14 +163,7 @@
 	| HID			{
 				  /* Decide how to parse HID based on proto */
 				  $$.q = $<blk>0.q;
-				  switch ($$.q.proto) {
-				  case Q_DECNET:
-					$$.b = gen_ncode($1, 0, $$.q);
-					break;
-				  default:
-					$$.b = gen_ncode($1, 0, $$.q);
-					break;
-				  }
+				  $$.b = gen_ncode($1, 0, $$.q);
 				}
 	| HID6 '/' NUM		{
 #ifdef INET6
@@ -271,6 +265,8 @@
 	| BYTE NUM byteop NUM	{ $$ = gen_byteop($3, $2, $4); }
 	| INBOUND		{ $$ = gen_inbound(0); }
 	| OUTBOUND		{ $$ = gen_inbound(1); }
+	| VLAN pnum		{ $$ = gen_vlan($2); }
+	| VLAN			{ $$ = gen_vlan(-1); }
 	;
 relop:	  '>'			{ $$ = BPF_JGT; }
 	| GEQ			{ $$ = BPF_JGE; }
diff --git a/scanner.l b/scanner.l
index ff95f42..03ea14e 100644
--- a/scanner.l
+++ b/scanner.l
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.66 2000-07-25 05:50:08 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.67 2000-10-22 04:15:56 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -218,6 +218,8 @@
 inbound		return INBOUND;
 outbound	return OUTBOUND;
 
+vlan		return VLAN;
+
 [ \n\t]			;
 [+\-*/:\[\]!<>()&|=]	return yytext[0];
 ">="			return GEQ;