1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::Result;
use crate::phy::{self, DeviceCapabilities, Device};
use crate::time::Instant;
const MTU: usize = 1536;
pub trait Fuzzer {
fn fuzz_packet(&self, packet_data: &mut [u8]);
}
#[allow(unused)]
#[derive(Debug)]
pub struct FuzzInjector<D: for<'a> Device<'a>, FTx: Fuzzer, FRx: Fuzzer> {
inner: D,
fuzz_tx: FTx,
fuzz_rx: FRx,
}
#[allow(unused)]
impl<D: for<'a> Device<'a>, FTx: Fuzzer, FRx: Fuzzer> FuzzInjector<D, FTx, FRx> {
pub fn new(inner: D, fuzz_tx: FTx, fuzz_rx: FRx) -> FuzzInjector<D, FTx, FRx> {
FuzzInjector { inner, fuzz_tx, fuzz_rx }
}
pub fn into_inner(self) -> D {
self.inner
}
}
impl<'a, D, FTx, FRx> Device<'a> for FuzzInjector<D, FTx, FRx>
where D: for<'b> Device<'b>,
FTx: Fuzzer + 'a,
FRx: Fuzzer + 'a
{
type RxToken = RxToken<'a, <D as Device<'a>>::RxToken, FRx>;
type TxToken = TxToken<'a, <D as Device<'a>>::TxToken, FTx>;
fn capabilities(&self) -> DeviceCapabilities {
let mut caps = self.inner.capabilities();
if caps.max_transmission_unit > MTU {
caps.max_transmission_unit = MTU;
}
caps
}
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
let &mut Self { ref mut inner, ref fuzz_rx, ref fuzz_tx } = self;
inner.receive().map(|(rx_token, tx_token)| {
let rx = RxToken {
fuzzer: fuzz_rx,
token: rx_token,
};
let tx = TxToken {
fuzzer: fuzz_tx,
token: tx_token,
};
(rx, tx)
})
}
fn transmit(&'a mut self) -> Option<Self::TxToken> {
let &mut Self { ref mut inner, fuzz_rx: _, ref fuzz_tx } = self;
inner.transmit().map(|token| TxToken {
fuzzer: fuzz_tx,
token: token,
})
}
}
#[doc(hidden)]
pub struct RxToken<'a, Rx: phy::RxToken, F: Fuzzer + 'a>{
fuzzer: &'a F,
token: Rx,
}
impl<'a, Rx: phy::RxToken, FRx: Fuzzer> phy::RxToken for RxToken<'a, Rx, FRx> {
fn consume<R, F>(self, timestamp: Instant, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let Self { fuzzer, token } = self;
token.consume(timestamp, |buffer| {
fuzzer.fuzz_packet(buffer);
f(buffer)
})
}
}
#[doc(hidden)]
pub struct TxToken<'a, Tx: phy::TxToken, F: Fuzzer + 'a> {
fuzzer: &'a F,
token: Tx,
}
impl<'a, Tx: phy::TxToken, FTx: Fuzzer> phy::TxToken for TxToken<'a, Tx, FTx> {
fn consume<R, F>(self, timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let Self { fuzzer, token } = self;
token.consume(timestamp, len, |mut buf| {
fuzzer.fuzz_packet(&mut buf);
f(buf)
})
}
}