#frame #wifi #parser #802-11

libwifi

A library for parsing IEEE 802.11 frames and handling wifi interfaces

4 releases (2 breaking)

0.3.1 Jun 23, 2022
0.3.0 May 9, 2021
0.2.0 Apr 23, 2021
0.1.0 Apr 16, 2021

#35 in #wifi

42 downloads per month

MIT license

66KB
1K SLoC

Libwifi

GitHub Actions Workflow docs license Crates.io codecov

First of all, this library is designed to be easily extendable.
There's an architectural/contribution guide in docs/Frame.md and pull requests are highly welcome.

Covering the whole spectrum of possible 802.11 frames or all different implementations of wifi tools out there is an impossible task for a single person, let's try to tackle this together!

What is Libwifi

The first goal of libwifi is to provide a convenient way of parsing raw IEEE 802.11 frames!

The emphasis is on convenient, since this library doesn't focus on providing a ultra high-performance implementation. The focus is rather on providing an easy-to-use API.
This includes consistent and intuitive structs representing the structure of a given frame.
However, this doesn't mean that this library isn't quite fast anyway ;).

The second goal is to provide an unified API to:

  1. query information about your wifi interfaces (iwlist equivalent).
  2. set attributes and configure your wifi interfaces (iwconfig equivalent).

As a prototype it's planned to call and parse existing binaries. However, a native re-implementation of those tools is desired in a long-term manner.
For instance, the wireless-tools are a great C-library with a lot of documentation and very will structured code. This could be used as a guide-line for re-implementation.

The project is still under heavy development, and a lot of features are missing, but it should be a good foundation for a proper wifi library :).

How to use it

Parsing a frame is fairly straight forward:

use libwifi::parse_frame;

let bytes = [
    180, 0, // FrameControl
    158, 0, // Duration
    116, 66, 127, 77, 29, 45, // First Address
    20, 125, 218, 170, 84, 81, // Second Address
];

match libwifi::parse_frame(&bytes) {
    Ok(frame) => {
        println!("Got frame: {:?}", frame);
    }
    Err(err) => {
        println!("Error during parsing :\n{}", err);
    }
};

A full example on how to capture, process and parse wifi traffic can be found in the examples directory.

Performance

There are a few benches in the benches folder.

  1. Install cargo-criterion by calling cargo install cargo-criterion.
  2. Run the benchmarks with cargo criterion.

Right now, parsing a Beacon frame, which is one of the more complex frames, takes ~1 µs on a i7-8550U.
Parsing a Data frame takes ~84 ns.

If we take this as a rough guideline, you can roughly expect a million frames per second.

Disclaimer: This will most likely become slower, as more missing features/parsers will be added to the library. Anyhow, I don't expect this to drop below 100k frames/s.

Roadmap and TODOs

Parser and Frames

  • Implement basic parsers for all frame subtypes.
  • Add specialized parsers for fields that are currently generically handled by the StationInfo struct.
  • Handle all edge-cases (there are a lot and I'll need help!)

Interface handling

I would love to add proper interface handling to the library. This includes features to:

  • Switch modes
  • Switch channels
  • Discover available channels

Implementation status

  • Management Frames
    • AssociationRequest,
    • AssociationResponse,
    • ReassociationRequest,
    • ReassociationResponse,
    • ProbeRequest,
    • ProbeResponse,
    • TimingAdvertisement,
    • Beacon,
    • Atim,
    • Disassociation,
    • Authentication,
    • Deauthentication,
    • Action,
    • ActionNoAck,
  • Control Frames
    • Trigger,
    • Tack,
    • BeamformingReportPoll,
    • NdpAnnouncement,
    • ControlFrameExtension,
    • ControlWrapper,
    • BlockAckRequest,
    • BlockAck,
    • PsPoll,
    • Rts,
    • Cts,
    • Ack,
    • CfEnd,
    • CfEndCfAck,
  • Data Frames
    • Data,
    • DataCfAck,
    • DataCfPoll,
    • DataCfAckCfPoll,
    • NullData,
    • CfAck,
    • CfPoll,
    • CfAckCfPoll,
    • QosData,
    • QosDataCfAck,
    • QosDataCfPoll,
    • QosDataCfAckCfPoll,
    • QosNull,
    • QosCfPoll,
    • QosCfAckCfPoll,
  • Frame Components
    • Frame Control
    • Sequence Control
    • Management Header
    • Dynamic Management Header fields
      • SSID
      • Supported rates
      • Generic extraction of remaining fields
      • All other fields
    • Data Header
    • QoS Data Header
      • The QoS flags must still be properly parsed

There's a lot more to the IEE 802.11 spec and a lot of stuff needs to be done.
If you find that something you need is missing, consider creating a ticket and contributing :).

Dependencies

~1.2–2MB
~39K SLoC