-/* $OpenBSD: bpf.c,v 1.165 2017/12/30 23:08:29 guenther Exp $ */
+/* $OpenBSD: bpf.c,v 1.166 2018/01/24 00:25:17 dlg Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/*
LIST_HEAD(, bpf_d) bpf_d_list;
int bpf_allocbufs(struct bpf_d *);
-void bpf_ifname(struct ifnet *, struct ifreq *);
+void bpf_ifname(struct bpf_if*, struct ifreq *);
int _bpf_mtap(caddr_t, const struct mbuf *, u_int,
void (*)(const void *, void *, size_t));
void bpf_mcopy(const void *, void *, size_t);
if (d->bd_promisc) {
int error;
+ KASSERT(bp->bif_ifp != NULL);
+
d->bd_promisc = 0;
bpf_get(d);
bpf_get(d);
ifp = d->bd_bif->bif_ifp;
- if ((ifp->if_flags & IFF_UP) == 0) {
+ if (ifp == NULL || (ifp->if_flags & IFF_UP) == 0) {
error = ENETDOWN;
goto out;
}
* No interface attached yet.
*/
error = EINVAL;
- } else {
+ } else if (d->bd_bif->bif_ifp != NULL) {
if (d->bd_promisc == 0) {
MUTEX_ASSERT_UNLOCKED(&d->bd_mtx);
error = ifpromisc(d->bd_bif->bif_ifp, 1);
if (d->bd_bif == NULL)
error = EINVAL;
else
- bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
+ bpf_ifname(d->bd_bif, (struct ifreq *)addr);
break;
/*
* Look through attached interfaces for the named one.
*/
for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
- struct ifnet *ifp = bp->bif_ifp;
-
- if (ifp == NULL ||
- strcmp(ifp->if_xname, ifr->ifr_name) != 0)
+ if (strcmp(bp->bif_name, ifr->ifr_name) != 0)
continue;
if (candidate == NULL || candidate->bif_dlt > bp->bif_dlt)
* Copy the interface name to the ifreq.
*/
void
-bpf_ifname(struct ifnet *ifp, struct ifreq *ifr)
+bpf_ifname(struct bpf_if *bif, struct ifreq *ifr)
{
- bcopy(ifp->if_xname, ifr->ifr_name, IFNAMSIZ);
+ bcopy(bif->bif_name, ifr->ifr_name, sizeof(ifr->ifr_name));
}
/*
free(bd, M_DEVBUF, sizeof(*bd));
}
-/*
- * Attach an interface to bpf. driverp is a pointer to a (struct bpf_if *)
- * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
- * size of the link header (variable length headers not yet supported).
- */
-void
-bpfattach(caddr_t *driverp, struct ifnet *ifp, u_int dlt, u_int hdrlen)
+void *
+bpfsattach(caddr_t *bpfp, const char *name, u_int dlt, u_int hdrlen)
{
struct bpf_if *bp;
if ((bp = malloc(sizeof(*bp), M_DEVBUF, M_NOWAIT)) == NULL)
panic("bpfattach");
SRPL_INIT(&bp->bif_dlist);
- bp->bif_driverp = (struct bpf_if **)driverp;
- bp->bif_ifp = ifp;
+ bp->bif_driverp = (struct bpf_if **)bpfp;
+ bp->bif_name = name;
+ bp->bif_ifp = NULL;
bp->bif_dlt = dlt;
bp->bif_next = bpf_iflist;
* performance reasons and to alleviate alignment restrictions).
*/
bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
+
+ return (bp);
+}
+
+void
+bpfattach(caddr_t *driverp, struct ifnet *ifp, u_int dlt, u_int hdrlen)
+{
+ struct bpf_if *bp;
+
+ bp = bpfsattach(driverp, ifp->if_xname, dlt, hdrlen);
+ bp->bif_ifp = ifp;
}
/* Detach an interface from its attached bpf device. */
bpfdetach(struct ifnet *ifp)
{
struct bpf_if *bp, *nbp, **pbp = &bpf_iflist;
- struct bpf_d *bd;
- int maj;
KERNEL_ASSERT_LOCKED();
for (bp = bpf_iflist; bp; bp = nbp) {
- nbp= bp->bif_next;
+ nbp = bp->bif_next;
if (bp->bif_ifp == ifp) {
*pbp = nbp;
- /* Locate the major number. */
- for (maj = 0; maj < nchrdev; maj++)
- if (cdevsw[maj].d_open == bpfopen)
- break;
-
- while ((bd = SRPL_FIRST_LOCKED(&bp->bif_dlist)))
- vdevgone(maj, bd->bd_unit, bd->bd_unit, VCHR);
-
- free(bp, M_DEVBUF, sizeof *bp);
+ bpfsdetach(bp);
} else
pbp = &bp->bif_next;
}
ifp->if_bpf = NULL;
}
+void
+bpfsdetach(void *p)
+{
+ struct bpf_if *bp = p;
+ struct bpf_d *bd;
+ int maj;
+
+ /* Locate the major number. */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == bpfopen)
+ break;
+
+ while ((bd = SRPL_FIRST_LOCKED(&bp->bif_dlist)))
+ vdevgone(maj, bd->bd_unit, bd->bd_unit, VCHR);
+
+ free(bp, M_DEVBUF, sizeof *bp);
+}
+
int
bpf_sysctl_locked(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen)
bpf_getdltlist(struct bpf_d *d, struct bpf_dltlist *bfl)
{
int n, error;
- struct ifnet *ifp;
struct bpf_if *bp;
+ const char *name;
- ifp = d->bd_bif->bif_ifp;
+ name = d->bd_bif->bif_name;
n = 0;
error = 0;
for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
- if (bp->bif_ifp != ifp)
+ if (strcmp(name, bp->bif_name) != 0)
continue;
if (bfl->bfl_list != NULL) {
if (n >= bfl->bfl_len)
int
bpf_setdlt(struct bpf_d *d, u_int dlt)
{
- struct ifnet *ifp;
+ const char *name;
struct bpf_if *bp;
MUTEX_ASSERT_LOCKED(&d->bd_mtx);
if (d->bd_bif->bif_dlt == dlt)
return (0);
- ifp = d->bd_bif->bif_ifp;
+ name = d->bd_bif->bif_name;
for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
- if (bp->bif_ifp == ifp && bp->bif_dlt == dlt)
+ if (strcmp(name, bp->bif_name) != 0)
+ continue;
+ if (bp->bif_dlt == dlt)
break;
}
if (bp == NULL)