packet_builder/
ethernet.rs

1
2#[macro_export]
3macro_rules! ether {
4   ({$($func:ident => $value:expr), *}, $payload_pkt:expr, $protocol:expr, $buf:expr ) => {{
5      const ETHERNET_HEADER_LEN: usize = 14;
6      let total_len = ETHERNET_HEADER_LEN + $payload_pkt.packet().len();
7      let buf_len = $buf.len();
8      let mut pkt = pnet::packet::ethernet::MutableEthernetPacket::new(&mut $buf[buf_len - total_len..]).unwrap();
9      pkt.set_ethertype($protocol);       
10      $(
11        pkt.$func($value);
12      )*
13      // The protocol element of the tuple is not actually used but the compiler requires us to
14      // provide a type.
15     (pkt, None as Option<&u16>)
16   }};
17   ({$($func:ident => $value:expr), *}, $buf:expr) => {{
18      const ETHERNET_HEADER_LEN: usize = 14;
19      let buf_len = $buf.len();
20      let mut pkt = pnet::packet::ethernet::MutableEthernetPacket::new(&mut $buf[buf_len - ETHERNET_HEADER_LEN..]).unwrap();
21      $(
22        pkt.$func($value);
23      )*
24      // The protocol element of the tuple is not actually used but the compiler requires us to
25      // provide a type.
26     (pkt, None as Option<&u16>)
27   }};
28}
29
30
31#[cfg(test)]
32mod tests {
33   use pnet::packet::Packet;
34
35   #[test]
36   fn macro_ether_basic() {
37      let mut buf = vec![0; 14];
38      let (pkt, proto) = ether!({set_destination =>  pnet::util::MacAddr(10,1,3,1,1,2), set_source => pnet::util::MacAddr(10,1,1,1,1,1)}, buf); 
39      assert_eq!(proto, None);
40      let buf_expected = vec![0; 14];
41      let mut pkt_expected = pnet::packet::ethernet::MutableEthernetPacket::owned(buf_expected).unwrap();
42      pkt_expected.set_destination(pnet::util::MacAddr(10,1,3,1,1,2)); 
43      pkt_expected.set_source(pnet::util::MacAddr(10,1,1,1,1,1)); 
44      assert_eq!(pkt_expected.packet(), pkt.packet());
45   }
46}