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 /src/protocol | |
| 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.
Diffstat (limited to 'src/protocol')
| -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 |
19 files changed, 68 insertions, 66 deletions
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, |
