mirror of
https://github.com/jgoerzen/xbnet.git
synced 2025-01-10 14:38:20 -04:00
adding
This commit is contained in:
parent
d0019d718e
commit
a7feabb93b
54
src/tap.rs
54
src/tap.rs
@ -29,10 +29,9 @@ use crossbeam_channel;
|
|||||||
use etherparse::*;
|
use etherparse::*;
|
||||||
use log::*;
|
use log::*;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{Read, Write};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::mem::drop;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use ifstructs::ifreq;
|
use ifstructs::ifreq;
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
@ -46,6 +45,12 @@ pub struct XBTap {
|
|||||||
pub myethermacstr: String,
|
pub myethermacstr: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub tap: Arc<Iface>,
|
pub tap: Arc<Iface>,
|
||||||
|
|
||||||
|
/** We can't just blindly generate destination MACs because there is a bug
|
||||||
|
in the firmware that causes the radio to lock up if we send too many
|
||||||
|
packets to a MAC that's not online. So, we keep a translation map of
|
||||||
|
MACs we've seen. */
|
||||||
|
pub dests: Arc<Mutex<HashMap<[u8; 6], u64>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XBTap {
|
impl XBTap {
|
||||||
@ -82,14 +87,17 @@ impl XBTap {
|
|||||||
myxbmac
|
myxbmac
|
||||||
);
|
);
|
||||||
|
|
||||||
let name = String::from(tap.name());
|
let mut desthm = HashMap::new();
|
||||||
|
desthm.insert(ETHER_BROADCAST, XB_BROADCAST);
|
||||||
|
|
||||||
|
|
||||||
Ok(XBTap {
|
Ok(XBTap {
|
||||||
myxbmac,
|
myxbmac,
|
||||||
myethermac,
|
myethermac,
|
||||||
myethermacstr,
|
myethermacstr,
|
||||||
name,
|
name: String::from(name),
|
||||||
tap: Arc::new(tap),
|
tap: Arc::new(tap),
|
||||||
|
dests: Arc::new(Mutex::new(desthm)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,30 +117,30 @@ impl XBTap {
|
|||||||
}
|
}
|
||||||
Ok(packet) => {
|
Ok(packet) => {
|
||||||
if let Some(LinkSlice::Ethernet2(header)) = packet.link {
|
if let Some(LinkSlice::Ethernet2(header)) = packet.link {
|
||||||
|
trace!("TAPIN: Packet is {} -> {}", hex::encode(header.source()), hex::encode(header.destination()));
|
||||||
if header.source() != &self.myethermac {
|
if header.source() != &self.myethermac {
|
||||||
warn!("Packet from tap with MAC address {} mismatches my own MAC address of {}; proceeding anyway",
|
warn!("Packet from tap with MAC address {} mismatches my own MAC address of {}; proceeding anyway",
|
||||||
showmac(header.source().try_into().unwrap()), self.myethermacstr);
|
showmac(header.source().try_into().unwrap()), self.myethermacstr);
|
||||||
}
|
}
|
||||||
let destxbmac = if header.destination() == ETHER_BROADCAST {
|
match self.dests.lock().unwrap().get(header.destination()) {
|
||||||
XB_BROADCAST
|
None =>
|
||||||
} else {
|
warn!("Destination MAC address unknown; discarding packet"),
|
||||||
mac48to64(header.destination().try_into().unwrap(), self.myxbmac)
|
Some(destxbmac) =>
|
||||||
};
|
{
|
||||||
trace!("TAPIN: Packet is {} -> {}", hex::encode(header.source()), hex::encode(header.destination()));
|
|
||||||
|
|
||||||
let res =
|
let res =
|
||||||
sender
|
sender
|
||||||
.try_send(XBTX::TXData(
|
.try_send(XBTX::TXData(
|
||||||
XBDestAddr::U64(destxbmac),
|
XBDestAddr::U64(*destxbmac),
|
||||||
Bytes::copy_from_slice(tapdata),
|
Bytes::copy_from_slice(tapdata),
|
||||||
));
|
));
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(crossbeam_channel::TrySendError::Full(_)) =>
|
Err(crossbeam_channel::TrySendError::Full(_)) =>
|
||||||
debug!("Dropped packet due to full TX buffer")
|
debug!("Dropped packet due to full TX buffer"),
|
||||||
,
|
|
||||||
Err(e) => Err(e).unwrap(),
|
Err(e) => Err(e).unwrap(),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!("Unable to get Ethernet2 header from tap packet; discarding");
|
warn!("Unable to get Ethernet2 header from tap packet; discarding");
|
||||||
}
|
}
|
||||||
@ -145,7 +153,21 @@ impl XBTap {
|
|||||||
xbreframer: &mut XBReframer,
|
xbreframer: &mut XBReframer,
|
||||||
ser: &mut XBSerReader) -> io::Result<()> {
|
ser: &mut XBSerReader) -> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
let (_fromu64, _fromu16, payload) = xbreframer.rxframe(ser);
|
let (fromu64, _fromu16, payload) = xbreframer.rxframe(ser);
|
||||||
|
|
||||||
|
// Register the sender in our map of known MACs
|
||||||
|
match SlicedPacket::from_ethernet(&payload) {
|
||||||
|
Err(x) => {
|
||||||
|
warn!("Packet from XBee wasn't valid Ethernet; continueing anyhow: {:?}", x);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.tap.send(&payload)?;
|
self.tap.send(&payload)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user