summaryrefslogtreecommitdiff
path: root/src/protocol
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-09-12 16:11:32 +0800
committerluwenpeng <[email protected]>2023-09-13 19:20:06 +0800
commit8f9e0f719055487e4a352f5da74cae063bbcdbcc (patch)
treea7d44661b4b2d79202abd2a79f3eeda1f791b98b /src/protocol
parent8755e95f068da56c099e9c51dc4a89b55960e48d (diff)
[feature] Support GTPv1-U Decode
Diffstat (limited to 'src/protocol')
-rw-r--r--src/protocol/gtpv1.rs278
-rw-r--r--src/protocol/ip.rs29
-rw-r--r--src/protocol/ipv4.rs18
-rw-r--r--src/protocol/ipv6.rs70
-rw-r--r--src/protocol/mod.rs3
5 files changed, 338 insertions, 60 deletions
diff --git a/src/protocol/gtpv1.rs b/src/protocol/gtpv1.rs
new file mode 100644
index 0000000..3791a58
--- /dev/null
+++ b/src/protocol/gtpv1.rs
@@ -0,0 +1,278 @@
+use crate::protocol::codec::Decode;
+use nom::bits;
+use nom::bytes;
+use nom::error::Error;
+use nom::number;
+use nom::sequence;
+use nom::IResult;
+
+/******************************************************************************
+ * Struct
+ ******************************************************************************/
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Gtpv1Option {
+ pub sequence_number: u16, // 16bit
+ pub npdu_number: u8, // 8bit
+ pub next_header_type: u8, // 8bit
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Gtpv1ExtensionHeader {
+ pub length: u8, // 8bit (单位4字节,包括长度/内容/下一扩展消息头字段)
+ pub contents: Vec<u8>,
+ pub next_header_type: u8, // 8bit
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Gtpv1Header {
+ pub version: u8, // 3bit 1: GTPv1
+ pub protocol_type: u8, // 1bit
+ pub reserved: u8, // 1bit
+ pub extension_header_flag: u8, // 1bit
+ pub sequence_number_flag: u8, // 1bit
+ pub npdu_number_flag: u8, // 1bit
+
+ pub message_type: u8, // 8bit
+ pub message_length: u16, // 16bit (单位为字节,不包括GTP头前8字节的必选字段)
+ pub teid: u32, // 32bit
+
+ // extension_header_flag/sequence_number_flag/npdu_number_flag任意一个取值为1时options字段才存在
+ pub options: Option<Gtpv1Option>,
+ pub extensions: Vec<Gtpv1ExtensionHeader>,
+}
+
+/******************************************************************************
+ * API
+ ******************************************************************************/
+
+fn bit_decode(input: &[u8]) -> IResult<&[u8], (u8, u8, u8, u8, u8, u8)> {
+ bits::bits::<_, _, Error<_>, _, _>(sequence::tuple((
+ bits::streaming::take(3u8),
+ bits::streaming::take(1u8),
+ bits::streaming::take(1u8),
+ bits::streaming::take(1u8),
+ bits::streaming::take(1u8),
+ bits::streaming::take(1u8),
+ )))(input)
+}
+
+fn option_decode(input: &[u8]) -> IResult<&[u8], Gtpv1Option> {
+ let (input, sequence_number) = number::streaming::be_u16(input)?;
+ let (input, npdu_number) = number::streaming::be_u8(input)?;
+ let (input, next_header_type) = number::streaming::be_u8(input)?;
+
+ Ok((
+ input,
+ Gtpv1Option {
+ sequence_number,
+ npdu_number,
+ next_header_type,
+ },
+ ))
+}
+
+fn extension_decode(input: &[u8]) -> IResult<&[u8], Gtpv1ExtensionHeader> {
+ let (input, length) = number::streaming::be_u8(input)?;
+ let (input, contents) = bytes::streaming::take(length * 4 - 2)(input)?;
+ let (input, next_header_type) = number::streaming::be_u8(input)?;
+ Ok((
+ input,
+ Gtpv1ExtensionHeader {
+ length,
+ contents: contents.to_vec(),
+ next_header_type,
+ },
+ ))
+}
+
+impl Decode for Gtpv1Header {
+ type Iterm = Gtpv1Header;
+ fn decode(input: &[u8]) -> IResult<&[u8], Gtpv1Header> {
+ let (
+ input,
+ (
+ version,
+ protocol_type,
+ reserved,
+ extension_header_flag,
+ sequence_number_flag,
+ npdu_number_flag,
+ ),
+ ) = bit_decode(input)?;
+ match (version, protocol_type) {
+ (1, 1) => (),
+ (_, _) => {
+ return Err(nom::Err::Error(Error::new(
+ input,
+ nom::error::ErrorKind::TagBits,
+ )))
+ }
+ }
+ let (input, message_type) = number::streaming::be_u8(input)?;
+ let (input, message_length) = number::streaming::be_u16(input)?;
+ let (input, teid) = number::streaming::be_u32(input)?;
+
+ // Optional word of GTP header, present if any of extension_header_flag, sequence_number_flag, npdu_number_flag is set
+ let mut remain = input;
+ let mut options = None;
+ if extension_header_flag == 1 || sequence_number_flag == 1 || npdu_number_flag == 1 {
+ let (left, _options) = option_decode(remain)?;
+ remain = left;
+ options = Some(_options);
+ }
+
+ 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);
+ }
+ }
+
+ Ok((
+ remain,
+ Gtpv1Header {
+ version,
+ protocol_type,
+ reserved,
+ extension_header_flag,
+ sequence_number_flag,
+ npdu_number_flag,
+ message_type,
+ message_length,
+ teid,
+ options,
+ extensions,
+ },
+ ))
+ }
+}
+
+/******************************************************************************
+ * TEST
+ ******************************************************************************/
+
+#[cfg(test)]
+mod tests {
+ use super::Gtpv1ExtensionHeader;
+ use super::Gtpv1Header;
+ use crate::protocol::codec::Decode;
+ const LAST_SLICE: &'static [u8] = &[0xff];
+
+ #[test]
+ fn gtpv1_header_decode() {
+ /*
+ * GPRS Tunneling Protocol
+ * Flags: 0x30
+ * 001. .... = Version: GTP release 99 version (1)
+ * ...1 .... = Protocol type: GTP (1)
+ * .... 0... = Reserved: 0
+ * .... .0.. = Is Next Extension Header present?: No
+ * .... ..0. = Is Sequence Number present?: No
+ * .... ...0 = Is N-PDU number present?: No
+ * Message Type: T-PDU (0xff)
+ * Length: 64
+ * TEID: 0x1f54d4b5 (525653173)
+ */
+
+ let bytes = [
+ 0x30, 0xff, 0x00, 0x40, 0x1f, 0x54, 0xd4, 0xb5, 0xff, /* Payload */
+ ];
+
+ let expectation = Gtpv1Header {
+ version: 1,
+ protocol_type: 1,
+ reserved: 0,
+ extension_header_flag: 0,
+ sequence_number_flag: 0,
+ npdu_number_flag: 0,
+ message_type: 0xff,
+ message_length: 64,
+ teid: 525653173,
+ options: None,
+ extensions: vec![],
+ };
+
+ assert_eq!(Gtpv1Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+
+ // example
+ let result = Gtpv1Header::decode(&bytes);
+ if let Ok((payload, header)) = result {
+ println!("return: {:?}, payload: {}", header, payload.len());
+ } else {
+ println!("return: Incomplete data");
+ }
+
+ // assert_eq!(1, 0);
+ }
+
+ #[test]
+ fn gtpv1_extension_decode() {
+ /*
+ * GPRS Tunneling Protocol
+ * Flags: 0x36
+ * 001. .... = Version: GTP release 99 version (1)
+ * ...1 .... = Protocol type: GTP (1)
+ * .... 0... = Reserved: 0
+ * .... .1.. = Is Next Extension Header present?: Yes
+ * .... ..1. = Is Sequence Number present?: Yes
+ * .... ...0 = Is N-PDU number present?: No
+ * Message Type: T-PDU (0xff)
+ * Length: 48
+ * TEID: 0x1c6596fc (476419836)
+ * Sequence number: 0x6739 (26425)
+ * Next extension header type: PDU Session container (0x85)
+ * Extension header (PDU Session container)
+ * Extension Header Length: 1
+ * PDU Session Container
+ * 0001 .... = PDU Type: UL PDU SESSION INFORMATION (1)
+ * .... 0000 = Spare: 0x0
+ * 00.. .... = Spare: 0x0
+ * ..00 0001 = QoS Flow Identifier (QFI): 1
+ * Next extension header type: No more extension headers (0x00)
+ */
+
+ let bytes = [
+ 0x36, 0xff, 0x00, 0x30, 0x1c, 0x65, 0x96, 0xfc, 0x67, 0x39, 0x00, 0x85, 0x01, 0x10,
+ 0x01, 0x00, 0xff, /* Payload */
+ ];
+
+ let expectation = Gtpv1Header {
+ version: 1,
+ protocol_type: 1,
+ reserved: 0,
+ extension_header_flag: 1,
+ sequence_number_flag: 1,
+ npdu_number_flag: 0,
+ message_type: 0xff,
+ message_length: 48,
+ teid: 476419836,
+ options: Some(super::Gtpv1Option {
+ sequence_number: 26425,
+ npdu_number: 0,
+ next_header_type: 0x85,
+ }),
+ extensions: vec![Gtpv1ExtensionHeader {
+ length: 1,
+ contents: vec![0x10, 0x01],
+ next_header_type: 0x00,
+ }],
+ };
+
+ assert_eq!(Gtpv1Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+
+ // example
+ let result = Gtpv1Header::decode(&bytes);
+ if let Ok((payload, header)) = result {
+ println!("return: {:?}, payload: {}", header, payload.len());
+ } else {
+ println!("return: Incomplete data");
+ }
+
+ // assert_eq!(1, 0);
+ }
+}
diff --git a/src/protocol/ip.rs b/src/protocol/ip.rs
index 8d22e15..c9b4f53 100644
--- a/src/protocol/ip.rs
+++ b/src/protocol/ip.rs
@@ -6,10 +6,9 @@ use nom::IResult;
* Struct
******************************************************************************/
-#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum IPProtocol {
- IPV6_HOP_HDR,
+ IPV6HOP,
ICMP,
IGMP,
GGP,
@@ -28,12 +27,12 @@ pub enum IPProtocol {
CHAOS,
UDP,
IPV6,
- IPV6_ROUTING_HDR,
- IPV6_FRAGMENT_HDR,
+ IPV6ROUTING,
+ IPV6FRAGMENT,
ESP,
AUTH,
ICMP6,
- IPV6_DEST_HDR,
+ IPV6DEST,
Other(u8),
}
@@ -44,7 +43,7 @@ pub enum IPProtocol {
impl From<u8> for IPProtocol {
fn from(raw: u8) -> Self {
match raw {
- 0 => IPProtocol::IPV6_HOP_HDR, // IPv6 Hop-by-Hop Options
+ 0 => IPProtocol::IPV6HOP, // IPv6 Hop-by-Hop Options
1 => IPProtocol::ICMP,
2 => IPProtocol::IGMP,
3 => IPProtocol::GGP,
@@ -63,12 +62,12 @@ impl From<u8> for IPProtocol {
16 => IPProtocol::CHAOS,
17 => IPProtocol::UDP,
41 => IPProtocol::IPV6,
- 43 => IPProtocol::IPV6_ROUTING_HDR, // IPv6 Routing Header
- 44 => IPProtocol::IPV6_FRAGMENT_HDR, // IPv6 Fragment Header
- 50 => IPProtocol::ESP, // Encap Security Payload [RFC4303]
- 51 => IPProtocol::AUTH, // Authentication Header [RFC4302]
+ 43 => IPProtocol::IPV6ROUTING, // IPv6 Routing Header
+ 44 => IPProtocol::IPV6FRAGMENT, // IPv6 Fragment Header
+ 50 => IPProtocol::ESP, // Encap Security Payload [RFC4303]
+ 51 => IPProtocol::AUTH, // Authentication Header [RFC4302]
58 => IPProtocol::ICMP6,
- 60 => IPProtocol::IPV6_DEST_HDR, // IPv6 Destination Options
+ 60 => IPProtocol::IPV6DEST, // IPv6 Destination Options
other => IPProtocol::Other(other),
}
}
@@ -77,12 +76,12 @@ impl From<u8> for IPProtocol {
impl IPProtocol {
pub fn is_ipv6_ext_header(next_header: IPProtocol) -> bool {
match next_header {
- IPProtocol::IPV6_HOP_HDR => true,
- IPProtocol::IPV6_ROUTING_HDR => true,
- IPProtocol::IPV6_FRAGMENT_HDR => true,
+ IPProtocol::IPV6HOP => true,
+ IPProtocol::IPV6ROUTING => true,
+ IPProtocol::IPV6FRAGMENT => true,
// IPProtocol::ESP => true,
IPProtocol::AUTH => true,
- IPProtocol::IPV6_DEST_HDR => true,
+ IPProtocol::IPV6DEST => true,
_ => false,
}
}
diff --git a/src/protocol/ipv4.rs b/src/protocol/ipv4.rs
index 61dce29..a869031 100644
--- a/src/protocol/ipv4.rs
+++ b/src/protocol/ipv4.rs
@@ -32,7 +32,7 @@ use std::net::Ipv4Addr;
*/
#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct IPv4Header {
+pub struct Ipv4Header {
pub version: u8, // 4 bit
pub ihl: u8, // 4 bit
pub tos: u8,
@@ -71,9 +71,9 @@ fn address_v4_decode(input: &[u8]) -> IResult<&[u8], Ipv4Addr> {
Ok((input, Ipv4Addr::from(<[u8; 4]>::try_from(ipv4).unwrap())))
}
-impl Decode for IPv4Header {
- type Iterm = IPv4Header;
- fn decode(input: &[u8]) -> IResult<&[u8], IPv4Header> {
+impl Decode for Ipv4Header {
+ type Iterm = Ipv4Header;
+ fn decode(input: &[u8]) -> IResult<&[u8], Ipv4Header> {
let (input, verihl) = version_hlen_decode(input)?;
let (input, tos) = number::streaming::be_u8(input)?;
let (input, length) = number::streaming::be_u16(input)?;
@@ -89,7 +89,7 @@ impl Decode for IPv4Header {
Ok((
input,
- IPv4Header {
+ Ipv4Header {
version: verihl.0,
ihl: verihl.1 * 4, // verihl.1 * 32 / 8
tos,
@@ -113,7 +113,7 @@ impl Decode for IPv4Header {
#[cfg(test)]
mod tests {
- use super::IPv4Header;
+ use super::Ipv4Header;
use crate::protocol::codec::Decode;
use crate::protocol::ip::IPProtocol;
use std::net::Ipv4Addr;
@@ -160,7 +160,7 @@ mod tests {
0xff, /* Payload */
];
- let expectation = IPv4Header {
+ let expectation = Ipv4Header {
version: 4,
ihl: 20,
tos: 0,
@@ -175,10 +175,10 @@ mod tests {
dest_address: Ipv4Addr::new(121, 14, 154, 93),
};
- assert_eq!(IPv4Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+ assert_eq!(Ipv4Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
// example
- let result = IPv4Header::decode(&bytes);
+ let result = Ipv4Header::decode(&bytes);
if let Ok((payload, header)) = result {
println!("return: {:?}, payload: {}", header, payload.len());
} else {
diff --git a/src/protocol/ipv6.rs b/src/protocol/ipv6.rs
index 5a30847..c32d21b 100644
--- a/src/protocol/ipv6.rs
+++ b/src/protocol/ipv6.rs
@@ -60,14 +60,14 @@ use std::net::Ipv6Addr;
*/
#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct IPv6Extension {
+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)]
-pub struct IPv6Header {
+pub struct Ipv6Header {
pub version: u8, // 4 bit
pub dsc: u8, // Differentiated Services Codepoint: 6 bit
pub ecn: u8, // Explicit Congestion Notification: 2 bit
@@ -77,7 +77,7 @@ pub struct IPv6Header {
pub hop_limit: u8,
pub source_address: Ipv6Addr,
pub dest_address: Ipv6Addr,
- pub extensions: Vec<IPv6Extension>,
+ pub extensions: Vec<Ipv6Extension>,
}
/******************************************************************************
@@ -97,7 +97,7 @@ fn address_v6_decode(input: &[u8]) -> IResult<&[u8], Ipv6Addr> {
Ok((input, Ipv6Addr::from(<[u8; 16]>::try_from(ipv6).unwrap())))
}
-fn extension_decode(input: &[u8], curr_proto: IPProtocol) -> IResult<&[u8], IPv6Extension> {
+fn extension_decode(input: &[u8], curr_proto: IPProtocol) -> IResult<&[u8], Ipv6Extension> {
let (input, next_header) = IPProtocol::decode(input)?;
let (input, mut ext_length) = number::streaming::be_u8(input)?;
@@ -117,7 +117,7 @@ fn extension_decode(input: &[u8], curr_proto: IPProtocol) -> IResult<&[u8], IPv6
Ok((
input,
- IPv6Extension {
+ Ipv6Extension {
next_header,
ext_length,
data: data.to_vec(),
@@ -125,9 +125,9 @@ fn extension_decode(input: &[u8], curr_proto: IPProtocol) -> IResult<&[u8], IPv6
))
}
-impl Decode for IPv6Header {
- type Iterm = IPv6Header;
- fn decode(input: &[u8]) -> IResult<&[u8], IPv6Header> {
+impl Decode for Ipv6Header {
+ type Iterm = Ipv6Header;
+ fn decode(input: &[u8]) -> IResult<&[u8], Ipv6Header> {
let (input, ver_tc) = half_byte_decode(input)?;
let (input, tc_fl) = half_byte_decode(input)?;
let (input, fl): (_, u32) =
@@ -150,7 +150,7 @@ impl Decode for IPv6Header {
Ok((
remain,
- IPv6Header {
+ Ipv6Header {
version: ver_tc.0,
dsc: (ver_tc.1 << 2) + ((tc_fl.0 & 0b1100) >> 2),
ecn: tc_fl.0 & 0b11,
@@ -172,8 +172,8 @@ impl Decode for IPv6Header {
#[cfg(test)]
mod tests {
- use super::IPv6Extension;
- use super::IPv6Header;
+ use super::Ipv6Extension;
+ use super::Ipv6Header;
use crate::protocol::codec::Decode;
use crate::protocol::ip::IPProtocol;
use std::net::Ipv6Addr;
@@ -210,7 +210,7 @@ mod tests {
0xff, /* Payload */
];
- let expectation = IPv6Header {
+ let expectation = Ipv6Header {
version: 6,
dsc: 0,
ecn: 0,
@@ -227,10 +227,10 @@ mod tests {
extensions: Vec::new(),
};
- assert_eq!(IPv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+ assert_eq!(Ipv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
// example
- let result = IPv6Header::decode(&bytes);
+ let result = Ipv6Header::decode(&bytes);
if let Ok((payload, header)) = result {
println!("return: {:?}, payload: {}", header, payload.len());
} else {
@@ -280,13 +280,13 @@ mod tests {
0xff, /* Payload */
];
- let expectation = IPv6Header {
+ let expectation = Ipv6Header {
version: 6,
dsc: 0,
ecn: 0,
flow_label: 0,
length: 36,
- next_header: IPProtocol::IPV6_HOP_HDR,
+ next_header: IPProtocol::IPV6HOP,
hop_limit: 1,
source_address: Ipv6Addr::new(
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -294,17 +294,17 @@ mod tests {
dest_address: Ipv6Addr::new(
0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0016,
),
- extensions: vec![IPv6Extension {
+ extensions: vec![Ipv6Extension {
next_header: IPProtocol::ICMP6,
ext_length: 8,
data: vec![0x05, 0x02, 0x00, 0x00, 0x01, 0x00],
}],
};
- assert_eq!(IPv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+ assert_eq!(Ipv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
// example
- let result = IPv6Header::decode(&bytes);
+ let result = Ipv6Header::decode(&bytes);
if let Ok((payload, header)) = result {
println!("return: {:?}, payload: {}", header, payload.len());
} else {
@@ -350,13 +350,13 @@ mod tests {
0xff, /* Payload */
];
- let expectation = IPv6Header {
+ let expectation = Ipv6Header {
version: 6,
dsc: 0,
ecn: 0,
flow_label: 0,
length: 32,
- next_header: IPProtocol::IPV6_ROUTING_HDR,
+ next_header: IPProtocol::IPV6ROUTING,
hop_limit: 4,
source_address: Ipv6Addr::new(
0x2200, 0x0000, 0x0000, 0x0244, 0x0212, 0x3fff, 0xfeae, 0x22f7,
@@ -364,7 +364,7 @@ mod tests {
dest_address: Ipv6Addr::new(
0x2200, 0x0000, 0x0000, 0x0240, 0x0002, 0x0000, 0x0000, 0x0004,
),
- extensions: vec![IPv6Extension {
+ extensions: vec![Ipv6Extension {
next_header: IPProtocol::ICMP6,
ext_length: 24,
data: vec![
@@ -374,10 +374,10 @@ mod tests {
}],
};
- assert_eq!(IPv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+ assert_eq!(Ipv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
// example
- let result = IPv6Header::decode(&bytes);
+ let result = Ipv6Header::decode(&bytes);
if let Ok((payload, header)) = result {
println!("return: {:?}, payload: {}", header, payload.len());
} else {
@@ -458,13 +458,13 @@ mod tests {
0xff, /* Payload */
];
- let expectation = IPv6Header {
+ let expectation = Ipv6Header {
version: 6,
dsc: 0,
ecn: 0,
flow_label: 0,
length: 32,
- next_header: IPProtocol::IPV6_HOP_HDR,
+ next_header: IPProtocol::IPV6HOP,
hop_limit: 64,
source_address: Ipv6Addr::new(
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
@@ -473,22 +473,22 @@ mod tests {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003,
),
extensions: vec![
- IPv6Extension {
- next_header: IPProtocol::IPV6_DEST_HDR,
+ Ipv6Extension {
+ next_header: IPProtocol::IPV6DEST,
ext_length: 8,
data: vec![0x01, 0x04, 0x00, 0x00, 0x00, 0x00],
},
- IPv6Extension {
- next_header: IPProtocol::IPV6_ROUTING_HDR,
+ Ipv6Extension {
+ next_header: IPProtocol::IPV6ROUTING,
ext_length: 8,
data: vec![0x01, 0x04, 0x00, 0x00, 0x00, 0x00],
},
- IPv6Extension {
- next_header: IPProtocol::IPV6_FRAGMENT_HDR,
+ Ipv6Extension {
+ next_header: IPProtocol::IPV6FRAGMENT,
ext_length: 8,
data: vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
},
- IPv6Extension {
+ Ipv6Extension {
next_header: IPProtocol::Other(59),
ext_length: 8,
data: vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
@@ -496,10 +496,10 @@ mod tests {
],
};
- assert_eq!(IPv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
+ assert_eq!(Ipv6Header::decode(&bytes), Ok((LAST_SLICE, expectation)));
// example
- let result = IPv6Header::decode(&bytes);
+ let result = Ipv6Header::decode(&bytes);
if let Ok((payload, header)) = result {
println!("return: {:?}, payload: {}", header, payload.len());
} else {
diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs
index 36f0ae6..82a35da 100644
--- a/src/protocol/mod.rs
+++ b/src/protocol/mod.rs
@@ -10,4 +10,5 @@ pub mod http;
pub mod vlan;
pub mod icmp;
pub mod icmpv6;
-pub mod mpls; \ No newline at end of file
+pub mod mpls;
+pub mod gtpv1; \ No newline at end of file