Update to 4.4-Lite networking code, with a few local changes.
This commit is contained in:
parent
9d020030ac
commit
d361acde18
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = ⊤
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
569
sys/net/bpf.c
569
sys/net/bpf.c
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
177
sys/net/if.c
177
sys/net/if.c
|
@ -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++;
|
||||
|
|
214
sys/net/if.h
214
sys/net/if.h
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *)⁡
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue