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>
