summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-09-22 17:00:40 +0800
committerluwenpeng <[email protected]>2023-09-22 17:33:15 +0800
commitc0cc75c093bfa667dcab4214587d70df83646277 (patch)
treec76714cc56da054ee99999ac919f2846a89616e7
parenta01e8ffad311862e2ab3af61560dc74e42ae337d (diff)
[test] Add l2tp_ppp test case
-rw-r--r--src/main.rs12
-rw-r--r--src/packet/capture.rs10
-rw-r--r--src/packet/packet.rs313
-rw-r--r--src/thread/thread.rs6
4 files changed, 324 insertions, 17 deletions
diff --git a/src/main.rs b/src/main.rs
index 012db40..78d5e8d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,7 +11,7 @@ use stellar_rs::plugin::example::ExamplePulgin;
use stellar_rs::session::session::Session;
use stellar_rs::session::session::SessionProto;
use stellar_rs::session::session::SessionState;
-use stellar_rs::thread::thread::ThreadContex;
+use stellar_rs::thread::thread::ThreadContext;
fn trigger_packet_event(
packet: &Packet,
@@ -117,9 +117,9 @@ fn trigger_session_event(session: Option<Rc<RefCell<Session>>>, queue: &mut Even
}
}
-fn handle_one_packet(data: &[u8], len: u32, ctx: Rc<RefCell<ThreadContex>>) {
- let event_mgr = ctx.borrow().get_event_mgr();
- let session_mgr = ctx.borrow().get_session_mgr();
+fn handle_one_packet(data: &[u8], len: u32, thread_ctx: &mut ThreadContext) {
+ let event_mgr = thread_ctx.get_event_mgr();
+ let session_mgr = thread_ctx.get_session_mgr();
let mut queue = EventQueue::new();
let mut packet = Packet::new(data, len);
@@ -162,9 +162,9 @@ fn main() {
plugin2.init(&mut event_mgr);
let event_mgr = Rc::new(RefCell::new(event_mgr));
- let thread_ctx = Rc::new(RefCell::new(ThreadContex::new(event_mgr)));
+ let mut thread_ctx = ThreadContext::new(event_mgr);
PacketCapture::show_devices();
let mut cap = PacketCapture::new("en0");
- cap.poll_packet(handle_one_packet, thread_ctx);
+ cap.poll_packet(handle_one_packet, &mut thread_ctx);
}
diff --git a/src/packet/capture.rs b/src/packet/capture.rs
index 6ba8144..d71b1a8 100644
--- a/src/packet/capture.rs
+++ b/src/packet/capture.rs
@@ -1,7 +1,5 @@
-use crate::thread::thread::ThreadContex;
+use crate::thread::thread::ThreadContext;
use pcap::Capture;
-use std::cell::RefCell;
-use std::rc::Rc;
pub struct PacketCapture {
capture: Capture<pcap::Active>,
@@ -21,8 +19,8 @@ impl PacketCapture {
pub fn poll_packet(
&mut self,
- callback: fn(data: &[u8], len: u32, ctx: Rc<RefCell<ThreadContex>>),
- ctx: Rc<RefCell<ThreadContex>>,
+ callback: fn(data: &[u8], len: u32, ctx: &mut ThreadContext),
+ ctx: &mut ThreadContext,
) {
let mut packet_num = 0;
while let Ok(packet) = self.capture.next_packet() {
@@ -30,7 +28,7 @@ impl PacketCapture {
println!("\n==================== New Packet ====================\n");
println!("Packet[{}]->header : {:?}", packet_num, packet.header);
println!("Packet[{}]->data : {:?}", packet_num, packet.data);
- callback(&packet.data, packet.header.len, ctx.clone());
+ callback(&packet.data, packet.header.len, ctx);
}
}
diff --git a/src/packet/packet.rs b/src/packet/packet.rs
index 0576f70..8d258d5 100644
--- a/src/packet/packet.rs
+++ b/src/packet/packet.rs
@@ -604,8 +604,7 @@ fn handle_l2tp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Packe
return Ok(());
}
L2TPType::Data => {
- // TODO handle PPP
- return Ok(());
+ return handle_ppp(packet, payload);
}
}
}
@@ -760,6 +759,8 @@ mod tests {
use crate::protocol::ip::IPProtocol;
use crate::protocol::ipv4::IPv4Header;
use crate::protocol::ipv6::IPv6Header;
+ use crate::protocol::l2tp::L2TPHeader;
+ use crate::protocol::l2tp::L2TPType;
use crate::protocol::mpls::MPLSHeader;
use crate::protocol::mpls::PWEthHeader;
use crate::protocol::ppp::PPPHeader;
@@ -3481,4 +3482,312 @@ mod tests {
// assert_eq!(1, 0);
}
+
+ #[test]
+ fn test_packet_handle_eth_ipv4_udp_l2tp_ppp_ipv4_tcp() {
+ /*
+ * Frame 1: 106 bytes on wire (848 bits), 106 bytes captured (848 bits)
+ * Encapsulation type: Ethernet (1)
+ * Arrival Time: Jul 20, 2016 16:11:58.749209000 CST
+ * [Time shift for this packet: 0.000000000 seconds]
+ * Epoch Time: 1469002318.749209000 seconds
+ * [Time delta from previous captured frame: 0.000000000 seconds]
+ * [Time delta from previous displayed frame: 0.000000000 seconds]
+ * [Time since reference or first frame: 0.000000000 seconds]
+ * Frame Number: 1
+ * Frame Length: 106 bytes (848 bits)
+ * Capture Length: 106 bytes (848 bits)
+ * [Frame is marked: False]
+ * [Frame is ignored: False]
+ * [Protocols in frame: eth:ethertype:ip:udp:l2tp:ppp:ip:tcp]
+ * [Coloring Rule Name: HTTP]
+ * [Coloring Rule String: http || tcp.port == 80 || http2]
+ * Ethernet II, Src: LCFCHeFe_43:38:37 (28:d2:44:43:38:37), Dst: c0:00:14:8c:00:00 (c0:00:14:8c:00:00)
+ * Destination: c0:00:14:8c:00:00 (c0:00:14:8c:00:00)
+ * Address: c0:00:14:8c:00:00 (c0:00:14:8c:00:00)
+ * .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+ * .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+ * Source: LCFCHeFe_43:38:37 (28:d2:44:43:38:37)
+ * Address: LCFCHeFe_43:38:37 (28:d2:44:43:38:37)
+ * .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+ * .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 172.16.0.100, Dst: 172.16.0.254
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 92
+ * Identification: 0x07f8 (2040)
+ * 000. .... = Flags: 0x0
+ * 0... .... = Reserved bit: Not set
+ * .0.. .... = Don't fragment: Not set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 128
+ * Protocol: UDP (17)
+ * Header Checksum: 0xd916 [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0xd916]
+ * Source Address: 172.16.0.100
+ * Destination Address: 172.16.0.254
+ * User Datagram Protocol, Src Port: 1701, Dst Port: 1701
+ * Source Port: 1701
+ * Destination Port: 1701
+ * Length: 72
+ * Checksum: 0xa761 [correct]
+ * [Calculated Checksum: 0xa761]
+ * [Checksum Status: Good]
+ * [Stream index: 0]
+ * [Timestamps]
+ * [Time since first frame: 0.000000000 seconds]
+ * [Time since previous frame: 0.000000000 seconds]
+ * UDP payload (64 bytes)
+ * Layer 2 Tunneling Protocol
+ * Flags: 0x4002, Type: Data Message, Length Bit
+ * 0... .... .... .... = Type: Data Message (0)
+ * .1.. .... .... .... = Length Bit: Length field is present
+ * .... 0... .... .... = Sequence Bit: Ns and Nr fields are not present
+ * .... ..0. .... .... = Offset bit: Offset size field is not present
+ * .... ...0 .... .... = Priority: No priority
+ * .... .... .... 0010 = Version: 2
+ * Length: 64
+ * Tunnel ID: 28998
+ * Session ID: 2
+ * Point-to-Point Protocol
+ * Address: 0xff
+ * Control: 0x03
+ * Protocol: Internet Protocol version 4 (0x0021)
+ * Internet Protocol Version 4, Src: 172.16.2.100, Dst: 10.0.6.229
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 52
+ * Identification: 0x00fc (252)
+ * 010. .... = Flags: 0x2, Don't fragment
+ * 0... .... = Reserved bit: Not set
+ * .1.. .... = Don't fragment: Set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 128
+ * Protocol: TCP (6)
+ * Header Checksum: 0x3a6f [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0x3a6f]
+ * Source Address: 172.16.2.100
+ * Destination Address: 10.0.6.229
+ * Transmission Control Protocol, Src Port: 49250, Dst Port: 80, Seq: 0, Len: 0
+ * Source Port: 49250
+ * Destination Port: 80
+ * [Stream index: 0]
+ * [Conversation completeness: Incomplete, DATA (15)]
+ * [TCP Segment Len: 0]
+ * Sequence Number: 0 (relative sequence number)
+ * Sequence Number (raw): 2092441352
+ * [Next Sequence Number: 1 (relative sequence number)]
+ * Acknowledgment Number: 0
+ * Acknowledgment number (raw): 0
+ * 1000 .... = Header Length: 32 bytes (8)
+ * Flags: 0x002 (SYN)
+ * 000. .... .... = Reserved: Not set
+ * ...0 .... .... = Accurate ECN: Not set
+ * .... 0... .... = Congestion Window Reduced: Not set
+ * .... .0.. .... = ECN-Echo: Not set
+ * .... ..0. .... = Urgent: Not set
+ * .... ...0 .... = Acknowledgment: Not set
+ * .... .... 0... = Push: Not set
+ * .... .... .0.. = Reset: Not set
+ * .... .... ..1. = Syn: Set
+ * [Expert Info (Chat/Sequence): Connection establish request (SYN): server port 80]
+ * [Connection establish request (SYN): server port 80]
+ * [Severity level: Chat]
+ * [Group: Sequence]
+ * .... .... ...0 = Fin: Not set
+ * [TCP Flags: ··········S·]
+ * Window: 8192
+ * [Calculated window size: 8192]
+ * Checksum: 0x340c [correct]
+ * [Checksum Status: Good]
+ * [Calculated Checksum: 0x340c]
+ * Urgent Pointer: 0
+ * Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
+ * TCP Option - Maximum segment size: 1260 bytes
+ * Kind: Maximum Segment Size (2)
+ * Length: 4
+ * MSS Value: 1260
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Window scale: 8 (multiply by 256)
+ * Kind: Window Scale (3)
+ * Length: 3
+ * Shift count: 8
+ * [Multiplier: 256]
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - SACK permitted
+ * Kind: SACK Permitted (4)
+ * Length: 2
+ * [Timestamps]
+ * [Time since first frame in this TCP stream: 0.000000000 seconds]
+ * [Time since previous frame in this TCP stream: 0.000000000 seconds]
+ */
+
+ let bytes = [
+ 0xc0, 0x00, 0x14, 0x8c, 0x00, 0x00, 0x28, 0xd2, 0x44, 0x43, 0x38, 0x37, 0x08, 0x00,
+ 0x45, 0x00, 0x00, 0x5c, 0x07, 0xf8, 0x00, 0x00, 0x80, 0x11, 0xd9, 0x16, 0xac, 0x10,
+ 0x00, 0x64, 0xac, 0x10, 0x00, 0xfe, 0x06, 0xa5, 0x06, 0xa5, 0x00, 0x48, 0xa7, 0x61,
+ 0x40, 0x02, 0x00, 0x40, 0x71, 0x46, 0x00, 0x02, 0xff, 0x03, 0x00, 0x21, 0x45, 0x00,
+ 0x00, 0x34, 0x00, 0xfc, 0x40, 0x00, 0x80, 0x06, 0x3a, 0x6f, 0xac, 0x10, 0x02, 0x64,
+ 0x0a, 0x00, 0x06, 0xe5, 0xc0, 0x62, 0x00, 0x50, 0x7c, 0xb8, 0x1f, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x02, 0x20, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x02, 0x04, 0x04, 0xec,
+ 0x01, 0x03, 0x03, 0x08, 0x01, 0x01, 0x04, 0x02,
+ ];
+
+ let mut packet = Packet::new(&bytes, bytes.len() as u32);
+ let result = packet.handle();
+ assert_eq!(result.is_ok(), true);
+
+ assert_eq!(packet.encapsulation.len(), 7);
+ assert_eq!(
+ packet.encapsulation[0],
+ Encapsulation::ETH(
+ EthHeader {
+ source_mac: MacAddress([0x28, 0xd2, 0x44, 0x43, 0x38, 0x37]),
+ dest_mac: MacAddress([0xc0, 0x00, 0x14, 0x8c, 0x00, 0x00]),
+ ether_type: EthType::IPv4,
+ },
+ &bytes[14..]
+ )
+ );
+ assert_eq!(
+ packet.encapsulation[1],
+ Encapsulation::IPv4(
+ IPv4Header {
+ version: 4,
+ ihl: 20,
+ tos: 0x00,
+ length: 92,
+ id: 0x07f8,
+ flags: 0x0,
+ frag_offset: 0,
+ ttl: 128,
+ protocol: IPProtocol::UDP,
+ checksum: 0xd916,
+ source_address: Ipv4Addr::new(172, 16, 0, 100),
+ dest_address: Ipv4Addr::new(172, 16, 0, 254),
+ },
+ &bytes[34..]
+ )
+ );
+ assert_eq!(
+ packet.encapsulation[2],
+ Encapsulation::UDP(
+ UDPHeader {
+ source_port: 1701,
+ dest_port: 1701,
+ length: 72,
+ checksum: 0xa761,
+ },
+ &bytes[42..]
+ )
+ );
+ assert_eq!(
+ packet.encapsulation[3],
+ Encapsulation::L2TP(
+ L2TPHeader {
+ flags: 0x4002 >> 4,
+ flag_type: L2TPType::Data,
+ flag_length: true,
+ flag_sequence: false,
+ flag_offset: false,
+ flag_priority: false,
+ ver: 2,
+ length: Some(64),
+ tunnel_id: 28998,
+ session_id: 2,
+ ns: None,
+ nr: None,
+ offset_size: None,
+ offset_pad: None,
+ avps: None,
+ },
+ &bytes[50..]
+ )
+ );
+ assert_eq!(
+ packet.encapsulation[4],
+ Encapsulation::PPP(
+ PPPHeader {
+ address: 0xff,
+ control: 0x03,
+ protocol: PPPProtocol::IPv4,
+ },
+ &bytes[54..]
+ )
+ );
+ assert_eq!(
+ packet.encapsulation[5],
+ Encapsulation::IPv4(
+ IPv4Header {
+ version: 4,
+ ihl: 20,
+ tos: 0x00,
+ length: 52,
+ id: 0x00fc,
+ flags: 0x2,
+ frag_offset: 0,
+ ttl: 128,
+ protocol: IPProtocol::TCP,
+ checksum: 0x3a6f,
+ source_address: Ipv4Addr::new(172, 16, 2, 100),
+ dest_address: Ipv4Addr::new(10, 0, 6, 229),
+ },
+ &bytes[74..]
+ )
+ );
+ assert_eq!(
+ packet.encapsulation[6],
+ Encapsulation::TCP(
+ TCPHeader {
+ source_port: 49250,
+ dest_port: 80,
+ seq_num: 2092441352,
+ ack_num: 0,
+ data_offset: 32,
+ reserved: 0,
+ flag_urg: false,
+ flag_ack: false,
+ flag_psh: false,
+ flag_rst: false,
+ flag_syn: true,
+ flag_fin: false,
+ window: 8192,
+ checksum: 0x340c,
+ urgent_ptr: 0,
+ options: Some(vec![
+ TCPOption::MSS {
+ length: 4,
+ mss: 1260
+ },
+ TCPOption::NOP,
+ TCPOption::WSCALE {
+ length: 3,
+ shift_count: 8
+ },
+ TCPOption::NOP,
+ TCPOption::NOP,
+ TCPOption::SACKPERMITTED,
+ ]),
+ },
+ &bytes[106..]
+ )
+ );
+
+ // assert_eq!(1, 0);
+ }
}
diff --git a/src/thread/thread.rs b/src/thread/thread.rs
index 75e7ab6..fea8426 100644
--- a/src/thread/thread.rs
+++ b/src/thread/thread.rs
@@ -3,14 +3,14 @@ use crate::session::manager::SessionManager;
use std::cell::RefCell;
use std::rc::Rc;
-pub struct ThreadContex {
+pub struct ThreadContext {
event_mgr: Rc<RefCell<EventManager>>,
session_mgr: Rc<RefCell<SessionManager>>,
}
-impl ThreadContex {
+impl ThreadContext {
pub fn new(event_mgr: Rc<RefCell<EventManager>>) -> Self {
- ThreadContex {
+ ThreadContext {
event_mgr,
session_mgr: Rc::new(RefCell::new(SessionManager::new(4096))),
}