From 1a5c2c47bf56cceb284bb56aa4e4e9c025dafee1 Mon Sep 17 00:00:00 2001 From: John Goerzen Date: Thu, 24 Sep 2020 21:16:25 -0500 Subject: [PATCH] Some more things handled here --- src/main.rs | 20 +++++++++++++++++--- src/tap.rs | 34 ++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2058081..06df5d6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,7 +75,21 @@ enum Command { // FIXME: add a paremter to accept data from only that place }, /// Create a virtual Ethernet interface and send frames across XBee - Tap, + Tap { + /// Broadcast to XBee, instead of dropping, packets to unknown destinations. Has no effect if --broadcast_everything is given. + #[structopt(long)] + broadcast_unknown: bool, + + /// Broadcast every packet out the XBee side + #[structopt(long)] + broadcast_everything: bool, + + /// Name for the interface; defaults to "xbnet%d" which the OS usually turns to "xbnet0". + /// Note that this name is not guaranteed; the name allocated by the OS is displayed + /// at startup. + #[structopt(long, default_value = "xbnet%d")] + iface_name: String, + }, } fn main() { @@ -118,8 +132,8 @@ fn main() { // Make sure queued up data is sent let _ = writerthread.join(); } - Command::Tap => { - let tap_reader = tap::XBTap::new_tap(xb.mymac).expect("Failure initializing tap"); + Command::Tap { broadcast_unknown, broadcast_everything, iface_name } => { + let tap_reader = tap::XBTap::new_tap(xb.mymac, broadcast_unknown, broadcast_everything, iface_name).expect("Failure initializing tap"); let tap_writer = tap_reader.clone(); let maxpacketsize = xb.maxpacketsize; thread::spawn(move || { diff --git a/src/tap.rs b/src/tap.rs index d5f5a6f..056b4a1 100644 --- a/src/tap.rs +++ b/src/tap.rs @@ -44,6 +44,8 @@ pub struct XBTap { pub myxbmac: u64, pub myethermacstr: String, pub name: String, + pub broadcast_unknown: bool, + pub broadcast_everything: bool, pub tap: Arc, /** We can't just blindly generate destination MACs because there is a bug @@ -54,10 +56,10 @@ pub struct XBTap { } impl XBTap { - pub fn new_tap(myxbmac: u64) -> io::Result { + pub fn new_tap(myxbmac: u64, broadcast_unknown: bool, broadcast_everything: bool, iface_name_requested: String) -> io::Result { let myethermac = mac64to48(myxbmac); let myethermacstr = showmac(&myethermac); - let tap = Iface::without_packet_info("xbnet%d", Mode::Tap)?; + let tap = Iface::without_packet_info(&iface_name_requested, Mode::Tap)?; let name = tap.name(); // Set the MAC address. @@ -84,7 +86,7 @@ impl XBTap { "Interface {} with ether MAC {} (XBee MAC {:x}) ready", name, myethermacstr, - myxbmac + myxbmac, ); let mut desthm = HashMap::new(); @@ -95,12 +97,30 @@ impl XBTap { myxbmac, myethermac, myethermacstr, + broadcast_unknown, + broadcast_everything, name: String::from(name), tap: Arc::new(tap), dests: Arc::new(Mutex::new(desthm)), }) } + pub fn get_xb_dest_mac(&self, ethermac: &[u8; 6]) -> Option { + if self.broadcast_everything { + return Some(XB_BROADCAST); + } + + match self.dests.lock().unwrap().get(ethermac) { + None => + if self.broadcast_unknown { + Some(XB_BROADCAST) + } else { + None + }, + Some(dest) => Some(*dest), + } + } + pub fn frames_from_tap_processor( &self, maxframesize: usize, @@ -122,7 +142,7 @@ impl XBTap { warn!("Packet from tap with MAC address {} mismatches my own MAC address of {}; proceeding anyway", showmac(header.source().try_into().unwrap()), self.myethermacstr); } - match self.dests.lock().unwrap().get(header.destination()) { + match self.get_xb_dest_mac(header.destination().try_into().unwrap()) { None => warn!("Destination MAC address unknown; discarding packet"), Some(destxbmac) => @@ -130,7 +150,7 @@ impl XBTap { let res = sender .try_send(XBTX::TXData( - XBDestAddr::U64(*destxbmac), + XBDestAddr::U64(destxbmac), Bytes::copy_from_slice(tapdata), )); match res { @@ -163,7 +183,9 @@ impl XBTap { Ok(packet) => { if let Some(LinkSlice::Ethernet2(header)) = packet.link { trace!("SERIN: Packet Ethernet header is {} -> {}", hex::encode(header.source()), hex::encode(header.destination())); - self.dests.lock().unwrap().insert(header.source().try_into().unwrap(), fromu64); + if ! self.broadcast_everything { + self.dests.lock().unwrap().insert(header.source().try_into().unwrap(), fromu64); + } } } }