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:
parent
14bacef14e
commit
114ae644b5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52248
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -355,7 +355,7 @@ struct vfsops {
|
||||
|
||||
#include <net/radix.h>
|
||||
|
||||
#define AF_MAX 31 /* XXX */
|
||||
#define AF_MAX 32 /* XXX */
|
||||
|
||||
/*
|
||||
* Network address lookup element
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user