1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use crate::wifi::hwsim_attr_set::HwsimAttrSet; 16 use anyhow::Context; 17 use netsim_packets::ieee80211::{Ieee80211, MacAddress}; 18 use netsim_packets::mac80211_hwsim::{HwsimCmd, HwsimMsg, TxRate}; 19 use pdl_runtime::Packet; 20 21 /// Parser for the hwsim Frame command (HWSIM_CMD_FRAME). 22 /// 23 /// The Frame command is sent by the kernel's mac80211_hwsim subsystem 24 /// and contains the IEEE 802.11 frame along with hwsim attributes. 25 /// 26 /// This module parses the required and optional hwsim attributes and 27 /// returns errors if any required attributes are missing. 28 29 // The Frame struct contains parsed attributes along with the raw and 30 // parsed 802.11 frame in `data` and `ieee80211.` 31 #[derive(Debug)] 32 pub struct Frame { 33 pub transmitter: Option<MacAddress>, 34 pub flags: Option<u32>, 35 pub tx_info: Option<Vec<TxRate>>, 36 pub cookie: Option<u64>, 37 pub signal: Option<u32>, 38 pub freq: Option<u32>, 39 pub data: Vec<u8>, 40 pub ieee80211: Ieee80211, 41 pub hwsim_msg: HwsimMsg, 42 pub attrs: HwsimAttrSet, 43 } 44 45 impl Frame { 46 // Builds and validates the Frame from the attributes in the 47 // packet. Called when a hwsim packet with HwsimCmd::Frame is 48 // found. parse(msg: &HwsimMsg) -> anyhow::Result<Frame>49 pub fn parse(msg: &HwsimMsg) -> anyhow::Result<Frame> { 50 // Only expected to be called with HwsimCmd::Frame 51 if msg.hwsim_hdr.hwsim_cmd != HwsimCmd::Frame { 52 panic!("Invalid hwsim_cmd"); 53 } 54 let attrs = HwsimAttrSet::parse(&msg.attributes).context("HwsimAttrSet")?; 55 let frame = attrs.frame.clone().context("Frame")?; 56 let ieee80211 = Ieee80211::decode_full(&frame).context("Ieee80211")?; 57 // Required attributes are unwrapped and return an error if 58 // they are not present. 59 Ok(Frame { 60 transmitter: attrs.transmitter, 61 flags: attrs.flags, 62 tx_info: attrs.tx_info.clone(), 63 cookie: attrs.cookie, 64 signal: attrs.signal, 65 freq: attrs.freq, 66 data: frame, 67 ieee80211, 68 hwsim_msg: msg.clone(), 69 attrs, 70 }) 71 } 72 } 73