in the driver's softc
bpf_devp is gone; instead we have an ioctl to get the link type
bpf_mtap now just passes mbuf to filter -- no pull up
SCCS-vsn: sys/net/bpf.c 1.4
int bpf_bufsize = MCLBYTES;
/*
int bpf_bufsize = MCLBYTES;
/*
- * 'bpf_iftab' is the driver state table per logical unit number
- * 'bpf_dtab' holds the descriptors, indexed by minor device #
- * 'bpf_units' is the number of attached units
+ * bpf_iflist is the list of interfaces; each corresponds to an ifnet
+ * bpf_dtab holds the descriptors, indexed by minor device #
*
* We really don't need NBPFILTER bpf_if entries, but this eliminates
* the need to account for all possible drivers here.
* This problem will go away when these structures are allocated dynamically.
*/
*
* We really don't need NBPFILTER bpf_if entries, but this eliminates
* the need to account for all possible drivers here.
* This problem will go away when these structures are allocated dynamically.
*/
-static struct bpf_if bpf_iftab[NBPFILTER];
+static struct bpf_if *bpf_iflist;
static struct bpf_d bpf_dtab[NBPFILTER];
static struct bpf_d bpf_dtab[NBPFILTER];
-static u_int bpf_units = 0;
static void bpf_ifname();
static void catchpacket();
static void bpf_ifname();
static void catchpacket();
* as kernel buffers.
*/
if (uio->uio_resid != d->bd_bufsize)
* as kernel buffers.
*/
if (uio->uio_resid != d->bd_bufsize)
if (uio->uio_resid > ifp->if_mtu)
return (EMSGSIZE);
if (uio->uio_resid > ifp->if_mtu)
return (EMSGSIZE);
- error = bpf_movein(uio, (int)d->bd_bif->bif_devp.bdev_type, &m, &dst);
+ error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst);
if (error)
return (error);
if (error)
return (error);
- * bpfioctl - packet filter control
- *
* FIONREAD Check for read packet available.
* SIOCGIFADDR Get interface address - convenient hook to driver.
* BIOCGFLEN Get max filter len.
* FIONREAD Check for read packet available.
* SIOCGIFADDR Get interface address - convenient hook to driver.
* BIOCGFLEN Get max filter len.
* BIOCSETF Set ethernet read filter.
* BIOCFLUSH Flush read packet buffer.
* BIOCPROMISC Put interface into promiscuous mode.
* BIOCSETF Set ethernet read filter.
* BIOCFLUSH Flush read packet buffer.
* BIOCPROMISC Put interface into promiscuous mode.
- * BIOCDEVP Get device parameters.
+ * BIOCGDLT Get link layer type.
* BIOCGETIF Get interface name.
* BIOCSETIF Set interface.
* BIOCSRTIMEOUT Set read timeout.
* BIOCGETIF Get interface name.
* BIOCSETIF Set interface.
* BIOCSRTIMEOUT Set read timeout.
/*
* Get device parameters.
*/
/*
* Get device parameters.
*/
if (d->bd_bif == 0)
error = EINVAL;
else
if (d->bd_bif == 0)
error = EINVAL;
else
- *(struct bpf_devp *)addr = d->bd_bif->bif_devp;
+ *(u_int *)addr = d->bd_bif->bif_dlt;
{
struct bpf_if *bp;
char *cp;
{
struct bpf_if *bp;
char *cp;
/*
* Separate string into name part and unit number. Put a null
/*
* Separate string into name part and unit number. Put a null
/*
* Look through attached interfaces for the named one.
*/
/*
* Look through attached interfaces for the named one.
*/
- bp = bpf_iftab;
- for (i = 0; i < NBPFILTER; ++bp, ++i) {
+ for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
struct ifnet *ifp = bp->bif_ifp;
if (ifp == 0 || unit != ifp->if_unit
struct ifnet *ifp = bp->bif_ifp;
if (ifp == 0 || unit != ifp->if_unit
struct bpf_if *bp;
register struct bpf_d *d;
register u_int slen;
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
/*
* 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
bp = (struct bpf_if *)arg;
for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
++d->bd_rcount;
bp = (struct bpf_if *)arg;
for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
++d->bd_rcount;
- if (d->bd_filter)
- slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
- else
- slen = (u_int)-1;
-
+ if (d->bd_filter == 0) {
+ catchpacket(d, pkt, pktlen, (u_int)-1, bcopy);
+ continue;
+ }
+ slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
- catchpacket(d, pkt, pktlen, slen, (void (*)())bcopy);
+ catchpacket(d, pkt, pktlen, slen, bcopy);
* from m_copydata in sys/uipc_mbuf.c.
*/
static void
* from m_copydata in sys/uipc_mbuf.c.
*/
static void
-bpf_m_copydata(src, dst, len)
+bpf_mcopy(src, dst, len)
u_char *src;
u_char *dst;
register int len;
u_char *src;
u_char *dst;
register int len;
while (len > 0) {
if (m == 0)
while (len > 0) {
if (m == 0)
- panic("bpf_m_copydata");
count = MIN(m->m_len, len);
count = MIN(m->m_len, len);
- (void)bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
- len -= count;
- dst += count;
+ bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
+ dst += count;
+ len -= count;
* is in an mbuf chain
*/
void
* is in an mbuf chain
*/
void
{
struct bpf_if *bp = (struct bpf_if *)arg;
struct bpf_d *d;
{
struct bpf_if *bp = (struct bpf_if *)arg;
struct bpf_d *d;
+ u_int pktlen, slen;
+ struct mbuf *m0;
+#ifdef notdef
static u_char buf[BPF_MIN_SNAPLEN];
static u_char buf[BPF_MIN_SNAPLEN];
- if (m0->m_len >= BPF_MIN_SNAPLEN) {
- slen = m0->m_len;
- cp = mtod(m0, u_char *);
+ if (m->m_len >= BPF_MIN_SNAPLEN) {
+ slen = m->m_len;
+ cp = mtod(m, u_char *);
}
else {
nbytes = BPF_MIN_SNAPLEN;
cp = buf;
}
else {
nbytes = BPF_MIN_SNAPLEN;
cp = buf;
- m = m0;
- while (m && nbytes > 0) {
- slen = MIN(m->m_len, nbytes);
- bcopy(mtod(m, char *), (char *)cp, slen);
+ m0 = m;
+ while (m0 && nbytes > 0) {
+ slen = MIN(m0->m_len, nbytes);
+ bcopy(mtod(m0, char *), (char *)cp, slen);
cp += slen;
nbytes -= slen;
cp += slen;
nbytes -= slen;
}
if (nbytes > 0)
/* Packet too small? */
}
if (nbytes > 0)
/* Packet too small? */
slen = BPF_MIN_SNAPLEN;
cp = buf;
}
slen = BPF_MIN_SNAPLEN;
cp = buf;
}
- m = m0;
- while (m) {
- pktlen += m->m_len;
- m = m->m_next;
+ m0 = m;
+ while (m0) {
+ pktlen += m0->m_len;
+ m0 = m0->m_next;
}
for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
++d->bd_rcount;
}
for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
++d->bd_rcount;
- if (d->bd_filter)
- slen = bpf_filter(d->bd_filter, cp, pktlen, slen);
- else
- slen = (u_int)-1;
+ if (d->bd_filter == 0) {
+ catchpacket(d, (u_char *)m, pktlen, (u_int)-1,
+ bpf_mcopy);
+ continue;
+ }
+ slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
- catchpacket(d, (u_char *)m0, pktlen, slen,
- bpf_m_copydata);
+ catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
- * Move the packet data from interface memory ('pkt') into the
+ * Move the packet data from interface memory (pkt) into the
* store buffer. Return 1 if it's time to wakeup a listener (buffer full),
* otherwise 0. 'copy' is the routine called to do the actual data
* transfer. 'bcopy' is passed in to copy contiguous chunks, while
* store buffer. Return 1 if it's time to wakeup a listener (buffer full),
* otherwise 0. 'copy' is the routine called to do the actual data
* transfer. 'bcopy' is passed in to copy contiguous chunks, while
- * 'bpf_m_copydata' is passed in to copy mbuf chains. In the latter
+ * 'bpf_mcopy' is passed in to copy mbuf chains. In the latter
* case, 'pkt' is really an mbuf.
*/
static void
* case, 'pkt' is really an mbuf.
*/
static void
- * Register 'ifp' with bpf. 'devp' is the link-level device descriptor
+ * Register 'ifp' with bpf. XXX
* and 'driverp' is a pointer to the 'struct bpf_if *' in the driver's softc.
*/
void
* and 'driverp' is a pointer to the 'struct bpf_if *' in the driver's softc.
*/
void
-bpfattach(driverp, ifp, devp)
+bpfattach(driverp, ifp, dlt, hdrlen)
caddr_t *driverp;
struct ifnet *ifp;
caddr_t *driverp;
struct ifnet *ifp;
{
struct bpf_if *bp;
int i;
{
struct bpf_if *bp;
int i;
- if (bpf_units >= NBPFILTER) {
- printf("bpf: too many interfaces: %s%d not attached\n",
- ifp->if_name, ifp->if_unit);
- return;
- }
- bp = &bpf_iftab[bpf_units++];
+ bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
+ if (bp == 0)
+ panic("bpfattach");
bp->bif_dlist = 0;
bp->bif_driverp = (struct bpf_if **)driverp;
bp->bif_ifp = ifp;
bp->bif_dlist = 0;
bp->bif_driverp = (struct bpf_if **)driverp;
bp->bif_ifp = ifp;
+ bp->bif_dlt = dlt;
+
+ bp->bif_next = bpf_iflist;
+ bpf_iflist = bp;
* that the network layer header begins on a longword boundary (for
* performance reasons and to alleviate alignment restrictions).
*/
* that the network layer header begins on a longword boundary (for
* performance reasons and to alleviate alignment restrictions).
*/
- i = devp->bdev_hdrlen;
- bp->bif_hdrlen = BPF_WORDALIGN(i + SIZEOF_BPF_HDR) - i;
+ bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
/*
* Mark all the descriptors free if this hasn't been done.
/*
* Mark all the descriptors free if this hasn't been done.