Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Oct 1999 02:10:02 -0700 (PDT)
From:      "Christopher N . Harrell" <cnh@mindspring.net>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/10860: bpf overwrites source ethernet addresses when writing to a bpf descriptor
Message-ID:  <199910050910.CAA69472@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/10860; it has been noted by GNATS.

From: "Christopher N . Harrell" <cnh@mindspring.net>
To: freebsd-gnats-submit@freebsd.org
Cc: imp@village.org, dima@rdy.com, security-officer@freebsd.org,
	pst@juniper.net, cmsedore@maxwell.syr.edu
Subject: Re: kern/10860: bpf overwrites source ethernet addresses when writing to a bpf descriptor
Date: Tue, 5 Oct 1999 05:04:55 -0400

 I just ported the netbsd solution and added a manpage update.  This solution
 works, and is already a bsd-ish standard.
 
 cheers,
 Christopher
 
 
 *** /usr/src/sys/net/bpf.c	Sat Sep 25 14:24:29 1999
 --- /usr/modsrc/net/bpf.c	Tue Oct  5 03:06:24 1999
 ***************
 *** 579,584 ****
 --- 579,587 ----
   	if (datlen > ifp->if_mtu)
   		return (EMSGSIZE);
   
 + 	if (d->bd_hdrcmplt)
 + 		dst.sa_family = pseudo_AF_HDRCMPLT;
 + 
   	s = splnet();
   #if BSD >= 199103
   	error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
 ***************
 *** 626,631 ****
 --- 629,636 ----
    *  BIOCGSTATS		Get packet stats.
    *  BIOCIMMEDIATE	Set immediate mode.
    *  BIOCVERSION		Get filter language version.
 +  *  BIOCGHDRCMPLT	Get "header already complete" flag
 +  *  BIOCSHDRCMPLT	Set "header already complete" flag
    */
   /* ARGSUSED */
   static	int
 ***************
 *** 821,826 ****
 --- 826,845 ----
   			bv->bv_minor = BPF_MINOR_VERSION;
   			break;
   		}
 + 
 + 	/*
 + 	 * Get "header already complete" flag
 + 	 */
 + 	case BIOCGHDRCMPLT:
 + 		*(u_int *)addr = d->bd_hdrcmplt;
 + 		break;
 + 
 + 	/*
 + 	 * Set "header already complete" flag
 + 	 */
 + 	case BIOCSHDRCMPLT:
 + 		d->bd_hdrcmplt = *(u_int *)addr ? 1 : 0;
 + 		break;
   
   	case FIONBIO:		/* Non-blocking I/O */
   		break;
 *** /usr/src/sys/net/bpf.h	Fri Aug 27 20:48:13 1999
 --- /usr/modsrc/net/bpf.h	Tue Oct  5 03:44:32 1999
 ***************
 *** 111,116 ****
 --- 111,118 ----
   #define BIOCVERSION	_IOR('B',113, struct bpf_version)
   #define BIOCGRSIG	_IOR('B',114, u_int)
   #define BIOCSRSIG	_IOW('B',115, u_int)
 + #define BIOCGHDRCMPLT	_IOR('B',116, u_int)
 + #define BIOCSHDRCMPLT	_IOW('B',117, u_int)
   
   /*
    * Structure prepended to each packet.
 *** /usr/src/sys/net/bpfdesc.h	Fri Aug 27 20:48:14 1999
 --- /usr/modsrc/net/bpfdesc.h	Tue Oct  5 03:02:44 1999
 ***************
 *** 76,81 ****
 --- 76,82 ----
   	u_char		bd_promisc;	/* true if listening promiscuously */
   	u_char		bd_state;	/* idle, waiting, or timed out */
   	u_char		bd_immediate;	/* true to return on packet arrival */
 + 	int		bd_hdrcmplt;	/* false to fill in src lladdr automatically */
   	int		bd_async;	/* non-zero if packet reception should generate signal */
   	int		bd_sig;		/* signal to send upon packet reception */
   	struct sigio *	bd_sigio;	/* information for async I/O */
 *** /usr/src/sys/net/if_ethersubr.c	Fri Aug 27 20:48:17 1999
 --- /usr/modsrc/net/if_ethersubr.c	Tue Oct  5 02:53:04 1999
 ***************
 *** 132,139 ****
   	struct rtentry *rt0;
   {
   	short type;
 ! 	int s, error = 0;
 !  	u_char edst[6];
   	register struct mbuf *m = m0;
   	register struct rtentry *rt;
   	register struct ether_header *eh;
 --- 132,139 ----
   	struct rtentry *rt0;
   {
   	short type;
 ! 	int s, error = 0, hdrcmplt = 0;
 !  	u_char esrc[6], edst[6];
   	register struct mbuf *m = m0;
   	register struct rtentry *rt;
   	register struct ether_header *eh;
 ***************
 *** 326,331 ****
 --- 326,337 ----
   		} break;
   #endif /* LLC */
   
 + 	case pseudo_AF_HDRCMPLT:
 + 		hdrcmplt = 1;
 + 		eh = (struct ether_header *)dst->sa_data;
 + 		(void)memcpy(esrc, eh->ether_shost, sizeof (esrc));
 + 		/* FALLTHROUGH */
 + 
   	case AF_UNSPEC:
   		loop_copy = -1; /* if this is for us, don't do it */
   		eh = (struct ether_header *)dst->sa_data;
 ***************
 *** 333,338 ****
 --- 339,345 ----
   		type = eh->ether_type;
   		break;
   
 + 
   	default:
   		printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
   			dst->sa_family);
 ***************
 *** 350,357 ****
   	(void)memcpy(&eh->ether_type, &type,
   		sizeof(eh->ether_type));
    	(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
 !  	(void)memcpy(eh->ether_shost, ac->ac_enaddr,
 ! 	    sizeof(eh->ether_shost));
   
   	/*
   	 * If a simplex interface, and the packet is being sent to our
 --- 357,368 ----
   	(void)memcpy(&eh->ether_type, &type,
   		sizeof(eh->ether_type));
    	(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
 ! 	if (hdrcmplt)
 ! 		(void)memcpy(eh->ether_shost, esrc,
 ! 			sizeof(eh->ether_shost));
 ! 	else
 ! 		(void)memcpy(eh->ether_shost, ac->ac_enaddr,
 ! 			sizeof(eh->ether_shost));
   
   	/*
   	 * If a simplex interface, and the packet is being sent to our
 *** /usr/src/sys/net/if_fddisubr.c	Sat Sep 25 08:05:56 1999
 --- /usr/modsrc/net/if_fddisubr.c	Tue Oct  5 03:22:39 1999
 ***************
 *** 136,143 ****
   	struct rtentry *rt0;
   {
   	u_int16_t type;
 ! 	int s, loop_copy = 0, error = 0;
 !  	u_char edst[6];
   	register struct mbuf *m = m0;
   	register struct rtentry *rt;
   	register struct fddi_header *fh;
 --- 136,143 ----
   	struct rtentry *rt0;
   {
   	u_int16_t type;
 ! 	int s, loop_copy = 0, error = 0, hdrcmplt = 0;
 !  	u_char esrc[6], edst[6];
   	register struct mbuf *m = m0;
   	register struct rtentry *rt;
   	register struct fddi_header *fh;
 ***************
 *** 295,300 ****
 --- 295,309 ----
   		} break;
   #endif /* LLC */	
   
 + 	case pseudo_AF_HDRCMPLT:
 + 	{
 + 		struct ether_header *eh;
 + 		hdrcmplt = 1;
 + 		eh = (struct ether_header *)dst->sa_data;
 +  		(void)memcpy((caddr_t)esrc, (caddr_t)eh->ether_shost, sizeof (esrc));
 + 		/* FALLTHROUGH */
 + 	}
 + 
   	case AF_UNSPEC:
   	{
   		struct ether_header *eh;
 ***************
 *** 370,378 ****
   	fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
    	(void)memcpy((caddr_t)fh->fddi_dhost, (caddr_t)edst, sizeof (edst));
     queue_it:
 !  	(void)memcpy((caddr_t)fh->fddi_shost, (caddr_t)ac->ac_enaddr,
 ! 	    sizeof(fh->fddi_shost));
 ! 
   	/*
   	 * If a simplex interface, and the packet is being sent to our
   	 * Ethernet address or a broadcast address, loopback a copy.
 --- 379,390 ----
   	fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
    	(void)memcpy((caddr_t)fh->fddi_dhost, (caddr_t)edst, sizeof (edst));
     queue_it:
 ! 	if (hdrcmplt)
 ! 		(void)memcpy((caddr_t)fh->fddi_shost, (caddr_t)esrc,
 ! 			sizeof(fh->fddi_shost));
 ! 	else
 ! 		(void)memcpy((caddr_t)fh->fddi_shost, (caddr_t)ac->ac_enaddr,
 ! 			sizeof(fh->fddi_shost));
   	/*
   	 * If a simplex interface, and the packet is being sent to our
   	 * Ethernet address or a broadcast address, loopback a copy.
 *** /usr/src/sys/sys/mount.h	Wed Sep 29 16:05:30 1999
 --- /usr/modsrc/sys/mount.h	Tue Oct  5 03:29:56 1999
 ***************
 *** 355,361 ****
   
   #include <net/radix.h>
   
 ! #define	AF_MAX		31	/* XXX */
   
   /*
    * Network address lookup element
 --- 355,361 ----
   
   #include <net/radix.h>
   
 ! #define	AF_MAX		32	/* XXX */
   
   /*
    * Network address lookup element
 *** /usr/src/sys/sys/socket.h	Fri Aug 27 20:52:01 1999
 --- /usr/modsrc/sys/socket.h	Tue Oct  5 03:15:55 1999
 ***************
 *** 128,135 ****
   #define	AF_INET6	28		/* IPv6 */
   #define	AF_NATM		29		/* native ATM access */
   #define	AF_ATM		30		/* ATM */
   
 ! #define	AF_MAX		31
   
   /*
    * Structure used by kernel to store most
 --- 128,138 ----
   #define	AF_INET6	28		/* IPv6 */
   #define	AF_NATM		29		/* native ATM access */
   #define	AF_ATM		30		/* ATM */
 + #define pseudo_AF_HDRCMPLT 31		/* Used by BPF to not rewrite headers
 + 					 * in interface output routine
 + 					 */
   
 ! #define	AF_MAX		32
   
   /*
    * Structure used by kernel to store most
 *** /usr/src/share/man/man4/bpf.4	Fri Aug 27 20:19:46 1999
 --- share/man/man4/bpf.4	Tue Oct  5 04:21:42 1999
 ***************
 *** 276,281 ****
 --- 276,289 ----
   may result in undefined behavior (most likely, an error returned by
   .Fn ioctl
   or haphazard packet matching).
 + .It Dv BIOCSHDRCMPLT
 + .It Dv BIOCGHDRCMPLT
 + .Pq Li u_int
 + Set or get the status of the ``header complete'' flag.
 + Set to zero if the link level source address should be filled in automatically
 + by the the interface output routine.  Set to one if the link level source
 + address will be written, as provided, to the wire.  This flag is initialized
 + to zero by default.
   .Sh BPF HEADER
   The following structure is prepended to each packet returned by
   .Xr read 2 :
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199910050910.CAA69472>