diff options
| author | luwenpeng <[email protected]> | 2023-09-22 17:00:40 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-09-22 17:33:15 +0800 |
| commit | c0cc75c093bfa667dcab4214587d70df83646277 (patch) | |
| tree | c76714cc56da054ee99999ac919f2846a89616e7 | |
| parent | a01e8ffad311862e2ab3af61560dc74e42ae337d (diff) | |
[test] Add l2tp_ppp test case
| -rw-r--r-- | src/main.rs | 12 | ||||
| -rw-r--r-- | src/packet/capture.rs | 10 | ||||
| -rw-r--r-- | src/packet/packet.rs | 313 | ||||
| -rw-r--r-- | src/thread/thread.rs | 6 |
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))), } |
