diff options
| author | luwenpeng <[email protected]> | 2023-09-27 17:54:40 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-09-27 17:54:50 +0800 |
| commit | e0c7dfa5bd9d424249b87ec07d377e94d49d139a (patch) | |
| tree | 1d9bab0ed3b366ce3ff9ef0d9190162546521e7f | |
| parent | 521fbe5464652d509e3290fd336c87ba28fa24c0 (diff) | |
[optimize] Packet Decode
1. Add a macro to obtain Packet’s encapsulation information (the returned data is an immutable reference to Packet)
* get_innermost_special_encapsulation!()
* get_outermost_special_encapsulation!()
Example: let icmp_encapsulation : Option<&Encapsulation> = get_innermost_special_encapsulation!(&Packet, ICMP);
Example: let l4_encapsulation : Option<&Encapsulation> = get_innermost_special_encapsulation!(&Packet, TCP | UDP);
2. Clean up the Clone/Copy Trait of PacketDecode to avoid memory copies caused by improper use by users.
| -rw-r--r-- | src/event/event.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 3 | ||||
| -rw-r--r-- | src/packet/packet.rs | 272 | ||||
| -rw-r--r-- | src/packet/status.rs | 2 | ||||
| -rw-r--r-- | src/plugin/example.rs | 2 | ||||
| -rw-r--r-- | src/protocol/codec.rs | 2 | ||||
| -rw-r--r-- | src/protocol/dns.rs | 26 | ||||
| -rw-r--r-- | src/protocol/ethernet.rs | 10 | ||||
| -rw-r--r-- | src/protocol/grev0.rs | 4 | ||||
| -rw-r--r-- | src/protocol/grev1.rs | 2 | ||||
| -rw-r--r-- | src/protocol/gtpv1.rs | 24 | ||||
| -rw-r--r-- | src/protocol/http.rs | 2 | ||||
| -rw-r--r-- | src/protocol/icmp.rs | 4 | ||||
| -rw-r--r-- | src/protocol/icmpv6.rs | 4 | ||||
| -rw-r--r-- | src/protocol/ipv4.rs | 2 | ||||
| -rw-r--r-- | src/protocol/ipv6.rs | 4 | ||||
| -rw-r--r-- | src/protocol/l2tp.rs | 8 | ||||
| -rw-r--r-- | src/protocol/mpls.rs | 4 | ||||
| -rw-r--r-- | src/protocol/ppp.rs | 4 | ||||
| -rw-r--r-- | src/protocol/pppoe.rs | 14 | ||||
| -rw-r--r-- | src/protocol/pptp.rs | 6 | ||||
| -rw-r--r-- | src/protocol/tcp.rs | 10 | ||||
| -rw-r--r-- | src/protocol/udp.rs | 2 | ||||
| -rw-r--r-- | src/protocol/vlan.rs | 2 | ||||
| -rw-r--r-- | src/session/manager.rs | 3 | ||||
| -rw-r--r-- | src/session/session.rs | 20 | ||||
| -rw-r--r-- | src/session/tuple.rs | 2 |
27 files changed, 194 insertions, 246 deletions
diff --git a/src/event/event.rs b/src/event/event.rs index 830bdda..476ddce 100644 --- a/src/event/event.rs +++ b/src/event/event.rs @@ -1,4 +1,4 @@ -#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] pub enum Event { L2Event, L3Event, diff --git a/src/main.rs b/src/main.rs index 38c35e0..20ec270 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use stellar_rs::event::event::Event; use stellar_rs::event::manager::EventHandle; use stellar_rs::event::manager::EventManager; use stellar_rs::event::manager::EventQueue; +use stellar_rs::get_innermost_special_encapsulation; use stellar_rs::packet::capture::PacketCapture; use stellar_rs::packet::packet::Encapsulation; use stellar_rs::packet::packet::Packet; @@ -141,7 +142,7 @@ fn handle_one_packet(mut packet: Packet, thread_ctx: &mut ThreadContext) { } } - match packet.get_inner_most_tuple() { + match get_innermost_special_encapsulation!(packet, TCP | UDP) { Some(_) => { let flow_id = packet.get_flow_id().unwrap(); let session = session_mgr.update(flow_id); diff --git a/src/packet/packet.rs b/src/packet/packet.rs index b0c7bc5..6a81c4d 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -1,3 +1,5 @@ +use crate::get_innermost_special_encapsulation; +use crate::get_outermost_special_encapsulation; use crate::packet::status::PacketStatus; use crate::protocol::codec::Decode; use crate::protocol::ethernet::EthHeader; @@ -24,7 +26,7 @@ use crate::protocol::udp::UDPHeader; use crate::protocol::vlan::VLANHeader; use nom::Err::Incomplete; -#[derive(Clone, Debug, PartialEq)] +#[derive(Debug, PartialEq)] pub enum Encapsulation<'a> { ETH(EthHeader, &'a [u8]), VLAN(VLANHeader, &'a [u8]), @@ -56,6 +58,36 @@ pub struct Packet<'a> { pub encapsulation: Vec<Encapsulation<'a>>, } +// return Option<&Encapsulation> +#[macro_export] +macro_rules! get_outermost_special_encapsulation { + ($packet:expr, $($layer_type:ident)|+ $(|)?) => { + $packet + .encapsulation + .iter() + .find(|&encap| { + $(matches!(encap, Encapsulation::$layer_type(..)) ||)+ + false + }) + .map(|layer| layer) + }; +} + +// return Option<&Encapsulation> +#[macro_export] +macro_rules! get_innermost_special_encapsulation { + ($packet:expr, $($layer_type:ident)|+ $(|)?) => { + $packet + .encapsulation + .iter() + .rfind(|&encap| { + $(matches!(encap, Encapsulation::$layer_type(..)) ||)+ + false + }) + .map(|layer| layer) + }; +} + impl Packet<'_> { pub fn new(data: &[u8], len: u32) -> Packet { Packet { @@ -73,155 +105,67 @@ impl Packet<'_> { } } - pub fn get_outer_most_l3_layer(&self) -> Option<Encapsulation> { - let num = self.encapsulation.len(); - for i in 0..num { - match self.encapsulation[i] { - Encapsulation::IPv4(_, _) => { - return Some(self.encapsulation[i].clone()); - } - Encapsulation::IPv6(_, _) => { - return Some(self.encapsulation[i].clone()); - } - _ => continue, + pub fn get_outermost_address(&self) -> Option<(String, String)> { + match get_outermost_special_encapsulation!(self, IPv4 | IPv6) { + Some(&Encapsulation::IPv4(ref header, _)) => { + return Some(( + header.source_address.to_string(), + header.dest_address.to_string(), + )); } - } - - None - } - - pub fn get_inner_most_l3_layer(&self) -> Option<Encapsulation> { - let num = self.encapsulation.len(); - for i in (0..num).rev() { - match self.encapsulation[i] { - Encapsulation::IPv4(_, _) => { - return Some(self.encapsulation[i].clone()); - } - Encapsulation::IPv6(_, _) => { - return Some(self.encapsulation[i].clone()); - } - _ => continue, + Some(&Encapsulation::IPv6(ref header, _)) => { + return Some(( + header.source_address.to_string(), + header.dest_address.to_string(), + )); } + _ => return None, } - - None } - pub fn get_outer_most_l4_layer(&self) -> Option<Encapsulation> { - let num = self.encapsulation.len(); - for i in 0..num { - match self.encapsulation[i] { - Encapsulation::TCP(_, _) => { - return Some(self.encapsulation[i].clone()); - } - Encapsulation::UDP(_, _) => { - return Some(self.encapsulation[i].clone()); - } - _ => continue, + pub fn get_innermost_address(&self) -> Option<(String, String)> { + match get_innermost_special_encapsulation!(self, IPv4 | IPv6) { + Some(&Encapsulation::IPv4(ref header, _)) => { + return Some(( + header.source_address.to_string(), + header.dest_address.to_string(), + )); } - } - - None - } - - pub fn get_inner_most_l4_layer(&self) -> Option<Encapsulation> { - let num = self.encapsulation.len(); - for i in (0..num).rev() { - match self.encapsulation[i] { - Encapsulation::TCP(_, _) => { - return Some(self.encapsulation[i].clone()); - } - Encapsulation::UDP(_, _) => { - return Some(self.encapsulation[i].clone()); - } - _ => continue, + Some(&Encapsulation::IPv6(ref header, _)) => { + return Some(( + header.source_address.to_string(), + header.dest_address.to_string(), + )); } + _ => return None, } - - None } - pub fn get_outer_most_address(&self) -> Option<(String, String)> { - let num = self.encapsulation.len(); - for i in 0..num { - match self.encapsulation[i] { - Encapsulation::IPv4(ref header, _) => { - return Some(( - header.source_address.to_string(), - header.dest_address.to_string(), - )); - } - Encapsulation::IPv6(ref header, _) => { - return Some(( - header.source_address.to_string(), - header.dest_address.to_string(), - )); - } - _ => continue, + pub fn get_outermost_port(&self) -> Option<(u16, u16)> { + match get_outermost_special_encapsulation!(self, TCP | UDP) { + Some(&Encapsulation::TCP(ref header, _)) => { + return Some((header.source_port, header.dest_port)); } - } - - None - } - - pub fn get_inner_most_address(&self) -> Option<(String, String)> { - let num = self.encapsulation.len(); - for i in (0..num).rev() { - match self.encapsulation[i] { - Encapsulation::IPv4(ref header, _) => { - return Some(( - header.source_address.to_string(), - header.dest_address.to_string(), - )); - } - Encapsulation::IPv6(ref header, _) => { - return Some(( - header.source_address.to_string(), - header.dest_address.to_string(), - )); - } - _ => continue, + Some(&Encapsulation::UDP(ref header, _)) => { + return Some((header.source_port, header.dest_port)); } + _ => return None, } - - None } - pub fn get_outer_most_port(&self) -> Option<(u16, u16)> { - let num = self.encapsulation.len(); - for i in 0..num { - match self.encapsulation[i] { - Encapsulation::TCP(ref header, _) => { - return Some((header.source_port, header.dest_port)); - } - Encapsulation::UDP(ref header, _) => { - return Some((header.source_port, header.dest_port)); - } - _ => continue, + pub fn get_innermost_port(&self) -> Option<(u16, u16)> { + match get_innermost_special_encapsulation!(self, TCP | UDP) { + Some(&Encapsulation::TCP(ref header, _)) => { + return Some((header.source_port, header.dest_port)); } - } - - None - } - - pub fn get_inner_most_port(&self) -> Option<(u16, u16)> { - let num = self.encapsulation.len(); - for i in (0..num).rev() { - match self.encapsulation[i] { - Encapsulation::TCP(ref header, _) => { - return Some((header.source_port, header.dest_port)); - } - Encapsulation::UDP(ref header, _) => { - return Some((header.source_port, header.dest_port)); - } - _ => continue, + Some(&Encapsulation::UDP(ref header, _)) => { + return Some((header.source_port, header.dest_port)); } + _ => return None, } - - None } - pub fn get_outer_most_tuple(&self) -> Option<(String, u16, String, u16)> { + pub fn get_outermost_tuple(&self) -> Option<(String, u16, String, u16)> { let num = self.encapsulation.len(); if num < 2 { return None; @@ -273,7 +217,7 @@ impl Packet<'_> { None } - pub fn get_inner_most_tuple(&self) -> Option<(String, u16, String, u16)> { + pub fn get_innermost_tuple(&self) -> Option<(String, u16, String, u16)> { let num = self.encapsulation.len(); if num < 2 { return None; @@ -818,6 +762,31 @@ mod tests { use std::net::Ipv6Addr; #[test] + fn test_encapsulated_immutable_references() { + let mut packet = Packet::new(b"0", 1 as u32); + let udp_hdr = UDPHeader { + source_port: 9995, + dest_port: 9996, + length: 147, + checksum: 0x57d4, + }; + + let udp_payload = [0x01, 0x02, 0x03]; + packet + .encapsulation + .push(Encapsulation::UDP(udp_hdr, &udp_payload)); + + match get_innermost_special_encapsulation!(packet, UDP) { + Some(&Encapsulation::UDP(ref header, payload)) => { + assert_eq!(header.source_port, 9995); + assert_eq!(header.dest_port, 9996); + assert_eq!(payload, &udp_payload); + } + _ => assert!(false), + } + } + + #[test] fn test_packet_api() { let mut packet = Packet::new(b"0", 1 as u32); let ipv4_hdr = IPv4Header { @@ -877,34 +846,30 @@ mod tests { packet .encapsulation - .push(Encapsulation::IPv4(ipv4_hdr.clone(), b"1")); + .push(Encapsulation::IPv4(ipv4_hdr, b"1")); + packet.encapsulation.push(Encapsulation::TCP(tcp_hdr, b"2")); packet .encapsulation - .push(Encapsulation::TCP(tcp_hdr.clone(), b"2")); - packet - .encapsulation - .push(Encapsulation::IPv6(ipv6_hdr.clone(), b"3")); - packet - .encapsulation - .push(Encapsulation::UDP(udp_hdr.clone(), b"4")); + .push(Encapsulation::IPv6(ipv6_hdr, b"3")); + packet.encapsulation.push(Encapsulation::UDP(udp_hdr, b"4")); assert_eq!( - packet.get_outer_most_address(), + packet.get_outermost_address(), Some(("192.168.0.101".to_string(), "121.14.154.93".to_string())) ); assert_eq!( - packet.get_inner_most_address(), + packet.get_innermost_address(), Some(( "2409:8034:4025::50:a31".to_string(), "2409:8034:4040:5301::204".to_string() )) ); - assert_eq!(packet.get_outer_most_port(), Some((50081, 443))); - assert_eq!(packet.get_inner_most_port(), Some((9993, 9994))); + assert_eq!(packet.get_outermost_port(), Some((50081, 443))); + assert_eq!(packet.get_innermost_port(), Some((9993, 9994))); assert_eq!( - packet.get_outer_most_tuple(), + packet.get_outermost_tuple(), Some(( "192.168.0.101".to_string(), 50081, @@ -913,7 +878,7 @@ mod tests { )) ); assert_eq!( - packet.get_inner_most_tuple(), + packet.get_innermost_tuple(), Some(( "2409:8034:4025::50:a31".to_string(), 9993, @@ -922,23 +887,6 @@ mod tests { )) ); - assert_eq!( - packet.get_outer_most_l3_layer(), - Some(Encapsulation::IPv4(ipv4_hdr, b"1")) - ); - assert_eq!( - packet.get_inner_most_l3_layer(), - Some(Encapsulation::IPv6(ipv6_hdr, b"3")) - ); - assert_eq!( - packet.get_outer_most_l4_layer(), - Some(Encapsulation::TCP(tcp_hdr, b"2")) - ); - assert_eq!( - packet.get_inner_most_l4_layer(), - Some(Encapsulation::UDP(udp_hdr, b"4")) - ); - assert_eq!(packet.get_flow_id(), Some("192.168.0.101->121.14.154.93;TCP->TCP;50081->443;2409:8034:4025::50:a31->2409:8034:4040:5301::204;UDP->UDP;9993->9994;".to_string())); } diff --git a/src/packet/status.rs b/src/packet/status.rs index 25585c0..cc536de 100644 --- a/src/packet/status.rs +++ b/src/packet/status.rs @@ -2,7 +2,7 @@ use crate::protocol::ethernet::EthType; use crate::protocol::ip::IPProtocol; use std::collections::HashMap; -#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] pub enum PacketStatus { Normal, diff --git a/src/plugin/example.rs b/src/plugin/example.rs index 7a4d4ec..a7afb5b 100644 --- a/src/plugin/example.rs +++ b/src/plugin/example.rs @@ -53,7 +53,7 @@ impl EventHandle for ExamplePulgin { match event { Event::TCPOpeningEvent => { println!("{} handle TCPOpeningEvent: {:?}", self.plugin_name, session); - let (src_port, dst_port) = packet.unwrap().get_inner_most_port().unwrap(); + let (src_port, dst_port) = packet.unwrap().get_innermost_port().unwrap(); if src_port == 80 || dst_port == 80 { println!("{} add HTTPRequestEvent", self.plugin_name); queue.add(Event::HTTPRequestEvent, Some(session)); diff --git a/src/protocol/codec.rs b/src/protocol/codec.rs index 7bf2243..575e49d 100644 --- a/src/protocol/codec.rs +++ b/src/protocol/codec.rs @@ -2,7 +2,7 @@ use nom::IResult; use std::fmt::Debug; pub trait Decode { - type Iterm: Debug; + type Iterm: Debug + PartialEq; fn decode(input: &[u8]) -> IResult<&[u8], Self::Iterm>; } diff --git a/src/protocol/dns.rs b/src/protocol/dns.rs index 0f62b49..c2d2411 100644 --- a/src/protocol/dns.rs +++ b/src/protocol/dns.rs @@ -220,7 +220,7 @@ use std::str; * DNS Header ******************************************************************************/ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum DNSHeaderQR { Query = 0, Response = 1, @@ -238,7 +238,7 @@ impl DNSHeaderQR { } // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5 -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum DNSHeaderOpcode { Query, IQuery, @@ -265,7 +265,7 @@ impl DNSHeaderOpcode { } // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum DNSHeaderRcode { NoError, // No Error FormErr, // Format Error @@ -319,7 +319,7 @@ impl DNSHeaderRcode { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct DNSHeader { pub id: u16, pub qr: DNSHeaderQR, @@ -424,7 +424,7 @@ impl DNSHeader { ******************************************************************************/ // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum DNSQtype { A, // a host address NS, // an authoritative name server @@ -620,7 +620,7 @@ impl DNSQtype { } // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2 -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum DNSQclass { Internet, Unassigned, @@ -645,7 +645,7 @@ impl DNSQclass { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct DNSQuestionSection { pub qname: String, pub qtype: DNSQtype, @@ -679,7 +679,7 @@ impl DNSQuestionSection { * DNS Resource Record Section ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct DNSResourceRecordHeader { pub qname: String, pub rr_type: DNSQtype, @@ -715,7 +715,7 @@ impl DNSResourceRecordHeader { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum DNSResourceRecordData { A { address: String, @@ -884,7 +884,7 @@ impl DNSResourceRecordData { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct DNSResourceRecordSection { pub hdr: DNSResourceRecordHeader, pub data: DNSResourceRecordData, @@ -915,7 +915,7 @@ impl DNSResourceRecordSection { ******************************************************************************/ // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-10 -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] enum DNSLabelType { Normal(usize), // Normal label lower 6 bits is the length of the label Pointer(usize), // Compressed label the lower 6 bits and the 8 bits from next octet form a pointer to the compression target @@ -965,7 +965,7 @@ impl DNSLabelType { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct DNSLabelTable { pub labels: Vec<((usize, usize), String)>, } @@ -1028,7 +1028,7 @@ impl DNSLabelTable { * DNS Message ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct DNSMessage { pub header: DNSHeader, labels: DNSLabelTable, diff --git a/src/protocol/ethernet.rs b/src/protocol/ethernet.rs index f8e39f8..375be59 100644 --- a/src/protocol/ethernet.rs +++ b/src/protocol/ethernet.rs @@ -6,10 +6,7 @@ use nom::IResult; * Struct ******************************************************************************/ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct MacAddress(pub [u8; 6]); - -#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] pub enum EthType { LANMIN, // 802.3 Min data length LANMAX, // 802.3 Max data length @@ -61,7 +58,10 @@ pub enum EthType { Other(u16), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] +pub struct MacAddress(pub [u8; 6]); + +#[derive(Debug, PartialEq)] pub struct EthHeader { pub source_mac: MacAddress, pub dest_mac: MacAddress, diff --git a/src/protocol/grev0.rs b/src/protocol/grev0.rs index 88a43f1..784613e 100644 --- a/src/protocol/grev0.rs +++ b/src/protocol/grev0.rs @@ -40,7 +40,7 @@ use nom::IResult; * https://datatracker.ietf.org/doc/html/rfc2890 */ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct SourceRouteEntry { pub address_family: u16, pub sre_offset: u8, @@ -48,7 +48,7 @@ pub struct SourceRouteEntry { pub sre_routing: Vec<u8>, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct GREv0Header { pub flag_checksum: bool, pub flag_routing: bool, diff --git a/src/protocol/grev1.rs b/src/protocol/grev1.rs index ed2d2f2..e444f5b 100644 --- a/src/protocol/grev1.rs +++ b/src/protocol/grev1.rs @@ -28,7 +28,7 @@ use nom::IResult; * https://datatracker.ietf.org/doc/html/rfc2637 */ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct GREv1Header { pub flag_checksum: bool, pub flag_routing: bool, diff --git a/src/protocol/gtpv1.rs b/src/protocol/gtpv1.rs index 8a7fc4d..c3d9896 100644 --- a/src/protocol/gtpv1.rs +++ b/src/protocol/gtpv1.rs @@ -10,21 +10,21 @@ use nom::IResult; * Struct ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct GTPv1Option { pub sequence_number: u16, // 16bit pub npdu_number: u8, // 8bit pub next_header_type: u8, // 8bit } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct GTPv1ExtensionHeader { pub length: u8, // 8bit (单位4字节,包括长度/内容/下一扩展消息头字段) pub contents: Vec<u8>, pub next_header_type: u8, // 8bit } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct GTPv1Header { pub version: u8, // 3bit 1: GTPv1 pub protocol_type: u8, // 1bit @@ -129,14 +129,18 @@ impl Decode for GTPv1Header { } let mut extensions = Vec::new(); - if options.is_some() { - let mut next_header = options.clone().unwrap().next_header_type; - while next_header != 0 { - let (left, extension) = extension_decode(remain)?; - remain = left; - next_header = extension.next_header_type; - extensions.push(extension); + let ref_options = &options; + match ref_options { + Some(ref _options) => { + let mut next_header = _options.next_header_type; + while next_header != 0 { + let (left, extension) = extension_decode(remain)?; + remain = left; + next_header = extension.next_header_type; + extensions.push(extension); + } } + None => (), } Ok(( diff --git a/src/protocol/http.rs b/src/protocol/http.rs index d05c59e..d1eaeeb 100644 --- a/src/protocol/http.rs +++ b/src/protocol/http.rs @@ -1,7 +1,7 @@ use crate::protocol::codec::Decode; use nom::IResult; -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct HTTPMessage { // TODO } diff --git a/src/protocol/icmp.rs b/src/protocol/icmp.rs index 99d0f2d..2c48962 100644 --- a/src/protocol/icmp.rs +++ b/src/protocol/icmp.rs @@ -6,7 +6,7 @@ use nom::IResult; * Struct ******************************************************************************/ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum ICMPType { EchoReply, DestinationUnreachable, @@ -27,7 +27,7 @@ pub enum ICMPType { Other(u8), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct ICMPHeader { pub icmp_type: ICMPType, pub icmp_code: u8, diff --git a/src/protocol/icmpv6.rs b/src/protocol/icmpv6.rs index 9bd58d2..d0c5e1c 100644 --- a/src/protocol/icmpv6.rs +++ b/src/protocol/icmpv6.rs @@ -6,7 +6,7 @@ use nom::IResult; * Struct ******************************************************************************/ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum ICMPv6Type { DestinationUnreachable, PacketTooBig, @@ -48,7 +48,7 @@ pub enum ICMPv6Type { Other(u8), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct ICMPv6Header { pub icmp_type: ICMPv6Type, pub icmp_code: u8, diff --git a/src/protocol/ipv4.rs b/src/protocol/ipv4.rs index 7606b1e..2297196 100644 --- a/src/protocol/ipv4.rs +++ b/src/protocol/ipv4.rs @@ -31,7 +31,7 @@ use std::net::Ipv4Addr; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct IPv4Header { pub version: u8, // 4 bit pub ihl: u8, // 4 bit diff --git a/src/protocol/ipv6.rs b/src/protocol/ipv6.rs index 11666d4..f9e4321 100644 --- a/src/protocol/ipv6.rs +++ b/src/protocol/ipv6.rs @@ -59,14 +59,14 @@ use std::net::Ipv6Addr; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct IPv6Extension { pub next_header: IPProtocol, pub ext_length: u8, // Extension total Length pub data: Vec<u8>, // Extension data length (ext_length - 2) } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct IPv6Header { pub version: u8, // 4 bit pub dsc: u8, // Differentiated Services Codepoint: 6 bit diff --git a/src/protocol/l2tp.rs b/src/protocol/l2tp.rs index 445062f..5474b23 100644 --- a/src/protocol/l2tp.rs +++ b/src/protocol/l2tp.rs @@ -42,7 +42,7 @@ use nom::IResult; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum L2TPAVPType { Message, Result, @@ -137,13 +137,13 @@ pub enum L2TPAVPType { Other(u16), } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum L2TPType { Data, Control, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct L2TPAVPHeader { pub mandatory: bool, pub hidden: bool, @@ -154,7 +154,7 @@ pub struct L2TPAVPHeader { pub attribute_value: Vec<u8>, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct L2TPHeader { pub flags: u16, pub flag_type: L2TPType, diff --git a/src/protocol/mpls.rs b/src/protocol/mpls.rs index add686d..2f441f9 100644 --- a/src/protocol/mpls.rs +++ b/src/protocol/mpls.rs @@ -9,7 +9,7 @@ use nom::IResult; * Struct ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct MPLSHeader { pub label: u32, pub experimental: u8, @@ -17,8 +17,8 @@ pub struct MPLSHeader { pub ttl: u8, } -#[derive(Clone, Debug, PartialEq, Eq)] // Ethernet pseudowire (PW) https://tools.ietf.org/html/rfc4448#section-3.1 +#[derive(Debug, PartialEq)] pub struct PWEthHeader { pub control_word: u32, } diff --git a/src/protocol/ppp.rs b/src/protocol/ppp.rs index 1c08ce7..0872915 100644 --- a/src/protocol/ppp.rs +++ b/src/protocol/ppp.rs @@ -7,7 +7,7 @@ use nom::IResult; ******************************************************************************/ // https://www.iana.org/assignments/ppp-numbers/ppp-numbers.xhtml -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum PPPProtocol { PAD, // Padding Protocol IPv4, // Internet Protocol version 4 (IPv4) @@ -21,7 +21,7 @@ pub enum PPPProtocol { } // https://www.rfc-editor.org/rfc/rfc1661.html -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct PPPHeader { pub address: u8, pub control: u8, diff --git a/src/protocol/pppoe.rs b/src/protocol/pppoe.rs index e63dbb1..7f3e05e 100644 --- a/src/protocol/pppoe.rs +++ b/src/protocol/pppoe.rs @@ -25,7 +25,7 @@ use nom::IResult; * https://info.support.huawei.com/info-finder/encyclopedia/zh/PPPoE.html */ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum PPPoECode { SessionData, // Session Data PADI, // Active Discovery Initiation @@ -36,7 +36,7 @@ pub enum PPPoECode { Other(u8), } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum PPPoETagType { EndOfList, ServiceName, @@ -51,20 +51,20 @@ pub enum PPPoETagType { Other(u16), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct PPPoETag { pub tag_type: PPPoETagType, pub tag_length: u16, pub tag_value: Vec<u8>, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum PPPoEStage { Discovery(Vec<PPPoETag>), Session(PPPProtocol), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct PPPoEHeader { pub version: u8, // 4 bits pub type_: u8, // 4 bits @@ -137,10 +137,10 @@ fn pppoe_tags_decode(input: &[u8]) -> IResult<&[u8], Vec<PPPoETag>> { let mut remain = input; loop { let (input, tag) = pppoe_tag_decode(remain)?; - let tag_type = tag.tag_type; + let is_end_of_list = tag.tag_type == PPPoETagType::EndOfList; remain = input; tags.push(tag); - if remain.is_empty() || tag_type == PPPoETagType::EndOfList { + if remain.is_empty() || is_end_of_list { break; } } diff --git a/src/protocol/pptp.rs b/src/protocol/pptp.rs index c9e2b40..c254631 100644 --- a/src/protocol/pptp.rs +++ b/src/protocol/pptp.rs @@ -29,14 +29,14 @@ use nom::Needed; // https://wwwdisc.chimica.unipd.it/luigino.feltre/pubblica/unix/winnt_doc/pppt/understanding_pptp.html // https://datatracker.ietf.org/doc/html/rfc2637 -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum PPTPMessageType { ControlMessage, ManagementMessage, UnknownMessage(u16), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum PPTPControlMessageType { StartControlConnectionRequest, StartControlConnectionReply, @@ -56,7 +56,7 @@ pub enum PPTPControlMessageType { Unknown(u16), } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct PPTPHeader { pub length: u16, pub message_type: PPTPMessageType, diff --git a/src/protocol/tcp.rs b/src/protocol/tcp.rs index 5ab7dde..09a5690 100644 --- a/src/protocol/tcp.rs +++ b/src/protocol/tcp.rs @@ -44,7 +44,7 @@ const TCP_OPTION_SACK_PERMITTED: u8 = 4; // Selective acknowledgements permitted const TCP_OPTION_SACK: u8 = 5; // Selective acknowledgment const TCP_OPTION_TIMESTAMPS: u8 = 8; // Timestamps -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub enum TCPOption { EOL, NOP, @@ -69,7 +69,7 @@ pub enum TCPOption { }, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct TCPHeader { pub source_port: u16, pub dest_port: u16, @@ -212,12 +212,10 @@ impl TCPHeader { match TCPOption::decode(left) { Ok((l, opt)) => { left = l; + let is_eol = opt == TCPOption::EOL; options.push(opt); - if left.len() <= 0 { - break; - } - if let TCPOption::EOL = opt { + if left.len() <= 0 || is_eol { break; } } diff --git a/src/protocol/udp.rs b/src/protocol/udp.rs index 1d7b43b..8554057 100644 --- a/src/protocol/udp.rs +++ b/src/protocol/udp.rs @@ -20,7 +20,7 @@ use nom::IResult; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct UDPHeader { pub source_port: u16, pub dest_port: u16, diff --git a/src/protocol/vlan.rs b/src/protocol/vlan.rs index 6a1dbe0..0e9b0c5 100644 --- a/src/protocol/vlan.rs +++ b/src/protocol/vlan.rs @@ -9,7 +9,7 @@ use nom::IResult; * Struct ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct VLANHeader { // A 3 bit number which refers to the IEEE 802.1p class of service and maps to the frame priority level. pub priority_code_point: u8, diff --git a/src/session/manager.rs b/src/session/manager.rs index 462949f..36bb19e 100644 --- a/src/session/manager.rs +++ b/src/session/manager.rs @@ -11,7 +11,6 @@ use std::rc::Rc; * Struct ******************************************************************************/ -#[derive(Debug)] pub struct SessionManager { sessions: HashMap<String, Rc<RefCell<Session>>>, } @@ -154,7 +153,5 @@ mod tests { // Research Session assert_eq!(session_mgr.get_session(&session_id).is_none(), true); assert_eq!(session_mgr.get_session(&reversed_id).is_none(), true); - - dbg!(session_mgr); } } diff --git a/src/session/session.rs b/src/session/session.rs index e8b2be4..1db4bfd 100644 --- a/src/session/session.rs +++ b/src/session/session.rs @@ -7,19 +7,19 @@ use std::collections::HashMap; const MAX_SESSION_EXPIRE_TIME: i64 = 60; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum SessionDirection { C2S, S2C, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum SessionProto { TCP, UDP, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum SessionState { New, Active, @@ -27,7 +27,7 @@ pub enum SessionState { Expired, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug)] pub struct SessionMetrics { pub send_pkts: u64, pub send_bytes: u64, @@ -35,7 +35,7 @@ pub struct SessionMetrics { pub recv_bytes: u64, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Debug)] struct SessionTimeStamp { ts_start: i64, ts_end: i64, @@ -49,7 +49,7 @@ struct SessionTimeStamp { * - if current packet is iterm of session, require packet lifetime > session lifetime ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug)] pub struct Session { session_id: String, session_proto: SessionProto, @@ -132,8 +132,8 @@ impl Session { self.session_metrics_c2s.recv_bytes += recv_bytes; } - pub fn get_session_c2s_metrics(&self) -> SessionMetrics { - self.session_metrics_c2s + pub fn get_session_c2s_metrics(&self) -> &SessionMetrics { + &self.session_metrics_c2s } pub fn inc_session_s2c_metrics( @@ -149,8 +149,8 @@ impl Session { self.session_metrics_s2c.recv_bytes += recv_bytes; } - pub fn get_session_s2c_metrics(&self) -> SessionMetrics { - self.session_metrics_s2c + pub fn get_session_s2c_metrics(&self) -> &SessionMetrics { + &self.session_metrics_s2c } pub fn update_session_expire_ts(&mut self) { diff --git a/src/session/tuple.rs b/src/session/tuple.rs index 9a4dacf..16616cb 100644 --- a/src/session/tuple.rs +++ b/src/session/tuple.rs @@ -2,7 +2,7 @@ * Struct ******************************************************************************/ -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub struct FiveTuple { src_ip: String, src_port: u16, |
