net_parser_rs/flow/layer2/
ethernet.rs1use crate::flow::Flow;
2use crate::flow::errors::Error;
3use crate::flow::info::layer2::{Id, Info};
4use crate::flow::layer2::FlowExtraction;
5use crate::flow::layer2::errors::{Error as L2Error};
6use crate::flow::layer3::{FlowExtraction as Layer3Extraction};
7use crate::layer2::ethernet::{Ethernet, EthernetTypeId, Layer3Id};
8use crate::layer3::{IPv4, IPv6, Arp};
9
10use log::*;
11
12pub mod errors {
13 use crate::layer2::ethernet::EthernetTypeId;
14 use crate::errors::Error as NetParserError;
15 use thiserror::{Error as ThisError};
16
17 #[derive(Debug, ThisError)]
18 pub enum Error {
19 #[error("Failed parse of {:?}: {}", l3, err)]
20 NetParser {
21 l3: EthernetTypeId,
22 err: NetParserError
23 },
24 #[error("Incomplete parse of {:?}: {}", l3, size)]
25 Incomplete {
26 l3: EthernetTypeId,
27 size: usize
28 },
29 #[error("Unknown Ethernet Type: {:?}", etype)]
30 EthernetType {
31 etype: EthernetTypeId
32 },
33 }
34
35 unsafe impl Sync for Error {}
36 unsafe impl Send for Error {}
37}
38
39impl<'a> FlowExtraction for Ethernet<'a> {
40 fn extract_flow(&self) -> Result<Flow, Error> {
41 let l2 = Info {
42 id: Id::Ethernet,
43 src_mac: self.src_mac.clone(),
44 dst_mac: self.dst_mac.clone(),
45 vlan: self.vlan(),
46 };
47
48 let ether_type = self.ether_type.clone();
49 debug!(
50 "Creating from layer 3 type {:?} using payload of {}B",
51 ether_type,
52 self.payload.len()
53 );
54
55 match ether_type {
56 EthernetTypeId::L3(Layer3Id::IPv4) => {
57 IPv4::parse(&self.payload)
58 .map_err(|e| {
59 error!("Error parsing ipv4 {:?}", e);
60 let e: L2Error = errors::Error::NetParser {
61 l3: ether_type.clone(),
62 err: e
63 }.into();
64 e.into()
65 })
66 .and_then(|r| {
67 let (rem, l3) = r;
68 if rem.is_empty() {
69 l3.extract_flow(l2)
70 } else {
71 let e: L2Error = errors::Error::Incomplete {
72 l3: ether_type.clone(),
73 size: rem.len()
74 }.into();
75 Err(e.into())
76 }
77 })
78 }
79 EthernetTypeId::L3(Layer3Id::IPv6) => {
80 IPv6::parse(&self.payload)
81 .map_err(|e| {
82 error!("Error parsing ipv6 {:?}", e);
83 let e: L2Error = errors::Error::NetParser {
84 l3: ether_type.clone(),
85 err: e
86 }.into();
87 e.into()
88 })
89 .and_then(|r| {
90 let (rem, l3) = r;
91 if rem.is_empty() {
92 l3.extract_flow(l2)
93 } else {
94 let e: L2Error = errors::Error::Incomplete {
95 l3: ether_type.clone(),
96 size: rem.len()
97 }.into();
98 Err(e.into())
99 }
100 })
101 }
102 EthernetTypeId::L3(Layer3Id::Arp) => {
103 Arp::parse(&self.payload)
104 .map_err(|e| {
105 error!("Error parsing arp {:?}", e);
106 let e: L2Error = errors::Error::NetParser {
107 l3: ether_type.clone(),
108 err: e
109 }.into();
110 e.into()
111 })
112 .and_then(|r| {
113 let (rem, l3) = r;
114 if rem.is_empty() {
115 l3.extract_flow(l2)
116 } else {
117 let e: L2Error = errors::Error::Incomplete {
118 l3: ether_type.clone(),
119 size: rem.len()
120 }.into();
121 Err(e.into())
122 }
123 })
124 }
125 _ => {
126 let e: L2Error = errors::Error::EthernetType {
127 etype: ether_type
128 }.into();
129 Err(e.into())
130 }
131 }
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 use crate::flow::info::layer2::{Id as L2Id};
140 use crate::layer2::ethernet::Ethernet;
141 use crate::layer2::ethernet::tests::TCP_RAW_DATA;
142
143 #[test]
144 fn convert_ethernet_tcp() {
145 let _ = env_logger::try_init();
146
147 let (rem, l2) = Ethernet::parse(TCP_RAW_DATA).expect("Could not parse");
148
149 assert!(rem.is_empty());
150
151 let info = l2.extract_flow().expect("Could not convert to layer 2 stream info");
152
153 assert_eq!(info.layer2, L2Id::Ethernet);
154 assert_eq!(info.source.port, 50871);
155 assert_eq!(info.destination.port, 80);
156 }
157}