1use pnet::datalink::{self, PacketMetadata as PnetPacketMetadata};
4use std::{
5 sync::{Arc, Mutex},
6 time,
7};
8
9use crate::{
10 error::{RLanLibError, Result},
11 network::NetworkInterface,
12};
13
14pub const DEFAULT_PACKET_SEND_TIMING: time::Duration =
19 time::Duration::from_micros(200);
20
21pub type PacketMetadata = PnetPacketMetadata;
23
24pub trait Reader: Send {
26 fn next_packet(&mut self) -> Result<&[u8]>;
28 fn next_packet_with_metadata(&mut self) -> Result<(&[u8], PacketMetadata)>;
30}
31
32pub trait Sender: Send {
34 fn send(&mut self, packet: &[u8]) -> Result<()>;
36}
37
38#[derive(Clone)]
40pub struct Wire(pub Arc<Mutex<dyn Sender>>, pub Arc<Mutex<dyn Reader>>);
41
42pub struct PNetReader {
44 receiver: Box<dyn datalink::DataLinkReceiver>,
45}
46
47impl Reader for PNetReader {
49 fn next_packet(&mut self) -> Result<&[u8]> {
50 self.receiver
51 .next()
52 .map_err(|e| RLanLibError::Wire(e.to_string()))
53 }
54
55 fn next_packet_with_metadata(&mut self) -> Result<(&[u8], PacketMetadata)> {
56 self.receiver
57 .next_with_metadata()
58 .map_err(|e| RLanLibError::Wire(e.to_string()))
59 }
60}
61
62pub struct PNetSender {
64 sender: Box<dyn datalink::DataLinkSender>,
65}
66
67impl Sender for PNetSender {
69 fn send(&mut self, packet: &[u8]) -> Result<()> {
70 let opt = self.sender.send_to(packet, None);
71 match opt {
72 Some(res) => {
73 Ok(res.map_err(|e| RLanLibError::Wire(e.to_string()))?)
74 }
75 None => Err(RLanLibError::Wire("failed to send packet".into())),
76 }
77 }
78}
79
80pub fn default(interface: &NetworkInterface) -> Result<Wire> {
91 let cfg = pnet::datalink::Config {
92 enable_timestamps: true,
93 read_buffer_size: 65536, write_buffer_size: 65536, ..pnet::datalink::Config::default()
96 };
97
98 let channel = match pnet::datalink::channel(&interface.into(), cfg) {
99 Ok(pnet::datalink::Channel::Ethernet(tx, rx)) => Ok((tx, rx)),
100 Ok(_) => {
101 Err(RLanLibError::Wire("failed to create packet reader".into()))
102 }
103 Err(e) => Err(RLanLibError::Wire(e.to_string())),
104 }?;
105
106 Ok(Wire(
107 Arc::new(Mutex::new(PNetSender { sender: channel.0 })),
108 Arc::new(Mutex::new(PNetReader {
109 receiver: channel.1,
110 })),
111 ))
112}
113
114#[cfg(test)]
115#[path = "./wire_tests.rs"]
116mod tests;
117
118#[cfg(test)]
120pub mod mocks {
121 use mockall::mock;
122
123 use super::*;
124
125 mock! {
126 pub PacketReader {}
127 impl Reader for PacketReader {
128 fn next_packet(&mut self) -> Result<&'static [u8]>;
129 fn next_packet_with_metadata(&mut self) -> Result<(&'static [u8], PacketMetadata)>;
130 }
131 }
132
133 mock! {
134 pub PacketSender {}
135 impl Sender for PacketSender {
136 fn send(&mut self, packet: &[u8]) -> Result<()>;
137 }
138 }
139}