bpf: add BIOCGETIFLIST ioctl that returns all available tap points
Differential Revision: https://reviews.freebsd.org/D53873
This commit is contained in:
+26
-1
@@ -47,7 +47,7 @@
|
|||||||
.\" This document is derived in part from the enet man page (enet.4)
|
.\" This document is derived in part from the enet man page (enet.4)
|
||||||
.\" distributed with 4.3BSD Unix.
|
.\" distributed with 4.3BSD Unix.
|
||||||
.\"
|
.\"
|
||||||
.Dd October 13, 2021
|
.Dd December 10, 2025
|
||||||
.Dt BPF 4
|
.Dt BPF 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -276,6 +276,31 @@ The (third) argument to
|
|||||||
.Xr ioctl 2
|
.Xr ioctl 2
|
||||||
should be a pointer to the type indicated.
|
should be a pointer to the type indicated.
|
||||||
.Bl -tag -width BIOCGETBUFMODE
|
.Bl -tag -width BIOCGETBUFMODE
|
||||||
|
.It Dv BIOCGETIFLIST
|
||||||
|
.Pq Li "struct bpf_iflist"
|
||||||
|
Returns list of available tapping points, that can later be attached
|
||||||
|
to with
|
||||||
|
.Dv BIOCSETIF .
|
||||||
|
On entry the
|
||||||
|
.Vt bi_ubuf
|
||||||
|
shall point to user supplied buffer.
|
||||||
|
The
|
||||||
|
.Vt bi_size
|
||||||
|
shall specify length of the buffer, or 0 if the request is used
|
||||||
|
to determine the required length.
|
||||||
|
The
|
||||||
|
.Vt bi_count
|
||||||
|
can be used to limit the output to first
|
||||||
|
.Va count
|
||||||
|
entries, otherwise shall be 0.
|
||||||
|
On return, if the buffer length was enough to accomodate all desired entries,
|
||||||
|
then the supplied buffer is filled with NUL-terminated names of
|
||||||
|
available tapping points and
|
||||||
|
.Vt bi_count
|
||||||
|
is set to the number of copied names.
|
||||||
|
Otherwise
|
||||||
|
.Er ENOSPC
|
||||||
|
is returned.
|
||||||
.It Dv BIOCGBLEN
|
.It Dv BIOCGBLEN
|
||||||
.Pq Li u_int
|
.Pq Li u_int
|
||||||
Returns the required buffer length for reads on
|
Returns the required buffer length for reads on
|
||||||
|
|||||||
+63
-2
@@ -221,8 +221,7 @@ struct bpf_dltlist32 {
|
|||||||
* structures registered by different layers in the stack (i.e., 802.11
|
* structures registered by different layers in the stack (i.e., 802.11
|
||||||
* frames, ethernet frames, etc).
|
* frames, ethernet frames, etc).
|
||||||
*/
|
*/
|
||||||
LIST_HEAD(bpf_iflist, bpf_if);
|
static LIST_HEAD(, bpf_if) bpf_iflist = LIST_HEAD_INITIALIZER();
|
||||||
static struct bpf_iflist bpf_iflist = LIST_HEAD_INITIALIZER();
|
|
||||||
static struct sx bpf_sx; /* bpf global lock */
|
static struct sx bpf_sx; /* bpf global lock */
|
||||||
|
|
||||||
static void bpfif_ref(struct bpf_if *);
|
static void bpfif_ref(struct bpf_if *);
|
||||||
@@ -240,6 +239,7 @@ static void catchpacket(struct bpf_d *, u_char *, u_int, u_int,
|
|||||||
void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int),
|
void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int),
|
||||||
struct bintime *);
|
struct bintime *);
|
||||||
static void reset_d(struct bpf_d *);
|
static void reset_d(struct bpf_d *);
|
||||||
|
static int bpf_getiflist(struct bpf_iflist *);
|
||||||
static int bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd);
|
static int bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd);
|
||||||
static int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
|
static int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
|
||||||
static int bpf_setdlt(struct bpf_d *, u_int);
|
static int bpf_setdlt(struct bpf_d *, u_int);
|
||||||
@@ -1100,6 +1100,7 @@ reset_d(struct bpf_d *d)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* FIONREAD Check for read packet available.
|
* FIONREAD Check for read packet available.
|
||||||
|
* BIOCGETIFLIST Get list of all tap points.
|
||||||
* BIOCGBLEN Get buffer len [for read()].
|
* BIOCGBLEN Get buffer len [for read()].
|
||||||
* BIOCSETF Set read filter.
|
* BIOCSETF Set read filter.
|
||||||
* BIOCSETFNR Set read filter without resetting descriptor.
|
* BIOCSETFNR Set read filter without resetting descriptor.
|
||||||
@@ -1153,6 +1154,7 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
|
|||||||
|
|
||||||
if (d->bd_flags & BPFD_LOCKED) {
|
if (d->bd_flags & BPFD_LOCKED) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case BIOCGETIFLIST:
|
||||||
case BIOCGBLEN:
|
case BIOCGBLEN:
|
||||||
case BIOCFLUSH:
|
case BIOCFLUSH:
|
||||||
case BIOCGDLT:
|
case BIOCGDLT:
|
||||||
@@ -1230,6 +1232,12 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
|
|||||||
*(int *)addr = n;
|
*(int *)addr = n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Get list of all tap points.
|
||||||
|
*/
|
||||||
|
case BIOCGETIFLIST:
|
||||||
|
error = bpf_getiflist((struct bpf_iflist *)addr);
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get buffer len [for read()].
|
* Get buffer len [for read()].
|
||||||
@@ -1706,6 +1714,59 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return list of available tapping points, or report how much space is
|
||||||
|
* required for a successful return.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
bpf_getiflist(struct bpf_iflist *bi)
|
||||||
|
{
|
||||||
|
struct bpf_if *bp;
|
||||||
|
u_int allsize, size, cnt;
|
||||||
|
char *uaddr;
|
||||||
|
|
||||||
|
BPF_LOCK();
|
||||||
|
|
||||||
|
cnt = allsize = size = 0;
|
||||||
|
LIST_FOREACH(bp, &bpf_iflist, bif_next) {
|
||||||
|
allsize += strlen(bp->bif_name) + 1;
|
||||||
|
if (++cnt == bi->bi_count)
|
||||||
|
size = allsize;
|
||||||
|
}
|
||||||
|
if (size == 0)
|
||||||
|
size = allsize;
|
||||||
|
|
||||||
|
if (bi->bi_size == 0) {
|
||||||
|
BPF_UNLOCK();
|
||||||
|
bi->bi_size = size;
|
||||||
|
bi->bi_count = cnt;
|
||||||
|
return (0);
|
||||||
|
} else if (bi->bi_size < size) {
|
||||||
|
BPF_UNLOCK();
|
||||||
|
return (ENOSPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
uaddr = bi->bi_ubuf;
|
||||||
|
cnt = 0;
|
||||||
|
LIST_FOREACH(bp, &bpf_iflist, bif_next) {
|
||||||
|
u_int len;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
len = strlen(bp->bif_name) + 1;
|
||||||
|
if ((error = copyout(bp->bif_name, uaddr, len)) != 0) {
|
||||||
|
BPF_UNLOCK();
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
if (++cnt == bi->bi_count)
|
||||||
|
break;
|
||||||
|
uaddr += len;
|
||||||
|
}
|
||||||
|
BPF_UNLOCK();
|
||||||
|
bi->bi_count = cnt;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set d's packet filter program to fp. If this file already has a filter,
|
* 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.
|
* free it and replace it. Returns EINVAL for bogus requests.
|
||||||
|
|||||||
@@ -118,6 +118,15 @@ struct bpf_zbuf {
|
|||||||
size_t bz_buflen; /* Size of zero-copy buffers. */
|
size_t bz_buflen; /* Size of zero-copy buffers. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Struct used by BIOCGETIFLIST.
|
||||||
|
*/
|
||||||
|
struct bpf_iflist {
|
||||||
|
u_int bi_size;
|
||||||
|
u_int bi_count;
|
||||||
|
void *bi_ubuf;
|
||||||
|
};
|
||||||
|
|
||||||
#define BIOCGBLEN _IOR('B', 102, u_int)
|
#define BIOCGBLEN _IOR('B', 102, u_int)
|
||||||
#define BIOCSBLEN _IOWR('B', 102, u_int)
|
#define BIOCSBLEN _IOWR('B', 102, u_int)
|
||||||
#define BIOCSETF _IOW('B', 103, struct bpf_program)
|
#define BIOCSETF _IOW('B', 103, struct bpf_program)
|
||||||
@@ -151,6 +160,7 @@ struct bpf_zbuf {
|
|||||||
#define BIOCGTSTAMP _IOR('B', 131, u_int)
|
#define BIOCGTSTAMP _IOR('B', 131, u_int)
|
||||||
#define BIOCSTSTAMP _IOW('B', 132, u_int)
|
#define BIOCSTSTAMP _IOW('B', 132, u_int)
|
||||||
#define BIOCSETVLANPCP _IOW('B', 133, u_int)
|
#define BIOCSETVLANPCP _IOW('B', 133, u_int)
|
||||||
|
#define BIOCGETIFLIST _IOWR('B', 134, struct bpf_iflist)
|
||||||
|
|
||||||
/* Obsolete */
|
/* Obsolete */
|
||||||
#define BIOCGSEESENT BIOCGDIRECTION
|
#define BIOCGSEESENT BIOCGDIRECTION
|
||||||
|
|||||||
+1
-1
@@ -74,7 +74,7 @@
|
|||||||
* cannot include sys/param.h and should only be updated here.
|
* cannot include sys/param.h and should only be updated here.
|
||||||
*/
|
*/
|
||||||
#undef __FreeBSD_version
|
#undef __FreeBSD_version
|
||||||
#define __FreeBSD_version 1600005
|
#define __FreeBSD_version 1600006
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||||
|
|||||||
Reference in New Issue
Block a user