Update to 4.4-Lite networking code, with a few local changes.

This commit is contained in:
mycroft 1994-05-13 06:01:27 +00:00
parent 9d020030ac
commit d361acde18
17 changed files with 1229 additions and 680 deletions

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
* $Id: sys_socket.c,v 1.9 1994/05/11 10:27:22 mycroft Exp $
* $Id: sys_socket.c,v 1.10 1994/05/13 06:01:27 mycroft Exp $
*/
#include <sys/param.h>
@ -43,7 +43,6 @@
#include <sys/socketvar.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <net/if.h>
#include <net/route.h>

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,32 +30,31 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)uipc_domain.c 7.9 (Berkeley) 3/4/91
* $Id: uipc_domain.c,v 1.10 1994/05/07 00:46:28 cgd Exp $
* from: @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
* $Id: uipc_domain.c,v 1.11 1994/05/13 06:01:30 mycroft Exp $
*/
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/domain.h>
#include <sys/mbuf.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <vm/vm.h>
#include <sys/sysctl.h>
void pffasttimo __P((void *));
void pfslowtimo __P((void *));
#define ADDDOMAIN(x) { \
extern struct domain __CONCAT(x,domain); \
__CONCAT(x,domain.dom_next) = domains; \
domains = &__CONCAT(x,domain); \
}
void pffasttimo __P((void *));
void pfslowtimo __P((void *));
void
domaininit()
{
@ -75,15 +74,15 @@ domaininit()
#ifdef ISO
ADDDOMAIN(iso);
#endif
#ifdef RMP
ADDDOMAIN(rmp);
#endif
#ifdef CCITT
ADDDOMAIN(ccitt);
#endif
#ifdef IMP
#ifdef notdef /* XXXX */
#include "imp.h"
#if NIMP > 0
ADDDOMAIN(imp);
#endif
#endif
#endif
for (dp = domains; dp; dp = dp->dom_next) {
@ -146,6 +145,7 @@ found:
return (maybe);
}
int
net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
int *name;
u_int namelen;
@ -166,6 +166,20 @@ net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
*/
if (namelen < 3)
return (EISDIR); /* overloaded */
family = name[0];
protocol = name[1];
if (family == 0)
return (0);
for (dp = domains; dp; dp = dp->dom_next)
if (dp->dom_family == family)
goto found;
return (ENOPROTOOPT);
found:
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_protocol == protocol && pr->pr_sysctl)
return ((*pr->pr_sysctl)(name + 2, namelen - 2,
oldp, oldlenp, newp, newlen));
return (ENOPROTOOPT);
}
@ -180,10 +194,9 @@ pfctlinput(cmd, sa)
for (dp = domains; dp; dp = dp->dom_next)
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_ctlinput)
(*pr->pr_ctlinput)(cmd, sa, (caddr_t) 0);
(*pr->pr_ctlinput)(cmd, sa, (caddr_t)0);
}
/* ARGSUSED */
void
pfslowtimo(arg)
void *arg;
@ -198,7 +211,6 @@ pfslowtimo(arg)
timeout(pfslowtimo, NULL, hz/2);
}
/* ARGSUSED */
void
pffasttimo(arg)
void *arg;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1982, 1986, 1988, 1991 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1986, 1988, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,14 +30,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)uipc_mbuf.c 7.19 (Berkeley) 4/20/91
* $Id: uipc_mbuf.c,v 1.8 1994/04/14 21:34:17 deraadt Exp $
* from: @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: uipc_mbuf.c,v 1.9 1994/05/13 06:01:32 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/map.h>
#define MBTYPES
#include <sys/mbuf.h>
#include <sys/kernel.h>
@ -46,7 +47,6 @@
#include <sys/protosw.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
extern vm_map_t mb_map;
struct mbuf *mbutl;
@ -79,11 +79,12 @@ bad:
/* ARGSUSED */
m_clalloc(ncl, nowait)
register int ncl;
int nowait;
{
int npg, mbx;
static int logged;
register caddr_t p;
register int i;
static int logged;
int npg;
npg = ncl * CLSIZE;
p = (caddr_t)kmem_malloc(mb_map, ctob(npg), !nowait);
@ -200,6 +201,7 @@ m_free(m)
return (n);
}
void
m_freem(m)
register struct mbuf *m;
{
@ -222,13 +224,13 @@ m_freem(m)
* copy junk along.
*/
struct mbuf *
m_prepend(m, len, nowait)
m_prepend(m, len, how)
register struct mbuf *m;
int len, nowait;
int len, how;
{
struct mbuf *mn;
MGET(mn, nowait, m->m_type);
MGET(mn, how, m->m_type);
if (mn == (struct mbuf *)NULL) {
m_freem(m);
return ((struct mbuf *)NULL);
@ -295,7 +297,7 @@ m_copym(m, off0, len, wait)
n->m_pkthdr.len = len;
copyhdr = 0;
}
n->m_len = MIN(len, m->m_len - off);
n->m_len = min(len, m->m_len - off);
if (m->m_flags & M_EXT) {
n->m_data = m->m_data + off;
mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
@ -344,7 +346,7 @@ m_copydata(m, off, len, cp)
while (len > 0) {
if (m == 0)
panic("m_copydata");
count = MIN(m->m_len - off, len);
count = min(m->m_len - off, len);
bcopy(mtod(m, caddr_t) + off, cp, count);
len -= count;
cp += count;
@ -519,3 +521,137 @@ bad:
MPFail++;
return (0);
}
/*
* Partition an mbuf chain in two pieces, returning the tail --
* all but the first len0 bytes. In case of failure, it returns NULL and
* attempts to restore the chain to its original state.
*/
struct mbuf *
m_split(m0, len0, wait)
register struct mbuf *m0;
int len0, wait;
{
register struct mbuf *m, *n;
unsigned len = len0, remain;
for (m = m0; m && len > m->m_len; m = m->m_next)
len -= m->m_len;
if (m == 0)
return (0);
remain = m->m_len - len;
if (m0->m_flags & M_PKTHDR) {
MGETHDR(n, wait, m0->m_type);
if (n == 0)
return (0);
n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
n->m_pkthdr.len = m0->m_pkthdr.len - len0;
m0->m_pkthdr.len = len0;
if (m->m_flags & M_EXT)
goto extpacket;
if (remain > MHLEN) {
/* m can't be the lead packet */
MH_ALIGN(n, 0);
n->m_next = m_split(m, len, wait);
if (n->m_next == 0) {
(void) m_free(n);
return (0);
} else
return (n);
} else
MH_ALIGN(n, remain);
} else if (remain == 0) {
n = m->m_next;
m->m_next = 0;
return (n);
} else {
MGET(n, wait, m->m_type);
if (n == 0)
return (0);
M_ALIGN(n, remain);
}
extpacket:
if (m->m_flags & M_EXT) {
n->m_flags |= M_EXT;
n->m_ext = m->m_ext;
mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */
n->m_data = m->m_data + len;
} else {
bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
}
n->m_len = remain;
m->m_len = len;
n->m_next = m->m_next;
m->m_next = 0;
return (n);
}
/*
* Routine to copy from device local memory into mbufs.
*/
struct mbuf *
m_devget(buf, totlen, off0, ifp, copy)
char *buf;
int totlen, off0;
struct ifnet *ifp;
void (*copy)();
{
register struct mbuf *m;
struct mbuf *top = 0, **mp = &top;
register int off = off0, len;
register char *cp;
char *epkt;
cp = buf;
epkt = cp + totlen;
if (off) {
cp += off + 2 * sizeof(u_short);
totlen -= 2 * sizeof(u_short);
}
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0)
return (0);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = totlen;
m->m_len = MHLEN;
while (totlen > 0) {
if (top) {
MGET(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
m_freem(top);
return (0);
}
m->m_len = MLEN;
}
len = min(totlen, epkt - cp);
if (len >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if (m->m_flags & M_EXT)
m->m_len = len = min(len, MCLBYTES);
else
len = m->m_len;
} else {
/*
* Place initial small packet/header at end of mbuf.
*/
if (len < m->m_len) {
if (top == 0 && len + max_linkhdr <= m->m_len)
m->m_data += max_linkhdr;
m->m_len = len;
} else
len = m->m_len;
}
if (copy)
copy(cp, mtod(m, caddr_t), (unsigned)len);
else
bcopy(cp, mtod(m, caddr_t), (unsigned)len);
cp += len;
*mp = m;
mp = &m->m_next;
totlen -= len;
if (cp == epkt)
cp = buf;
}
return (top);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)uipc_proto.c 7.6 (Berkeley) 5/9/91
* $Id: uipc_proto.c,v 1.3 1993/12/18 04:22:26 mycroft Exp $
* from: @(#)uipc_proto.c 8.1 (Berkeley) 6/10/93
* $Id: uipc_proto.c,v 1.4 1994/05/13 06:01:34 mycroft Exp $
*/
#include <sys/param.h>
@ -44,8 +44,8 @@
* Definitions of protocols supported in the UNIX domain.
*/
int uipc_usrreq();
int raw_init(),raw_usrreq(),raw_input(),raw_ctlinput();
int uipc_usrreq(), raw_usrreq();
void raw_init(), raw_input(), raw_ctlinput();
extern struct domain unixdomain; /* or at least forward */
struct protosw unixsw[] = {

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1982, 1986, 1988, 1990 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1986, 1988, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)uipc_socket.c 7.28 (Berkeley) 5/4/91
* $Id: uipc_socket.c,v 1.14 1994/05/04 11:24:06 mycroft Exp $
* from: @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
* $Id: uipc_socket.c,v 1.15 1994/05/13 06:01:37 mycroft Exp $
*/
#include <sys/param.h>
@ -71,7 +71,7 @@ socreate(dom, aso, type, proto)
prp = pffindproto(dom, proto, type);
else
prp = pffindtype(dom, type);
if (!prp || !prp->pr_usrreq)
if (prp == 0 || prp->pr_usrreq == 0)
return (EPROTONOSUPPORT);
if (prp->pr_type != type)
return (EPROTOTYPE);
@ -299,6 +299,7 @@ bad:
return (error);
}
#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
/*
* Send on a socket.
* If send must go all at once and message is larger than
@ -325,7 +326,7 @@ sosend(so, addr, uio, top, control, flags)
struct mbuf *control;
int flags;
{
struct proc *p = curproc; /* XXX */
struct proc *p = curproc; /* XXX */
struct mbuf **mp;
register struct mbuf *m;
register long space, len, resid;
@ -354,7 +355,7 @@ sosend(so, addr, uio, top, control, flags)
#define snderr(errno) { error = errno; splx(s); goto release; }
restart:
if (error = sblock(&so->so_snd))
if (error = sblock(&so->so_snd, SBLOCKWAIT(flags)))
goto out;
do {
s = splnet();
@ -408,15 +409,25 @@ restart:
MGET(m, M_WAIT, MT_DATA);
mlen = MLEN;
}
if (resid >= MINCLSIZE) {
if (resid >= MINCLSIZE && space >= MCLBYTES) {
MCLGET(m, M_WAIT);
if ((m->m_flags & M_EXT) == 0)
goto nopages;
mlen = MCLBYTES;
len = min(min(mlen, resid), space);
#ifdef MAPPED_MBUFS
len = min(MCLBYTES, resid);
#else
if (atomic && top == 0) {
len = min(MCLBYTES - max_hdr, resid);
m->m_data += max_hdr;
} else
len = min(MCLBYTES, resid);
#endif
space -= MCLBYTES;
} else {
nopages:
len = min(min(mlen, resid), space);
space -= len;
/*
* For datagram protocols, leave room
* for protocol headers in first mbuf.
@ -424,7 +435,6 @@ nopages:
if (atomic && top == 0 && len < mlen)
MH_ALIGN(m, len);
}
space -= len;
error = uiomove(mtod(m, caddr_t), (int)len, uio);
resid = uio->uio_resid;
m->m_len = len;
@ -492,7 +502,6 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp)
struct mbuf **controlp;
int *flagsp;
{
struct proc *p = curproc; /* XXX */
register struct mbuf *m, **mp;
register int flags, len, error, s, offset;
struct protosw *pr = so->so_proto;
@ -532,7 +541,7 @@ bad:
(struct mbuf *)0, (struct mbuf *)0);
restart:
if (error = sblock(&so->so_rcv))
if (error = sblock(&so->so_rcv, SBLOCKWAIT(flags)))
return (error);
s = splnet();
@ -540,14 +549,16 @@ restart:
/*
* If we have less data than requested, block awaiting more
* (subject to any timeout) if:
* 1. the current count is less than the low water mark, or
* 1. the current count is less than the low water mark,
* 2. MSG_WAITALL is set, and it is possible to do the entire
* receive operation at once if we block (resid <= hiwat).
* receive operation at once if we block (resid <= hiwat), or
* 3. MSG_DONTWAIT is not set.
* If MSG_WAITALL is set but resid is larger than the receive buffer,
* we have to do the receive in sections, and thus risk returning
* a short count if a timeout or signal occurs after we start.
*/
while (m == 0 || so->so_rcv.sb_cc < uio->uio_resid &&
if (m == 0 || ((flags & MSG_DONTWAIT) == 0 &&
so->so_rcv.sb_cc < uio->uio_resid) &&
(so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0) {
@ -557,7 +568,7 @@ restart:
#endif
if (so->so_error) {
if (m)
break;
goto dontblock;
error = so->so_error;
if ((flags & MSG_PEEK) == 0)
so->so_error = 0;
@ -565,7 +576,7 @@ restart:
}
if (so->so_state & SS_CANTRCVMORE) {
if (m)
break;
goto dontblock;
else
goto release;
}
@ -581,7 +592,7 @@ restart:
}
if (uio->uio_resid == 0)
goto release;
if (so->so_state & SS_NBIO) {
if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
error = EWOULDBLOCK;
goto release;
}
@ -593,7 +604,10 @@ restart:
goto restart;
}
dontblock:
p->p_stats->p_ru.ru_msgrcv++;
#ifdef notyet /* XXXX */
if (uio->uio_procp)
uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
#endif
nextrecord = m->m_nextpkt;
if (pr->pr_flags & PR_ADDR) {
#ifdef DIAGNOSTIC
@ -806,7 +820,7 @@ sorflush(so)
struct sockbuf asb;
sb->sb_flags |= SB_NOINTR;
(void) sblock(sb);
(void) sblock(sb, M_WAITOK);
s = splimp();
socantrcvmore(so);
sbunlock(sb);
@ -849,6 +863,7 @@ sosetopt(so, level, optname, m0)
case SO_USELOOPBACK:
case SO_BROADCAST:
case SO_REUSEADDR:
case SO_REUSEPORT:
case SO_OOBINLINE:
if (m == NULL || m->m_len < sizeof (int)) {
error = EINVAL;
@ -922,6 +937,11 @@ sosetopt(so, level, optname, m0)
error = ENOPROTOOPT;
break;
}
if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
(void) ((*so->so_proto->pr_ctloutput)
(PRCO_SETOPT, so, level, optname, &m0));
m = NULL; /* freed by protocol */
}
}
bad:
if (m)
@ -961,6 +981,7 @@ sogetopt(so, level, optname, mp)
case SO_DEBUG:
case SO_KEEPALIVE:
case SO_REUSEADDR:
case SO_REUSEPORT:
case SO_BROADCAST:
case SO_OOBINLINE:
*mtod(m, int *) = so->so_options & optname;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
* $Id: uipc_socket2.c,v 1.7 1994/05/04 11:04:58 mycroft Exp $
* $Id: uipc_socket2.c,v 1.8 1994/05/13 06:01:40 mycroft Exp $
*/
#include <sys/param.h>
@ -40,7 +40,6 @@
#include <sys/file.h>
#include <sys/buf.h>
#include <sys/malloc.h>
#include <sys/select.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>

View File

@ -1,10 +1,10 @@
/*-
* Copyright (c) 1991-1993 The Regents of the University of California.
* All rights reserved.
/*
* Copyright (c) 1990, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
@ -35,27 +35,32 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.c 7.4 (Berkeley) 6/17/91
*
* from: Header: bpf.c,v 1.3 93/12/11 02:52:18 mccanne Exp
* $Id: bpf.c,v 1.11 1994/01/25 06:10:08 deraadt Exp $
* from: @(#)bpf.c 8.2 (Berkeley) 3/28/94
* $Id: bpf.c,v 1.12 1994/05/13 06:02:14 mycroft Exp $
*/
#include "bpfilter.h"
#if (NBPFILTER > 0)
#ifndef __GNUC__
#define inline
#else
#define inline __inline
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/buf.h>
#include <sys/time.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/ioctl.h>
#include <sys/map.h>
#include <sys/select.h>
#include <sys/file.h>
#if defined(sparc) && BSD < 199103
#include <sys/stream.h>
#endif
#include <sys/tty.h>
#include <sys/uio.h>
@ -67,16 +72,27 @@
#include <net/bpfdesc.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include "sl.h"
#include "ppp.h"
#ifndef BPF_BUFSIZE
#define BPF_BUFSIZE NBPG
/*
* Older BSDs don't have kernel malloc.
*/
#if BSD < 199103
extern bcopy();
static caddr_t bpf_alloc();
#include <net/bpf_compat.h>
#define BPF_BUFSIZE (MCLBYTES-8)
#define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)
#else
#define BPF_BUFSIZE 4096
#define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)
#endif
#define PRINET 26 /* interruptible */
/*
* The default read buffer size is patchable.
*/
@ -86,20 +102,136 @@ int bpf_bufsize = BPF_BUFSIZE;
* bpf_iflist is the list of interfaces; each corresponds to an ifnet
* bpf_dtab holds the descriptors, indexed by minor device #
*/
struct bpf_if *bpf_iflist;
struct bpf_if *bpf_iflist;
struct bpf_d bpf_dtab[NBPFILTER];
static void bpf_ifname();
static void catchpacket();
static void bpf_freed();
static int bpf_setif();
static int bpf_allocbufs();
#if BSD >= 199207 || NetBSD0_9 >= 2
/*
* bpfilterattach() is called at boot time in new systems. We do
* nothing here since old systems will not call this.
*/
/* ARGSUSED */
void
bpfilterattach(n)
int n;
{
}
#endif
static int bpf_allocbufs __P((struct bpf_d *));
static int bpf_allocbufs __P((struct bpf_d *));
static void bpf_freed __P((struct bpf_d *));
static void bpf_freed __P((struct bpf_d *));
static void bpf_ifname __P((struct ifnet *, struct ifreq *));
static void bpf_ifname __P((struct ifnet *, struct ifreq *));
static void bpf_mcopy __P((const void *, void *, u_int));
static int bpf_movein __P((struct uio *, int,
struct mbuf **, struct sockaddr *, int *));
static int bpf_setif __P((struct bpf_d *, struct ifreq *));
static int bpf_setif __P((struct bpf_d *, struct ifreq *));
static inline void
bpf_wakeup __P((struct bpf_d *));
static void catchpacket __P((struct bpf_d *, u_char *, u_int,
u_int, void (*)(const void *, void *, u_int)));
static void reset_d __P((struct bpf_d *));
static int
bpf_movein(uio, linktype, mp, sockp, datlen)
register struct uio *uio;
int linktype, *datlen;
register struct mbuf **mp;
register struct sockaddr *sockp;
{
struct mbuf *m;
int error;
int len;
int hlen;
/*
* Build a sockaddr based on the data link layer type.
* We do this at this level because the ethernet header
* is copied directly into the data field of the sockaddr.
* In the case of SLIP, there is no header and the packet
* is forwarded as is.
* Also, we are careful to leave room at the front of the mbuf
* for the link level header.
*/
switch (linktype) {
case DLT_SLIP:
sockp->sa_family = AF_INET;
hlen = 0;
break;
case DLT_PPP:
sockp->sa_family = AF_UNSPEC;
hlen = 0;
break;
case DLT_EN10MB:
sockp->sa_family = AF_UNSPEC;
/* XXX Would MAXLINKHDR be better? */
hlen = sizeof(struct ether_header);
break;
case DLT_FDDI:
sockp->sa_family = AF_UNSPEC;
/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
hlen = 24;
break;
case DLT_NULL:
sockp->sa_family = AF_UNSPEC;
hlen = 0;
break;
default:
return (EIO);
}
len = uio->uio_resid;
*datlen = len - hlen;
if ((unsigned)len > MCLBYTES)
return (EIO);
MGET(m, M_WAIT, MT_DATA);
if (m == 0)
return (ENOBUFS);
if (len > MLEN) {
#if BSD >= 199103
MCLGET(m, M_WAIT);
if ((m->m_flags & M_EXT) == 0) {
#else
MCLGET(m);
if (m->m_len != MCLBYTES) {
#endif
error = ENOBUFS;
goto bad;
}
}
m->m_len = len;
*mp = m;
/*
* Make room for link header.
*/
if (hlen != 0) {
m->m_len -= hlen;
#if BSD >= 199103
m->m_data += hlen; /* XXX */
#else
m->m_off += hlen;
#endif
error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
if (error)
goto bad;
}
error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
if (!error)
return (0);
bad:
m_freem(m);
return (error);
}
/*
* Attach file to the bpf interface, i.e. make d listen on bp.
@ -165,7 +297,7 @@ bpf_detachd(d)
/*
* Mark a descriptor free by making it point to itself.
* Mark a descriptor free by making it point to itself.
* This is probably cheaper than marking with a constant since
* the address should be in a register anyway.
*/
@ -184,7 +316,7 @@ bpfopen(dev, flag)
int flag;
{
register struct bpf_d *d;
if (minor(dev) >= NBPFILTER)
return (ENXIO);
/*
@ -224,9 +356,48 @@ bpfclose(dev, flag)
return (0);
}
/*
* Support for SunOS, which does not have tsleep.
*/
#if BSD < 199103
static
bpf_timeout(arg)
caddr_t arg;
{
struct bpf_d *d = (struct bpf_d *)arg;
d->bd_timedout = 1;
wakeup(arg);
}
#define BPF_SLEEP(chan, pri, s, t) bpf_sleep((struct bpf_d *)chan)
int
bpf_sleep(d)
register struct bpf_d *d;
{
register int rto = d->bd_rtout;
register int st;
if (rto != 0) {
d->bd_timedout = 0;
timeout(bpf_timeout, (caddr_t)d, rto);
}
st = sleep((caddr_t)d, PRINET|PCATCH);
if (rto != 0) {
if (d->bd_timedout == 0)
untimeout(bpf_timeout, (caddr_t)d);
else if (st == 0)
return EWOULDBLOCK;
}
return (st != 0) ? EINTR : 0;
}
#else
#define BPF_SLEEP tsleep
#endif
/*
* Rotate the packet buffers in descriptor d. Move the store buffer
* into the hold slot, and the free buffer into the store slot.
* into the hold slot, and the free buffer into the store slot.
* Zero the length of the new store buffer.
*/
#define ROTATE_BUFFERS(d) \
@ -234,22 +405,21 @@ bpfclose(dev, flag)
(d)->bd_hlen = (d)->bd_slen; \
(d)->bd_sbuf = (d)->bd_fbuf; \
(d)->bd_slen = 0; \
(d)->bd_fbuf = 0;
(d)->bd_fbuf = 0;
/*
* bpfread - read next chunk of packets from buffers
*/
int
bpfread(dev, uio, ioflag)
bpfread(dev, uio)
dev_t dev;
register struct uio *uio;
int ioflag;
{
register struct bpf_d *d = &bpf_dtab[minor(dev)];
int error;
int s;
/*
* Restrict application to use a buffer the same size as
* Restrict application to use a buffer the same size as
* as kernel buffers.
*/
if (uio->uio_resid != d->bd_bufsize)
@ -262,14 +432,6 @@ bpfread(dev, uio, ioflag)
* have arrived to fill the store buffer.
*/
while (d->bd_hbuf == 0) {
if (ioflag & IO_NDELAY) {
if (d->bd_slen == 0) {
splx(s);
return (EWOULDBLOCK);
}
ROTATE_BUFFERS(d);
break;
}
if (d->bd_immediate && d->bd_slen != 0) {
/*
* A packet(s) either arrived since the previous
@ -279,64 +441,65 @@ bpfread(dev, uio, ioflag)
ROTATE_BUFFERS(d);
break;
}
error = tsleep((caddr_t)d, PWAIT | PCATCH, "bpf", d->bd_rtout);
if (error != 0) {
if (error == EWOULDBLOCK) {
/*
* On a timeout, return what's in the buffer,
* which may be nothing. If there is something
* in the store buffer, we can do a rotation.
*/
if (d->bd_hbuf)
/*
* We filled up the buffer in between
* getting the timeout and arriving
* here, so we don't need to rotate.
*/
break;
if (d->bd_slen == 0) {
splx(s);
return (0);
}
ROTATE_BUFFERS(d);
break;
}
error = BPF_SLEEP((caddr_t)d, PRINET|PCATCH, "bpf",
d->bd_rtout);
if (error == EINTR || error == ERESTART) {
splx(s);
return (error);
}
if (error == EWOULDBLOCK) {
/*
* On a timeout, return what's in the buffer,
* which may be nothing. If there is something
* in the store buffer, we can rotate the buffers.
*/
if (d->bd_hbuf)
/*
* We filled up the buffer in between
* getting the timeout and arriving
* here, so we don't need to rotate.
*/
break;
if (d->bd_slen == 0) {
splx(s);
return (0);
}
ROTATE_BUFFERS(d);
break;
}
}
/*
* At this point, we know we have something in the hold slot.
*/
splx(s);
/*
/*
* Move data from hold buffer into user space.
* We know the entire buffer is transferred since
* we checked above that the read buffer is bpf_bufsize bytes.
*/
error = uiomove(d->bd_hbuf, d->bd_hlen, uio);
error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
s = splimp();
d->bd_fbuf = d->bd_hbuf;
d->bd_hbuf = 0;
d->bd_hlen = 0;
splx(s);
return (error);
}
/*
* If there are processes sleeping on this descriptor, wake them up.
* If there are processes sleeping on this descriptor, wake them up.
*/
static inline void
bpf_wakeup(d)
register struct bpf_d *d;
{
wakeup((caddr_t)d);
#if (BSD > 199103) || defined(__NetBSD__)
#if BSD >= 199103
selwakeup(&d->bd_sel);
/* XXX */
d->bd_sel.si_pid = 0;
@ -354,113 +517,37 @@ bpfwrite(dev, uio)
dev_t dev;
struct uio *uio;
{
register struct bpf_if *bp = bpf_dtab[minor(dev)].bd_bif;
register struct ifnet *ifp;
register struct mbuf *m;
register u_int len, hlen;
register int error, s;
struct sockaddr dst;
register struct bpf_d *d = &bpf_dtab[minor(dev)];
struct ifnet *ifp;
struct mbuf *m;
int error, s;
static struct sockaddr dst;
int datlen;
if (bp == 0)
if (d->bd_bif == 0)
return (ENXIO);
/*
* Build a sockaddr based on the data link layer type.
* The AF_UNSPEC kludge allows us to hand the link level
* header to the driver via the sockaddr. This isn't
* very clean. It would be better if AF_UNSPEC meant that
* the driver shouldn't bother with encapsulation (i.e., the
* link header is already in the mbuf). The code here is
* structured this way, then things are kludged back before
* calling if_output.
*
* NOTE: When adding new link layers make sure the driver supports
* AF_UNSPEC and that the link header can fit in the sa_data
* field of a sockaddr.
*/
switch (bp->bif_dlt) {
ifp = d->bd_bif->bif_ifp;
#if NSL > 0
case DLT_SLIP:
dst.sa_family = AF_INET;
hlen = 0;
break;
#endif
if (uio->uio_resid == 0)
return (0);
#if NPPP > 0
case DLT_PPP:
dst.sa_family = AF_UNSPEC;
hlen = 0;
break;
#endif
case DLT_EN10MB:
dst.sa_family = AF_UNSPEC;
hlen = 14;
break;
case DLT_FDDI:
dst.sa_family = AF_UNSPEC;
/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
hlen = 24;
break;
case DLT_NULL:
dst.sa_family = AF_UNSPEC;
hlen = 0;
break;
default:
return (EIO);
}
ifp = bp->bif_ifp;
len = uio->uio_resid;
/*
* If we didn't get enough for the link level header, or we
* exceed the interface's mtu, return an error.
*/
if (len < hlen || len - hlen > ifp->if_mtu)
return (EMSGSIZE);
/*
* XXX Avoid complicated buffer chaining ---
* bail if it won't fit in a single mbuf.
*/
if (len > MCLBYTES)
return (EMSGSIZE);
MGETHDR(m, M_WAIT, MT_DATA);
if (m == 0)
return (ENOBUFS);
if (len > MLEN) {
MCLGET(m, M_WAIT);
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
return (ENOBUFS);
}
}
/*
* Move the whole packet, including the data link header,
* into the mbuf. Then, copy the link header back out of the
* packet into the sockaddr. Finally, strip the link header
* from the front of the mbuf.
*/
error = uiomove(mtod(m, caddr_t), len, uio);
if (error) {
m_freem(m);
error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen);
if (error)
return (error);
}
if (hlen > 0) {
bcopy(mtod(m, caddr_t), dst.sa_data, hlen);
m->m_data += hlen;
len -= hlen;
}
m->m_pkthdr.len = m->m_len = len;
if (datlen > ifp->if_mtu)
return (EMSGSIZE);
s = splnet();
#if BSD >= 199103
error = (*ifp->if_output)(ifp, m, &dst, (struct rtentry *)0);
#else
error = (*ifp->if_output)(ifp, m, &dst);
#endif
splx(s);
/*
* The driver frees the mbuf.
* The driver frees the mbuf.
*/
return (error);
}
@ -517,20 +604,16 @@ bpfioctl(dev, cmd, addr, flag)
error = EINVAL;
break;
case FIONBIO:
case FIOASYNC:
break;
/*
* Check for read packet available.
*/
case FIONREAD:
{
int n;
s = splimp();
n = d->bd_slen;
if (d->bd_hbuf)
if (d->bd_hbuf)
n += d->bd_hlen;
splx(s);
@ -546,7 +629,7 @@ bpfioctl(dev, cmd, addr, flag)
error = EINVAL;
else {
ifp = d->bd_bif->bif_ifp;
error = (*ifp->if_ioctl)(ifp, cmd, addr);
error = (*ifp->if_ioctl)(ifp, cmd, addr);
}
break;
}
@ -562,6 +645,9 @@ bpfioctl(dev, cmd, addr, flag)
* Set buffer length.
*/
case BIOCSBLEN:
#if BSD < 199103
error = EINVAL;
#else
if (d->bd_bif != 0)
error = EINVAL;
else {
@ -573,12 +659,13 @@ bpfioctl(dev, cmd, addr, flag)
*(u_int *)addr = size = BPF_MINBUFSIZE;
d->bd_bufsize = size;
}
#endif
break;
/*
* Set link layer read filter.
*/
case BIOCSETF:
case BIOCSETF:
error = bpf_setf(d, (struct bpf_program *)addr);
break;
@ -641,7 +728,7 @@ bpfioctl(dev, cmd, addr, flag)
/*
* Set read timeout.
*/
case BIOCSRTIMEOUT:
case BIOCSRTIMEOUT:
{
struct timeval *tv = (struct timeval *)addr;
u_long msec;
@ -659,7 +746,7 @@ bpfioctl(dev, cmd, addr, flag)
/*
* Get read timeout.
*/
case BIOCGRTIMEOUT:
case BIOCGRTIMEOUT:
{
struct timeval *tv = (struct timeval *)addr;
u_long msec = d->bd_rtout;
@ -696,12 +783,12 @@ bpfioctl(dev, cmd, addr, flag)
bv->bv_major = BPF_MAJOR_VERSION;
bv->bv_minor = BPF_MINOR_VERSION;
break;
}
}
}
return (error);
}
/*
/*
* Set d's packet filter program to fp. If this file already has a filter,
* free it and replace it. Returns EINVAL for bogus requests.
*/
@ -732,8 +819,6 @@ bpf_setf(d, fp)
size = flen * sizeof(*fp->bf_insns);
fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
if (fcode == 0)
return (ENOMEM);
if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
bpf_validate(fcode, (int)flen)) {
s = splimp();
@ -765,7 +850,7 @@ bpf_setif(d, ifr)
/*
* Separate string into name part and unit number. Put a null
* byte at the end of the name part, and compute the number.
* byte at the end of the name part, and compute the number.
* If the a unit number is unspecified, the default is 0,
* as initialized above. XXX This should be common code.
*/
@ -787,7 +872,7 @@ bpf_setif(d, ifr)
for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
struct ifnet *ifp = bp->bif_ifp;
if (ifp == 0 || unit != ifp->if_unit
if (ifp == 0 || unit != ifp->if_unit
|| strcmp(ifp->if_name, ifr->ifr_name) != 0)
continue;
/*
@ -808,7 +893,7 @@ bpf_setif(d, ifr)
s = splimp();
if (bp != d->bd_bif) {
if (d->bd_bif)
/*
/*
* Detach if attached to something else.
*/
bpf_detachd(d);
@ -842,29 +927,44 @@ bpf_ifname(ifp, ifr)
*d = '\0';
}
/*
* The new select interface passes down the proc pointer; the old select
* stubs had to grab it out of the user struct. This glue allows either case.
*/
#if BSD >= 199103
#define bpf_select bpfselect
#else
int
bpfselect(dev, rw)
register dev_t dev;
int rw;
{
return (bpf_select(dev, rw, u.u_procp));
}
#endif
/*
* Support for select() system call
* Inspired by the code in tty.c for the same purpose.
*
* Return true iff the specific operation will not block indefinitely.
* Otherwise, return false but make a note that a selwakeup() must be done.
*/
int
bpfselect(dev, rw, p)
bpf_select(dev, rw, p)
register dev_t dev;
int rw;
struct proc *p;
{
register struct bpf_d *d;
register int s;
if (rw != FREAD)
return (0);
/*
* An imitation of the FIONREAD ioctl code.
*/
d = &bpf_dtab[minor(dev)];
s = splimp();
if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) {
/*
@ -873,23 +973,22 @@ bpfselect(dev, rw, p)
splx(s);
return (1);
}
#if BSD >= 199103
selrecord(p, &d->bd_sel);
#else
/*
* No data ready. If there's already a select() waiting on this
* minor device then this is a collision. This shouldn't happen
* minor device then this is a collision. This shouldn't happen
* because minors really should not be shared, but if a process
* forks while one of these is open, it is possible that both
* processes could select on the same descriptor.
*/
#if defined(__NetBSD__)
selrecord(p, &d->bd_sel);
#else
if (d->bd_selproc && d->bd_selproc->p_wchan == (caddr_t)&selwait)
d->bd_selcoll = 1;
else
d->bd_selproc = p;
#endif
splx(s);
splx(s);
return (0);
}
@ -908,7 +1007,6 @@ bpf_tap(arg, pkt, pktlen)
struct bpf_if *bp;
register struct bpf_d *d;
register u_int slen;
/*
* Note that the ipl does not have to be raised at this point.
* The only problem that could arise here is that if two different
@ -928,18 +1026,21 @@ bpf_tap(arg, pkt, pktlen)
* from m_copydata in sys/uipc_mbuf.c.
*/
static void
bpf_mcopy(src, dst, len)
u_char *src;
u_char *dst;
register int len;
bpf_mcopy(src_arg, dst_arg, len)
const void *src_arg;
void *dst_arg;
register u_int len;
{
register struct mbuf *m = (struct mbuf *)src;
register unsigned count;
register const struct mbuf *m;
register u_int count;
u_char *dst;
m = src_arg;
dst = dst_arg;
while (len > 0) {
if (m == 0)
panic("bpf_mcopy");
count = MIN(m->m_len, len);
count = min(m->m_len, len);
bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
m = m->m_next;
dst += count;
@ -985,7 +1086,7 @@ catchpacket(d, pkt, pktlen, snaplen, cpfn)
register struct bpf_d *d;
register u_char *pkt;
register u_int pktlen, snaplen;
register void (*cpfn)();
register void (*cpfn) __P((const void *, void *, u_int));
{
register struct bpf_hdr *hp;
register int totlen, curlen;
@ -996,7 +1097,7 @@ catchpacket(d, pkt, pktlen, snaplen, cpfn)
* much. Otherwise, transfer the whole packet (unless
* we hit the buffer size limit).
*/
totlen = hdrlen + MIN(snaplen, pktlen);
totlen = hdrlen + min(snaplen, pktlen);
if (totlen > d->bd_bufsize)
totlen = d->bd_bufsize;
@ -1011,8 +1112,8 @@ catchpacket(d, pkt, pktlen, snaplen, cpfn)
* pending reads.
*/
if (d->bd_fbuf == 0) {
/*
* We haven't completed the previous read yet,
/*
* We haven't completed the previous read yet,
* so drop the packet.
*/
++d->bd_dcount;
@ -1022,7 +1123,7 @@ catchpacket(d, pkt, pktlen, snaplen, cpfn)
bpf_wakeup(d);
curlen = 0;
}
else if (d->bd_immediate)
else if (d->bd_immediate)
/*
* Immediate mode is set. A packet arrived so any
* reads should be woken up.
@ -1033,7 +1134,13 @@ catchpacket(d, pkt, pktlen, snaplen, cpfn)
* Append the bpf header.
*/
hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
#if BSD >= 199103
microtime(&hp->bh_tstamp);
#elif defined(sun)
uniqtime(&hp->bh_tstamp);
#else
hp->bh_tstamp = time;
#endif
hp->bh_datalen = pktlen;
hp->bh_hdrlen = hdrlen;
/*
@ -1043,7 +1150,7 @@ catchpacket(d, pkt, pktlen, snaplen, cpfn)
d->bd_slen = curlen + totlen;
}
/*
/*
* Initialize all nonzero fields of a descriptor.
*/
static int
@ -1103,12 +1210,17 @@ bpfattach(driverp, ifp, dlt, hdrlen)
{
struct bpf_if *bp;
int i;
#if BSD < 199103
static struct bpf_if bpf_ifs[NBPFILTER];
static int bpfifno;
bp = (bpfifno < NBPFILTER) ? &bpf_ifs[bpfifno++] : 0;
#else
bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
if (bp == 0) {
printf("bpf: no buffers in attach");
return;
}
#endif
if (bp == 0)
panic("bpfattach");
bp->bif_dlist = 0;
bp->bif_driverp = (struct bpf_if **)driverp;
bp->bif_ifp = ifp;
@ -1121,8 +1233,8 @@ bpfattach(driverp, ifp, dlt, hdrlen)
/*
* Compute the length of the bpf header. This is not necessarily
* equal to SIZEOF_BPF_HDR because we want to insert spacing such
* that the network layer header begins on a longword boundary (for
* equal to SIZEOF_BPF_HDR because we want to insert spacing such
* that the network layer header begins on a longword boundary (for
* performance reasons and to alleviate alignment restrictions).
*/
bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
@ -1139,6 +1251,7 @@ bpfattach(driverp, ifp, dlt, hdrlen)
#endif
}
#if BSD >= 199103
/* XXX This routine belongs in net/if.c. */
/*
* Set/clear promiscuous mode on interface ifp based on the truth value
@ -1152,7 +1265,7 @@ ifpromisc(ifp, pswitch)
int pswitch;
{
struct ifreq ifr;
/*
/*
* If the device is not configured up, we cannot put it in
* promiscuous mode.
*/
@ -1171,5 +1284,35 @@ ifpromisc(ifp, pswitch)
ifr.ifr_flags = ifp->if_flags;
return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
}
#endif
#endif (NBPFILTER > 0)
#if BSD < 199103
/*
* Allocate some memory for bpf. This is temporary SunOS support, and
* is admittedly a hack.
* If resources unavaiable, return 0.
*/
static caddr_t
bpf_alloc(size, canwait)
register int size;
register int canwait;
{
register struct mbuf *m;
if ((unsigned)size > (MCLBYTES-8))
return 0;
MGET(m, canwait, MT_DATA);
if (m == 0)
return 0;
if ((unsigned)size > (MLEN-8)) {
MCLGET(m);
if (m->m_len != MCLBYTES) {
m_freem(m);
return 0;
}
}
*mtod(m, struct mbuf **) = m;
return mtod(m, caddr_t) + 8;
}
#endif

View File

@ -1,10 +1,10 @@
/*-
* Copyright (c) 1990-1991 The Regents of the University of California.
* All rights reserved.
/*
* Copyright (c) 1990, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
@ -17,8 +17,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@ -35,13 +35,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)bpf.h 7.1 (Berkeley) 5/7/91
* $Id: bpf.h,v 1.4 1993/05/20 03:05:50 cgd Exp $
* from: @(#)bpf.h 8.1 (Berkeley) 6/10/93
* $Id: bpf.h,v 1.5 1994/05/13 06:02:19 mycroft Exp $
*/
#ifndef _NET_BPF_H_
#define _NET_BPF_H_
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
@ -233,10 +230,18 @@ struct bpf_insn {
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#ifdef KERNEL
extern u_int bpf_filter();
extern void bpfattach();
extern void bpf_tap();
extern void bpf_mtap();
int bpf_validate __P((struct bpf_insn *, int));
int bpfopen __P((dev_t, int));
int bpfclose __P((dev_t, int));
int bpfread __P((dev_t, struct uio *));
int bpfwrite __P((dev_t, struct uio *));
int bpfioctl __P((dev_t, int, caddr_t, int));
int bpf_select __P((dev_t, int, struct proc *));
void bpf_tap __P((caddr_t, u_char *, u_int));
void bpf_mtap __P((caddr_t, struct mbuf *));
void bpfattach __P((caddr_t *, struct ifnet *, u_int, u_int));
void bpfilterattach __P((int));
u_int bpf_filter __P((struct bpf_insn *, u_char *, u_int, u_int));
#endif
/*
@ -244,4 +249,3 @@ extern void bpf_mtap();
*/
#define BPF_MEMWORDS 16
#endif /* !_NET_BPF_H_ */

View File

@ -1,10 +1,10 @@
/*-
* Copyright (c) 1990-1991 The Regents of the University of California.
* All rights reserved.
/*
* Copyright (c) 1990, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
@ -35,16 +35,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)bpf_filter.c 7.2 (Berkeley) 5/14/91
* $Id: bpf_filter.c,v 1.4 1993/12/18 00:40:51 mycroft Exp $
* from: @(#)bpf_filter.c 8.1 (Berkeley) 6/10/93
* $Id: bpf_filter.c,v 1.5 1994/05/13 06:02:22 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#include <net/bpf.h>
#ifdef sun
#include <netinet/in.h>
#endif
@ -161,6 +159,7 @@ m_xhalf(m, k, err)
}
#endif
#include <net/bpf.h>
/*
* Execute the filter program starting at pc on the packet p
* wirelen is the length of the original packet

View File

@ -1,10 +1,10 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
/*
* Copyright (c) 1990, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
@ -35,14 +35,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)bpfdesc.h 7.1 (Berkeley) 5/7/91
* $Id: bpfdesc.h,v 1.7 1993/11/23 04:51:29 cgd Exp $
* from: @(#)bpfdesc.h 8.1 (Berkeley) 6/10/93
* $Id: bpfdesc.h,v 1.8 1994/05/13 06:02:24 mycroft Exp $
*/
#ifndef _NET_BPFDESC_H_
#define _NET_BPFDESC_H_
#include "select.h"
#include <sys/select.h>
/*
* Descriptor associated with each open bpf file.
@ -75,11 +72,11 @@ 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 */
#if (BSD <= 199103) && !defined(__NetBSD__)
#if BSD < 199103
u_char bd_selcoll; /* true if selects collide */
int bd_timedout;
struct proc * bd_selproc; /* process that last selected us */
#else /* BSD > 199103 */
#else
u_char bd_pad; /* explicit alignment */
struct selinfo bd_sel; /* bsd select info */
#endif
@ -97,4 +94,6 @@ struct bpf_if {
struct ifnet *bif_ifp; /* correspoding interface */
};
#endif /* !_NET_BPFDESC_H_ */
#ifdef KERNEL
int bpf_setf __P((struct bpf_d *, struct bpf_program *));
#endif

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1980, 1986 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1980, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,30 +30,26 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if.c 7.14 (Berkeley) 4/20/91
* $Id: if.c,v 1.14 1994/05/05 09:33:21 mycroft Exp $
* from: @(#)if.c 8.3 (Berkeley) 1/4/94
* $Id: if.c,v 1.15 1994/05/13 06:02:26 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
#include "ether.h"
int ifqmaxlen = IFQ_MAXLEN;
void if_slowtimo __P((void *));
void if_slowtimo __P((void *arg));
/*
* Network interface utility routines.
@ -61,7 +57,6 @@ void if_slowtimo __P((void *));
* Routines with ifa_ifwith* names take sockaddr *'s as
* parameters.
*/
void
ifinit()
{
@ -77,6 +72,7 @@ ifinit()
/*
* Call each interface on a Unibus reset.
*/
void
ifubareset(uban)
int uban;
{
@ -90,23 +86,24 @@ ifubareset(uban)
int if_index = 0;
struct ifaddr **ifnet_addrs;
static char *sprint_d();
static char *sprint_d __P((u_int, char *, int));
/*
* Attach an interface to the
* list of "active" interfaces.
*/
void
if_attach(ifp)
struct ifnet *ifp;
{
unsigned socksize, ifasize;
int namelen, unitlen;
int namelen, unitlen, masklen;
char workbuf[12], *unitname;
register struct ifnet **p = &ifnet;
register struct sockaddr_dl *sdl;
register struct ifaddr *ifa;
static int if_indexlim = 8;
extern link_rtrequest(), ether_output();
extern void link_rtrequest();
while (*p)
p = &((*p)->if_next);
@ -122,14 +119,6 @@ if_attach(ifp)
}
ifnet_addrs = q;
}
#if defined(INET) && NETHER > 0
/* XXX -- Temporary fix before changing 10 ethernet drivers */
if (ifp->if_output == ether_output) {
ifp->if_type = IFT_ETHER;
ifp->if_addrlen = 6;
ifp->if_hdrlen = 14;
}
#endif
/*
* create a Link Level name for this device
*/
@ -137,8 +126,9 @@ if_attach(ifp)
namelen = strlen(ifp->if_name);
unitlen = strlen(unitname);
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
socksize = _offsetof(struct sockaddr_dl, sdl_data[0]) +
unitlen + namelen + ifp->if_addrlen;
masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) +
unitlen + namelen;
socksize = masklen + ifp->if_addrlen;
#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
socksize = ROUNDUP(socksize);
if (socksize < sizeof(*sdl))
@ -147,25 +137,26 @@ if_attach(ifp)
ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
if (ifa == 0)
return;
ifnet_addrs[if_index - 1] = ifa;
bzero((caddr_t)ifa, ifasize);
sdl = (struct sockaddr_dl *)(ifa + 1);
ifa->ifa_addr = (struct sockaddr *)sdl;
ifa->ifa_ifp = ifp;
sdl->sdl_len = socksize;
sdl->sdl_family = AF_LINK;
bcopy(ifp->if_name, sdl->sdl_data, namelen);
bcopy(unitname, namelen + (caddr_t)sdl->sdl_data, unitlen);
sdl->sdl_nlen = (namelen += unitlen);
sdl->sdl_index = ifp->if_index;
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
ifa->ifa_netmask = (struct sockaddr *)sdl;
sdl->sdl_len = socksize - ifp->if_addrlen;
while (namelen != 0)
sdl->sdl_data[--namelen] = 0xff;
sdl->sdl_type = ifp->if_type;
ifnet_addrs[if_index - 1] = ifa;
ifa->ifa_ifp = ifp;
ifa->ifa_next = ifp->if_addrlist;
ifa->ifa_rtrequest = link_rtrequest;
ifp->if_addrlist = ifa;
ifa->ifa_addr = (struct sockaddr *)sdl;
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
ifa->ifa_netmask = (struct sockaddr *)sdl;
sdl->sdl_len = masklen;
while (namelen != 0)
sdl->sdl_data[--namelen] = 0xff;
}
/*
* Locate an interface based on a complete address.
@ -216,7 +207,7 @@ ifa_ifwithdstaddr(addr)
/*
* Find an interface on a specific network. If many, choice
* is first found.
* is most specific found.
*/
struct ifaddr *
ifa_ifwithnet(addr)
@ -224,32 +215,36 @@ ifa_ifwithnet(addr)
{
register struct ifnet *ifp;
register struct ifaddr *ifa;
struct ifaddr *ifa_maybe = 0;
u_int af = addr->sa_family;
char *addr_data = addr->sa_data, *cplim;
if (af >= AF_MAX)
return (0);
if (af == AF_LINK) {
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
if (sdl->sdl_index && sdl->sdl_index <= if_index)
return (ifnet_addrs[sdl->sdl_index - 1]);
}
for (ifp = ifnet; ifp; ifp = ifp->if_next)
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
register char *cp, *cp2, *cp3;
register char *cplim;
if (ifa->ifa_addr->sa_family != af || ifa->ifa_netmask == 0)
continue;
cp = addr->sa_data;
cp2 = ifa->ifa_addr->sa_data;
cp3 = ifa->ifa_netmask->sa_data;
cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
for (; cp3 < cplim; cp3++)
if ((*cp++ ^ *cp2++) & *cp3)
break;
if (cp3 == cplim)
return (ifa);
}
return ((struct ifaddr *)0);
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
register char *cp, *cp2, *cp3;
if (ifa->ifa_addr->sa_family != af ||
ifa->ifa_netmask == 0)
next: continue;
cp = addr_data;
cp2 = ifa->ifa_addr->sa_data;
cp3 = ifa->ifa_netmask->sa_data;
cplim = (char *)ifa->ifa_netmask +
ifa->ifa_netmask->sa_len;
while (cp3 < cplim)
if ((*cp++ ^ *cp2++) & *cp3++)
goto next;
if (ifa_maybe == 0 ||
rn_refines((caddr_t)ifa->ifa_netmask,
(caddr_t)ifa_maybe->ifa_netmask))
ifa_maybe = ifa;
}
return (ifa_maybe);
}
/*
@ -309,24 +304,30 @@ ifaof_ifpforaddr(addr, ifp)
return (ifa_maybe);
}
#include <net/route.h>
/*
* Default action when installing a route with a Link Level gateway.
* Lookup an appropriate real ifa to point to.
* This should be moved to /sys/net/link.c eventually.
*/
void
link_rtrequest(cmd, rt, sa)
register struct rtentry *rt;
struct sockaddr *sa;
int cmd;
register struct rtentry *rt;
struct sockaddr *sa;
{
register struct ifaddr *ifa;
struct sockaddr *dst;
struct ifnet *ifp, *oldifnet = ifnet;
struct ifnet *ifp;
if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
return;
if (ifa = ifaof_ifpforaddr(dst, ifp)) {
IFAFREE(rt->rt_ifa);
rt->rt_ifa = ifa;
ifa->ifa_refcnt++;
if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
ifa->ifa_rtrequest(cmd, rt, sa);
}
@ -337,6 +338,7 @@ struct sockaddr *sa;
* the transition.
* NOTE: must be called at splnet or eqivalent.
*/
void
if_down(ifp)
register struct ifnet *ifp;
{
@ -346,11 +348,33 @@ if_down(ifp)
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
if_qflush(&ifp->if_snd);
rt_ifmsg(ifp);
}
/*
* Mark an interface up and notify protocols of
* the transition.
* NOTE: must be called at splnet or equivalent.
*/
void
if_up(ifp)
register struct ifnet *ifp;
{
register struct ifaddr *ifa;
ifp->if_flags |= IFF_UP;
#ifdef notyet
/* this has no effect on IP, and will kill all ISO connections XXX */
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
pfctlinput(PRC_IFUP, ifa->ifa_addr);
#endif
rt_ifmsg(ifp);
}
/*
* Flush an interface queue.
*/
void
if_qflush(ifq)
register struct ifqueue *ifq;
{
@ -371,7 +395,6 @@ if_qflush(ifq)
* from softclock, we decrement timers (if set) and
* call the appropriate interface routine on expiration.
*/
/* ARGSUSED */
void
if_slowtimo(arg)
void *arg;
@ -432,6 +455,7 @@ ifunit(name)
/*
* Interface ioctls.
*/
int
ifioctl(so, cmd, data, p)
struct socket *so;
int cmd;
@ -447,17 +471,6 @@ ifioctl(so, cmd, data, p)
case SIOCGIFCONF:
case OSIOCGIFCONF:
return (ifconf(cmd, data));
#if defined(INET) && NETHER > 0
case SIOCSARP:
case SIOCDARP:
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
/* FALL THROUGH */
case SIOCGARP:
case OSIOCGARP:
return (arpioctl(cmd, data));
#endif
}
ifr = (struct ifreq *)data;
ifp = ifunit(ifr->ifr_name);
@ -473,14 +486,6 @@ ifioctl(so, cmd, data, p)
ifr->ifr_metric = ifp->if_metric;
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
if (! ifp->if_ioctl) /* BUG:: 10NOV93 CMAEDA */
return (EOPNOTSUPP);
return ((*ifp->if_ioctl)(ifp, cmd, data));
case SIOCSIFFLAGS:
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
@ -489,6 +494,11 @@ ifioctl(so, cmd, data, p)
if_down(ifp);
splx(s);
}
if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
int s = splimp();
if_up(ifp);
splx(s);
}
ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
(ifr->ifr_flags &~ IFF_CANTCHANGE);
if (ifp->if_ioctl)
@ -501,14 +511,13 @@ ifioctl(so, cmd, data, p)
ifp->if_metric = ifr->ifr_metric;
break;
case SIOCSIFMTU:
case SIOCGIFMTU:
case SIOCSIFASYNCMAP:
case SIOCGIFASYNCMAP:
if (!ifp->if_ioctl)
case SIOCADDMULTI:
case SIOCDELMULTI:
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
if (ifp->if_ioctl == 0)
return (EOPNOTSUPP);
return ((*ifp->if_ioctl)(ifp, cmd, data));
break;
default:
if (so->so_proto == 0)
@ -578,6 +587,7 @@ ifioctl(so, cmd, data, p)
* other information.
*/
/*ARGSUSED*/
int
ifconf(cmd, data)
int cmd;
caddr_t data;
@ -592,13 +602,14 @@ ifconf(cmd, data)
ifrp = ifc->ifc_req;
ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2;
for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2);
strncpy(ifr.ifr_name, ifp->if_name, sizeof(ifr.ifr_name) - 2);
for (cp = ifr.ifr_name; cp < ep && *cp; cp++)
;
continue;
*cp++ = '0' + ifp->if_unit; *cp = '\0';
if ((ifa = ifp->if_addrlist) == 0) {
bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
sizeof(ifr));
if (error)
break;
space -= sizeof (ifr), ifrp++;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if.h 7.11 (Berkeley) 3/19/91
* $Id: if.h,v 1.8 1994/02/16 20:12:50 mycroft Exp $
* from: @(#)if.h 8.1 (Berkeley) 6/10/93
* $Id: if.h,v 1.9 1994/05/13 06:02:29 mycroft Exp $
*/
#ifndef _NET_IF_H_
#define _NET_IF_H_
/*
* Structures defining a network interface, providing a packet
* transport mechanism (ala level 0 of the PUP protocols).
@ -45,8 +42,8 @@
* length, and provides higher level routines with input datagrams
* received from its medium.
*
* Output occurs when the routine if_output is called, with three parameters:
* (*ifp->if_output)(ifp, m, dst)
* Output occurs when the routine if_output is called, with four parameters:
* (*ifp->if_output)(ifp, m, dst, rt)
* Here m is the mbuf chain to be sent and dst is the destination address.
* The output routine encapsulates the supplied datagram if necessary,
* and then transmits it on its medium.
@ -64,20 +61,61 @@
/* XXX fast fix for SNMP, going away soon */
#include <sys/time.h>
struct mbuf;
struct proc;
struct rtentry;
struct socket;
struct ether_header;
/*
* Structure defining a queue for a network interface.
*
* (Would like to call this struct ``if'', but C isn't PL/1.)
*/
struct ifnet {
char *if_name; /* name, e.g. ``en'' or ``lo'' */
short if_unit; /* sub-unit for lower level driver */
short if_mtu; /* maximum transmission unit */
short if_flags; /* up/down, broadcast, etc. */
short if_timer; /* time 'til if_watchdog called */
int if_metric; /* routing metric (external only) */
struct ifnet *if_next; /* all struct ifnets are chained */
struct ifaddr *if_addrlist; /* linked list of addresses per if */
int if_pcount; /* number of promiscuous listeners */
caddr_t if_bpf; /* packet filter structure */
u_short if_index; /* numeric abbreviation for this if */
short if_unit; /* sub-unit for lower level driver */
short if_timer; /* time 'til if_watchdog called */
short if_flags; /* up/down, broadcast, etc. */
struct if_data {
/* generic interface information */
u_char ifi_type; /* ethernet, tokenring, etc. */
u_char ifi_addrlen; /* media address length */
u_char ifi_hdrlen; /* media header length */
u_long ifi_mtu; /* maximum transmission unit */
u_long ifi_metric; /* routing metric (external only) */
u_long ifi_baudrate; /* linespeed */
/* volatile statistics */
u_long ifi_ipackets; /* packets received on interface */
u_long ifi_ierrors; /* input errors on interface */
u_long ifi_opackets; /* packets sent on interface */
u_long ifi_oerrors; /* output errors on interface */
u_long ifi_collisions; /* collisions on csma interfaces */
u_long ifi_ibytes; /* total number of octets received */
u_long ifi_obytes; /* total number of octets sent */
u_long ifi_imcasts; /* packets received via multicast */
u_long ifi_omcasts; /* packets sent via multicast */
u_long ifi_iqdrops; /* dropped on input, this interface */
u_long ifi_noproto; /* destined for unsupported protocol */
struct timeval ifi_lastchange;/* last updated */
} if_data;
/* procedure handles */
int (*if_output) /* output routine (enqueue) */
__P((struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *));
int (*if_start) /* initiate output routine */
__P((struct ifnet *));
int (*if_ioctl) /* ioctl routine */
__P((struct ifnet *, int, caddr_t));
int (*if_reset) /* XXX bus reset routine */
__P((int));
int (*if_watchdog) /* timer routine */
__P((int));
struct ifqueue {
struct mbuf *ifq_head;
struct mbuf *ifq_tail;
@ -85,35 +123,25 @@ struct ifnet {
int ifq_maxlen;
int ifq_drops;
} if_snd; /* output queue */
/* procedure handles */
int (*if_output)(); /* output routine (enqueue) */
int (*if_start)(); /* initiate output routine */
int (*if_ioctl)(); /* ioctl routine */
int (*if_reset)(); /* bus reset routine */
int (*if_watchdog)(); /* timer routine */
/* generic interface statistics */
int if_ipackets; /* packets received on interface */
int if_ierrors; /* input errors on interface */
int if_opackets; /* packets sent on interface */
int if_oerrors; /* output errors on interface */
int if_collisions; /* collisions on csma interfaces */
/* end statistics */
struct ifnet *if_next;
u_char if_type; /* ethernet, tokenring, etc */
u_char if_addrlen; /* media address length */
u_char if_hdrlen; /* media header length */
u_char if_index; /* numeric abbreviation for this if */
/* more statistics here to avoid recompiling netstat */
struct timeval if_lastchange; /* last updated */
int if_ibytes; /* total number of octets received */
int if_obytes; /* total number of octets sent */
int if_imcasts; /* packets received via multicast */
int if_omcasts; /* packets sent via multicast */
int if_iqdrops; /* dropped on input, this interface */
int if_noproto; /* destined for unsupported protocol */
int if_baudrate; /* linespeed */
int if_pcount; /* number of promiscuous listeners */
};
#define if_mtu if_data.ifi_mtu
#define if_type if_data.ifi_type
#define if_addrlen if_data.ifi_addrlen
#define if_hdrlen if_data.ifi_hdrlen
#define if_metric if_data.ifi_metric
#define if_baudrate if_data.ifi_baudrate
#define if_ipackets if_data.ifi_ipackets
#define if_ierrors if_data.ifi_ierrors
#define if_opackets if_data.ifi_opackets
#define if_oerrors if_data.ifi_oerrors
#define if_collisions if_data.ifi_collisions
#define if_ibytes if_data.ifi_ibytes
#define if_obytes if_data.ifi_obytes
#define if_imcasts if_data.ifi_imcasts
#define if_omcasts if_data.ifi_omcasts
#define if_iqdrops if_data.ifi_iqdrops
#define if_noproto if_data.ifi_noproto
#define if_lastchange if_data.ifi_lastchange
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
@ -123,7 +151,6 @@ struct ifnet {
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
#define IFF_RUNNING 0x40 /* resources allocated */
#define IFF_NOARP 0x80 /* no address resolution protocol */
/* next two not supported now, but reserved: */
#define IFF_PROMISC 0x100 /* receive all packets */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
#define IFF_OACTIVE 0x400 /* transmission in progress */
@ -131,12 +158,12 @@ struct ifnet {
#define IFF_LINK0 0x1000 /* per link layer defined bit */
#define IFF_LINK1 0x2000 /* per link layer defined bit */
#define IFF_LINK2 0x4000 /* per link layer defined bit */
#define IFF_MULTICAST 0x8000 /* supports multicast */
#define IFF_MULTICAST 0x8000 /* supports multicast */
/* flags set internally only: */
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE| \
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
/*
* Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
@ -188,12 +215,41 @@ struct ifaddr {
struct sockaddr *ifa_netmask; /* used to determine subnet */
struct ifnet *ifa_ifp; /* back-pointer to interface */
struct ifaddr *ifa_next; /* next address for interface */
int (*ifa_rtrequest)(); /* check or clean routes (+ or -)'d */
struct rtentry *ifa_rt; /* ??? for ROUTETOIF */
void (*ifa_rtrequest)(); /* check or clean routes (+ or -)'d */
u_short ifa_flags; /* mostly rt_flags for cloning */
u_short ifa_llinfolen; /* extra to malloc for link info */
short ifa_refcnt; /* count of references */
int ifa_metric; /* cost of going out this interface */
};
#define IFA_ROUTE RTF_UP /* route installed */
#define IFA_ROUTE RTF_UP /* route installed */
/*
* Message format for use in obtaining information about interfaces
* from sysctl and the routing socket.
*/
struct if_msghdr {
u_short ifm_msglen; /* to skip over non-understood messages */
u_char ifm_version; /* future binary compatability */
u_char ifm_type; /* message type */
int ifm_addrs; /* like rtm_addrs */
int ifm_flags; /* value of if_flags */
u_short ifm_index; /* index for associated ifp */
struct if_data ifm_data;/* statistics and other data about if */
};
/*
* Message format for use in obtaining information about interface addresses
* from sysctl and the routing socket.
*/
struct ifa_msghdr {
u_short ifam_msglen; /* to skip over non-understood messages */
u_char ifam_version; /* future binary compatability */
u_char ifam_type; /* message type */
int ifam_addrs; /* like rtm_addrs */
int ifam_flags; /* value of ifa_flags */
u_short ifam_index; /* index for associated ifp */
int ifam_metric; /* value of ifa_metric */
};
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
@ -242,14 +298,50 @@ struct ifconf {
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
};
#ifdef KERNEL
#include "../net/if_arp.h"
struct ifqueue rawintrq; /* raw packet input queue */
struct ifnet *ifnet;
struct ifaddr *ifa_ifwithaddr(), *ifa_ifwithnet();
struct ifaddr *ifa_ifwithdstaddr();
#else KERNEL
#include <net/if_arp.h>
#endif KERNEL
#endif /* !_NET_IF_H_ */
#ifdef KERNEL
#define IFAFREE(ifa) \
if ((ifa)->ifa_refcnt <= 0) \
ifafree(ifa); \
else \
(ifa)->ifa_refcnt--;
struct ifnet *ifnet;
void ether_ifattach __P((struct ifnet *));
void ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *));
int ether_output __P((struct ifnet *,
struct mbuf *, struct sockaddr *, struct rtentry *));
char *ether_sprintf __P((u_char *));
void if_attach __P((struct ifnet *));
void if_down __P((struct ifnet *));
void if_qflush __P((struct ifqueue *));
void if_slowtimo __P((void *));
void if_up __P((struct ifnet *));
#ifdef vax
void ifubareset __P((int));
#endif
int ifconf __P((int, caddr_t));
void ifinit __P((void));
int ifioctl __P((struct socket *, int, caddr_t, struct proc *));
int ifpromisc __P((struct ifnet *, int));
struct ifnet *ifunit __P((char *));
struct ifaddr *ifa_ifwithaddr __P((struct sockaddr *));
struct ifaddr *ifa_ifwithaf __P((int));
struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *));
struct ifaddr *ifa_ifwithnet __P((struct sockaddr *));
struct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *,
struct sockaddr *));
struct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *));
void ifafree __P((struct ifaddr *));
void link_rtrequest __P((int, struct rtentry *, struct sockaddr *));
int loioctl __P((struct ifnet *, int, caddr_t));
void loopattach __P((int));
int looutput __P((struct ifnet *,
struct mbuf *, struct sockaddr *, struct rtentry *));
void lortrequest __P((int, struct rtentry *, struct sockaddr *));
#endif /* KERNEL */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_arp.h 7.4 (Berkeley) 6/28/90
* $Id: if_arp.h,v 1.5 1993/09/05 00:46:54 cassidy Exp $
* from: @(#)if_arp.h 8.1 (Berkeley) 6/10/93
* $Id: if_arp.h,v 1.6 1994/05/13 06:02:31 mycroft Exp $
*/
#ifndef _NET_IF_ARP_H_
#define _NET_IF_ARP_H_
/*
* Address Resolution Protocol.
*
@ -49,23 +46,28 @@
*/
struct arphdr {
u_short ar_hrd; /* format of hardware address */
#define ARPHRD_ETHER 1 /* ethernet hardware address */
#define ARPHRD_ETHER 1 /* ethernet hardware format */
#define ARPHRD_FRELAY 15 /* frame relay hardware format */
u_short ar_pro; /* format of protocol address */
u_char ar_hln; /* length of hardware address */
u_char ar_pln; /* length of protocol address */
u_short ar_op; /* one of: */
#define ARPOP_REQUEST 1 /* request to resolve address */
#define ARPOP_REPLY 2 /* response to previous request */
#define REVARP_REQUEST 3 /* reverse ARP request */
#define REVARP_REPLY 4 /* reverse ARP reply */
#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
#define ARPOP_REVREPLY 4 /* response giving protocol address */
#define ARPOP_INVREQUEST 8 /* request to identify peer */
#define ARPOP_INVREPLY 9 /* response identifying peer */
/*
* The remaining fields are variable in size,
* according to the sizes above.
*/
/* u_char ar_sha[]; * sender hardware address */
/* u_char ar_spa[]; * sender protocol address */
/* u_char ar_tha[]; * target hardware address */
/* u_char ar_tpa[]; * target protocol address */
#ifdef COMMENT_ONLY
u_char ar_sha[]; /* sender hardware address */
u_char ar_spa[]; /* sender protocol address */
u_char ar_tha[]; /* target hardware address */
u_char ar_tpa[]; /* target protocol address */
#endif
};
/*
@ -82,5 +84,3 @@ struct arpreq {
#define ATF_PERM 0x04 /* permanent entry */
#define ATF_PUBL 0x08 /* publish entry (respond for other host) */
#define ATF_USETRAILERS 0x10 /* has requested trailers */
#endif /* !_NET_IF_ARP_H_ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_dl.h 7.2 (Berkeley) 2/22/91
* $Id: if_dl.h,v 1.3 1993/05/20 03:05:58 cgd Exp $
* from: @(#)if_dl.h 8.1 (Berkeley) 6/10/93
* $Id: if_dl.h,v 1.4 1994/05/13 06:02:33 mycroft Exp $
*/
#ifndef _NET_IF_DL_H_
#define _NET_IF_DL_H_
/*
* A Link-Level Sockaddr may specify the interface in one of two
* ways: either by means of a system-provided index number (computed
@ -82,5 +79,3 @@ char *link_ntoa __P((const struct sockaddr_dl *));
__END_DECLS
#endif /* !KERNEL */
#endif /* !_NET_IF_DL_H_ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1982, 1989 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,8 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_ethersubr.c 7.13 (Berkeley) 4/20/91
* $Id: if_ethersubr.c,v 1.7 1994/04/18 06:18:10 glass Exp $
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
*/
#include <sys/param.h>
@ -45,11 +44,14 @@
#include <sys/errno.h>
#include <sys/syslog.h>
#include <machine/cpu.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/if_llc.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#ifdef INET
#include <netinet/in.h>
@ -69,10 +71,18 @@
#include <netiso/iso_snpac.h>
#endif
#include <machine/cpu.h>
#ifdef LLC
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
#endif
#if defined(LLC) && defined(CCITT)
extern struct ifqueue pkintrq;
#endif
u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
extern struct ifnet loif;
#define senderr(e) { error = (e); goto bad;}
/*
* Ethernet output routine.
@ -81,55 +91,64 @@ extern struct ifnet loif;
* packet leaves a multiple of 512 bytes of data in remainder.
* Assumes that ifp is actually pointer to arpcom structure.
*/
ether_output(ifp, m0, dst, rt)
int
ether_output(ifp, m0, dst, rt0)
register struct ifnet *ifp;
struct mbuf *m0;
struct sockaddr *dst;
struct rtentry *rt;
struct rtentry *rt0;
{
u_short type;
u_short etype;
int s, error = 0;
u_char edst[6];
struct in_addr idst;
register struct mbuf *m = m0;
register struct rtentry *rt;
struct mbuf *mcopy = (struct mbuf *)0;
register struct ether_header *eh;
int usetrailers, off, len = m->m_pkthdr.len;
#define ac ((struct arpcom *)ifp)
int off, len = m->m_pkthdr.len;
struct arpcom *ac = (struct arpcom *)ifp;
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
error = ENETDOWN;
goto bad;
}
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
ifp->if_lastchange = time;
if (rt = rt0) {
if ((rt->rt_flags & RTF_UP) == 0) {
if (rt0 = rt = rtalloc1(dst, 1))
rt->rt_refcnt--;
else
senderr(EHOSTUNREACH);
}
if (rt->rt_flags & RTF_GATEWAY) {
if (rt->rt_gwroute == 0)
goto lookup;
if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
rtfree(rt); rt = rt0;
lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
if ((rt = rt->rt_gwroute) == 0)
senderr(EHOSTUNREACH);
}
}
if (rt->rt_flags & RTF_REJECT)
if (rt->rt_rmx.rmx_expire == 0 ||
time.tv_sec < rt->rt_rmx.rmx_expire)
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
}
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
idst = ((struct sockaddr_in *)dst)->sin_addr;
if (!arpresolve(ac, m, &idst, edst, &usetrailers))
if (!arpresolve(ac, rt, m, dst, edst))
return (0); /* if not yet resolved */
/* If broadcasting on a simplex interface, loopback a copy */
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
mcopy = m_copy(m, 0, (int)M_COPYALL);
off = m->m_pkthdr.len - m->m_len;
if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
(m->m_flags & M_EXT) == 0 &&
m->m_data >= m->m_pktdat + 2 * sizeof (u_short)) {
type = ETHERTYPE_TRAIL + (off>>9);
m->m_data -= 2 * sizeof (u_short);
m->m_len += 2 * sizeof (u_short);
len += 2 * sizeof (u_short);
*mtod(m, u_short *) = htons((u_short)ETHERTYPE_IP);
*(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
goto gottrailertype;
}
type = ETHERTYPE_IP;
goto gottype;
etype = ETHERTYPE_IP;
break;
#endif
#ifdef NS
case AF_NS:
type = ETHERTYPE_NS;
etype = ETHERTYPE_NS;
bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
(caddr_t)edst, sizeof (edst));
if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
@ -137,36 +156,24 @@ ether_output(ifp, m0, dst, rt)
/* If broadcasting on a simplex interface, loopback a copy */
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
mcopy = m_copy(m, 0, (int)M_COPYALL);
goto gottype;
break;
#endif
#ifdef ISO
case AF_ISO: {
int snpalen;
struct llc *l;
register struct sockaddr_dl *sdl;
iso_again:
if (rt && rt->rt_gateway && (rt->rt_flags & RTF_UP)) {
if (rt->rt_flags & RTF_GATEWAY) {
if (rt->rt_llinfo) {
rt = (struct rtentry *)rt->rt_llinfo;
goto iso_again;
}
} else {
register struct sockaddr_dl *sdl =
(struct sockaddr_dl *)rt->rt_gateway;
if (sdl && sdl->sdl_family == AF_LINK
&& sdl->sdl_alen > 0) {
bcopy(LLADDR(sdl), (char *)edst,
sizeof(edst));
goto iso_resolved;
}
}
}
if ((error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
(char *)edst, &snpalen)) > 0)
if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
} else if (error =
iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
(char *)edst, &snpalen))
goto bad; /* Not Resolved */
iso_resolved:
/* If broadcasting on a simplex interface, loopback a copy */
if (*edst & 1)
m->m_flags |= (M_BCAST|M_MCAST);
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
@ -181,7 +188,7 @@ ether_output(ifp, m0, dst, rt)
M_PREPEND(m, 3, M_DONTWAIT);
if (m == NULL)
return (0);
type = m->m_pkthdr.len;
etype = m->m_pkthdr.len;
l = mtod(m, struct llc *);
l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
l->llc_control = LLC_UI;
@ -193,46 +200,62 @@ ether_output(ifp, m0, dst, rt)
printf("%x ", edst[i] & 0xff);
printf("\n");
ENDDEBUG
} break;
#endif /* ISO */
#ifdef LLC
/* case AF_NSAP: */
case AF_CCITT: {
register struct sockaddr_dl *sdl =
(struct sockaddr_dl *) rt -> rt_gateway;
if (sdl && sdl->sdl_family == AF_LINK
&& sdl->sdl_alen > 0) {
bcopy(LLADDR(sdl), (char *)edst,
sizeof(edst));
} else goto bad; /* Not a link interface ? Funny ... */
if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
if (mcopy) {
eh = mtod(mcopy, struct ether_header *);
bcopy((caddr_t)edst,
(caddr_t)eh->ether_dhost, sizeof (edst));
bcopy((caddr_t)ac->ac_enaddr,
(caddr_t)eh->ether_shost, sizeof (edst));
}
}
goto gottype;
#endif ISO
#ifdef RMP
case AF_RMP:
/*
* This is IEEE 802.3 -- the Ethernet `type' field is
* really a `length' field.
*/
type = m->m_len;
bcopy((caddr_t)dst->sa_data, (caddr_t)edst, sizeof(edst));
break;
#endif
etype = m->m_pkthdr.len;
#ifdef LLC_DEBUG
{
int i;
register struct llc *l = mtod(m, struct llc *);
printf("ether_output: sending LLC2 pkt to: ");
for (i=0; i<6; i++)
printf("%x ", edst[i] & 0xff);
printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
etype & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff,
l->llc_control & 0xff);
}
#endif /* LLC_DEBUG */
} break;
#endif /* LLC */
case AF_UNSPEC:
eh = (struct ether_header *)dst->sa_data;
bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
/* AF_UNSPEC doesn't swap the byte order of the ether_type */
type = ntohs(eh->ether_type);
goto gottype;
/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
etype = ntohs(eh->ether_type);
break;
default:
printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
dst->sa_family);
error = EAFNOSUPPORT;
goto bad;
senderr(EAFNOSUPPORT);
}
gottrailertype:
/*
* Packet to be sent as trailer: move first packet
* (control information) to end of chain.
*/
while (m->m_next)
m = m->m_next;
m->m_next = m0;
m = m0->m_next;
m0->m_next = 0;
gottype:
if (mcopy)
(void) looutput(ifp, mcopy, dst, rt);
/*
@ -240,13 +263,11 @@ gottype:
* allocate another.
*/
M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
if (m == 0) {
error = ENOBUFS;
goto bad;
}
if (m == 0)
senderr(ENOBUFS);
eh = mtod(m, struct ether_header *);
type = htons((u_short)type);
bcopy((caddr_t)&type,(caddr_t)&eh->ether_type,
etype = htons(etype);
bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
sizeof(eh->ether_type));
bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
@ -259,8 +280,7 @@ gottype:
if (IF_QFULL(&ifp->if_snd)) {
IF_DROP(&ifp->if_snd);
splx(s);
error = ENOBUFS;
goto bad;
senderr(ENOBUFS);
}
IF_ENQUEUE(&ifp->if_snd, m);
if ((ifp->if_flags & IFF_OACTIVE) == 0)
@ -282,6 +302,7 @@ bad:
* the packet is in the mbuf chain m without
* the ether header, which is provided separately.
*/
void
ether_input(ifp, eh, m)
struct ifnet *ifp;
register struct ether_header *eh;
@ -290,17 +311,22 @@ ether_input(ifp, eh, m)
register struct ifqueue *inq;
register struct llc *l;
u_short etype;
struct arpcom *ac = (struct arpcom *)ifp;
int s;
if ((ifp->if_flags & IFF_UP) == 0) {
m_freem(m);
return;
}
ifp->if_lastchange = time;
ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
if (eh->ether_dhost[0] & 1) {
if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
sizeof(etherbroadcastaddr)) == 0)
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
}
if (eh->ether_dhost[0] & 1) {
if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
sizeof(etherbroadcastaddr)) == 0)
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
}
if (m->m_flags & (M_BCAST|M_MCAST))
ifp->if_imcasts++;
@ -313,11 +339,12 @@ ether_input(ifp, eh, m)
break;
case ETHERTYPE_ARP:
arpinput((struct arpcom *)ifp, m);
return;
schednetisr(NETISR_ARP);
inq = &arpintrq;
break;
case ETHERTYPE_REVARP:
revarpinput((struct arpcom *) ifp, m);
revarpinput(m); /* XXX queue? */
return;
#endif
#ifdef NS
@ -328,76 +355,107 @@ ether_input(ifp, eh, m)
#endif
default:
#ifdef ISO
if (etype > ETHERMTU)
#if defined (ISO) || defined (LLC)
if (eh->ether_type > ETHERMTU)
goto dropanyway;
l = mtod(m, struct llc *);
switch (l->llc_control) {
case LLC_UI:
/* LLC_UI_P forbidden in class 1 service */
if ((l->llc_dsap == LLC_ISO_LSAP) &&
(l->llc_ssap == LLC_ISO_LSAP)) {
/* LSAP for ISO */
if (m->m_pkthdr.len > etype)
m_adj(m, etype - m->m_pkthdr.len);
m->m_data += 3; /* XXX */
m->m_len -= 3; /* XXX */
m->m_pkthdr.len -= 3; /* XXX */
M_PREPEND(m, sizeof *eh, M_DONTWAIT);
switch (l->llc_dsap) {
#ifdef ISO
case LLC_ISO_LSAP:
switch (l->llc_control) {
case LLC_UI:
/* LLC_UI_P forbidden in class 1 service */
if ((l->llc_dsap == LLC_ISO_LSAP) &&
(l->llc_ssap == LLC_ISO_LSAP)) {
/* LSAP for ISO */
if (m->m_pkthdr.len > eh->ether_type)
m_adj(m, eh->ether_type - m->m_pkthdr.len);
m->m_data += 3; /* XXX */
m->m_len -= 3; /* XXX */
m->m_pkthdr.len -= 3; /* XXX */
M_PREPEND(m, sizeof *eh, M_DONTWAIT);
if (m == 0)
return;
*mtod(m, struct ether_header *) = *eh;
IFDEBUG(D_ETHER)
printf("clnp packet");
ENDDEBUG
schednetisr(NETISR_ISO);
inq = &clnlintrq;
break;
}
goto dropanyway;
case LLC_XID:
case LLC_XID_P:
if(m->m_len < 6)
goto dropanyway;
l->llc_window = 0;
l->llc_fid = 9;
l->llc_class = 1;
l->llc_dsap = l->llc_ssap = 0;
/* Fall through to */
case LLC_TEST:
case LLC_TEST_P:
{
struct sockaddr sa;
register struct ether_header *eh2;
int i;
u_char c = l->llc_dsap;
l->llc_dsap = l->llc_ssap;
l->llc_ssap = c;
if (m->m_flags & (M_BCAST | M_MCAST))
bcopy((caddr_t)ac->ac_enaddr,
(caddr_t)eh->ether_dhost, 6);
sa.sa_family = AF_UNSPEC;
sa.sa_len = sizeof(sa);
eh2 = (struct ether_header *)sa.sa_data;
for (i = 0; i < 6; i++) {
eh2->ether_shost[i] = c = eh->ether_dhost[i];
eh2->ether_dhost[i] =
eh->ether_dhost[i] = eh->ether_shost[i];
eh->ether_shost[i] = c;
}
ifp->if_output(ifp, m, &sa, NULL);
return;
}
default:
m_freem(m);
return;
}
break;
#endif /* ISO */
#ifdef LLC
case LLC_X25_LSAP:
{
if (m->m_pkthdr.len > eh->ether_type)
m_adj(m, eh->ether_type - m->m_pkthdr.len);
M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
if (m == 0)
return;
*mtod(m, struct ether_header *) = *eh;
IFDEBUG(D_ETHER)
printf("clnp packet");
ENDDEBUG
schednetisr(NETISR_ISO);
inq = &clnlintrq;
if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
eh->ether_dhost, LLC_X25_LSAP, 6,
mtod(m, struct sdl_hdr *)))
panic("ETHER cons addr failure");
mtod(m, struct sdl_hdr *)->sdlhdr_len = eh->ether_type;
#ifdef LLC_DEBUG
printf("llc packet\n");
#endif /* LLC_DEBUG */
schednetisr(NETISR_CCITT);
inq = &llcintrq;
break;
}
goto dropanyway;
case LLC_XID:
case LLC_XID_P:
if(m->m_len < 6)
goto dropanyway;
l->llc_window = 0;
l->llc_fid = 9;
l->llc_class = 1;
l->llc_dsap = l->llc_ssap = 0;
/* Fall through to */
case LLC_TEST:
case LLC_TEST_P:
{
struct sockaddr sa;
register struct ether_header *eh2;
int i;
u_char c = l->llc_dsap;
l->llc_dsap = l->llc_ssap;
l->llc_ssap = c;
if (m->m_flags & (M_BCAST | M_MCAST))
bcopy((caddr_t)ac->ac_enaddr,
(caddr_t)eh->ether_dhost, 6);
sa.sa_family = AF_UNSPEC;
sa.sa_len = sizeof(sa);
eh2 = (struct ether_header *)sa.sa_data;
for (i = 0; i < 6; i++) {
eh2->ether_shost[i] = c = eh->ether_dhost[i];
eh2->ether_dhost[i] =
eh->ether_dhost[i] = eh->ether_shost[i];
eh->ether_shost[i] = c;
}
ifp->if_output(ifp, m, &sa);
return;
}
#endif /* LLC */
dropanyway:
default:
m_freem(m);
return;
}
#else
m_freem(m);
return;
}
#else /* ISO || LLC */
m_freem(m);
return;
#endif ISO
#endif /* ISO || LLC */
}
s = splimp();
@ -429,12 +487,34 @@ ether_sprintf(ap)
*--cp = 0;
return (etherbuf);
}
/*
* Perform common duties while attaching to interface list
*/
void
ether_ifattach(ifp)
register struct ifnet *ifp;
{
register struct ifaddr *ifa;
register struct sockaddr_dl *sdl;
ifp->if_type = IFT_ETHER;
ifp->if_addrlen = 6;
ifp->if_hdrlen = 14;
ifp->if_mtu = ETHERMTU;
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
sdl->sdl_family == AF_LINK) {
sdl->sdl_type = IFT_ETHER;
sdl->sdl_alen = ifp->if_addrlen;
bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
LLADDR(sdl), ifp->if_addrlen);
break;
}
}
u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
/* XXX */
#undef ac
/*
* Add an Ethernet multicast address or range of addresses to the list for a
* given interface.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_llc.h 7.2 (Berkeley) 6/28/90
* $Id: if_llc.h,v 1.3 1993/05/20 03:06:00 cgd Exp $
* from: @(#)if_llc.h 8.1 (Berkeley) 6/10/93
* $Id: if_llc.h,v 1.4 1994/05/13 06:02:41 mycroft Exp $
*/
#ifndef _NET_IF_LLC_H_
#define _NET_IF_LLC_H_
/*
* IEEE 802.2 Link Level Control headers, for use in conjunction with
* 802.{3,4,5} media access control methods.
@ -63,26 +60,81 @@ struct llc {
u_char control;
u_char num_rcv_x2;
} type_s;
struct {
u_char control;
struct frmrinfo {
u_char rej_pdu_0;
u_char rej_pdu_1;
u_char frmr_control;
u_char frmr_control_ext;
u_char frmr_cause;
} frmrinfo;
} type_frmr;
struct {
u_char control;
u_char org_code[3];
u_short ether_type;
} type_snap;
struct {
u_char control;
u_char control_ext;
} type_raw;
} llc_un;
};
#define llc_control llc_un.type_u.control
#define llc_fid llc_un.type_u.format_id
#define llc_class llc_un.type_u.class
#define llc_window llc_un.type_u.window_x2
#define llc_control llc_un.type_u.control
#define llc_control_ext llc_un.type_raw.control_ext
#define llc_fid llc_un.type_u.format_id
#define llc_class llc_un.type_u.class
#define llc_window llc_un.type_u.window_x2
#define llc_frmrinfo llc_un.type_frmr.frmrinfo
#define llc_frmr_pdu0 llc_un.type_frmr.frmrinfo.rej_pdu0
#define llc_frmr_pdu1 llc_un.type_frmr.frmrinfo.rej_pdu1
#define llc_frmr_control llc_un.type_frmr.frmrinfo.frmr_control
#define llc_frmr_control_ext llc_un.type_frmr.frmrinfo.frmr_control_ext
#define llc_frmr_cause llc_un.type_frmr.frmrinfo.frmr_control_ext
/*
* Don't use sizeof(struct llc_un) for LLC header sizes
*/
#define LLC_ISFRAMELEN 4
#define LLC_UFRAMELEN 3
#define LLC_FRMRLEN 7
/*
* Unnumbered LLC format commands
*/
#define LLC_UI 0x3
#define LLC_UI_P 0x13
#define LLC_XID 0xaf
#define LLC_XID_P 0xbf
#define LLC_DISC 0x43
#define LLC_DISC_P 0x53
#define LLC_UA 0x63
#define LLC_UA_P 0x73
#define LLC_TEST 0xe3
#define LLC_TEST_P 0xf3
#define LLC_FRMR 0x87
#define LLC_FRMR_P 0x97
#define LLC_DM 0x0f
#define LLC_DM_P 0x1f
#define LLC_XID 0xaf
#define LLC_XID_P 0xbf
#define LLC_SABME 0x6f
#define LLC_SABME_P 0x7f
#define LLC_ISO_LSAP 0xfe
/*
* Supervisory LLC commands
*/
#define LLC_RR 0x01
#define LLC_RNR 0x05
#define LLC_REJ 0x09
/*
* Info format - dummy only
*/
#define LLC_INFO 0x00
/*
* ISO PDTR 10178 contains among others
*/
#define LLC_X25_LSAP 0x7e
#define LLC_SNAP_LSAP 0xaa
#endif /* !_NET_IF_LLC_H_ */
#define LLC_ISO_LSAP 0xfe

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_loop.c 7.13 (Berkeley) 4/26/91
* $Id: if_loop.c,v 1.10 1994/02/02 01:21:35 hpeyerl Exp $
* from: @(#)if_loop.c 8.1 (Berkeley) 6/10/93
* $Id: if_loop.c,v 1.11 1994/05/13 06:02:44 mycroft Exp $
*/
/*
@ -43,11 +43,14 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/protosw.h>
#include <sys/time.h>
#include <machine/cpu.h>
#include <net/if.h>
#include <net/if_types.h>
@ -72,31 +75,26 @@
#endif
#if NBPFILTER > 0
#include <sys/time.h>
#include <net/bpf.h>
static caddr_t lo_bpf;
#endif
#include <machine/cpu.h>
#define LOMTU (1024+512)
#define LOMTU (32768)
struct ifnet loif[NLOOP];
int looutput(), loioctl();
void
loopattach()
loopattach(n)
int n;
{
register int i;
register struct ifnet *ifp;
for (i = 0; i < NLOOP; i++)
{
for (i = 0; i < NLOOP; i++) {
ifp = &loif[i];
ifp->if_unit = i;
ifp->if_name = "lo";
ifp->if_mtu = LOMTU;
ifp->if_flags = IFF_LOOPBACK|IFF_MULTICAST;
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
ifp->if_ioctl = loioctl;
ifp->if_output = looutput;
ifp->if_type = IFT_LOOP;
@ -104,11 +102,12 @@ loopattach()
ifp->if_addrlen = 0;
if_attach(ifp);
#if NBPFILTER > 0
bpfattach(&lo_bpf, ifp, DLT_NULL, sizeof(u_int));
bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));
#endif
}
}
int
looutput(ifp, m, dst, rt)
struct ifnet *ifp;
register struct mbuf *m;
@ -120,8 +119,9 @@ looutput(ifp, m, dst, rt)
if ((m->m_flags & M_PKTHDR) == 0)
panic("looutput no HDR");
ifp->if_lastchange = time;
#if NBPFILTER > 0
if (lo_bpf) {
if (ifp->if_bpf) {
/*
* We need to prepend the address family as
* a four byte field. Cons up a dummy header
@ -136,14 +136,15 @@ looutput(ifp, m, dst, rt)
m0.m_len = 4;
m0.m_data = (char *)&af;
bpf_mtap(lo_bpf, &m0);
bpf_mtap(ifp->if_bpf, &m0);
}
#endif
m->m_pkthdr.rcvif = ifp;
if (rt && rt->rt_flags & RTF_REJECT) {
if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
m_freem(m);
return (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
}
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
@ -189,10 +190,13 @@ looutput(ifp, m, dst, rt)
}
/* ARGSUSED */
void
lortrequest(cmd, rt, sa)
struct rtentry *rt;
struct sockaddr *sa;
int cmd;
struct rtentry *rt;
struct sockaddr *sa;
{
if (rt)
rt->rt_rmx.rmx_mtu = LOMTU;
}
@ -201,6 +205,7 @@ struct sockaddr *sa;
* Process an ioctl request.
*/
/* ARGSUSED */
int
loioctl(ifp, cmd, data)
register struct ifnet *ifp;
int cmd;
@ -208,7 +213,7 @@ loioctl(ifp, cmd, data)
{
register struct ifaddr *ifa;
register struct ifreq *ifr;
int error = 0;
register int error = 0;
switch (cmd) {
@ -235,11 +240,13 @@ loioctl(ifp, cmd, data)
case AF_INET:
break;
#endif
default:
error = EAFNOSUPPORT;
break;
}
break;
default:
error = EINVAL;
}