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
#![macro_use]
#![allow(unused_macros)]

extern crate derive_new;
extern crate ipnetwork;
extern crate pnet;

pub mod icmp;
pub mod tcp;
pub mod udp;
pub mod ethernet;
pub mod arp;
pub mod vlan;
pub mod ipv4;
pub mod payload;

use std::net::Ipv4Addr;

pub trait L4Checksum {
  fn checksum_ipv4(&mut self, source: &Ipv4Addr, destination: &Ipv4Addr) -> ();
}

#[macro_export]
macro_rules! build_channel {
  ($ifname:expr) => {{
    let interfaces = pnet_datalink::interfaces();
    let interface = interfaces
        .into_iter()
        .find(|iface| iface.name == $ifname)
        .unwrap();

    let (sender, receiver) = match pnet_datalink::channel(&interface, Default::default()) {
        Ok(pnet_datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
        Ok(_) => panic!("Unknown channel type"),
        Err(e) => panic!("Error happened {}", e),
    };
    (sender, receiver)
  }};
}


#[macro_export]
macro_rules! sub_builder {
    ($pkt_buf:expr, $build_macro:ident($args:tt) $(/ $rem_macros:ident($rem_args:tt))+) => {{
      let (mut payload_pkt, _payload_proto) = sub_builder!($pkt_buf, $($rem_macros($rem_args) )/ *);
      let (pkt, proto) = $build_macro!($args, payload_pkt, _payload_proto, $pkt_buf);
      (pkt, proto)
    }}; 
   ($pkt_buf:expr, $build_macro:ident($args:tt)) => {{
      $build_macro!($args, $pkt_buf)
   }};
}

// Call the sub builder so we can return just the packet rather than the tuple that gets returned
// by the sub builder for use during the recursion.
#[macro_export]
macro_rules! packet_builder {
   ($pkt_buf:expr, $( $rem_macros:ident($rem_args:tt))/ * ) => {{
    let (pkt, _proto) = sub_builder!($pkt_buf, $( $rem_macros($rem_args) )/ *);
    pkt
   }};
}