### Access Timestamp Information in Rust Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses frame timing information, including timestamps and TSFT values, from radiotap headers. This Rust example shows how to access the `timestamp` and `tsft` fields using the `radiotap` crate. ```rust use radiotap::Radiotap; fn main() { let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { // Timestamp field (802.11 frame timing) if let Some(timestamp) = radiotap.timestamp { println!("Timestamp: {}", timestamp.timestamp); println!("Unit: {:?}", timestamp.unit); println!("Position: {:?}", timestamp.position); if let Some(accuracy) = timestamp.accuracy { println!("Accuracy: {} units", accuracy); } } // TSFT (Time Synchronization Function Timer) if let Some(tsft) = radiotap.tsft { println!("TSFT: {} microseconds", tsft.value); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` -------------------------------- ### Parse Radiotap capture into Radiotap struct (Rust) Source: https://github.com/rossmacarthur/radiotap/blob/trunk/README.md This Rust code demonstrates how to parse a byte slice representing a Radiotap capture into a `Radiotap` struct. It uses the `from_bytes` constructor and assumes the capture data is valid. The example prints the `vht` field if present. ```rust let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; let radiotap = Radiotap::from_bytes(&capture).unwrap(); println!("{:?}", radiotap.vht); ``` -------------------------------- ### Capture Live WiFi Packets in Rust with pcap and radiotap Source: https://context7.com/rossmacarthur/radiotap/llms.txt This code snippet demonstrates how to capture live WiFi packets using the `pcap` and `radiotap` Rust crates. It opens a network interface in monitor mode, sets the data link type to `DLT_IEEE802_11_RADIO`, and then captures a specified number of packets. For each captured packet, it attempts to parse the Radiotap header and prints information such as antenna signal, data rate, and channel frequency. ```rust use std::env; fn main() { // Get network interface (default: en0 on macOS, wlan0 on Linux) let device = env::args().nth(1).unwrap_or_else(|| { if cfg!(target_os = "macos") { "en0".to_string() } else { "wlan0".to_string() } }); // Open capture in monitor mode with Radiotap link type let mut cap = pcap::Capture::from_device(&device[..]) .unwrap() .timeout(1000) .rfmon(true) .open() .unwrap(); cap.set_datalink(pcap::Linktype(127)).unwrap(); // DLT_IEEE802_11_RADIO println!("Capturing on {}...", device); let mut count = 0; while count < 100 { match cap.next_packet() { Ok(packet) => { match radiotap::Radiotap::from_bytes(&packet.data) { Ok(rt) => { println!("\n--- Packet {} ---", count + 1); if let Some(signal) = rt.antenna_signal { println!("Signal: {} dBm", signal.value); } if let Some(rate) = rt.rate { println!("Rate: {} Mbps", rate.value); } else if let Some(mcs) = rt.mcs { println!("MCS: {:?}", mcs.datarate); } else if let Some(vht) = rt.vht { println!("VHT: {:?}", vht.bw); } if let Some(channel) = rt.channel { println!("Channel: {} MHz", channel.freq); } count += 1; } Err(e) => eprintln!("Parse error: {}", e), } } Err(pcap::Error::TimeoutExpired) => continue, Err(e) => { eprintln!("Capture error: {:?}", e); break; } } } } ``` -------------------------------- ### Add radiotap dependency to Cargo.toml Source: https://github.com/rossmacarthur/radiotap/blob/trunk/README.md This snippet shows how to add the radiotap crate as a dependency to your Rust project by either using the `cargo add` command or by manually editing the `Cargo.toml` file. ```bash cargo add radiotap ``` ```toml [dependencies] radiotap = "1" ``` -------------------------------- ### Implement Custom Radiotap Field Parsers in Rust Source: https://context7.com/rossmacarthur/radiotap/llms.txt This snippet demonstrates how to create custom parsers for Radiotap fields by implementing the `Field` trait from the `radiotap` crate. It defines `CustomAntennaSignal` and `CustomRate` structs, each implementing `from_bytes` to parse specific field data. The `main` function then iterates over captured packet data, applying these custom parsers when the corresponding field types are encountered. ```rust use radiotap::{field, Error, RadiotapIterator}; #[derive(Debug)] struct CustomAntennaSignal { value: i8, value_dbm: f32, } impl field::Field for CustomAntennaSignal { fn from_bytes(input: &[u8]) -> Result { let value = input[0] as i8; Ok(CustomAntennaSignal { value, value_dbm: value as f32, }) } } #[derive(Debug)] struct CustomRate { raw_value: u8, mbps: f32, } impl field::Field for CustomRate { fn from_bytes(input: &[u8]) -> Result { let raw = input[0]; Ok(CustomRate { raw_value: raw, mbps: (raw as f32) / 2.0, }) } } fn main() { let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match RadiotapIterator::from_bytes(&capture) { Ok(iterator) => { for element in iterator { match element { Ok((field::Kind::AntennaSignal, data)) => { let signal: CustomAntennaSignal = field::from_bytes(data).unwrap(); println!("Custom Signal Parser: {:?}", signal); } Ok((field::Kind::Rate, data)) => { let rate: CustomRate = field::from_bytes(data).unwrap(); println!("Custom Rate Parser: {:?}", rate); } _ => {} } } } Err(e) => eprintln!("Error: {}", e), } } ``` -------------------------------- ### Rust Radiotap Parsing Error Handling Source: https://context7.com/rossmacarthur/radiotap/llms.txt Handles common Radiotap parsing errors including unsupported versions, invalid lengths, incomplete data, and format issues. It takes raw byte data as input and returns a Result indicating success or a descriptive error string. Dependencies include the `radiotap` crate. ```rust use radiotap::{Radiotap, Error}; fn process_capture(data: &[u8]) -> Result<(), String> { match Radiotap::from_bytes(data) { Ok(radiotap) => { println!("Successfully parsed Radiotap header"); println!("Header length: {} bytes", radiotap.header.length); println!("Fields present: {} fields", radiotap.header.present.len()); Ok(()) } Err(Error::UnsupportedVersion) => { Err("Unsupported Radiotap version (only v0 supported)".to_string()) } Err(Error::InvalidLength) => { Err("Data shorter than header length indicates".to_string()) } Err(Error::IncompleteError) => { Err("Incomplete Radiotap capture data".to_string()) } Err(Error::InvalidFormat) => { Err("Invalid Radiotap format".to_string()) } Err(Error::UnsupportedField) => { Err("Unsupported field encountered".to_string()) } Err(Error::ParseError(io_err)) => { Err(format!("IO parse error: {}", io_err)) } } } fn main() { let valid_capture = [0, 0, 8, 0, 0, 0, 0, 0]; let invalid_version = [1, 0, 8, 0, 0, 0, 0, 0]; let truncated = [0, 0, 20, 0, 0, 0]; println!("Testing valid capture:"); if let Err(e) = process_capture(&valid_capture) { println!("Error: {}", e); } println!("\nTesting invalid version:"); if let Err(e) = process_capture(&invalid_version) { println!("Error: {}", e); } println!("\nTesting truncated data:"); if let Err(e) = process_capture(&truncated) { println!("Error: {}", e); } } ``` -------------------------------- ### Parse Extended Channel Information in Rust Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses detailed channel properties such as frequency, bandwidth, and modulation type from radiotap headers. It utilizes the `radiotap` crate and handles both extended channel information (XChannel) and basic channel information. ```rust use radiotap::Radiotap; fn main() { let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { // Extended channel information (XChannel field) if let Some(xchannel) = radiotap.xchannel { println!("Extended Channel Information:"); println!(" Frequency: {} MHz", xchannel.freq); println!(" Channel Number: {}", xchannel.channel); println!(" Max Power: {} dBm", xchannel.max_power); let flags = xchannel.flags; println!(" Flags:"); println!(" 2.4 GHz: {}", flags.ghz2); println!(" 5 GHz: {}", flags.ghz5); println!(" Turbo: {}", flags.turbo); println!(" CCK: {}", flags.cck); println!(" OFDM: {}", flags.ofdm); println!(" HT20: {}", flags.ht20); println!(" HT40+: {}", flags.ht40u); println!(" HT40-: {}", flags.ht40d); println!(" Half Rate: {}", flags.half); println!(" Quarter Rate: {}", flags.quarter); } // Basic channel information if let Some(channel) = radiotap.channel { println!("Basic Channel: {} MHz", channel.freq); println!(" 2.4 GHz: {}, 5 GHz: {}", channel.flags.ghz2, channel.flags.ghz5); println!(" OFDM: {}, CCK: {}", channel.flags.ofdm, channel.flags.cck); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` -------------------------------- ### Access 802.11n MCS Information from Radiotap (Rust) Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses a Radiotap header and extracts High Throughput (802.11n) modulation and coding scheme (MCS) information. It handles optional fields like MCS index, bandwidth, guard interval, and more. ```rust use radiotap::Radiotap; fn main() { let capture = [ 0, 0, 39, 0, 46, 72, 0, 192, 0, 0, 0, 128, 0, 0, 0, 160, 4, 0, 0, 0, 16, 2, 158, 9, 160, 0, 227, 5, 0, 0, 255, 255, 255, 255, 2, 0, 222, 173, 4 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { if let Some(mcs) = radiotap.mcs { println!("802.11n (HT) Information:"); if let Some(index) = mcs.index { println!("MCS Index: {}", index); } if let Some(bw) = mcs.bw { println!("Bandwidth: {} MHz", bw.bandwidth); } if let Some(gi) = mcs.gi { println!("Guard Interval: {:?}", gi); } if let Some(format) = mcs.format { println!("HT Format: {:?}", format); } if let Some(fec) = mcs.fec { println!("FEC Type: {:?}", fec); } if let Some(datarate) = mcs.datarate { println!("Data Rate: {} Mbps", datarate); } if let Some(stbc) = mcs.stbc { println!("STBC Streams: {}", stbc); } } // Access legacy rate if present instead if let Some(rate) = radiotap.rate { println!("Legacy Rate: {} Mbps", rate.value); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` -------------------------------- ### Handle Radiotap Transmission and Reception Flags (Rust) Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses a Radiotap header to extract detailed flags related to frame transmission (TX) and reception (RX). It also provides access to retry counts and general frame status flags. ```rust use radiotap::Radiotap; fn main() { let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { // General frame flags if let Some(flags) = radiotap.flags { println!("Frame Flags:"); println!(" CFP: {}", flags.cfp); println!(" Short Preamble: {}", flags.preamble); println!(" WEP Encrypted: {}", flags.wep); println!(" Fragmented: {}", flags.fragmentation); println!(" FCS Included: {}", flags.fcs); println!(" Data Padding: {}", flags.data_pad); println!(" Bad FCS: {}", flags.bad_fcs); println!(" Short GI: {}", flags.sgi); } // Transmission-specific flags if let Some(tx_flags) = radiotap.tx_flags { println!("TX Flags:"); println!(" Failed: {}", tx_flags.fail); println!(" CTS-to-self: {}", tx_flags.cts); println!(" RTS/CTS: {}", tx_flags.rts); println!(" No ACK: {}", tx_flags.no_ack); println!(" No Sequence: {}", tx_flags.no_seq); } // Reception-specific flags if let Some(rx_flags) = radiotap.rx_flags { println!("RX Flags:"); println!(" Bad PLCP: {}", rx_flags.bad_plcp); } // Retry information if let Some(retries) = radiotap.data_retries { println!("Data Retries: {}", retries.value); } if let Some(rts_retries) = radiotap.rts_retries { println!("RTS Retries: {}", rts_retries.value); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` -------------------------------- ### Parse AMPDU Status in Rust Source: https://context7.com/rossmacarthur/radiotap/llms.txt Extracts aggregated MAC protocol data unit (A-MPDU) information for 802.11n/ac frames. This Rust code snippet demonstrates how to check for and parse the `ampdu_status` field from radiotap headers. ```rust use radiotap::Radiotap; fn main() { let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { if let Some(ampdu) = radiotap.ampdu_status { println!("A-MPDU Status:"); println!(" Reference Number: {}", ampdu.reference); if let Some(is_zero_length) = ampdu.zero_length { println!(" Zero Length Subframe: {}", is_zero_length); } if let Some(is_last) = ampdu.last { println!(" Last Subframe: {}", is_last); } if let Some(crc) = ampdu.delimiter_crc { println!(" Delimiter CRC: 0x{:02x}", crc); } } else { println!("Not an A-MPDU frame"); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` -------------------------------- ### Parse Complete Radiotap Header in Rust Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses all available fields from a Radiotap capture into a structured `Radiotap` object. This method provides comprehensive access to metadata like VHT information, signal strength, channel details, and transmission flags. It requires the `radiotap` crate and takes raw capture bytes as input, returning a `Result` with either the parsed `Radiotap` object or an error. ```rust use radiotap::Radiotap; fn main() { // Raw Radiotap capture bytes from a WiFi packet let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { // Access VHT (802.11ac) information if let Some(vht) = radiotap.vht { println!("VHT Present: {:?}", vht); println!("Bandwidth: {:?}", vht.bw); println!("Guard Interval: {:?}", vht.gi); // Check each user's data rate for (i, user) in vht.users.iter().enumerate() { if let Some(u) = user { println!("User {}: MCS={}, NSS={}, Rate={:?} Mbps", i, u.index, u.nss, u.datarate); } } } // Access signal strength in dBm if let Some(signal) = radiotap.antenna_signal { println!("Signal Strength: {} dBm", signal.value); } // Access channel information if let Some(channel) = radiotap.channel { println!("Frequency: {} MHz", channel.freq); println!("2.4GHz: {}, 5GHz: {}", channel.flags.ghz2, channel.flags.ghz5); } // Access transmission flags if let Some(flags) = radiotap.flags { println!("FCS Present: {}", flags.fcs); println!("WEP Encrypted: {}", flags.wep); println!("Fragmented: {}", flags.fragmentation); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` -------------------------------- ### Iterate Over Specific Fields Source: https://context7.com/rossmacarthur/radiotap/llms.txt Efficiently parses only the fields you need from a Radiotap capture using an iterator, avoiding the overhead of parsing the entire header. ```APIDOC ## Iterate Over Specific Fields ### Description Efficiently parse only the fields you need from a Radiotap capture using an iterator. ### Method Not applicable (this is a library function call) ### Endpoint Not applicable (this is a library function call) ### Parameters None ### Request Example ```rust use radiotap::{field, RadiotapIterator}; fn main() { let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match RadiotapIterator::from_bytes(&capture) { Ok(iterator) => { for element in iterator { match element { Ok((field::Kind::VHT, data)) => { let vht: field::VHT = field::from_bytes(data).unwrap(); println!("VHT Field: {:?}", vht); } Ok((field::Kind::AntennaSignal, data)) => { let signal: field::AntennaSignal = field::from_bytes(data).unwrap(); println!("Signal: {} dBm", signal.value); } Ok((field::Kind::Rate, data)) => { let rate: field::Rate = field::from_bytes(data).unwrap(); println!("Legacy Rate: {} Mbps", rate.value); } Ok((field::Kind::Channel, data)) => { let channel: field::Channel = field::from_bytes(data).unwrap(); println!("Channel: {} MHz", channel.freq); } Ok((kind, _)) => { println!("Found field: {:?}", kind); } Err(e) => eprintln!("Field parse error: {}", e), } } } Err(e) => eprintln!("Iterator creation failed: {}", e), } } ``` ### Response #### Success Response (Ok) - **Iterator** - An iterator yielding `Result<(field::Kind, &[u8]), Error>` for each field found in the Radiotap header. ``` -------------------------------- ### Iterate over specific Radiotap fields (Rust) Source: https://github.com/rossmacarthur/radiotap/blob/trunk/README.md This Rust code snippet shows how to use `RadiotapIterator` to parse only specific fields from a Radiotap capture. It iterates over the capture, matching on the `field::Kind::VHT` to extract and print the VHT data. ```rust let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; for element in RadiotapIterator::from_bytes(&capture).unwrap() { match element { Ok((field::Kind::VHT, data)) => { let vht: field::VHT = field::from_bytes(data).unwrap(); println!("{:?}", vht); }, _ => {} } } ``` -------------------------------- ### Parse Complete Radiotap Header Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses all fields from a Radiotap capture into a structured object containing all available metadata. ```APIDOC ## Parse Complete Radiotap Header ### Description Parse all fields from a Radiotap capture into a structured object with all available metadata. ### Method Not applicable (this is a library function call) ### Endpoint Not applicable (this is a library function call) ### Parameters None ### Request Example ```rust use radiotap::Radiotap; fn main() { // Raw Radiotap capture bytes from a WiFi packet let capture = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0 ]; match Radiotap::from_bytes(&capture) { Ok(radiotap) => { // Access VHT (802.11ac) information if let Some(vht) = radiotap.vht { println!("VHT Present: {:?}", vht); println!("Bandwidth: {:?}", vht.bw); println!("Guard Interval: {:?}", vht.gi); // Check each user's data rate for (i, user) in vht.users.iter().enumerate() { if let Some(u) = user { println!("User {}: MCS={}, NSS={}, Rate={:?} Mbps", i, u.index, u.nss, u.datarate); } } } // Access signal strength in dBm if let Some(signal) = radiotap.antenna_signal { println!("Signal Strength: {} dBm", signal.value); } // Access channel information if let Some(channel) = radiotap.channel { println!("Frequency: {} MHz", channel.freq); println!("2.4GHz: {}, 5GHz: {}", channel.flags.ghz2, channel.flags.ghz5); } // Access transmission flags if let Some(flags) = radiotap.flags { println!("FCS Present: {}", flags.fcs); println!("WEP Encrypted: {}", flags.wep); println!("Fragmented: {}", flags.fragmentation); } } Err(e) => eprintln!("Parse error: {}", e), } } ``` ### Response #### Success Response (Ok) - **Radiotap** (struct) - A structured object containing all parsed Radiotap fields. ``` -------------------------------- ### Parse Radiotap Header and Preserve Remaining Data (Rust) Source: https://context7.com/rossmacarthur/radiotap/llms.txt Parses a Radiotap header from a byte slice and returns the parsed header along with any remaining data. This is useful for processing the encapsulated frame after the header. ```rust use radiotap::Radiotap; fn main() { // Radiotap header followed by 802.11 frame data let packet = [ 0, 0, 56, 0, 107, 8, 52, 0, 185, 31, 155, 154, 0, 0, 0, 0, 20, 0, 124, 21, 64, 1, 213, 166, 1, 0, 0, 0, 64, 1, 1, 0, 124, 21, 100, 34, 249, 1, 0, 0, 0, 0, 0, 0, 255, 1, 80, 4, 115, 0, 0, 0, 1, 63, 0, 0, // 802.11 frame data follows... 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff ]; match Radiotap::parse(&packet) { Ok((radiotap, remaining_data)) => { println!("Parsed Radiotap header, size: {} bytes", radiotap.header.length); println!("Remaining 802.11 frame: {} bytes", remaining_data.len()); // Process the 802.11 frame data if !remaining_data.is_empty() { println!("Frame type: 0x{:02x}", remaining_data[0]); // Continue processing 802.11 management/data/control frame... } } Err(e) => eprintln!("Parse error: {}", e), } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.