Posts filed under 'libtrace'

Thoughts on libtrace wireless API and radiotap

With libtrace 3.0 we included an API for extracting wireless metadata from packets. So for example, you can call trace_get_wireless_signal_strength_dbm() on a libtrace packet and get it’s absolute signal strength. This is done by decoding the Radiotap monitoring header if present. This is all fine for physical layer attributes, such as signal and noise levels, but the abstraction starts to get fuzzy when it comes to link-layer specific stuff. For example, libtrace 3.0 released with trace_get_wireless_fcs() which extracted the 802.11 FCS from the Radiotap header (even though this was a non-standard field and has since been removed). The problem is, trace_get_wireless_* shouldn’t be specific to certain MAC layer protocols. What if a CRC-16 is used instead of a CRC-32? trace_get_wireless_fcs() has since been removed, but the point also applies to some of the other functions.

So some of the functions as they exist now extract physical layer attributes, and others extract MAC layer attributes. Since libtrace was released, the Radiotap standard has been updated to include a couple of extra fields, such as the number of retries a packet had. Should a new accessor be added to libtrace to extract this? I’d say no, even though it’s a very interesting piece of data. Keep the trace_get_wireless_* functions as generic ways to get physical layer attributes of wireless frames. Let the user decode the Radiotap header in full if they want the 802.11 specific stuff.

Turns out I’m one of those users, so I’ve created a stand-alone Radiotap decoder in C which can extract all the Radiotap fields. If a new Radiotap field is added that describes an interesting physical layer attribute, then maybe an accessor can be added to libtrace for it, but for MAC layer specific fields a stand-alone Radiotap decoder should be used. This should hopefully keep libtrace as generic as possible.

Download version 0.1 of my C Radiotap decoder if you’re interested. Maybe I’ll get around to uploading it to Google Code Hosting at some point in the future.

Add comment April 25th, 2007

libtrace and madwifi progress

So after a couple of revisions, I’ve pretty much got radiotap in libtrace sorted. As well as that, I’ve implemented an abstract interface for dealing with wireless information in libtrace, so the application doesn’t need to know whether the trace is based on radiotap or prism, it can just call one of the trace_get_wireless_* functions. At the moment this only works for radiotap traces, but prism shouldn’t be too much of an issue to get going. I think the interface has turned out quite well, as it guarantees that any values returned are in host byte order, are of a certain type, and gracefully deals with unsupported link-types (like prism at the moment) as well as fields that aren’t available.

I’ve also submitted a patch to madwifi to include the absolute signal and noise levels in the radiotap header, as the only signal information that was present previously was the rssi. Hopefully that will be committed soon.

Had a look this evening at whether we can get any sort of measured noise levels out of the HAL. The atheros descriptors (structures that are used to send frames to and from the HAL and which all information is taken from) only contain a field for rssi, which is db relative to a fixed reference (in this case the noise floor of -95 dBm). So the atheros descriptors don’t tell us much. None of the HAL functions seem to return anything useful, but interestingly there is a “new” public HAL function - at least it was introduced since the madwifi project last updated the HAL-usage wiki page…

/*
* Calibrate noise floor data following a channel scan or similar.
* This must be called prior retrieving noise floor data.
*/
extern void __ahdecl ath_hal_process_noisefloor(struct ath_hal *ah);

Interesting… this function isn’t called anywhere in madwifi. I wonder what it does… it certainly doesn’t return anything - the only thing it could do is update a field in the hal struct… which leads us to…

int16_t __ahdecl(*ah_getChanNoise)(struct ath_hal *, HAL_CHANNEL *);

Which also isn’t called anywhere in madwifi, nor is it documented in the madwifi wiki page. It seems this function has slipped in under the radar. Unfortunately I’ve turned off my test box at work, so I can’t play with it from home. I think with this new information and a bit of hacking I’ll be able to get actual measured noise data, even if it is only updated once per scan, or similar. A patch to end the silly “noise is always -95 dBm” in madwifi would be really really cool. Can’t wait to get hacking on that!

I also have a patch in the works to add a /proc entry to monitor vaps to allow us to see error frames, such as frames that failed their fcs, were too short, etc.

Well, that was a long post. It’s been a very productive week and next week is looking very interesting indeed.

Add comment September 8th, 2006

madwifi, radiotap and libtrace

Spent some time today figuring out how to get low-level radio information from Atheros-based wireless cards. A madwifi device can be set to a pretty standard monitor mode, with a choice of several encapsulations. 802.11 is better than nothing, but doesn’t give the physical layer information I’m after. Radiotap and Prism monitoring headers are also supported, as well as output of the actual atheros descriptors used by the driver/HAL which contain HAL status information after each descriptor is processed by the hardware. The atheros descriptor format is something I’d like to look at later. With a choice of Prism or Radiotap, I’m going with Radiotap as it seems much saner.
Radiotap allows us to on a per-packet basis get RSSI (signal in db above noise floor), timing information (a 64-bit value in microseconds indicating when the first bit of the MPDU hit the MAC), rate, channel, and most importantly (for me at least) the 802.11 frame-check sequence which is usually stripped off the end of the frame before being passed up.
Unfortunately, it seems that pcap doesn’t know about the radiotap ARPHRD used by madwifi, which is fair enough I guess, as neither libc nor linux have defined an ARPHRD for radiotap yet. What this means is that tcpdump will fall back to linux SLL and you’ll end up with an unusable trace.
Enter libtrace. libtrace doesn’t have radiotap support yet, but after a bit of a chat with Perry I’ve got it recognising the ARPHRD madwifi uses and I can now open a trace on a live device and get the radiotap headers. Right now I’m just grabbing each frame and manually casting to a radiotap structure, but I plan on implementing proper radiotap support in libtrace over the next while, which should be interesting and allow us to do fun things like run tracedump over a radiotap trace.
So there’s a few things on my todo list now…

  • Implement proper radiotap support in libtrace
  • Add a /proc interface to madwifi monitor vaps to enable passing up frames that fail their FCS (and other error frames)
  • Figure out exactly what does/doesn’t work when creating a monitor mode vap when there’s already a sta/ap/adhoc vap around
  • Create libtrace packages for crcnet-bpc
  • Grab some decent traces from CRCnet with radiotap headers enabled
  • Analyse :)
    • That should keep me busy for a while at least… Hopefully this work will also help with things like the link-testing stuff that Ivan is up to at the moment.

      1 comment September 6th, 2006


Calendar

January 2009
M T W T F S S
« Aug    
 1234
567891011
12131415161718
19202122232425
262728293031  

Posts by Month

Posts by Category