net_parser_rs/layer4/
vxlan.rs1use crate::Error;
2use byteorder::{BigEndian as BE, WriteBytesExt};
3use nom::*;
4use std::mem::size_of;
5use std::io::{Cursor, Write};
6
7#[derive(Clone, Copy, Debug)]
8pub struct Vxlan<'a> {
9 pub flags: u16,
10 pub group_policy_id: u16,
11 pub raw_network_identifier: u32,
12 pub network_identifier: u32, pub payload: &'a [u8],
14}
15
16impl<'a> Vxlan<'a> {
17 pub fn as_bytes(&self) -> Vec<u8> {
18 let inner = Vec::with_capacity(
19 size_of::<u16>() * 2
20 + size_of::<u32>()
21 + self.payload.len()
22 );
23 let mut writer = Cursor::new(inner);
24 writer.write_u16::<BE>(self.flags).unwrap();
25 writer.write_u16::<BE>(self.group_policy_id).unwrap();
26 writer.write_u32::<BE>(self.raw_network_identifier).unwrap();
27 writer.write(self.payload).unwrap();
28 writer.into_inner()
29 }
30
31 pub fn parse<'b>(input: &'b [u8], endianness: nom::Endianness) -> Result<(&'b [u8], Vxlan<'b>), Error> {
32 do_parse!(input,
34 flags: u16!(endianness) >>
35 group_policy_id: u16!(endianness) >>
36 network_identifier: u32!(endianness) >> payload: rest >> (
39 Vxlan {
40 flags: flags,
41 group_policy_id: group_policy_id,
42 raw_network_identifier: network_identifier,
43 network_identifier: network_identifier>>8,
44 payload: payload
45 }
46 )
47 ).map_err(Error::from)
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use crate::{
54 layer2::ethernet::Ethernet,
55 layer3::ipv4::IPv4,
56 layer4::{
57 udp::Udp,
58 vxlan::Vxlan,
59 },
60 tests::util::parse_hex_dump,
61 };
62
63 #[test]
64 fn encapsulated() {
65 let bytes = parse_hex_dump(r##"
67 # Frame 3: 148 bytes on wire (1184 bits), 148 bytes captured (1184 bits) on interface 0
68 # Ethernet II, Src: CadmusCo_ae:4d:62 (08:00:27:ae:4d:62), Dst: CadmusCo_f2:1d:8c (08:00:27:f2:1d:8c)
69 # Internet Protocol Version 4, Src: 192.168.56.11, Dst: 192.168.56.12
70 # User Datagram Protocol, Src Port: 48134 (48134), Dst Port: 4789 (4789)
71 # Virtual eXtensible Local Area Network
72 # Ethernet II, Src: ba:09:2b:6e:f8:be (ba:09:2b:6e:f8:be), Dst: 4a:7f:01:3b:a2:71 (4a:7f:01:3b:a2:71)
73 # Internet Protocol Version 4, Src: 10.0.0.1, Dst: 10.0.0.2
74 # Internet Control Message Protocol
75 0000 08 00 27 f2 1d 8c 08 00 27 ae 4d 62 08 00 45 00 ..'.....'.Mb..E.
76 0010 00 86 d9 99 40 00 40 11 6f 65 c0 a8 38 0b c0 a8 ....@.@.oe..8...
77 0020 38 0c bc 06 12 b5 00 72 00 00 08 00 00 00 00 00 8......r........
78 0030 7b 00 4a 7f 01 3b a2 71 ba 09 2b 6e f8 be 08 00 {.J..;.q..+n....
79 0040 45 00 00 54 2f 4f 40 00 40 01 f7 57 0a 00 00 01 E..T/O@.@..W....
80 0050 0a 00 00 02 08 00 4c 8a 0d 3d 00 01 a3 8c 7c 57 ......L..=....|W
81 0060 00 00 00 00 b5 80 0a 00 00 00 00 00 10 11 12 13 ................
82 0070 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 ............ !"#
83 0080 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 $%&'()*+,-./0123
84 0090 34 35 36 37 4567
85 "##).unwrap();
86 assert_eq!(bytes.len(), 148);
87
88 let enet = Ethernet::parse(bytes.as_slice()).expect("Invalid ethernet").1;
89 assert_eq!(format!("{}", enet.dst_mac), "08:00:27:f2:1d:8c");
90
91 let ip: IPv4 = IPv4::parse(enet.payload).expect("Invalid IPv4").1;
92 assert_eq!(format!("{}", ip.dst_ip), "192.168.56.12");
93
94 let udp: Udp = Udp::parse(ip.payload).expect("Invalid udp").1;
95 assert_eq!(udp.dst_port, 4789);
96
97 let (remainder, vxlan) = Vxlan::parse(&udp.payload, nom::Endianness::Big).expect("Invalid VXLAN");
98 assert_eq!(remainder.len(), 0);
99 assert_eq!(vxlan.flags, 0x0800);
100 assert_eq!(vxlan.network_identifier, 123);
101
102 assert_eq!(vxlan.as_bytes().as_slice(), udp.payload);
103
104 let enet2 = Ethernet::parse(vxlan.payload).expect("Invalid inner Ethernet").1;
105 assert_eq!(format!("{}", enet2.dst_mac), "4a:7f:01:3b:a2:71");
106
107 let ip2: IPv4 = IPv4::parse(enet2.payload).expect("Invalid Inner IPv4").1;
108 assert_eq!(format!("{}", ip2.dst_ip), "10.0.0.2");
109 }
110
111 #[test]
112 fn not_encapsulated() {
113 let bytes = parse_hex_dump(r##"
114 # Frame 4: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface 1
115 # Ethernet II, Src: Apple_b2:43:ff (68:5b:35:b2:43:ff), Dst: 00:86:9c:66:13:11 (00:86:9c:66:13:11)
116 # Internet Protocol Version 4, Src: 192.168.0.216, Dst: 1.1.1.1
117 # User Datagram Protocol, Src Port: 60406 (60406), Dst Port: 5300 (5300)
118 # Data (2 bytes)
119 0000 00 86 9c 66 13 11 68 5b 35 b2 43 ff 08 00 45 00 ...f..h[5.C...E.
120 0010 00 1e e2 7c 00 00 40 11 00 00 c0 a8 00 d8 01 01 ...|..@.........
121 0020 01 01 eb f6 14 b4 00 0a c3 9d 20 0a .......... .
122 "##).unwrap();
123
124 assert_eq!(bytes.len(), 44);
125
126 let enet = Ethernet::parse(bytes.as_slice()).expect("Invalid ethernet").1;
127 assert_eq!(format!("{}", enet.dst_mac), "00:86:9c:66:13:11");
128
129 let ip: IPv4 = IPv4::parse(enet.payload).expect("Invalid IPv4").1;
130 assert_eq!(format!("{}", ip.dst_ip), "1.1.1.1");
131
132 let udp: Udp = Udp::parse(ip.payload).expect("Invalid udp").1;
133 assert_eq!(udp.dst_port, 5300);
134
135 let vxlan = Vxlan::parse(&udp.payload, nom::Endianness::Big);
136 assert!(vxlan.is_err(), "Should not parse as VXLan")
137
138 }
139}