Date: Wed, 16 Jun 1999 18:53:02 -0700 (PDT) From: brooks@one-eyed-alien.net To: freebsd-hackers@freebsd.org Subject: changes to ether_output() Message-ID: <Pine.GSO.4.05.9906161832510.2401-100000@orion.ac.hmc.edu>
next in thread | raw e-mail | index | archive | help
Hi, I've been doing some work which caused me to want to write a simple userland bridging/filtering program (don't ask ;-). The easy way to do it seemed to be to use BPF to read and write the packets one each side. I wrote something up in a few hundred lines of code which worked (mostly) as long as no one did much broadcast and I threw away multicast packets. After some searching I found a refrence in libnet (ports/net/libnet) which said the problem was that while BPF takes a whole packet and claims to write it to the wire, it actually ignores the source address and uses the one assigned to the card. They had an LKM which fixed the problem, but it was based on a mid-1997 version of net/if_ethersubr.c from 2.2.x and had a number of things commented out that probably shouldn't have been. I've taken the key lines from the LKM and produced a patch which adds optional support for for spoofing the source address of certain ethernet packets. It's a compile time option and is controled by a sysctl which defaults to off and doesn't work in secure mode. The patch is included below. The diff is against 3.2-STABLE as of a couple weeks ago and it looks like part of it may have to be applyed by hand on -current. Please let me know what you think. -- Brooks P.S. If someone is willing to commit this, I'll also create the appropriate LINT entry to go with it. *** net/if_ethersubr.c.orig Tue Jun 15 18:46:10 1999 --- net/if_ethersubr.c Wed Jun 16 18:21:42 1999 *************** *** 38,43 **** --- 38,44 ---- #include "opt_inet.h" #include "opt_ipx.h" #include "opt_bdg.h" + #include "opt_ether.h" #include <sys/param.h> #include <sys/systm.h> *************** *** 111,116 **** --- 112,125 ---- #include <net/if_vlan_var.h> #endif /* NVLAN > 0 */ + SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); + + #ifdef ETHER_SPOOF_SRC + static int spoof_src = 0; + SYSCTL_INT(_net_link_ether, OID_AUTO, spoof_src, CTLFLAG_RW|CTLFLAG_SECURE, + &spoof_src, 0, "Allow Ethernet source addresses to be spoofed"); + #endif + static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **, struct sockaddr *)); u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; *************** *** 133,138 **** --- 142,150 ---- short type; int s, error = 0; u_char edst[6]; + #ifdef ETHER_SPOOF_SRC + u_char esrc[6]; + #endif register struct mbuf *m = m0; register struct rtentry *rt; register struct ether_header *eh; *************** *** 167,172 **** --- 179,187 ---- time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } + #ifdef ETHER_SPOOF_SRC + (void)memcpy(esrc, ac->ac_enaddr, sizeof (esrc)); + #endif hlen = ETHER_HDR_LEN; switch (dst->sa_family) { #ifdef INET *************** *** 333,338 **** --- 348,357 ---- loop_copy = -1; /* if this is for us, don't do it */ eh = (struct ether_header *)dst->sa_data; (void)memcpy(edst, eh->ether_dhost, sizeof (edst)); + #ifdef ETHER_SPOOF_SRC + if (spoof_src != 0) + (void)memcpy(esrc, eh->ether_shost, sizeof (esrc)); + #endif type = eh->ether_type; break; *************** *** 353,360 **** --- 372,383 ---- (void)memcpy(&eh->ether_type, &type, sizeof(eh->ether_type)); (void)memcpy(eh->ether_dhost, edst, sizeof (edst)); + #ifdef ETHER_SPOOF_SRC + (void)memcpy(eh->ether_shost, esrc, sizeof (esrc)); + #else (void)memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost)); + #endif /* * If a simplex interface, and the packet is being sent to our *************** *** 679,686 **** sdl->sdl_alen = ifp->if_addrlen; bcopy(((struct arpcom *)ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen); } - - SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); int ether_ioctl(ifp, command, data) --- 702,707 ---- *** conf/options.orig Fri May 21 15:45:39 1999 --- conf/options Wed Jun 16 18:19:51 1999 *************** *** 221,226 **** --- 221,227 ---- IPFILTER opt_ipfilter.h IPFILTER_LOG opt_ipfilter.h IPFILTER_LKM opt_ipfilter.h + ETHER_SPOOF_SRC opt_ether.h # ATM (HARP version) ATM_CORE opt_atm.h To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.05.9906161832510.2401-100000>