#wifi #frame #parser #802-11

libwifi

A library for parsing IEEE 802.11 frames and handling wifi interfaces

10 releases

Uses new Rust 2024

new 0.4.6 Mar 20, 2025
0.4.5 Mar 20, 2025
0.4.3 Feb 10, 2025
0.4.1 Jan 17, 2025
0.1.0 Apr 16, 2021

#189 in Network programming

Download history 7/week @ 2024-11-27 6/week @ 2024-12-04 13/week @ 2024-12-11 87/week @ 2025-01-08 216/week @ 2025-01-15 16/week @ 2025-01-22 4/week @ 2025-01-29 260/week @ 2025-02-05 32/week @ 2025-02-12 12/week @ 2025-02-19 13/week @ 2025-02-26 35/week @ 2025-03-05 121/week @ 2025-03-12

184 downloads per month

MIT/Apache

190KB
4K 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!

Large parts of this library have been upstreamed from @Ragnt's AngryOxide.

What is Libwifi

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

The emphasis is on convenient, as the focus is to provide an easy-to-use API that includes consistent and intuitive structs representing the structure of a given frame.
Also this library is very fast, despite the focus on convenience.

The project is still under heavy development, quite a few features and some documentation are missing, but it should be a good foundation for a proper IEE 802.11 library :).

Contributing

I'm no longer actively using this library myself, so it relies on external contributions.

Writing documentation and tests are an easy way to start contributing and a huge help!

How to use it

Parsing a frame is fairly straight forward:

use libwifi::parse_frame;

// A simple RTS 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 benchmarks in the benches folder, which can be run by calling cargo bench.

Right now, parsing a Beacon frame, which is one of the more complex frames, takes ~300ns on a AMD Ryzen 7 7840HS.
Parsing a Data frame takes ~28 ns.

If we take this as a rough guideline, you can roughly expect 3-35 million frames per second per core on that CPU, depending on frame type.

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)

Implementation status

  • Management Frames
    • AssociationRequest,
    • AssociationResponse,
    • ReassociationRequest,
    • ReassociationResponse,
    • Deauthentication,
    • ProbeRequest,
    • ProbeResponse,
    • TimingAdvertisement,
    • Beacon,
    • Atim,
    • Disassociation,
    • Authentication,
    • 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
    • Data Header
    • QoS Data Header

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 :).

Fuzzing

cargo-fuzz can be used to check for potential crashes while processing unvalidated input data. After installing cargo-fuzz (note: may require rust nightly), the frame parsing can be tested with cargo fuzz run parse_frame.

Dependencies

~4MB
~77K SLoC