antarctic-obscurity/src/main.rs

85 lines
2.8 KiB
Rust

use pcap::Capture;
use stable_eyre::eyre::{eyre, Result};
mod ieee80211 {
use int_enum::IntEnum;
use std::convert::TryFrom;
// data/extension frames are irrelevant so just ignore their subtype
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum FrameType {
Management(ManagementSubtype),
Control(ControlSubtype),
Data,
Extension
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntEnum)]
pub enum ManagementSubtype {
ProbeRequest = 0b0100,
ProbeResponse = 0b0101,
TimingAdvertisement = 0b0110,
Beacon = 0b1000
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntEnum)]
pub enum ControlSubtype {
Rts = 0b1011,
Cts = 0b1100,
Ack = 0b1101
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct FrameControl {
pub version: u8,
pub ftype: FrameType
}
pub fn parse_frame_control(version_type_subtype: u8, flags: u8) -> Option<FrameControl> {
let subtype = version_type_subtype >> 4 & 0b1111;
let ftype = match version_type_subtype >> 2 & 0b11 {
0b00 => FrameType::Management(ManagementSubtype::try_from(subtype).ok()?),
0b01 => FrameType::Control(ControlSubtype::try_from(subtype).ok()?),
0b10 => FrameType::Data,
0b11 => FrameType::Extension,
_ => unreachable!()
};
Some(FrameControl {
version: version_type_subtype & 0b11,
ftype: ftype
})
}
pub struct MacAddress([u8; 12]);
}
fn main() -> Result<()> {
let cap = Capture::from_device("mon0")?.immediate_mode(true);
let mut cap = cap.open()?;
if cap.get_datalink() != pcap::Linktype::IEEE802_11_RADIOTAP { return Err(eyre!("device link type wrong")) }
while let Ok(packet) = cap.next() {
//println!("{:?}", packet);
match radiotap::parse(packet.data) {
Ok(header) => {
let data = &packet.data[header.length()..];
match ieee80211::parse_frame_control(data[0], data[1]) {
Some(x) if x.ftype != ieee80211::FrameType::Data => {
println!("RTH={:?} FH={:?} MAC1={:?}", header, x, &data[4..10]);
if data.len() >= 16 { println!("MAC2={:?}", &data[10..16]); }
if data.len() >= 22 { println!("MAC3={:?}", &data[16..22]); }
},
_ => {}
}
},
// This happens sometimes. I don't know why, since it really shouldn't (the radiotap headers are applied by the kernel). Thusly, just ignore it and hope it goes away.
Err(e) => {
eprintln!("header decoding failed: {:?}", e);
}
}
}
Ok(())
}