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 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)