Skip to content

📦 A library for parsing IEEE 802.11 frames

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE.APACHE
MIT
LICENSE.MIT
Notifications You must be signed in to change notification settings

Nukesor/libwifi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

d741490 Â· Mar 20, 2025
Feb 20, 2025
Jun 8, 2021
Jan 17, 2025
Mar 5, 2025
Mar 20, 2025
Feb 20, 2025
Feb 14, 2023
Jan 11, 2025
Mar 20, 2025
Mar 5, 2025
Jan 11, 2025
Jan 11, 2025
Jan 11, 2025
Feb 5, 2025
Jun 22, 2022

Repository files navigation

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.