diff -P -C 2 --recursive dhcp.orig/common/bpf.c dhcp.vlan/common/bpf.c
*** dhcp.orig/common/bpf.c	Thu May 27 10:44:51 1999
--- dhcp.vlan/common/bpf.c	Wed Jan 19 14:44:39 2000
***************
*** 97,101 ****
  	char filename[50];
  	int b;
! 
  	/* Open a BPF device */
  	for (b = 0; 1; b++) {
--- 97,102 ----
  	char filename[50];
  	int b;
!         TRC_IN;
!         
  	/* Open a BPF device */
  	for (b = 0; 1; b++) {
***************
*** 160,163 ****
--- 161,165 ----
  
  struct bpf_insn dhcp_bpf_filter [] = {
+    
  	/* Make sure this is an IP packet... */
  	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
***************
*** 185,190 ****
  	BPF_STMT(BPF_RET+BPF_K, 0),
  };
- 
  int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
  
  struct bpf_insn dhcp_bpf_tr_filter [] = {
--- 187,229 ----
  	BPF_STMT(BPF_RET+BPF_K, 0),
  };
  int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
+ 
+ 
+ 
+ /** VLAN ethernet pkts have an extra 4 bytes in them, so going
+  * to shift the offsets by +4 --Ben
+  */
+ 
+ #define VLAN_BPF_OFFSET 4
+ 
+ struct bpf_insn dhcp_bpf_vlan_filter [] = {
+ 	/* Make sure this is an IP packet... */
+ 	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12 + VLAN_BPF_OFFSET),
+ 	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
+ 
+ 	/* Make sure it's a UDP packet... */
+ 	BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23 + VLAN_BPF_OFFSET),
+ 	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
+ 
+ 	/* Make sure this isn't a fragment... */
+ 	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20 + VLAN_BPF_OFFSET),
+ 	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
+ 
+ 	/* Get the IP header length... */
+ 	BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14 + VLAN_BPF_OFFSET),
+ 
+ 	/* Make sure it's to the right port... */
+ 	BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16 + VLAN_BPF_OFFSET),
+ 	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),             /* patch */
+ 
+ 	/* If we passed all the tests, ask for the whole packet. */
+ 	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+ 
+ 	/* Otherwise, drop it. */
+ 	BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+ int dhcp_bpf_vlan_filter_len = (sizeof dhcp_bpf_vlan_filter /
+                                 sizeof (struct bpf_insn));
+ 
  
  struct bpf_insn dhcp_bpf_tr_filter [] = {
diff -P -C 2 --recursive dhcp.orig/common/dispatch.c dhcp.vlan/common/dispatch.c
*** dhcp.orig/common/dispatch.c	Mon Mar 29 15:16:36 1999
--- dhcp.vlan/common/dispatch.c	Thu Jan 20 12:28:30 2000
***************
*** 84,87 ****
--- 84,88 ----
  #endif
  
+         TRC_IN;
  	/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
  	if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
***************
*** 162,165 ****
--- 163,194 ----
  			strcpy (tmp -> name, ifp -> ifr_name);
  			tmp -> next = interfaces;
+ 
+                         /* Now, check for vlan */
+                         if (strncmp(tmp->name, "vlan", 4) == 0) {
+                            FILE *vlan_proc;
+                            char vlan_buf[256];
+                            char junk1[256];
+                            char junk2[256];
+                            int vid;
+ 
+                            note("Found a VLAN device.");
+                            tmp->is_vlan = 1;
+                            /* get the vlan ID (how ugly!) --Ben */
+                            sprintf(vlan_buf, "/proc/net/vlan/%s", tmp->name);
+                            vlan_proc = fopen (vlan_buf, "r");
+                            if (!vlan_proc) {
+                               error ("Could not open file: %s:", vlan_buf);
+                               tmp->VID = 0;
+                            }
+                            else {
+                               fscanf(vlan_proc, "%s %s %i", junk1, junk2, &vid);
+                               tmp->VID = vid;
+                               fclose(vlan_proc);
+                            }
+                         }/* if a vlan device */
+                         else {
+                            note("Not a VLAN device.");
+                         }
+ 
  			tmp -> flags = ir;
  			interfaces = tmp;
***************
*** 275,280 ****
--- 304,314 ----
  	if (state == DISCOVER_UNCONFIGURED) {
  		FILE *proc_dev;
+                 FILE *vlan_proc;
+                 char vlan_buf[256];
  		char buffer [256];
  		int skip = 2;
+                 char junk1[256];
+                 char junk2[256];
+                 int vid;
  
  		proc_dev = fopen (PROCDEV_DEVICE, "r");
***************
*** 318,321 ****
--- 352,376 ----
  			strcpy (tmp -> name, name);
  
+                         /* Now, check for vlan */
+                         if (strncmp(tmp->name, "vlan", 4) == 0) {
+                            note("Found a VLAN device.");
+                            tmp->is_vlan = 1;
+                            /* get the vlan ID (how ugly!) --Ben */
+                            sprintf(vlan_buf, "/proc/net/vlan/%s", tmp->name);
+                            vlan_proc = fopen (vlan_buf, "r");
+                            if (!vlan_proc) {
+                               error ("Could not open file: %s", vlan_buf);
+                               tmp->VID = 0;
+                            }
+                            else {
+                               fscanf(vlan_proc, "%s %s %i", junk1, junk2, &vid);
+                               tmp->VID = vid;
+                               fclose(vlan_proc);
+                            }
+                         }/* if a vlan device */
+                         else {
+                            note("Not a VLAN device.");
+                         }
+ 
  			tmp -> flags = ir;
  			tmp -> next = interfaces;
***************
*** 699,702 ****
--- 754,761 ----
  	struct interface_info *ip = l -> local;
  
+ #ifdef DEBUG
+         /*note ("%s %s: %s", __FILE__, __LINE__, __FUNCTION__); */ /* BEN */
+         note ("in got_one.");
+ #endif        
  	if ((result =
  	     receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) < 0) {
diff -P -C 2 --recursive dhcp.orig/common/lpf.c dhcp.vlan/common/lpf.c
*** dhcp.orig/common/lpf.c	Thu May 27 10:44:52 1999
--- dhcp.vlan/common/lpf.c	Wed Jan 19 14:58:50 2000
***************
*** 62,65 ****
--- 62,66 ----
  static void lpf_gen_filter_setup PROTO ((struct interface_info *));
  static void lpf_tr_filter_setup PROTO ((struct interface_info *));
+ static void lpf_vlan_filter_setup PROTO ((struct interface_info *));
  
  /* Reinitializes the specified interface after an address change.   This
***************
*** 92,95 ****
--- 93,98 ----
  	struct sockaddr sa;
  
+         /* note(__PRETTY_FUNCTION__);  BEN */
+         
  	/* Make an LPF socket. */
  	if ((sock = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
***************
*** 129,133 ****
  	struct interface_info *info;
  {
! 	/* If we're using the lpf API for sending and receiving,
  	   we don't need to register this interface twice. */
  #ifndef USE_LPF_RECEIVE
--- 132,138 ----
  	struct interface_info *info;
  {
!    TRC_IN;
! 
!    /* If we're using the lpf API for sending and receiving,
  	   we don't need to register this interface twice. */
  #ifndef USE_LPF_RECEIVE
***************
*** 155,170 ****
  extern struct sock_filter dhcp_bpf_tr_filter [];
  extern int dhcp_bpf_tr_filter_len;
  
  void if_register_receive (info)
  	struct interface_info *info;
  {
  	/* Open a LPF device and hang it on this interface... */
  	info -> rfdesc = if_register_lpf (info);
  
! 	if (info -> hw_address.htype == HTYPE_IEEE802)
! 		lpf_tr_filter_setup (info);
! 	else
! 		lpf_gen_filter_setup (info);
! 
  	if (!quiet_interface_discovery)
  		note ("Listening on LPF/%s/%s%s%s",
--- 160,184 ----
  extern struct sock_filter dhcp_bpf_tr_filter [];
  extern int dhcp_bpf_tr_filter_len;
+ extern struct sock_filter dhcp_bpf_vlan_filter [];
+ extern int dhcp_bpf_vlan_filter_len;
  
  void if_register_receive (info)
  	struct interface_info *info;
  {
+         TRC_IN;
  	/* Open a LPF device and hang it on this interface... */
  	info -> rfdesc = if_register_lpf (info);
  
!         /* check for VLAN interfaces */
!         if (info->is_vlan) {
!            lpf_vlan_filter_setup(info);
!         }
!         else {
!            if (info -> hw_address.htype == HTYPE_IEEE802)
!               lpf_tr_filter_setup (info);
!            else
!               lpf_gen_filter_setup (info);
!         }
!         
  	if (!quiet_interface_discovery)
  		note ("Listening on LPF/%s/%s%s%s",
***************
*** 182,185 ****
--- 196,200 ----
  {
  	struct sock_fprog p;
+         TRC_IN;
  
  	/* Set up the bpf filter program structure.    This is defined in
***************
*** 187,190 ****
--- 202,235 ----
  	p.len = dhcp_bpf_filter_len;
  	p.filter = dhcp_bpf_filter;
+ 
+         /* Patch the server port into the LPF  program...
+ 	   XXX changes to filter program may require changes
+ 	   to the insn number(s) used below! XXX */
+ 	dhcp_bpf_filter [8].k = ntohs (local_port);
+ 
+ 	if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
+ 			sizeof p) < 0) {
+ 		if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+ 		    errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+ 		    errno == EAFNOSUPPORT)
+ 			error ("socket: %m - make sure %s %s!",
+ 			       "CONFIG_PACKET and CONFIG_FILTER are defined",
+ 			       "in your kernel configuration");
+ 		error ("Can't install packet filter program: %m");
+ 	}
+ }
+ 
+ /* for 802.1Q vlan devices */
+ static void lpf_vlan_filter_setup (info)
+ 	struct interface_info *info;
+ {
+ 	struct sock_fprog p;
+         TRC_IN;
+         
+ 
+ 	/* Set up the bpf filter program structure.    This is defined in
+ 	   bpf.c */
+ 	p.len = dhcp_bpf_vlan_filter_len;
+ 	p.filter = dhcp_bpf_vlan_filter;
  
          /* Patch the server port into the LPF  program...
diff -P -C 2 --recursive dhcp.orig/common/options.c dhcp.vlan/common/options.c
*** dhcp.orig/common/options.c	Thu May  6 14:54:34 1999
--- dhcp.vlan/common/options.c	Wed Jan 19 11:11:43 2000
***************
*** 617,620 ****
--- 617,624 ----
  	int i;
  
+ #ifdef DEBUG
+         note ("in do_packet");
+ #endif        
+        
  	if (packet -> hlen > sizeof packet -> chaddr) {
  		note ("Discarding packet with invalid hlen.");
diff -P -C 2 --recursive dhcp.orig/common/packet.c dhcp.vlan/common/packet.c
*** dhcp.orig/common/packet.c	Wed Jun  9 17:58:16 1999
--- dhcp.vlan/common/packet.c	Wed Jan 19 15:14:15 2000
***************
*** 127,131 ****
  	else
  #endif
! 		assemble_ethernet_header (interface, buf, bufix, to);
  
  }
--- 127,139 ----
  	else
  #endif
! 	{
!            if (interface->is_vlan) {
!               assemble_vlan_ethernet_header (interface, buf, bufix, to);
!            }
!            else {
!               assemble_ethernet_header (interface, buf, bufix, to);
!            }
!         }
!            
  
  }
***************
*** 206,210 ****
--- 214,225 ----
  	else
  #endif
+            {
+               if (interface->is_vlan) {
+ 		return decode_vlan_ethernet_header (interface, buf, bufix, from);
+               }
+               else {
  		return decode_ethernet_header (interface, buf, bufix, from);
+               }
+            }
  }
  
***************
*** 231,234 ****
--- 246,251 ----
    int len;
  
+   note("decode_upd_ip_header:  buffix: %i", bufix);
+   
    ip = (struct ip *)(buf + bufix);
    udp = (struct udphdr *)(buf + bufix + ip_len);
diff -P -C 2 --recursive dhcp.orig/common/vlan_ethernet.c dhcp.vlan/common/vlan_ethernet.c
*** dhcp.orig/common/vlan_ethernet.c	Wed Dec 31 17:00:00 1969
--- dhcp.vlan/common/vlan_ethernet.c	Wed Jan 19 14:53:50 2000
***************
*** 0 ****
--- 1,118 ----
+ /* packet.c
+ 
+    Packet assembly code, originally contributed by Archie Cobbs. */
+ 
+ /*
+  * Copyright (c) 1995, 1996 The Internet Software Consortium.
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  *
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. Neither the name of The Internet Software Consortium nor the names
+  *    of its contributors may be used to endorse or promote products derived
+  *    from this software without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  *
+  * This software has been written for the Internet Software Consortium
+  * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+  * Enterprises.  To learn more about the Internet Software Consortium,
+  * see ``http://www.vix.com/isc''.  To learn more about Vixie
+  * Enterprises, see ``http://www.vix.com''.
+  */
+ 
+ #ifndef lint
+ static char copyright[] =
+ "$Id: dhcpd_vlan.patch,v 1.1 2000/02/07 04:50:35 greear Exp $ Copyright (c) 1996 The Internet Software Consortium.  All rights reserved.\n";
+ #endif /* not lint */
+ 
+ #include "dhcpd.h"
+ 
+ #if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
+ #include "includes/netinet/if_ether.h"
+ #endif /* PACKET_ASSEMBLY || PACKET_DECODING */
+ 
+ #if defined (PACKET_ASSEMBLY)
+ 
+ struct my_vlan_ethhdr 
+ {
+    unsigned char	h_dest[6];	/* destination eth addr	*/
+    unsigned char	h_source[6];	/* source ether addr	*/
+    unsigned short       h_vlan_proto;           /* Should always be 0x8100 */
+    unsigned short       h_vlan_TCI;             /* Encapsulates priority and VLAN ID */
+    unsigned short	h_vlan_encapsulated_proto; /* packet type ID field (or len) */
+ };
+ 
+ /* Assemble an hardware header... */
+ /* XXX currently only supports ethernet; doesn't check for other types. */
+ 
+ void assemble_vlan_ethernet_header (interface, buf, bufix, to)
+ 	struct interface_info *interface;
+ 	unsigned char *buf;
+ 	int *bufix;
+ 	struct hardware *to;
+ {
+ 	struct my_vlan_ethhdr eh;
+ 
+ 	if (to && to -> hlen == 6) /* XXX */
+ 		memcpy (eh.h_dest, to -> haddr, 6);
+ 	else
+ 		memset (eh.h_dest, 0xff, 6);
+ 	if (interface -> hw_address.hlen == sizeof (eh.h_source))
+            memcpy (eh.h_source, interface -> hw_address.haddr, 6);
+ 	else
+            memset (eh.h_source, 0x00, 6);
+ 
+         eh.h_vlan_proto = htons(0x8100); /* VLAN */
+         eh.h_vlan_TCI = htons(interface->VID); /* obtained this from the proc fs */
+         
+ 	eh.h_vlan_encapsulated_proto = htons (ETHERTYPE_IP);
+ 
+ 	memcpy (&buf [*bufix], &eh, sizeof eh);
+ 	*bufix += sizeof eh;
+ }
+ #endif /* PACKET_ASSEMBLY */
+ 
+ #ifdef PACKET_DECODING
+ /* Decode a hardware header... */
+ 
+ ssize_t decode_vlan_ethernet_header (interface, buf, bufix, from)
+      struct interface_info *interface;
+      unsigned char *buf;
+      int bufix;
+      struct hardware *from;
+ {
+   struct my_vlan_ethhdr eh;
+ 
+   memcpy (&eh, buf + bufix, sizeof eh);
+ 
+ #ifdef USERLAND_FILTER
+   if (ntohs (eh.h_vlan_encapsulate_proto) != ETHERTYPE_IP)
+ 	  return -1;
+ #endif
+   memcpy (from -> haddr, eh.h_source, 6);
+   from -> htype = ARPHRD_ETHER;
+   from -> hlen = 6;
+ 
+   return sizeof eh;
+ }
+ #endif /* PACKET_DECODING */
diff -P -C 2 --recursive dhcp.orig/includes/dhcpd.h dhcp.vlan/includes/dhcpd.h
*** dhcp.orig/includes/dhcpd.h	Thu May 27 10:44:52 1999
--- dhcp.vlan/includes/dhcpd.h	Wed Jan 19 13:58:01 2000
***************
*** 378,381 ****
--- 378,386 ----
  	struct ifreq *ifp;		/* Pointer to ifreq struct. */
  	u_int32_t flags;		/* Control flags... */
+ 
+         /* used by VLAN code --Ben */
+         unsigned short VID;
+         int is_vlan;  /* 1 if it is, zero if it's a regular ethernet device */
+ 
  #define INTERFACE_REQUESTED 1
  #define INTERFACE_AUTOMATIC 2
diff -P -C 2 --recursive dhcp.orig/includes/site.h dhcp.vlan/includes/site.h
*** dhcp.orig/includes/site.h	Thu Aug 29 02:18:44 1996
--- dhcp.vlan/includes/site.h	Thu Jan 20 13:50:37 2000
***************
*** 17,20 ****
--- 17,33 ----
  /* #define DEBUG */
  
+ /* Define these if you want to trace program flow through a few methods.
+  */
+ 
+ /*
+ #define TRC_IN printf("ENTER: %s %s: %s\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+ #define TRC_OUT printf("LEAVE: %s %s: %s\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+ */
+ 
+ #define TRC_IN note(__PRETTY_FUNCTION__);
+ /* #define TRC_IN /* do nothing */
+ #define TRC_OUT /* do nothing */
+ 
+ 
  /* Define this to see what the parser is parsing.   You probably don't
     want to see this. */
***************
*** 37,41 ****
     /etc or /var/run. */
  
! /* #define _PATH_DHCPD_PID	"/var/run/dhcpd.pid" */
  
  /* Define this if you want the dhcpd.leases file (the dynamic lease database)
--- 50,54 ----
     /etc or /var/run. */
  
! #define _PATH_DHCPD_PID	"/var/run/dhcpd.pid"
  
  /* Define this if you want the dhcpd.leases file (the dynamic lease database)
