Subject: RFC: 802.11 radio capture header
To: None <tech-net@netbsd.org>
From: David Young <dyoung@pobox.com>
List: tech-net
Date: 08/02/2003 01:19:39
--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
For your review, I have attached the header file
(sys/net/if_ieee80211radiotap.h) defining a generic 802.11 radio
capture format. I have also attached patches containing my reference
implementation for wi(4).
If I do not hear any objections to this format on tech-net@ or on
tcpdump-workers@tcpdump.org, I will commit the wi patches next weekend.
The idea behind this capture format is that
* it is generic: it is suitable for an, atw, awi, wi, and future
drivers (Atheros, Atmel, Realtek)
* it is extensible: if new hardware provides useful new radio
information, you can add them to this capture format without breaking
existing parsers
* it conserves bandwidth: the capture header length can vary
with the content of the header; drivers can take advantage when
libpcap finally groks variable-length headers.
* it is highly informative: the units and meaning of each field are
rigidly specified; fields can be left out which are meaningless in
context (e.g., Rx signal strength can be left out of transmitted frames)
* it supports advanced wireless applications: an existing sniffer
app such as bsd-airtools provides can be adapted to use this format,
and then all radios (ADMtek, Atheros) will be supported; wireless
routers algorithms can monitor a link and assign costs based on S/N
ratio or on peers' data rate; stations can share S/N information with
each other to support improved rate adaptation; and so on.
Here is an example capture:
> sudo ./tcpdump -ne -y ieee802_11_radio -s 256 -i wi0
Password:
tcpdump: data link type ieee802_11_radio
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wi0, link-type 127, capture size 256 bytes
01:17:58.503262 2.0 Mb/s -64dB signal -73dB noise 2762646109us mactime BSSID:00:05:5d:da:ac:a8 DA:00:05:5d:da:ac:a8 SA:00:30:65:15:46:38 Authentication (Open System)-1: Succesful
01:17:58.503292 2.0 Mb/s BSSID:00:05:5d:da:ac:a8 DA:00:30:65:15:46:38 SA:00:05:5d:da:ac:a8 Authentication (Open System)-2:
01:17:58.505034 2.0 Mb/s -64dB signal -73dB noise 2876613213us mactime BSSID:00:05:5d:da:ac:a8 DA:00:05:5d:da:ac:a8 SA:00:30:65:15:46:38 Assoc Request (ojc) [1.0 2.0 5.5 11.0 Mbit]
01:17:58.505051 2.0 Mb/s BSSID:00:05:5d:da:ac:a8 DA:00:30:65:15:46:38 SA:00:05:5d:da:ac:a8 Assoc Response AID(1) :: Succesful
01:17:59.033918 2.0 Mb/s -64dB signal -73dB noise 3153437285us mactime BSSID:00:05:5d:da:ac:a8 SA:00:30:65:15:46:38 DA:00:05:5d:da:ac:a8 LLC, dsap 0xaa, ssap 0xaa, cmd 0x03, IP 192.168.1.109 > 192.168.1.1: icmp 64: echo request seq 2660
01:17:59.034024 2.0 Mb/s DA:00:30:65:15:46:38 BSSID:00:05:5d:da:ac:a8 SA:00:05:5d:da:ac:a8 LLC, dsap 0xaa, ssap 0xaa, cmd 0x03, IP 192.168.1.1 > 192.168.1.109: icmp 64: echo reply seq 2660
01:17:59.627226 2.0 Mb/s -64dB signal -73dB noise 3309281902us mactime BSSID:00:05:5d:da:ac:a8 SA:00:30:65:15:46:38 DA:ff:ff:ff:ff:ff:ff LLC, dsap 0xaa, ssap 0xaa, cmd 0x03, IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:30:65:15:46:38, length: 303
01:17:59.630303 2.0 Mb/s DA:00:30:65:15:46:38 BSSID:00:05:5d:da:ac:a8 SA:00:05:5d:da:ac:a8 LLC, dsap 0xaa, ssap 0xaa, cmd 0x03, IP 192.168.1.1.67 > 192.168.1.109.68: BOOTP/DHCP, Reply, length: 300
01:18:00.034279 2.0 Mb/s -64dB signal -73dB noise 4287079028us mactime BSSID:00:05:5d:da:ac:a8 SA:00:30:65:15:46:38 DA:00:05:5d:da:ac:a8 LLC, dsap 0xaa, ssap 0xaa, cmd 0x03, IP 192.168.1.109 > 192.168.1.1: icmp 64: echo request seq 2661
01:18:00.034373 2.0 Mb/s DA:00:30:65:15:46:38 BSSID:00:05:5d:da:ac:a8 SA:00:05:5d:da:ac:a8 LLC, dsap 0xaa, ssap 0xaa, cmd 0x03, IP 192.168.1.1 > 192.168.1.109: icmp 64: echo reply seq 2661
Dave
--
David Young OJC Technologies
dyoung@ojctech.com Urbana, IL * (217) 278-3933
--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="if_ieee80211radiotap.h"
/* $NetBSD: $ */
/*-
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of David Young may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef _NET_IF_IEEE80211RADIOTAP_H_
#define _NET_IF_IEEE80211RADIOTAP_H_
/* A generic radio capture format is desirable. There is one for
* Linux, but it is neither rigidly defined (there were not even
* units given for some fields) nor easily extensible.
*
* I suggest the following extensible radio capture format. It is
* based on a bitmap indicating which fields are present.
*
* I am trying to describe precisely what the application programmer
* should expect in the following, and for that reason I tell the
* units and origin of each measurement (where it applies), or else I
* use sufficiently weaselly language ("is a monotonically nondecreasing
* function of...") that I cannot set false expectations for lawyerly
* readers.
*/
/* The radio capture header precedes the 802.11 header. */
struct ieee80211_radiotap_header {
u_int8_t it_version; /* Version 0. Only increases
* for drastic changes,
* introduction of compatible
* new LTVs does not count.
*/
u_int8_t it_pad;
u_int16_t it_len; /* length of the whole
* header in bytes, including
* it_version, it_pad,
* it_len, and LTVs.
*/
u_int32_t it_present; /* A bitmap telling which
* fields are present. Set bit 31
* (0x80000000) to extend the
* bitmap by another 32 bits.
* Additional extensions are made
* by setting bit 31.
*/
};
/* Name Data type Units
* ---- --------- -----
*
* IEEE80211_RADIOTAP_CHANNEL u_int16_t MHz
*
* Tx/Rx channel number (for DSSS/OFDM/PBCC PHY)
*
* IEEE80211_RADIOTAP_FHSS u_int16_t see below
*
* For frequency-hopping radios, the hop set (first byte)
* and pattern (second byte).
*
* IEEE80211_RADIOTAP_RATE u_int16_t 100kb/s
*
* Tx/Rx data rate
*
* IEEE80211_RADIOTAP_DB_ANTSIGNAL int16_t decibel (dB)
*
* RF signal power at the antenna, measured from a fixed,
* arbitrary reference point.
*
* IEEE80211_RADIOTAP_DB_ANTNOISE int16_t decibel (dB)
*
* RF noise power at the antenna in decibels from an arbitrary,
* fixed reference point.
*
* IEEE80211_RADIOTAP_BARKER_CODE_LOCK u_int16_t unitless
*
* Quality of Barker code lock. Unitless. Monotonically
* nondecreasing with "better" lock strength. Called "Signal
* Quality" in datasheets. (Is there a standard way to measure
* this?)
*
* IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless
*
* Transmit power expressed as unitless distance from max
* power set at factory calibration. 0 is max power.
* Monotonically nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB)
*
* Transmit power expressed as decibel distance from max power
* set at factory calibration. 0 is max power. Monotonically
* nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DBM_TX_POWER u_int16_t decibels from
* milliwatt (dBm)
*
* Transmit power expressed as dBm (decibels from a 1 milliwatt
* reference). This is the absolute power level measured at
* the antenna port.
*
* IEEE80211_RADIOTAP_TSFT u_int64_t microseconds
*
* Value in microseconds of the MAC's 64-bit 802.11 Time
* Synchronization Function timer when the first bit of the
* MPDU arrived at the MAC. For received frames, only.
* Little-endian byte order.
*
* IEEE80211_RADIOTAP_FLAGS u_int16_t bitmap
*
* Properties of transmitted and received frames. See flags
* defined below.
*
* IEEE80211_RADIOTAP_TIME u_int32_t microseconds
*
* For radios that provide it: packet arrival time in
* microseconds. Prism hardware will provide this, but it is
* not known whether it marks the first or the last bit of
* the frame. Nor is it known where that bit has arrived
* (antenna, modem, MAC?) when the time is measured.
*
* IEEE80211_RADIOTAP_ANTENNA u_int16_t antenna index
*
* Unitless indication of the Rx/Tx antenna for this packet.
* The first antenna is antenna 0.
*/
enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_PAD = 0,
IEEE80211_RADIOTAP_FLAGS = 1,
IEEE80211_RADIOTAP_RATE = 2,
IEEE80211_RADIOTAP_CHANNEL = 3,
IEEE80211_RADIOTAP_FHSS = 4,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 5,
IEEE80211_RADIOTAP_DB_ANTNOISE = 6,
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_TSFT = 12,
IEEE80211_RADIOTAP_EXT = 31,
IEEE80211_RADIOTAP_TIME = 32
};
/* For IEEE80211_RADIOTAP_FLAGS */
#define IEEE80211_RADIOTAP_F_CFP 0x0001 /* sent/received
* during CFP
*/
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x0002 /* sent/received
* with short
* preamble
*/
#define IEEE80211_RADIOTAP_F_WEP 0x0004 /* sent/received
* with WEP encryption
*/
#define IEEE80211_RADIOTAP_F_FRAG 0x0008 /* sent/received
* with fragmentation
*/
#endif /* _NET_IF_IEEE80211RADIOTAP_H_ */
--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=cap-diffs
Index: wi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wi.c,v
retrieving revision 1.132
diff -u -r1.132 wi.c
--- wi.c 2003/07/06 20:01:17 1.132
+++ wi.c 2003/08/02 06:02:40
@@ -93,6 +93,7 @@
#include <net/if_media.h>
#include <net/if_ether.h>
#include <net/if_ieee80211.h>
+#include <net/if_ieee80211radiotap.h>
#if NBPFILTER > 0
#include <net/bpf.h>
@@ -378,6 +380,11 @@
ic->ic_media.ifm_status = wi_media_status;
ic->ic_media.ifm_change = wi_media_change;
+#if NBPFILTER > 0
+ bpfattach2(ifp, DLT_IEEE802_11_RADIO,
+ sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf);
+#endif
+
/* Attach is successful. */
sc->sc_attached = 1;
@@ -842,22 +858,33 @@
}
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
}
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
(caddr_t)&frmhdr.wi_whdr);
m_adj(m0, sizeof(struct ieee80211_frame));
frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
#if NBPFILTER > 0
if (sc->sc_drvbpf) {
struct mbuf mb;
+ union {
+ struct wi_tx_radiotap_header wttap;
+ u_int8_t pad[64];
+ } u;
+
+ /* XXX endianness */
+ memset(&u, 0, sizeof(u));
+ u.wttap.wt_ihdr.it_len = sizeof(u);
+ u.wttap.wt_rate = frmhdr.wi_tx_rate / 5;
+ u.wttap.wt_chan = ic->ic_bss.ni_chan;
+ u.wttap.wt_ihdr.it_present = WI_TX_RADIOTAP_PRESENT;
+ if (frmhdr.wi_tx_rate == 0)
+ u.wttap.wt_ihdr.it_present &=
+ ~(1 << IEEE80211_RADIOTAP_RATE);
+ /* TBD u.wttap.wt_flags */
M_COPY_PKTHDR(&mb, m0);
- mb.m_data = (caddr_t)&frmhdr;
- mb.m_len = sizeof(frmhdr);
+ mb.m_data = (caddr_t)&u;
+ mb.m_len = u.wttap.wt_ihdr.it_len;
mb.m_next = m0;
mb.m_pkthdr.len += mb.m_len;
bpf_mtap(sc->sc_drvbpf, &mb);
}
#endif
if (IFF_DUMPPKTS(ifp))
wi_dump_pkt(&frmhdr, ni, -1);
fid = sc->sc_txd[cur].d_fid;
@@ -1259,12 +1326,27 @@
#if NBPFILTER > 0
if (sc->sc_drvbpf) {
struct mbuf mb;
+ union {
+ struct wi_rx_radiotap_header wrtap;
+ u_int8_t pad[64];
+ } u;
+
+ /* XXX endianness */
+ memset(&u, 0, sizeof(u));
+ u.wrtap.wr_ihdr.it_len = sizeof(u);
+ u.wrtap.wr_ihdr.it_present = WI_RX_RADIOTAP_PRESENT0;
+ u.wrtap.wr_present1 = WI_RX_RADIOTAP_PRESENT1;
+ u.wrtap.wr_rate = frmhdr.wi_rx_rate / 5;
+ u.wrtap.wr_chan = ic->ic_bss.ni_chan;
+ u.wrtap.wr_antsignal = WI_RSSI_TO_DBM(sc, frmhdr.wi_rx_signal);
+ u.wrtap.wr_antnoise = WI_RSSI_TO_DBM(sc, frmhdr.wi_rx_silence);
+ /* TBD u.wrtap.wr_flags */
+ u.wrtap.wr_time =
+ (frmhdr.wi_rx_tstamp1 << 16) | frmhdr.wi_rx_tstamp0;
M_COPY_PKTHDR(&mb, m);
- mb.m_data = (caddr_t)&frmhdr;
- frmhdr.wi_rx_signal = WI_RSSI_TO_DBM(sc, frmhdr.wi_rx_signal);
- frmhdr.wi_rx_silence = WI_RSSI_TO_DBM(sc, frmhdr.wi_rx_silence);
- mb.m_len = (char *)&frmhdr.wi_whdr - (char *)&frmhdr;
+ mb.m_data = (caddr_t)&u;
+ mb.m_len = u.wrtap.wr_ihdr.it_len;
mb.m_next = m;
mb.m_pkthdr.len += mb.m_len;
bpf_mtap(sc->sc_drvbpf, &mb);
Index: wireg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wireg.h,v
retrieving revision 1.45
diff -u -r1.45 wireg.h
--- wireg.h 2003/05/13 08:35:58 1.45
+++ wireg.h 2003/08/02 06:02:41
@@ -578,3 +584,39 @@
/* Limit on the number of AIDs handled in the PRISM2-based Host AP mode. */
#define WI_MAX_AID 256
+
+/* Radio capture format for Prism. */
+
+#define WI_RX_RADIOTAP_PRESENT0 ((1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \
+ (1 << IEEE80211_RADIOTAP_EXT))
+
+#define WI_RX_RADIOTAP_PRESENT1 (1 << (IEEE80211_RADIOTAP_TIME - 32))
+
+struct wi_rx_radiotap_header {
+ struct ieee80211_radiotap_header wr_ihdr;
+ u_int32_t wr_present1;
+ u_int16_t wr_flags;
+ u_int16_t wr_rate;
+ u_int16_t wr_chan;
+ u_int16_t wr_antsignal;
+ u_int16_t wr_antnoise;
+ u_int32_t wr_time;
+};
+
+#define WI_TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL))
+
+struct wi_tx_radiotap_header {
+ struct ieee80211_radiotap_header wt_ihdr;
+ u_int16_t wt_flags;
+ u_int16_t wt_rate;
+ u_int16_t wt_chan;
+};
+
+#undef BIT
+
--VbJkn9YxBvnuCH5J--