summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-01-07 16:28:39 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-01-07 16:28:39 +0000
commit682952bd0cc8980caff3a517215b6bff24209daa (patch)
tree1338aa52aa3868ea1654066cbaaf2d7513c1ab85
parent5cd782835d8ea66f755f3c21fc2b137ef1fb7330 (diff)
add support for BIOCGDLTLIST and BIOCSDLT, see bpf(4)
ok canacar@, fgsch@, tested by some other people
-rw-r--r--share/man/man4/bpf.440
-rw-r--r--sys/net/bpf.c85
-rw-r--r--sys/net/bpf.h13
-rw-r--r--sys/net80211/ieee80211_radiotap.h7
4 files changed, 136 insertions, 9 deletions
diff --git a/share/man/man4/bpf.4 b/share/man/man4/bpf.4
index 59caba0ac2a..348ec0d7ea2 100644
--- a/share/man/man4/bpf.4
+++ b/share/man/man4/bpf.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bpf.4,v 1.22 2004/05/31 17:06:37 canacar Exp $
+.\" $OpenBSD: bpf.4,v 1.23 2005/01/07 16:28:38 reyk Exp $
.\" $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $
.\"
.\" Copyright (c) 1990 The Regents of the University of California.
@@ -146,6 +146,44 @@ The device types, prefixed with
.Dq DLT_ ,
are defined in
.Aq Pa net/bpf.h .
+.It Dv BIOCGDLTLIST (struct bpf_dltlist)
+Returns an array of the available types of the data link layer
+underlying the attached interface:
+.Bd -literal -offset indent
+struct bpf_dltlist {
+ u_int bfl_len;
+ u_int *bfl_list;
+};
+.Ed
+.Pp
+The available types are returned in the array pointed to by the
+.Va bfl_list
+field while their length in
+.Vt u_int
+is supplied to the
+.Va bfl_len
+field.
+.Er ENOMEM
+is returned if there is not enough buffer space and
+.Er EFAULT
+is returned if a bad address is encountered. The
+.Va bfl_len
+field is modified on return to indicate the actual length in
+.Vt u_int
+of the array returned.
+If
+.Va bfl_list
+is
+.Dv NULL ,
+the
+.Va bfl_len
+field is set to indicate the required length of the array in
+.Vt u_int .
+.It Dv BIOCSDLT (u_int)
+Changes the type of the data link layer underlying the attached interface.
+.Er EINVAL
+is returned if no interface has been specified or the specified
+type is not available for the interface.
.It Dv BIOCPROMISC
Forces the interface into promiscuous mode.
All packets, not just those destined for the local host, are processed.
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 25440ec33ec..b1d29bba72d 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.c,v 1.55 2004/12/17 15:56:58 reyk Exp $ */
+/* $OpenBSD: bpf.c,v 1.56 2005/01/07 16:28:38 reyk Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/*
@@ -92,6 +92,8 @@ static __inline void bpf_wakeup(struct bpf_d *);
void bpf_catchpacket(struct bpf_d *, u_char *, size_t, size_t,
void (*)(const void *, void *, size_t));
void bpf_reset_d(struct bpf_d *);
+int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
+int bpf_setdlt(struct bpf_d *, u_int);
void filt_bpfrdetach(struct knote *);
int filt_bpfread(struct knote *, long);
@@ -573,7 +575,9 @@ bpf_reset_d(struct bpf_d *d)
* BIOCSETF Set ethernet read filter.
* BIOCFLUSH Flush read packet buffer.
* BIOCPROMISC Put interface into promiscuous mode.
+ * BIOCGDLTLIST Get supported link layer types.
* BIOCGDLT Get link layer type.
+ * BIOCSDLT Set link layer type.
* BIOCGETIF Get interface name.
* BIOCSETIF Set interface.
* BIOCSRTIMEOUT Set read timeout.
@@ -598,6 +602,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
case BIOCGBLEN:
case BIOCFLUSH:
case BIOCGDLT:
+ case BIOCGDLTLIST:
case BIOCGETIF:
case BIOCGRTIMEOUT:
case BIOCGSTATS:
@@ -706,6 +711,16 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
break;
/*
+ * Get a list of supported device parameters.
+ */
+ case BIOCGDLTLIST:
+ if (d->bd_bif == NULL)
+ error = EINVAL;
+ else
+ error = bpf_getdltlist(d, (struct bpf_dltlist *)addr);
+ break;
+
+ /*
* Get device parameters.
*/
case BIOCGDLT:
@@ -716,6 +731,16 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
break;
/*
+ * Set device parameters.
+ */
+ case BIOCSDLT:
+ if (d->bd_bif == NULL)
+ error = EINVAL;
+ else
+ error = bpf_setdlt(d, *(u_int *)addr);
+ break;
+
+ /*
* Set interface name.
*/
case BIOCGETIF:
@@ -1420,3 +1445,61 @@ bpfilter_destroy(struct bpf_d *bd)
LIST_REMOVE(bd, bd_list);
free(bd, M_DEVBUF);
}
+
+/*
+ * Get a list of available data link type of the interface.
+ */
+int
+bpf_getdltlist(struct bpf_d *d, struct bpf_dltlist *bfl)
+{
+ int n, error;
+ struct ifnet *ifp;
+ struct bpf_if *bp;
+
+ ifp = d->bd_bif->bif_ifp;
+ n = 0;
+ error = 0;
+ for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+ if (bp->bif_ifp != ifp)
+ continue;
+ if (bfl->bfl_list != NULL) {
+ if (n >= bfl->bfl_len)
+ return (ENOMEM);
+ error = copyout(&bp->bif_dlt,
+ bfl->bfl_list + n, sizeof(u_int));
+ if (error)
+ break;
+ }
+ n++;
+ }
+
+ bfl->bfl_len = n;
+ return (error);
+}
+
+/*
+ * Set the data link type of a BPF instance.
+ */
+int
+bpf_setdlt(struct bpf_d *d, u_int dlt)
+{
+ int s;
+ struct ifnet *ifp;
+ struct bpf_if *bp;
+
+ if (d->bd_bif->bif_dlt == dlt)
+ return (0);
+ ifp = d->bd_bif->bif_ifp;
+ for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+ if (bp->bif_ifp == ifp && bp->bif_dlt == dlt)
+ break;
+ }
+ if (bp == NULL)
+ return (EINVAL);
+ s = splimp();
+ bpf_detachd(d);
+ bpf_attachd(d, bp);
+ bpf_reset_d(d);
+ splx(s);
+ return (0);
+}
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index da4dc8a06ae..c8465ea15c7 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.h,v 1.29 2004/12/17 15:56:58 reyk Exp $ */
+/* $OpenBSD: bpf.h,v 1.30 2005/01/07 16:28:38 reyk Exp $ */
/* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */
/*
@@ -115,6 +115,8 @@ struct bpf_version {
#define BIOCSETWF _IOW('B',119, struct bpf_program)
#define BIOCGFILDROP _IOR('B',120, u_int)
#define BIOCSFILDROP _IOW('B',121, u_int)
+#define BIOCSDLT _IOW('B',122, u_int)
+#define BIOCGDLTLIST _IOWR('B',123, struct bpf_dltlist)
struct bpf_timeval {
u_int32_t tv_sec;
@@ -174,6 +176,7 @@ struct bpf_hdr {
#define DLT_PPP_ETHER 51 /* PPP over Ethernet; session only w/o ether header */
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
#define DLT_PFLOG 117 /* Packet filter logging, by pcap people */
+#define DLT_IEEE802_11_RADIO 127 /* IEEE 802.11 plus WLAN header */
/*
* The instruction encodings.
@@ -242,6 +245,14 @@ struct bpf_insn {
};
/*
+ * Structure to retrieve available DLTs for the interface.
+ */
+struct bpf_dltlist {
+ u_int bfl_len; /* number of bfd_list array */
+ u_int *bfl_list; /* array of DLTs */
+};
+
+/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_int16_t)(code), 0, 0, k }
diff --git a/sys/net80211/ieee80211_radiotap.h b/sys/net80211/ieee80211_radiotap.h
index d0559e3fc01..1d355d2af0e 100644
--- a/sys/net80211/ieee80211_radiotap.h
+++ b/sys/net80211/ieee80211_radiotap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_radiotap.h,v 1.4 2004/12/30 23:32:55 reyk Exp $ */
+/* $OpenBSD: ieee80211_radiotap.h,v 1.5 2005/01/07 16:28:38 reyk Exp $ */
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.3 2004/04/05 22:13:21 sam Exp $ */
/* $NetBSD: ieee80211_radiotap.h,v 1.9 2004/06/06 04:13:28 dyoung Exp $ */
@@ -47,11 +47,6 @@
* function of...") that I cannot set false expectations for lawyerly
* readers.
*/
-#ifdef _KERNEL
-#ifndef DLT_IEEE802_11_RADIO
-#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */
-#endif
-#endif /* _KERNEL */
/* XXX tcpdump/libpcap do not tolerate variable-length headers,
* yet, so we pad every radiotap header to 64 bytes. Ugh.