diff --git a/src/beacon.rs b/src/beacon.rs index 0c74e4c..815db0a 100644 --- a/src/beacon.rs +++ b/src/beacon.rs @@ -47,6 +47,7 @@ pub fn distribute(pcd: PathBuf, region: GGID, device: String, address: MacAddres let broadcast_addr: MacAddress = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; eprintln!("Use device '{}' with ethernet address '{:02x?}' and broadcast address '{:02x?}'", device, address, broadcast_addr); let mut cap = pcap::Capture::from_device(device.as_str())?.open()?; + eprintln!("Open wondercard file '{}'", pcd.as_path().display()); let pcd: PCD = PCD::try_from(fs::read(pcd)?.as_slice())?; let partitioned: PCD = pcd.into(); let header = partitioned.header(); @@ -55,6 +56,7 @@ pub fn distribute(pcd: PathBuf, region: GGID, device: String, address: MacAddres eprintln!("Wondercard has checksum {:04x}", checksum); let encrypted = extended.encrypt(&address)?; let generator = BeaconFrameGenerator::new(address, region, &encrypted, header, checksum); + eprintln!("Distributing in {} µs intervals for region '{}'...", interval, region); for packet in generator { cap.sendpacket(packet.as_slice())?; thread::sleep(Duration::from_micros(interval)); @@ -198,6 +200,23 @@ const WIRELESS_MANAGEMENT: [u8; 32] = [ /// /// Returns a [Vec] containing the constructed packet. /// +fn packet(frames_count: u32, fragment_index: u16, checksum: u16, payload_length: u32, packet_payload: PCDFragment, ggid: GGID) -> Vec { + [ + frames_count.to_le_bytes().as_slice(), + &0x1u16.to_le_bytes(), + &0x1u16.to_le_bytes(), + &(ggid as u32).to_le_bytes(), + &0x0u16.to_le_bytes(), + &0x70u16.to_le_bytes(), + &0x28u16.to_le_bytes(), + &0xcu16.to_le_bytes(), + &checksum.to_le_bytes(), + &(if fragment_index == (frames_count - 1) as u16 { 0xffff } else { fragment_index }).to_le_bytes(), + &payload_length.to_le_bytes(), + &packet_payload + ].concat() +} + fn wireless_management(packet: Vec) -> Vec { [ WIRELESS_MANAGEMENT.as_slice(), diff --git a/src/main.rs b/src/main.rs index 4c12431..8ed99db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use std::error::Error; +use std::fmt::{Display, Formatter}; use std::path::PathBuf; use std::result::Result; @@ -106,6 +107,21 @@ pub enum GGID { Korean = 0xc00018, } +impl Display for GGID { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str( + match self { + GGID::Japanese => "jp", + GGID::English => "en", + GGID::French => "fr", + GGID::German => "de", + GGID::Italian => "it", + GGID::Spanish => "es", + GGID::Korean => "ko", + }) + } +} + /// A simple MAC Address representation. type MacAddress = [u8; 6];