Implement pseudo_AF_HDRCMPLT, which controls the state of the 'header

completion' flag.  If set, the interface output routine will assume that
the packet already has a valid link-level source address.  This defaults
to off (the address is overwritten)

PR:		kern/10680
Submitted by:	"Christopher N . Harrell" <cnh@mindspring.net>
Obtained from:	NetBSD
This commit is contained in:
Mike Smith 1999-10-15 05:07:00 +00:00
parent 14bacef14e
commit 114ae644b5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52248
7 changed files with 58 additions and 11 deletions

View File

@ -579,6 +579,9 @@ bpfwrite(dev, uio, ioflag)
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,6 +629,8 @@ reset_d(d)
* 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
@ -822,6 +827,20 @@ bpfioctl(dev, cmd, addr, flags, p)
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;

View File

@ -111,6 +111,8 @@ struct bpf_version {
#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.

View File

@ -76,6 +76,7 @@ struct bpf_d {
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 */

View File

@ -132,8 +132,8 @@ ether_output(ifp, m0, dst, rt0)
struct rtentry *rt0;
{
short type;
int s, error = 0;
u_char edst[6];
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,6 +326,12 @@ ether_output(ifp, m0, dst, rt0)
} 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;
@ -350,8 +356,12 @@ ether_output(ifp, m0, dst, rt0)
(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 (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

View File

@ -136,8 +136,8 @@ fddi_output(ifp, m0, dst, rt0)
struct rtentry *rt0;
{
u_int16_t type;
int s, loop_copy = 0, error = 0;
u_char edst[6];
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,6 +295,15 @@ fddi_output(ifp, m0, dst, rt0)
} 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,9 +379,12 @@ fddi_output(ifp, m0, dst, rt0)
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 (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.

View File

@ -355,7 +355,7 @@ struct vfsops {
#include <net/radix.h>
#define AF_MAX 31 /* XXX */
#define AF_MAX 32 /* XXX */
/*
* Network address lookup element

View File

@ -128,8 +128,11 @@ struct linger {
#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 31
#define AF_MAX 32
/*
* Structure used by kernel to store most