net_parser_rs/flow/layer2/
ethernet.rs

1use 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}