diff options
Diffstat (limited to 'src/packet/packet.rs')
| -rw-r--r-- | src/packet/packet.rs | 224 |
1 files changed, 223 insertions, 1 deletions
diff --git a/src/packet/packet.rs b/src/packet/packet.rs index cc9e2d7..13140be 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -14,6 +14,7 @@ use crate::protocol::l2tp::L2tpHeader; use crate::protocol::l2tp::L2tpType; use crate::protocol::mpls::MplsHeader; use crate::protocol::mpls::PwEthHeader; +use crate::protocol::pptp::PptpHeader; use crate::protocol::tcp::TcpHeader; use crate::protocol::udp::UdpHeader; use crate::protocol::vlan::VlanHeader; @@ -39,6 +40,7 @@ pub enum Encapsulation<'a> { Gtpv1(Gtpv1Header, &'a [u8]), L2tp(L2tpHeader, &'a [u8]), + Pptp(PptpHeader, &'a [u8]), } #[derive(Debug)] @@ -479,13 +481,23 @@ fn handle_tcp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Packet if let Ok((payload, header)) = result { dbg!(&header); + let source_port = header.source_port; + let dest_port = header.dest_port; packet .encapsulation .push(Encapsulation::Tcp(header, payload)); // TODO TCP Reassembly - return Ok(()); + if payload.len() == 0 { + return Ok(()); + } + + match (source_port, dest_port) { + // PPTP + (1723, _) | (_, 1723) => handle_pptp(packet, payload), + _ => Ok(()), + } } else { return Err(PacketError::IncompleteTcpHeader); } @@ -646,6 +658,21 @@ fn handle_gre<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Packet } } +fn handle_pptp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> { + let result = PptpHeader::decode(input); + if let Ok((payload, header)) = result { + dbg!(&header); + + packet + .encapsulation + .push(Encapsulation::Pptp(header, payload)); + + return Ok(()); + } else { + return Err(PacketError::IncompletePptpHeader); + } +} + fn handle_l3<'a>( packet: &mut Packet<'a>, input: &'a [u8], @@ -705,6 +732,9 @@ mod tests { use crate::protocol::ipv6::Ipv6Header; use crate::protocol::mpls::MplsHeader; use crate::protocol::mpls::PwEthHeader; + use crate::protocol::pptp::PptpControlMessageType; + use crate::protocol::pptp::PptpHeader; + use crate::protocol::pptp::PptpMessageType; use crate::protocol::tcp::TcpHeader; use crate::protocol::tcp::TcpOption; use crate::protocol::udp::UdpHeader; @@ -3006,4 +3036,196 @@ mod tests { // assert_eq!(1, 0); } + + #[test] + fn test_packet_handle_eth_ipv4_tcp_pptp() { + /* + * Frame 11: 78 bytes on wire (624 bits), 78 bytes captured (624 bits) + * Encapsulation type: Ethernet (1) + * Arrival Time: Jul 20, 2016 10:34:53.718678000 CST + * [Time shift for this packet: 0.000000000 seconds] + * Epoch Time: 1468982093.718678000 seconds + * [Time delta from previous captured frame: 0.015937000 seconds] + * [Time delta from previous displayed frame: 0.000000000 seconds] + * [Time since reference or first frame: 0.074252000 seconds] + * Frame Number: 11 + * Frame Length: 78 bytes (624 bits) + * Capture Length: 78 bytes (624 bits) + * [Frame is marked: False] + * [Frame is ignored: False] + * [Protocols in frame: eth:ethertype:ip:tcp:pptp] + * [Coloring Rule Name: TCP] + * [Coloring Rule String: tcp] + * 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: 64 + * Identification: 0x0a28 (2600) + * 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: 0x970d [correct] + * [Header checksum status: Good] + * [Calculated Checksum: 0x970d] + * Source Address: 172.16.0.100 + * Destination Address: 172.16.0.254 + * Transmission Control Protocol, Src Port: 50112, Dst Port: 1723, Seq: 325, Ack: 189, Len: 24 + * Source Port: 50112 + * Destination Port: 1723 + * [Stream index: 0] + * [Conversation completeness: Complete, WITH_DATA (63)] + * [TCP Segment Len: 24] + * Sequence Number: 325 (relative sequence number) + * Sequence Number (raw): 2945311102 + * [Next Sequence Number: 349 (relative sequence number)] + * Acknowledgment Number: 189 (relative ack number) + * Acknowledgment number (raw): 3263707926 + * 0101 .... = Header Length: 20 bytes (5) + * Flags: 0x018 (PSH, ACK) + * 000. .... .... = Reserved: Not set + * ...0 .... .... = Accurate ECN: Not set + * .... 0... .... = Congestion Window Reduced: Not set + * .... .0.. .... = ECN-Echo: Not set + * .... ..0. .... = Urgent: Not set + * .... ...1 .... = Acknowledgment: Set + * .... .... 1... = Push: Set + * .... .... .0.. = Reset: Not set + * .... .... ..0. = Syn: Not set + * .... .... ...0 = Fin: Not set + * [TCP Flags: ·······AP···] + * Window: 65332 + * [Calculated window size: 65332] + * [Window size scaling factor: -2 (no window scaling used)] + * Checksum: 0xa732 [correct] + * [Checksum Status: Good] + * [Calculated Checksum: 0xa732] + * Urgent Pointer: 0 + * [Timestamps] + * [Time since first frame in this TCP stream: 0.058594000 seconds] + * [Time since previous frame in this TCP stream: 0.015937000 seconds] + * [SEQ/ACK analysis] + * [This is an ACK to the segment in frame: 10] + * [The RTT to ACK the segment was: 0.015937000 seconds] + * [iRTT: 0.011036000 seconds] + * [Bytes in flight: 24] + * [Bytes sent since last PSH flag: 24] + * TCP payload (24 bytes) + * Point-to-Point Tunnelling Protocol + * Length: 24 + * Message type: Control Message (1) + * Magic Cookie: 0x1a2b3c4d (correct) + * Control Message Type: Set-Link-Info (15) + * Reserved: 0000 + * Peer Call ID: 3 + * Reserved: 0000 + * Send ACCM: 0xffffffff + * Receive ACCM: 0xffffffff + * + */ + + let bytes = [ + 0xc0, 0x00, 0x14, 0x8c, 0x00, 0x00, 0x28, 0xd2, 0x44, 0x43, 0x38, 0x37, 0x08, 0x00, + 0x45, 0x00, 0x00, 0x40, 0x0a, 0x28, 0x40, 0x00, 0x80, 0x06, 0x97, 0x0d, 0xac, 0x10, + 0x00, 0x64, 0xac, 0x10, 0x00, 0xfe, 0xc3, 0xc0, 0x06, 0xbb, 0xaf, 0x8d, 0xe1, 0x7e, + 0xc2, 0x88, 0x3b, 0x16, 0x50, 0x18, 0xff, 0x34, 0xa7, 0x32, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x01, 0x1a, 0x2b, 0x3c, 0x4d, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ]; + + 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(), 4); + assert_eq!( + packet.encapsulation[0], + Encapsulation::Eth( + EthernetFrame { + source_mac: MacAddress([0x28, 0xd2, 0x44, 0x43, 0x38, 0x37]), + dest_mac: MacAddress([0xc0, 0x00, 0x14, 0x8c, 0x00, 0x00]), + ether_type: EtherType::IPv4, + }, + &bytes[14..] + ) + ); + assert_eq!( + packet.encapsulation[1], + Encapsulation::Ipv4( + Ipv4Header { + version: 4, + ihl: 20, + tos: 0x00, + length: 64, + id: 0x0a28, + flags: 0x2, + frag_offset: 0, + ttl: 128, + protocol: IPProtocol::TCP, + checksum: 0x970d, + source_address: Ipv4Addr::new(172, 16, 0, 100), + dest_address: Ipv4Addr::new(172, 16, 0, 254), + }, + &bytes[34..] + ) + ); + assert_eq!( + packet.encapsulation[2], + Encapsulation::Tcp( + TcpHeader { + source_port: 50112, + dest_port: 1723, + seq_num: 2945311102, + ack_num: 3263707926, + data_offset: 20, + reserved: 0, + flag_urg: false, + flag_ack: true, + flag_psh: true, + flag_rst: false, + flag_syn: false, + flag_fin: false, + window: 65332, + checksum: 0xa732, + urgent_ptr: 0, + options: None, + }, + &bytes[54..] + ) + ); + assert_eq!( + packet.encapsulation[3], + Encapsulation::Pptp( + PptpHeader { + length: 24, + message_type: PptpMessageType::ControlMessage, + magic_cookie: 0x1a2b3c4d, + control_message_type: PptpControlMessageType::SetLinkInfo, + reserved0: 0, + payload: vec![ + 0x00, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], + }, + &bytes[78..] + ) + ); + + // assert_eq!(1, 0); + } } |
