mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-25 03:05:08 +00:00
Add BPF and IP multicast capabilities to the tun' and
lp' network
interfaces. Submitted by: Bill Fenner <fenner@parc.xerox.com>
This commit is contained in:
parent
99171ec4ca
commit
e508a00419
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11004
|
@ -46,7 +46,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: unknown origin, 386BSD 0.1
|
||||
* $Id: lpt.c,v 1.33 1995/07/16 10:12:04 bde Exp $
|
||||
* $Id: lpt.c,v 1.34 1995/09/08 11:07:45 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -131,6 +131,11 @@
|
|||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#include "bpfilter.h"
|
||||
#if NBPFILTER > 0
|
||||
#include <net/bpf.h>
|
||||
#include <net/bpfdesc.h>
|
||||
#endif
|
||||
#endif /* INET */
|
||||
|
||||
#define LPINITRDY 4 /* wait up to 4 seconds for a ready */
|
||||
|
@ -824,7 +829,7 @@ lpattach (struct lpt_softc *sc, int unit)
|
|||
ifp->if_name = "lp";
|
||||
ifp->if_unit = unit;
|
||||
ifp->if_mtu = LPMTU;
|
||||
ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT;
|
||||
ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
|
||||
ifp->if_ioctl = lpioctl;
|
||||
ifp->if_output = lpoutput;
|
||||
ifp->if_type = IFT_PARA;
|
||||
|
@ -833,6 +838,10 @@ lpattach (struct lpt_softc *sc, int unit)
|
|||
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
|
||||
if_attach(ifp);
|
||||
printf("lp%d: TCP/IP capable interface\n", unit);
|
||||
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&ifp->if_bpf, ifp, DLT_NULL, LPIPHDRLEN);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Build the translation tables for the LPIP (BSD unix) protocol.
|
||||
|
@ -917,6 +926,23 @@ lpioctl (struct ifnet *ifp, int cmd, caddr_t data)
|
|||
ifr->ifr_mtu = sc->sc_if.if_mtu;
|
||||
break;
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
if (ifr == 0) {
|
||||
return EAFNOSUPPORT; /* XXX */
|
||||
}
|
||||
switch (ifr->ifr_addr.sa_family) {
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return EAFNOSUPPORT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
lprintf("LP:ioctl(0x%x)\n",cmd);
|
||||
return EINVAL;
|
||||
|
@ -977,6 +1003,11 @@ lpintr (int unit)
|
|||
IF_DROP(&ipintrq);
|
||||
goto done;
|
||||
}
|
||||
#if NBPFILTER > 0
|
||||
if (sc->sc_if.if_bpf) {
|
||||
bpf_tap(sc->sc_if.if_bpf, sc->sc_ifbuf, len);
|
||||
}
|
||||
#endif
|
||||
len -= LPIPHDRLEN;
|
||||
sc->sc_if.if_ipackets++;
|
||||
sc->sc_if.if_ibytes += len;
|
||||
|
@ -1078,6 +1109,25 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
|
|||
} else {
|
||||
ifp->if_opackets++;
|
||||
ifp->if_obytes += m->m_pkthdr.len;
|
||||
#if NBPFILTER > 0
|
||||
if (ifp->if_bpf) {
|
||||
/*
|
||||
* We need to prepend the packet type as
|
||||
* a two byte field. Cons up a dummy header
|
||||
* to pacify bpf. This is safe because bpf
|
||||
* will only read from the mbuf (i.e., it won't
|
||||
* try to free it or keep a pointer to it).
|
||||
*/
|
||||
struct mbuf m0;
|
||||
u_short hdr = 0x800;
|
||||
|
||||
m0.m_next = m;
|
||||
m0.m_len = 2;
|
||||
m0.m_data = (char *)&hdr;
|
||||
|
||||
bpf_mtap(ifp->if_bpf, &m0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
m_freem(m);
|
||||
|
|
|
@ -112,7 +112,7 @@ tunattach(udata)
|
|||
ifp->if_mtu = TUNMTU;
|
||||
ifp->if_ioctl = tunifioctl;
|
||||
ifp->if_output = tunoutput;
|
||||
ifp->if_flags = IFF_POINTOPOINT;
|
||||
ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
ifp->if_collisions = 0;
|
||||
ifp->if_ierrors = 0;
|
||||
|
@ -238,6 +238,7 @@ tunifioctl(ifp, cmd, data)
|
|||
int cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
register struct ifreq *ifr = (struct ifreq *)data;
|
||||
struct tun_softc *tp = &tunctl[ifp->if_unit];
|
||||
int error = 0, s;
|
||||
|
||||
|
@ -253,6 +254,26 @@ tunifioctl(ifp, cmd, data)
|
|||
TUNDEBUG("%s%d: destination address set\n",
|
||||
ifp->if_name, ifp->if_unit);
|
||||
break;
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
if (ifr == 0) {
|
||||
error = EAFNOSUPPORT; /* XXX */
|
||||
break;
|
||||
}
|
||||
switch (ifr->ifr_addr.sa_family) {
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
error = EAFNOSUPPORT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
|
@ -284,6 +305,14 @@ tunoutput(ifp, m0, dst, rt)
|
|||
}
|
||||
|
||||
#if NBPFILTER > 0
|
||||
/* BPF write needs to be handled specially */
|
||||
if (dst->sa_family == AF_UNSPEC) {
|
||||
dst->sa_family = *(mtod(m0, int *));
|
||||
m0->m_len -= sizeof(int);
|
||||
m0->m_pkthdr.len -= sizeof(int);
|
||||
m0->m_data += sizeof(int);
|
||||
}
|
||||
|
||||
if (tp->tun_bpf) {
|
||||
/*
|
||||
* We need to prepend the address family as
|
||||
|
|
Loading…
Reference in a new issue