summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/event/event.rs2
-rw-r--r--src/main.rs3
-rw-r--r--src/packet/packet.rs272
-rw-r--r--src/packet/status.rs2
-rw-r--r--src/plugin/example.rs2
-rw-r--r--src/protocol/codec.rs2
-rw-r--r--src/protocol/dns.rs26
-rw-r--r--src/protocol/ethernet.rs10
-rw-r--r--src/protocol/grev0.rs4
-rw-r--r--src/protocol/grev1.rs2
-rw-r--r--src/protocol/gtpv1.rs24
-rw-r--r--src/protocol/http.rs2
-rw-r--r--src/protocol/icmp.rs4
-rw-r--r--src/protocol/icmpv6.rs4
-rw-r--r--src/protocol/ipv4.rs2
-rw-r--r--src/protocol/ipv6.rs4
-rw-r--r--src/protocol/l2tp.rs8
-rw-r--r--src/protocol/mpls.rs4
-rw-r--r--src/protocol/ppp.rs4
-rw-r--r--src/protocol/pppoe.rs14
-rw-r--r--src/protocol/pptp.rs6
-rw-r--r--src/protocol/tcp.rs10
-rw-r--r--src/protocol/udp.rs2
-rw-r--r--src/protocol/vlan.rs2
-rw-r--r--src/session/manager.rs3
-rw-r--r--src/session/session.rs20
-rw-r--r--src/session/tuple.rs2
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,