aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schilit <schilit@google.com>2023-12-28 05:01:16 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2023-12-28 05:01:16 +0000
commitc7582a7f1ab43ed850e66ac014e14bbca2ecafac (patch)
tree80552476ffc7eb26b5650381ddd53a2deffd80e0
parent3fc3d5d14d809df1c73faf38f6b5404c781fdbfa (diff)
parentc7a500e8588ca29f9ffa85e330af229cf27a0686 (diff)
downloadnetsim-c7582a7f1ab43ed850e66ac014e14bbca2ecafac.tar.gz
Merge "Add wifi packet process and reorganize hwsim attributes to be used from multiple commands." into main
-rw-r--r--rust/daemon/src/echip/wifi.rs5
-rw-r--r--rust/daemon/src/wifi/frame.rs194
-rw-r--r--rust/daemon/src/wifi/hwsim_attr_set.rs178
-rw-r--r--rust/daemon/src/wifi/ieee80211.rs37
-rw-r--r--rust/daemon/src/wifi/medium.rs75
-rw-r--r--rust/daemon/src/wifi/mod.rs1
6 files changed, 314 insertions, 176 deletions
diff --git a/rust/daemon/src/echip/wifi.rs b/rust/daemon/src/echip/wifi.rs
index 2dba81a..c2cc1f6 100644
--- a/rust/daemon/src/echip/wifi.rs
+++ b/rust/daemon/src/echip/wifi.rs
@@ -16,7 +16,7 @@ use crate::devices::chip::ChipIdentifier;
use crate::echip::{EmulatedChip, SharedEmulatedChip};
use crate::ffi::ffi_wifi;
use crate::wifi::medium;
-use log::info;
+use log::{info, warn};
use netsim_proto::common::ChipKind as ProtoChipKind;
use netsim_proto::config::WiFi as WiFiConfig;
use netsim_proto::model::chip::Radio;
@@ -36,6 +36,9 @@ pub struct Wifi {
impl EmulatedChip for Wifi {
fn handle_request(&self, packet: &[u8]) {
+ if let Err(e) = medium::process(self.chip_id, packet) {
+ warn!("Error medium::process {}", e);
+ }
if crate::config::get_dev() {
let _ = medium::parse_hwsim_cmd(packet);
}
diff --git a/rust/daemon/src/wifi/frame.rs b/rust/daemon/src/wifi/frame.rs
index 4b8f462..1ec8904 100644
--- a/rust/daemon/src/wifi/frame.rs
+++ b/rust/daemon/src/wifi/frame.rs
@@ -12,175 +12,59 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use super::ieee80211::Ieee80211;
-use super::packets::mac80211_hwsim::HwsimAttrChild::*;
-use super::packets::mac80211_hwsim::{HwsimAttr, HwsimMsg, HwsimMsgHdr, TxRate, TxRateFlag};
-use super::packets::netlink::{NlAttrHdr, NlMsgHdr};
+use super::ieee80211::{Ieee80211, MacAddress};
+use super::packets::mac80211_hwsim::{
+ HwsimAttr, HwsimCmd, HwsimMsg, HwsimMsgHdr, TxRate, TxRateFlag,
+};
+use crate::wifi::hwsim_attr_set::HwsimAttrSet;
use anyhow::{anyhow, Context};
use log::{info, warn};
-use std::mem;
-// Decode the hwsim Frame.
-//
-// HWSIM_CMD_FRAME is used to send/receive a broadcasted frame from/to
-// kernel/user space, uses these attributes:
-//
-// HWSIM_ATTR_ADDR_TRANSMITTER,
-// HWSIM_ATTR_ADDR_RECEIVER,
-// HWSIM_ATTR_FRAME,
-// HWSIM_ATTR_FLAGS,
-// HWSIM_ATTR_RX_RATE,
-// HWSIM_ATTR_SIGNAL,
-// HWSIM_ATTR_COOKIE,
-// HWSIM_ATTR_FREQ (optional)
-// HWSIM_ATTR_TX_INFO (new use)
-// HWSIM_ATTR_TX_INFO_FLAGS (new use)
-
-const NLA_ALIGNTO: usize = 4;
-
-fn nla_align(len: usize) -> usize {
- len.wrapping_add(NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
-}
-
-#[derive(Default)]
-struct FrameBuilder {
- transmitter: Option<[u8; 6]>,
- receiver: Option<[u8; 6]>,
- data: Option<Vec<u8>>,
- flags: Option<u32>,
- rx_rate_idx: Option<u32>,
- signal: Option<u32>,
- cookie: Option<u64>,
- freq: Option<u32>,
- tx_rates: Option<Vec<TxRate>>,
- tx_rate_flags: Option<Vec<TxRateFlag>>,
-}
+/// Parser for the hwsim Frame command (HWSIM_CMD_FRAME).
+///
+/// The Frame command is sent by the kernel's mac80211_hwsim subsystem
+/// and contains the IEEE 802.11 frame along with hwsim attributes.
+///
+/// This module parses the required and optional hwsim attributes and
+/// returns errors if any required attributes are missing.
+// The Frame struct contains parsed attributes along with the raw and
+// parsed 802.11 frame in `data` and `ieee80211.`
#[derive(Debug)]
pub struct Frame {
- transmitter: Option<[u8; 6]>,
- receiver: Option<[u8; 6]>,
- pub data: Vec<u8>,
- pub ieee80211_hdr: Option<Ieee80211>,
- pub flags: Option<u32>,
- rx_rate_idx: Option<u32>,
+ pub transmitter: MacAddress,
+ pub flags: u32,
+ pub tx_info: Vec<TxRate>,
+ pub cookie: u64,
pub signal: Option<u32>,
- cookie: Option<u64>,
pub freq: Option<u32>,
- tx_rates: Option<Vec<TxRate>>,
- tx_rate_flags: Option<Vec<TxRateFlag>>,
-}
-
-fn anymsg(attr: &str) -> anyhow::Error {
- anyhow!("hwsim Frame missing {} attribute", attr)
-}
-
-impl FrameBuilder {
- fn transmitter(&mut self, transmitter: &[u8; 6]) -> &mut Self {
- self.transmitter = Some(*transmitter);
- self
- }
-
- fn receiver(&mut self, receiver: &[u8; 6]) -> &mut Self {
- self.receiver = Some(*receiver);
- self
- }
-
- fn frame(&mut self, data: &[u8]) -> &mut Self {
- self.data = Some(data.to_vec());
- self
- }
-
- fn flags(&mut self, flags: u32) -> &mut Self {
- self.flags = Some(flags);
- self
- }
-
- fn rx_rate(&mut self, rx_rate_idx: u32) -> &mut Self {
- self.rx_rate_idx = Some(rx_rate_idx);
- self
- }
-
- fn signal(&mut self, signal: u32) -> &mut Self {
- self.signal = Some(signal);
- self
- }
-
- fn cookie(&mut self, cookie: u64) -> &mut Self {
- self.cookie = Some(cookie);
- self
- }
-
- fn freq(&mut self, freq: u32) -> &mut Self {
- self.freq = Some(freq);
- self
- }
-
- fn tx_rates(&mut self, tx_rates: &[TxRate]) -> &mut Self {
- self.tx_rates = Some(tx_rates.to_vec());
- self
- }
-
- fn tx_rate_flags(&mut self, tx_rate_flags: &[TxRateFlag]) -> &mut Self {
- self.tx_rate_flags = Some(tx_rate_flags.to_vec());
- self
- }
-
- fn build(mut self) -> anyhow::Result<Frame> {
- let data = self.data.ok_or(anymsg("frame"))?;
- let ieee80211_hdr = Ieee80211::parse(&data).ok();
- Ok(Frame {
- transmitter: self.transmitter,
- receiver: self.receiver,
- cookie: self.cookie,
- flags: self.flags,
- rx_rate_idx: self.rx_rate_idx,
- signal: self.signal,
- data,
- ieee80211_hdr,
- freq: self.freq,
- tx_rates: self.tx_rates,
- tx_rate_flags: self.tx_rate_flags,
- })
- }
+ pub data: Vec<u8>,
+ pub ieee80211: Ieee80211,
}
impl Frame {
- fn builder() -> FrameBuilder {
- FrameBuilder::default()
- }
-
// Builds and validates the Frame from the attributes in the
// packet. Called when a hwsim packet with HwsimCmd::Frame is
// found.
- pub fn new(attributes: &[u8]) -> anyhow::Result<Frame> {
- let mut index: usize = 0;
- let mut builder = Frame::builder();
- while (index < attributes.len()) {
- // Parse a generic netlink attribute to get the size
- let nla = NlAttrHdr::parse(&attributes[index..index + 4]).unwrap();
- let nla_len = nla.nla_len as usize;
- let hwsim_attr = HwsimAttr::parse(&attributes[index..index + nla_len])?;
- match hwsim_attr.specialize() {
- HwsimAttrAddrTransmitter(child) => builder.transmitter(child.get_address()),
- HwsimAttrAddrReceiver(child) => builder.receiver(child.get_address()),
- HwsimAttrFrame(child) => builder.frame(child.get_data()),
- HwsimAttrFlags(child) => builder.flags(child.get_flags()),
- HwsimAttrRxRate(child) => builder.rx_rate(child.get_rx_rate_idx()),
- HwsimAttrSignal(child) => builder.signal(child.get_signal()),
- HwsimAttrCookie(child) => builder.cookie(child.get_cookie()),
- HwsimAttrFreq(child) => builder.freq(child.get_freq()),
- HwsimAttrTxInfo(child) => builder.tx_rates(child.get_tx_rates()),
- HwsimAttrTxInfoFlags(child) => builder.tx_rate_flags(child.get_tx_rate_flags()),
- _ => {
- return Err(anyhow!(
- "Invalid attribute in frame: {:?}",
- hwsim_attr.get_nla_type() as u32
- ))
- }
- };
- index += nla_align(nla_len);
+ pub fn parse(msg: &HwsimMsg) -> anyhow::Result<Frame> {
+ // Only expected to be called with HwsimCmd::Frame
+ if (msg.hwsim_hdr.hwsim_cmd != HwsimCmd::Frame) {
+ panic!("Invalid hwsim_cmd");
}
- builder.build()
+ let attrs = HwsimAttrSet::parse(&msg.attributes).context("HwsimAttrSet")?;
+ let frame = attrs.frame.clone().context("Frame")?;
+ let ieee80211 = Ieee80211::parse(&frame).context("Ieee80211")?;
+ // Required attributes are unwrapped and return an error if
+ // they are not present.
+ Ok(Frame {
+ transmitter: attrs.transmitter.context("transmitter")?,
+ flags: attrs.flags.context("flags")?,
+ tx_info: attrs.tx_info.clone().context("tx_info")?,
+ cookie: attrs.cookie.context("cookie")?,
+ signal: attrs.signal,
+ freq: attrs.freq,
+ data: frame,
+ ieee80211,
+ })
}
}
diff --git a/rust/daemon/src/wifi/hwsim_attr_set.rs b/rust/daemon/src/wifi/hwsim_attr_set.rs
new file mode 100644
index 0000000..2cb6507
--- /dev/null
+++ b/rust/daemon/src/wifi/hwsim_attr_set.rs
@@ -0,0 +1,178 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::ieee80211::MacAddress;
+use super::packets::mac80211_hwsim::HwsimAttrChild::*;
+use super::packets::mac80211_hwsim::{HwsimAttr, HwsimMsg, HwsimMsgHdr, TxRate, TxRateFlag};
+use super::packets::netlink::{NlAttrHdr, NlMsgHdr};
+use anyhow::{anyhow, Context};
+use log::{info, warn};
+
+// Decode the hwsim attributes into a set.
+//
+// Hwsim attributes are used to exchange data between kernel's
+// mac80211_hwsim subsystem and this user space process and include:
+//
+// HWSIM_ATTR_ADDR_TRANSMITTER,
+// HWSIM_ATTR_ADDR_RECEIVER,
+// HWSIM_ATTR_FRAME,
+// HWSIM_ATTR_FLAGS,
+// HWSIM_ATTR_RX_RATE,
+// HWSIM_ATTR_SIGNAL,
+// HWSIM_ATTR_COOKIE,
+// HWSIM_ATTR_FREQ (optional)
+// HWSIM_ATTR_TX_INFO (new use)
+// HWSIM_ATTR_TX_INFO_FLAGS (new use)
+
+const NLA_ALIGNTO: usize = 4;
+
+fn nla_align(len: usize) -> usize {
+ len.wrapping_add(NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
+}
+
+#[derive(Default)]
+struct HwsimAttrSetBuilder {
+ transmitter: Option<MacAddress>,
+ receiver: Option<MacAddress>,
+ frame: Option<Vec<u8>>,
+ flags: Option<u32>,
+ rx_rate_idx: Option<u32>,
+ signal: Option<u32>,
+ cookie: Option<u64>,
+ freq: Option<u32>,
+ tx_info: Option<Vec<TxRate>>,
+ tx_rate_flags: Option<Vec<TxRateFlag>>,
+}
+
+#[derive(Debug)]
+pub struct HwsimAttrSet {
+ pub transmitter: Option<MacAddress>,
+ pub receiver: Option<MacAddress>,
+ pub frame: Option<Vec<u8>>,
+ pub flags: Option<u32>,
+ pub rx_rate_idx: Option<u32>,
+ pub signal: Option<u32>,
+ pub cookie: Option<u64>,
+ pub freq: Option<u32>,
+ pub tx_info: Option<Vec<TxRate>>,
+ pub tx_rate_flags: Option<Vec<TxRateFlag>>,
+}
+
+impl HwsimAttrSetBuilder {
+ fn transmitter(&mut self, transmitter: &[u8; 6]) -> &mut Self {
+ self.transmitter = Some(MacAddress::from(transmitter));
+ self
+ }
+
+ fn receiver(&mut self, receiver: &[u8; 6]) -> &mut Self {
+ self.receiver = Some(MacAddress::from(receiver));
+ self
+ }
+
+ fn frame(&mut self, frame: &[u8]) -> &mut Self {
+ self.frame = Some(frame.to_vec());
+ self
+ }
+
+ fn flags(&mut self, flags: u32) -> &mut Self {
+ self.flags = Some(flags);
+ self
+ }
+
+ fn rx_rate(&mut self, rx_rate_idx: u32) -> &mut Self {
+ self.rx_rate_idx = Some(rx_rate_idx);
+ self
+ }
+
+ fn signal(&mut self, signal: u32) -> &mut Self {
+ self.signal = Some(signal);
+ self
+ }
+
+ fn cookie(&mut self, cookie: u64) -> &mut Self {
+ self.cookie = Some(cookie);
+ self
+ }
+
+ fn freq(&mut self, freq: u32) -> &mut Self {
+ self.freq = Some(freq);
+ self
+ }
+
+ fn tx_info(&mut self, tx_info: &[TxRate]) -> &mut Self {
+ self.tx_info = Some(tx_info.to_vec());
+ self
+ }
+
+ fn tx_rate_flags(&mut self, tx_rate_flags: &[TxRateFlag]) -> &mut Self {
+ self.tx_rate_flags = Some(tx_rate_flags.to_vec());
+ self
+ }
+
+ fn build(mut self) -> anyhow::Result<HwsimAttrSet> {
+ Ok(HwsimAttrSet {
+ transmitter: self.transmitter,
+ receiver: self.receiver,
+ cookie: self.cookie,
+ flags: self.flags,
+ rx_rate_idx: self.rx_rate_idx,
+ signal: self.signal,
+ frame: self.frame,
+ freq: self.freq,
+ tx_info: self.tx_info,
+ tx_rate_flags: self.tx_rate_flags,
+ })
+ }
+}
+
+impl HwsimAttrSet {
+ fn builder() -> HwsimAttrSetBuilder {
+ HwsimAttrSetBuilder::default()
+ }
+
+ // Builds and validates the attributes in the command.
+ pub fn parse(attributes: &[u8]) -> anyhow::Result<HwsimAttrSet> {
+ let mut index: usize = 0;
+ let mut builder = HwsimAttrSet::builder();
+ while (index < attributes.len()) {
+ // Parse a generic netlink attribute to get the size
+ let nla = NlAttrHdr::parse(&attributes[index..index + 4]).unwrap();
+ let nla_len = nla.nla_len as usize;
+ let hwsim_attr = HwsimAttr::parse(&attributes[index..index + nla_len])?;
+ match hwsim_attr.specialize() {
+ HwsimAttrAddrTransmitter(child) => builder.transmitter(child.get_address()),
+ HwsimAttrAddrReceiver(child) => builder.receiver(child.get_address()),
+ HwsimAttrFrame(child) => builder.frame(child.get_data()),
+ HwsimAttrFlags(child) => builder.flags(child.get_flags()),
+ HwsimAttrRxRate(child) => builder.rx_rate(child.get_rx_rate_idx()),
+ HwsimAttrSignal(child) => builder.signal(child.get_signal()),
+ HwsimAttrCookie(child) => builder.cookie(child.get_cookie()),
+ HwsimAttrFreq(child) => builder.freq(child.get_freq()),
+ HwsimAttrTxInfo(child) => builder.tx_info(child.get_tx_rates()),
+ HwsimAttrTxInfoFlags(child) => builder.tx_rate_flags(child.get_tx_rate_flags()),
+ _ => {
+ return Err(anyhow!(
+ "Invalid attribute message: {:?}",
+ hwsim_attr.get_nla_type() as u32
+ ))
+ }
+ };
+ // Manually step through the attribute bytes aligning as
+ // we go because netlink aligns each attribute which isn't
+ // a feature of PDL parser.
+ index += nla_align(nla_len);
+ }
+ builder.build()
+ }
+}
diff --git a/rust/daemon/src/wifi/ieee80211.rs b/rust/daemon/src/wifi/ieee80211.rs
index 7e501b8..54f5301 100644
--- a/rust/daemon/src/wifi/ieee80211.rs
+++ b/rust/daemon/src/wifi/ieee80211.rs
@@ -25,8 +25,20 @@ impl fmt::Display for MacAddress {
let bytes = u64::to_le_bytes(self.0);
write!(
f,
- "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
- bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0],
+ "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
+ bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5],
+ )
+ }
+}
+
+impl fmt::Display for Ieee80211 {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{{ds: {}, src: {}, dst: {}}}",
+ self.get_ds(),
+ self.get_source(),
+ self.get_destination()
)
}
}
@@ -66,6 +78,17 @@ impl Ieee80211 {
&& self.ieee80211.stype == (ManagementSubType::ProbeReq as u8)
}
+ pub fn get_ds(&self) -> String {
+ match self.specialize() {
+ Ieee80211Child::Ieee80211ToAp(hdr) => "ToAp",
+ Ieee80211Child::Ieee80211FromAp(hdr) => "FromAp",
+ Ieee80211Child::Ieee80211Ibss(hdr) => "Ibss",
+ Ieee80211Child::Ieee80211Wds(hdr) => "Wds",
+ _ => panic!("unexpected specialized header"),
+ }
+ .to_string()
+ }
+
pub fn get_source(&self) -> MacAddress {
match self.specialize() {
Ieee80211Child::Ieee80211ToAp(hdr) => hdr.get_source(),
@@ -75,6 +98,16 @@ impl Ieee80211 {
_ => panic!("unexpected specialized header"),
}
}
+
+ pub fn get_destination(&self) -> MacAddress {
+ match self.specialize() {
+ Ieee80211Child::Ieee80211ToAp(hdr) => hdr.get_destination(),
+ Ieee80211Child::Ieee80211FromAp(hdr) => hdr.get_destination(),
+ Ieee80211Child::Ieee80211Ibss(hdr) => hdr.get_destination(),
+ Ieee80211Child::Ieee80211Wds(hdr) => hdr.get_destination(),
+ _ => panic!("unexpected specialized header"),
+ }
+ }
}
fn parse_mac_address(s: &str) -> Option<MacAddress> {
diff --git a/rust/daemon/src/wifi/medium.rs b/rust/daemon/src/wifi/medium.rs
index 11454df..ddaa563 100644
--- a/rust/daemon/src/wifi/medium.rs
+++ b/rust/daemon/src/wifi/medium.rs
@@ -14,15 +14,11 @@
use super::packets::mac80211_hwsim::{HwsimAttr, HwsimCmd, HwsimMsg, HwsimMsgHdr};
use super::packets::netlink::{NlAttrHdr, NlMsgHdr};
+use crate::devices::chip::ChipIdentifier;
use crate::wifi::frame::Frame;
+use crate::wifi::hwsim_attr_set::HwsimAttrSet;
use anyhow::{anyhow, Context};
-use log::{info, warn};
-
-const NLA_ALIGNTO: usize = 4;
-
-fn nla_align(len: usize) -> usize {
- len.wrapping_add(NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
-}
+use log::{debug, info, warn};
#[derive(Debug)]
pub enum HwsimCmdEnum {
@@ -37,16 +33,59 @@ pub enum HwsimCmdEnum {
DelMacAddr,
}
-pub fn parse_hwsim_cmd(packet: &[u8]) -> anyhow::Result<HwsimCmdEnum> {
- match HwsimMsg::parse(packet) {
- Ok(hwsim_msg) => match (hwsim_msg.hwsim_hdr.hwsim_cmd) {
- HwsimCmd::Frame => {
- let frame = Frame::new(&hwsim_msg.attributes)?;
- Ok(HwsimCmdEnum::Frame(Box::new(frame)))
+/// Process commands from the kernel's mac80211_hwsim subsystem.
+///
+/// This is the processing that will be implemented:
+///
+/// * The source MacAddress in 802.11 frames is re-mapped to a globally
+/// unique MacAddress because resumed Emulator AVDs appear with the
+/// same address.
+///
+/// * 802.11 multicast frames are re-broadcast to connected stations.
+///
+pub fn process(chip_id: ChipIdentifier, packet: &[u8]) -> anyhow::Result<()> {
+ let hwsim_msg = HwsimMsg::parse(packet)?;
+ match (hwsim_msg.hwsim_hdr.hwsim_cmd) {
+ HwsimCmd::Frame => {
+ let frame = Frame::parse(&hwsim_msg)?;
+ info!(
+ "Frame chip {}, addr {}, flags {}, cookie {:?}, ieee80211 {}",
+ chip_id, frame.transmitter, frame.flags, frame.cookie, frame.ieee80211
+ );
+ }
+ HwsimCmd::AddMacAddr => {
+ let attr_set = HwsimAttrSet::parse(&hwsim_msg.attributes)?;
+ if let (Some(addr), Some(hwaddr)) = (attr_set.transmitter, attr_set.receiver) {
+ info!("ADD_MAC_ADDR transmitter {:?} receiver {:?}", hwaddr, addr);
+ } else {
+ warn!("ADD_MAC_ADDR missing transmitter or receiver");
+ }
+ }
+ HwsimCmd::DelMacAddr => {
+ let attr_set = HwsimAttrSet::parse(&hwsim_msg.attributes)?;
+ if let (Some(addr), Some(hwaddr)) = (attr_set.transmitter, attr_set.receiver) {
+ info!("DEL_MAC_ADDR transmitter {:?} receiver {:?}", hwaddr, addr);
+ } else {
+ warn!("DEL_MAC_ADDR missing transmitter or receiver");
}
- _ => Err(anyhow!("Unknown HwsimkMsg cmd={:?}", hwsim_msg.hwsim_hdr.hwsim_cmd)),
- },
- Err(e) => Err(anyhow!("Unable to parse netlink message! {:?}", e)),
+ }
+ _ => {
+ info!("Another command found {:?}", hwsim_msg);
+ }
+ }
+ Ok(())
+}
+
+// TODO: move code below here into test module usable from CMake
+
+pub fn parse_hwsim_cmd(packet: &[u8]) -> anyhow::Result<HwsimCmdEnum> {
+ let hwsim_msg = HwsimMsg::parse(packet)?;
+ match (hwsim_msg.hwsim_hdr.hwsim_cmd) {
+ HwsimCmd::Frame => {
+ let frame = Frame::parse(&hwsim_msg)?;
+ Ok(HwsimCmdEnum::Frame(Box::new(frame)))
+ }
+ _ => Err(anyhow!("Unknown HwsimMsg cmd={:?}", hwsim_msg.hwsim_hdr.hwsim_cmd)),
}
}
@@ -72,7 +111,7 @@ pub fn test_parse_hwsim_cmd() {
16, 255, 255, 57, 216, 0, 0, 8, 0, 5, 0, 1, 0, 0, 0, 8, 0, 6, 0, 206, 255, 255, 255, 8, 0,
19, 0, 143, 9, 0, 0,
];
- assert!(parse_hwsim_cmd(&packet2).is_ok());
+ assert!(parse_hwsim_cmd(&packet2).is_err());
// missing cookie attribute
let packet3: Vec<u8> = vec![
@@ -93,7 +132,7 @@ pub fn test_parse_hwsim_cmd() {
0, 0, 2, 90, 3, 36, 1, 0, 0, 0, 0, 8, 0, 5, 0, 1, 0, 0, 0, 8, 0, 6, 0, 206, 255, 255, 255,
8, 0, 19, 0, 143, 9, 0, 0,
];
- assert!(parse_hwsim_cmd(&packet3).is_ok());
+ assert!(parse_hwsim_cmd(&packet3).is_err());
// HwsimkMsg cmd=TxInfoFrame packet
let packet3: Vec<u8> = vec![
diff --git a/rust/daemon/src/wifi/mod.rs b/rust/daemon/src/wifi/mod.rs
index 8891cce..80842a8 100644
--- a/rust/daemon/src/wifi/mod.rs
+++ b/rust/daemon/src/wifi/mod.rs
@@ -18,6 +18,7 @@
#![allow(unused)]
pub(crate) mod frame;
+pub(crate) mod hwsim_attr_set;
pub(crate) mod ieee80211;
pub(crate) mod medium;
pub(crate) mod packets;