xref: /aosp_15_r20/tools/netsim/rust/daemon/src/wifi/radiotap.rs (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*cf78ab8cSAndroid Build Coastguard Worker //
3*cf78ab8cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*cf78ab8cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*cf78ab8cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*cf78ab8cSAndroid Build Coastguard Worker //
7*cf78ab8cSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*cf78ab8cSAndroid Build Coastguard Worker //
9*cf78ab8cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*cf78ab8cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*cf78ab8cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cf78ab8cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*cf78ab8cSAndroid Build Coastguard Worker // limitations under the License.
14*cf78ab8cSAndroid Build Coastguard Worker 
15*cf78ab8cSAndroid Build Coastguard Worker /// Produce PCAP Radiotap buffers from Hwsim Frames
16*cf78ab8cSAndroid Build Coastguard Worker ///
17*cf78ab8cSAndroid Build Coastguard Worker /// This module produces the Radiotap buffers used by PCAP and PcapNG
18*cf78ab8cSAndroid Build Coastguard Worker /// for logging 802.11 frames.
19*cf78ab8cSAndroid Build Coastguard Worker ///
20*cf78ab8cSAndroid Build Coastguard Worker /// See https://www.radiotap.org/
21*cf78ab8cSAndroid Build Coastguard Worker use crate::wifi::frame::Frame;
22*cf78ab8cSAndroid Build Coastguard Worker use crate::wifi::medium;
23*cf78ab8cSAndroid Build Coastguard Worker use crate::wifi::medium::HwsimCmdEnum;
24*cf78ab8cSAndroid Build Coastguard Worker use log::info;
25*cf78ab8cSAndroid Build Coastguard Worker 
26*cf78ab8cSAndroid Build Coastguard Worker #[repr(C, packed)]
27*cf78ab8cSAndroid Build Coastguard Worker struct RadiotapHeader {
28*cf78ab8cSAndroid Build Coastguard Worker     version: u8,
29*cf78ab8cSAndroid Build Coastguard Worker     pad: u8,
30*cf78ab8cSAndroid Build Coastguard Worker     len: u16,
31*cf78ab8cSAndroid Build Coastguard Worker     present: u32,
32*cf78ab8cSAndroid Build Coastguard Worker     channel: ChannelInfo,
33*cf78ab8cSAndroid Build Coastguard Worker     signal: u8,
34*cf78ab8cSAndroid Build Coastguard Worker }
35*cf78ab8cSAndroid Build Coastguard Worker 
36*cf78ab8cSAndroid Build Coastguard Worker #[repr(C)]
37*cf78ab8cSAndroid Build Coastguard Worker struct ChannelInfo {
38*cf78ab8cSAndroid Build Coastguard Worker     freq: u16,
39*cf78ab8cSAndroid Build Coastguard Worker     flags: u16,
40*cf78ab8cSAndroid Build Coastguard Worker }
41*cf78ab8cSAndroid Build Coastguard Worker 
into_pcap(packet: &[u8]) -> Option<Vec<u8>>42*cf78ab8cSAndroid Build Coastguard Worker pub fn into_pcap(packet: &[u8]) -> Option<Vec<u8>> {
43*cf78ab8cSAndroid Build Coastguard Worker     match medium::parse_hwsim_cmd(packet) {
44*cf78ab8cSAndroid Build Coastguard Worker         Ok(HwsimCmdEnum::Frame(frame)) => frame_into_pcap(*frame).ok(),
45*cf78ab8cSAndroid Build Coastguard Worker         Ok(_) => None,
46*cf78ab8cSAndroid Build Coastguard Worker         Err(e) => {
47*cf78ab8cSAndroid Build Coastguard Worker             info!("Failed to convert packet to pcap format. Err: {}. Packet: {:?}", e, &packet);
48*cf78ab8cSAndroid Build Coastguard Worker             None
49*cf78ab8cSAndroid Build Coastguard Worker         }
50*cf78ab8cSAndroid Build Coastguard Worker     }
51*cf78ab8cSAndroid Build Coastguard Worker }
52*cf78ab8cSAndroid Build Coastguard Worker 
frame_into_pcap(frame: Frame) -> anyhow::Result<Vec<u8>>53*cf78ab8cSAndroid Build Coastguard Worker pub fn frame_into_pcap(frame: Frame) -> anyhow::Result<Vec<u8>> {
54*cf78ab8cSAndroid Build Coastguard Worker     // Create an instance of the RadiotapHeader with fields for
55*cf78ab8cSAndroid Build Coastguard Worker     // Channel and Signal.  In the future add more fields from the
56*cf78ab8cSAndroid Build Coastguard Worker     // Frame.
57*cf78ab8cSAndroid Build Coastguard Worker 
58*cf78ab8cSAndroid Build Coastguard Worker     let radiotap_hdr: RadiotapHeader = RadiotapHeader {
59*cf78ab8cSAndroid Build Coastguard Worker         version: 0,
60*cf78ab8cSAndroid Build Coastguard Worker         pad: 0,
61*cf78ab8cSAndroid Build Coastguard Worker         len: (std::mem::size_of::<RadiotapHeader>() as u16),
62*cf78ab8cSAndroid Build Coastguard Worker         present: (1 << 3 /* channel */ | 1 << 5/* signal dBm */),
63*cf78ab8cSAndroid Build Coastguard Worker         channel: ChannelInfo { freq: frame.freq.unwrap_or(0) as u16, flags: 0 },
64*cf78ab8cSAndroid Build Coastguard Worker         signal: frame.signal.unwrap_or(0) as u8,
65*cf78ab8cSAndroid Build Coastguard Worker     };
66*cf78ab8cSAndroid Build Coastguard Worker 
67*cf78ab8cSAndroid Build Coastguard Worker     // Add the struct fields to the buffer manually in little-endian.
68*cf78ab8cSAndroid Build Coastguard Worker     let mut buffer = Vec::<u8>::new();
69*cf78ab8cSAndroid Build Coastguard Worker     buffer.push(radiotap_hdr.version);
70*cf78ab8cSAndroid Build Coastguard Worker     buffer.push(radiotap_hdr.pad);
71*cf78ab8cSAndroid Build Coastguard Worker     buffer.extend_from_slice(&radiotap_hdr.len.to_le_bytes());
72*cf78ab8cSAndroid Build Coastguard Worker     buffer.extend_from_slice(&radiotap_hdr.present.to_le_bytes());
73*cf78ab8cSAndroid Build Coastguard Worker     buffer.extend_from_slice(&radiotap_hdr.channel.freq.to_le_bytes());
74*cf78ab8cSAndroid Build Coastguard Worker     buffer.extend_from_slice(&radiotap_hdr.channel.flags.to_le_bytes());
75*cf78ab8cSAndroid Build Coastguard Worker     buffer.push(radiotap_hdr.signal);
76*cf78ab8cSAndroid Build Coastguard Worker     buffer.extend_from_slice(&frame.data);
77*cf78ab8cSAndroid Build Coastguard Worker 
78*cf78ab8cSAndroid Build Coastguard Worker     Ok(buffer)
79*cf78ab8cSAndroid Build Coastguard Worker }
80