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
#[macro_export]
macro_rules! ether {
({$($func:ident => $value:expr), *}, $payload_pkt:expr, $protocol:expr, $buf:expr ) => {{
const ETHERNET_HEADER_LEN: usize = 14;
let total_len = ETHERNET_HEADER_LEN + $payload_pkt.packet().len();
let buf_len = $buf.len();
let mut pkt = pnet::packet::ethernet::MutableEthernetPacket::new(&mut $buf[buf_len - total_len..]).unwrap();
pkt.set_ethertype($protocol);
$(
pkt.$func($value);
)*
(pkt, None as Option<&u16>)
}};
({$($func:ident => $value:expr), *}, $buf:expr) => {{
const ETHERNET_HEADER_LEN: usize = 14;
let buf_len = $buf.len();
let mut pkt = pnet::packet::ethernet::MutableEthernetPacket::new(&mut $buf[buf_len - ETHERNET_HEADER_LEN..]).unwrap();
$(
pkt.$func($value);
)*
(pkt, None as Option<&u16>)
}};
}
#[cfg(test)]
mod tests {
use pnet::packet::Packet;
#[test]
fn macro_ether_basic() {
let mut buf = vec![0; 14];
let (pkt, proto) = ether!({set_destination => pnet_base::MacAddr(10,1,3,1,1,2), set_source => pnet_base::MacAddr(10,1,1,1,1,1)}, buf);
assert_eq!(proto, None);
let buf_expected = vec![0; 14];
let mut pkt_expected = pnet::packet::ethernet::MutableEthernetPacket::owned(buf_expected).unwrap();
pkt_expected.set_destination(pnet_base::MacAddr(10,1,3,1,1,2));
pkt_expected.set_source(pnet_base::MacAddr(10,1,1,1,1,1));
assert_eq!(pkt_expected.packet(), pkt.packet());
}
}