diff --git a/src/main.rs b/src/main.rs index 010ff2b..2a98431 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,77 +3,40 @@ extern crate serde_json; extern crate tokio; use rayon::prelude::*; use serde::ser::{Serialize, Serializer, SerializeStruct}; -mod parser; use std::fs::File; use serde_json::json; - +mod parser; use tokio_postgres::types::ToSql; -//use futures::{TryStreamExt}; use tokio_postgres::{NoTls, Error}; - impl Serialize for parser::QryData { fn serialize(&self, serializer: S) -> Result where S: Serializer, { - // 34 is the number of fields in the struct. + // 34 (42) is the number of fields in the struct. let mut state = serializer.serialize_struct("parser::QryData", 34)?; state.serialize_field("time", &self.time)?; state.serialize_field("ether_header.ether_dhost", &self.ether_header.ether_dhost)?; state.serialize_field("ether_header.ether_shost", &self.ether_header.ether_shost)?; state.serialize_field("ether_header.ether_type", &self.ether_header.ether_type)?; - state.serialize_field("ipv4_header.ip_version", &self.ipv4_header.ip_version)?; - state.serialize_field("ipv4_header.ip_ihl", &self.ipv4_header.ip_ihl)?; - state.serialize_field("ipv4_header.ip_dscp", &self.ipv4_header.ip_dscp)?; - state.serialize_field("ipv4_header.ip_ecn", &self.ipv4_header.ip_ecn)?; - state.serialize_field("ipv4_header.ip_total_length", &self.ipv4_header.ip_total_length)?; - state.serialize_field("ipv4_header.ip_identification", &self.ipv4_header.ip_identification)?; - state.serialize_field("ipv4_header.ip_df", &self.ipv4_header.ip_df)?; - state.serialize_field("ipv4_header.ip_mf", &self.ipv4_header.ip_mf)?; - state.serialize_field("ipv4_header.ip_fragment_offset", &self.ipv4_header.ip_fragment_offset)?; - state.serialize_field("ipv4_header.ip_source_address", &self.ipv4_header.ip_source_address)?; - state.serialize_field("ipv4_header.ip_destination_address", &self.ipv4_header.ip_destination_address)?; - state.serialize_field("ipv6_header.version", &self.ipv6_header.version)?; - state.serialize_field("ipv6_header.traffic_class", &self.ipv6_header.traffic_class)?; - state.serialize_field("ipv6_header.flow_label" , &self.ipv6_header.flow_label)?; - state.serialize_field("ipv6_header.payload_length" , &self.ipv6_header.payload_length)?; - state.serialize_field("ipv6_header.next_header" , &self.ipv6_header.next_header)?; - state.serialize_field("ipv6_header.hop_limit" , &self.ipv6_header.hop_limit)?; - state.serialize_field("ipv6_header.source_address" , &self.ipv6_header.source_address)?; - state.serialize_field("ipv6_header.destination_address" , &self.ipv6_header.destination_address)?; - state.serialize_field("tcp_header.source_port", &self.tcp_header.source_port)?; - state.serialize_field("tcp_header.destination_port", &self.tcp_header.destination_port)?; - state.serialize_field("tcp_header.seq_num", &self.tcp_header.seq_num)?; - state.serialize_field("tcp_header.ack_num", &self.tcp_header.ack_num)?; - state.serialize_field("tcp_header.data_offset", &self.tcp_header.data_offset)?; - state.serialize_field("tcp_header.reserved", &self.tcp_header.reserved)?; - state.serialize_field("tcp_header.ns", &self.tcp_header.ns)?; - state.serialize_field("tcp_header.cwr", &self.tcp_header.cwr)?; - state.serialize_field("tcp_header.ece", &self.tcp_header.ece)?; - state.serialize_field("tcp_header.urg", &self.tcp_header.urg)?; - state.serialize_field("tcp_header.ack", &self.tcp_header.ack)?; - state.serialize_field("tcp_header.psh", &self.tcp_header.psh)?; - state.serialize_field("tcp_header.rst", &self.tcp_header.rst)?; - state.serialize_field("tcp_header.syn", &self.tcp_header.syn)?; - state.serialize_field("tcp_header.fin", &self.tcp_header.fin)?; - state.serialize_field("tcp_header.window_size", &self.tcp_header.window_size)?; - state.serialize_field("tcp_header.checksum", &self.tcp_header.checksum)?; - state.serialize_field("tcp_header.urgent_pointer", &self.tcp_header.urgent_pointer)?; + state.serialize_field("ipv4_header", &self.ipv4_header)?; + state.serialize_field("ipv6_header", &self.ipv6_header)?; + state.serialize_field("tcp_header", &self.tcp_header)?; state.serialize_field("data", &self.data)?; state.end() } } fn serialize_packets ( v: Vec ) -> Vec { - let mut packets_serialized: Vec<_> = Vec::new(); + // let mut packets_serialized: Vec<_> = Vec::new(); // for packet in v.iter() { // // packets_serialized.push(json!(&packet)); // } /* rayon parallelized */ - packets_serialized = v.par_iter().map( |x| json!(x) ).collect(); + let packets_serialized = v.par_iter().map( |x| json!(x) ).collect(); packets_serialized } diff --git a/src/parser.json b/src/parser.json index c7a935c..2ddc091 100644 --- a/src/parser.json +++ b/src/parser.json @@ -1,7 +1,7 @@ { - "insert_max": 80, + "insert_max": 20000, "filter": "tcp && !ip6", - "from_device": true, + "from_device": false, "parse_device": "enp7s0", "pcap_file": "../target/wohnung2.pcapng", "database_user": "postgres", diff --git a/src/parser.rs b/src/parser.rs index c0100ae..169e783 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4,7 +4,7 @@ extern crate eui48; mod packet_handler; use pcap::Capture; use eui48::MacAddress; -use std::net::{IpAddr, Ipv4Addr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::str; fn build_ether () -> packet_handler::EtherHeader { @@ -15,47 +15,6 @@ fn build_ether () -> packet_handler::EtherHeader { } } -fn build_ipv4 () -> packet_handler::IpV4Header { - packet_handler::IpV4Header { - ip_version: 0, - ip_ihl: 0, - ip_dscp: 0, - ip_ecn: 0, - ip_total_length: 0, - ip_identification: 0, - ip_df: 0, - ip_mf: 0, - ip_fragment_offset: 0, - ip_time_to_live: 0, - ip_protocol: 0, - ip_header_checksum: 0, - ip_source_address: IpAddr::V4(Ipv4Addr::new(0,0,0,0)), - ip_destination_address: IpAddr::V4(Ipv4Addr::new(0,0,0,0)), - } -} - -fn build_tcp () -> packet_handler::TcpHeader { - packet_handler::TcpHeader { - source_port: 0, - destination_port: 0, - seq_num: 0, - ack_num: 0, - data_offset: 0, - reserved: 0, - ns: 0, - cwr: 0, - ece: 0, - urg: 0, - ack: 0, - psh: 0, - rst: 0, - syn: 0, - fin: 0, - window_size: 0, - checksum: 0, - urgent_pointer: 0, - } -} // TODO: wrap packet_handler types inside Option #[derive(Debug, Clone)] @@ -64,22 +23,23 @@ pub struct QryData{ pub time: f64, pub data: Option>, pub ether_header: packet_handler::EtherHeader, - pub ipv4_header: packet_handler::IpV4Header, - pub tcp_header: packet_handler::TcpHeader, + pub ipv4_header: Option, + pub ipv6_header: Option, + pub tcp_header: Option, } pub fn parse (parse_file: &str, filter_str: &str) -> Vec { let ether_init = build_ether(); - let ipv4_init = build_ipv4(); - let tcp_init = build_tcp(); let mut me = QryData { id: 0, time: 0.0, data: None, ether_header: ether_init, - ipv4_header: ipv4_init, - tcp_header: tcp_init, + ipv4_header: None::, + ipv6_header: None::, + tcp_header: None::, + }; let mut v: Vec = Vec::new(); @@ -96,15 +56,24 @@ pub fn parse (parse_file: &str, filter_str: &str) -> Vec { me.data = Some(packet.data.to_vec()); me.ether_header = packet_handler::ethernet_handler( packet.data ); if 8 == me.ether_header.ether_type { - me.ipv4_header = packet_handler::ip_handler( packet.data ); - if 6 == me.ipv4_header.ip_protocol { - me.tcp_header = packet_handler::tcp_handler( me.ipv4_header.ip_ihl, packet.data ); - me.data= packet_handler::payload_handler( me.ipv4_header.ip_ihl, me.tcp_header.data_offset, packet.data); + me.ipv6_header = None::; + me.ipv4_header = Some(packet_handler::ip_handler( packet.data )).unwrap(); + if 6 == me.ipv4_header.unwrap().ip_protocol { + me.tcp_header = Some(packet_handler::tcp_handler( me.ipv4_header.unwrap().ip_ihl, packet.data )).unwrap(); + me.data= packet_handler::payload_handler( me.ipv4_header.unwrap().ip_ihl, me.tcp_header.unwrap().data_offset, packet.data); } + } + if 56710 == me.ether_header.ether_type{ + me.ipv4_header = None::; + me.ipv6_header = Some(packet_handler::ipv6_handler( packet.data )).unwrap(); + if 6 == me.ipv6_header.unwrap().next_header{ + me.tcp_header = Some(packet_handler::tcp_handler( 10, packet.data )).unwrap(); + me.data = packet_handler::payload_handler( 10, 0, packet.data); + } } - - v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, tcp_header: me.tcp_header}); + + v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, ipv6_header: me.ipv6_header, tcp_header: me.tcp_header}); } v @@ -113,15 +82,17 @@ pub fn parse (parse_file: &str, filter_str: &str) -> Vec { pub fn parse_device (parse_device: &str, filter_str: &str, insert_max: &usize) -> Vec { let ether_init = build_ether(); let ipv4_init = build_ipv4(); - let tcp_init = build_tcp(); + let ipv6_init = build_ipv6(); + //let tcp_init = build_tcp(); let mut me = QryData { id: 0, time: 0.0, data: None, ether_header: ether_init, - ipv4_header: ipv4_init, - tcp_header: tcp_init, + ipv4_header: None::, + ipv6_header: None::, + tcp_header: None::, }; let mut v: Vec = Vec::new(); let mut cap = Capture::from_device(parse_device).unwrap().open().unwrap(); @@ -132,15 +103,26 @@ pub fn parse_device (parse_device: &str, filter_str: &str, insert_max: &usize) - me.data = Some(packet.data.to_vec()); me.ether_header = packet_handler::ethernet_handler( packet.data ); if 8 == me.ether_header.ether_type { - me.ipv4_header = packet_handler::ip_handler( packet.data ); - if 6 == me.ipv4_header.ip_protocol { - me.tcp_header = packet_handler::tcp_handler( me.ipv4_header.ip_ihl, packet.data ); - me.data= packet_handler::payload_handler( me.ipv4_header.ip_ihl, me.tcp_header.data_offset, packet.data); + me.ipv6_header = None::; + me.ipv4_header = Some(packet_handler::ip_handler( packet.data )).unwrap(); + if 6 == me.ipv4_header.unwrap().ip_protocol { + me.tcp_header = Some(packet_handler::tcp_handler( me.ipv4_header.unwrap().ip_ihl, packet.data )).unwrap(); + me.data= packet_handler::payload_handler( me.ipv4_header.unwrap().ip_ihl, me.tcp_header.unwrap().data_offset, packet.data); } + } + if 56710 == me.ether_header.ether_type{ + me.ipv4_header = None::; + me.ipv6_header = Some(packet_handler::ipv6_handler( packet.data)).unwrap(); + if 6 == me.ipv6_header.unwrap().next_header{ + me.tcp_header = Some(packet_handler::tcp_handler( 10, packet.data )).unwrap(); + me.data = packet_handler::payload_handler( 10, 0, packet.data); + } } + + v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, ipv6_header: me.ipv6_header, tcp_header: me.tcp_header}); + - v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, tcp_header: me.tcp_header}); if &v.len() >= insert_max { break 'parse; } diff --git a/src/parser/packet_handler.rs b/src/parser/packet_handler.rs index 154aca6..d1d886f 100644 --- a/src/parser/packet_handler.rs +++ b/src/parser/packet_handler.rs @@ -1,12 +1,12 @@ extern crate eui48; extern crate byteorder; extern crate bitfield; - -use byteorder::{ByteOrder, BigEndian, LittleEndian, ReadBytesExt}; +extern crate serde; +use byteorder::{ByteOrder, BigEndian, LittleEndian}; use eui48::{MacAddress, Eui48}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use bitfield::{bitfield, BitRange}; -use std::io::Cursor; +use bitfield::{bitfield}; +use serde::{Serialize, Deserialize}; /* ethernet */ const ETH_ALEN: usize = 6; @@ -42,7 +42,7 @@ pub fn ethernet_handler ( packet_data: &[u8] ) -> EtherHeader { } /* ip */ -#[derive(Debug,Copy, Clone)] +#[derive(Debug,Copy, Clone, Serialize, Deserialize)] pub struct IpV4Header { pub ip_version: u32, pub ip_ihl: u32, @@ -91,7 +91,7 @@ impl + AsMut<[u8]>> BitfieldIpV4Header { } } -pub fn ip_handler ( packet_data: &[u8] ) -> IpV4Header { +pub fn ip_handler ( packet_data: &[u8] ) -> Option { let (_head, tail) = packet_data.split_at(ETHER_HDRLEN); let (raw_hdr, _) = tail.split_at(20); let mut _tail: [u8; 20] = [0; 20]; @@ -99,7 +99,7 @@ pub fn ip_handler ( packet_data: &[u8] ) -> IpV4Header { let ip_header = BitfieldIpV4Header(_tail); - IpV4Header { + Some(IpV4Header { ip_version: ip_header.get_version(), ip_ihl: ip_header.get_ihl(), ip_dscp: ip_header.get_dscp(), @@ -114,11 +114,11 @@ pub fn ip_handler ( packet_data: &[u8] ) -> IpV4Header { ip_header_checksum: ip_header.get_header_checksum(), ip_source_address: IpAddr::V4(ip_header.get_source_as_ip_addr()), ip_destination_address: IpAddr::V4(ip_header.get_destination_address()), - } + }) } /* ipv6 */ -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct IpV6Header { pub version: u8, pub traffic_class: u8, @@ -130,7 +130,7 @@ pub struct IpV6Header { pub destination_address: IpAddr, } -pub fn ipv6_handler ( packet_data: &[u8] ) -> IpV6Header { +pub fn ipv6_handler ( packet_data: &[u8] ) -> Option { let (_head, tail) = packet_data.split_at(ETHER_HDRLEN); let (raw_hdr, _) = tail.split_at(40); let mut _tail: [u8; 40] = [0; 40]; @@ -139,16 +139,16 @@ pub fn ipv6_handler ( packet_data: &[u8] ) -> IpV6Header { - IpV6Header { + Some(IpV6Header { version: (&raw_hdr[0] & 0xf0) >> 4, traffic_class: ((&raw_hdr[0] & 0x0f) >> 4)| ((&raw_hdr[1] & 0xf0 <<4)) , flow_label: BigEndian::read_u32( &[0x00 ,(&_tail[1] &0x0f) , _tail[2] , _tail[3]]), payload_length: BigEndian::read_u16(&[_tail[4], _tail[5]]), next_header: _tail[6], hop_limit: _tail[7], - source_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[8..24]))), - destination_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[24..40]))), - } + source_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[8..24]))), // Results in correct addresses, but interval range is not default [incl..excl]. Watch out! + destination_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[24..40]))), // Must be byteorder crate !? + }) } /* I ve got no glue how this bitfield macro syntax works with impl and bitranges involved, if you do plz enlighten me */ @@ -199,7 +199,7 @@ pub fn ipv6_handler( packet_data: &[u8] ) -> IpV6Header { */ /* tcp */ -#[derive(Debug,Copy,Clone)] +#[derive(Debug,Copy,Clone, Serialize, Deserialize)] pub struct TcpHeader { pub source_port: u32, pub destination_port: u32, @@ -245,14 +245,14 @@ bitfield! { get_urgent_pointer, _: 159,144; } -pub fn tcp_handler ( ip_hlen: u32, packet_data: &[u8] ) ->TcpHeader { +pub fn tcp_handler ( ip_hlen: u32, packet_data: &[u8] ) -> Option { let (_head, tail) = packet_data.split_at(ETHER_HDRLEN+ip_hlen as usize * 4); let (raw_hdr, _) = tail.split_at(20); let mut _tail: [u8; 20] = [0; 20]; _tail.copy_from_slice(raw_hdr); let tcp_header = BitfieldTcpHeader(_tail); - TcpHeader { + Some(TcpHeader { source_port: tcp_header.get_source_port(), destination_port: tcp_header.get_destination_port(), seq_num: tcp_header.get_seq_num(), @@ -271,13 +271,13 @@ pub fn tcp_handler ( ip_hlen: u32, packet_data: &[u8] ) ->TcpHeader { window_size: tcp_header.get_window_size(), checksum: tcp_header.get_checksum(), urgent_pointer: tcp_header.get_urgent_pointer(), - } + }) } /* arp */ -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ArpHeader { pub htype: u32, pub ptype: u32, @@ -317,7 +317,7 @@ impl + AsMut<[u8]>> BitfieldArpHeader { } } -pub fn arp_handler ( packet_data: &[u8] ) -> ArpHeader { +pub fn arp_handler ( packet_data: &[u8] ) -> Option { let (_head, tail) = packet_data.split_at(ETHER_HDRLEN); let (raw_hdr, _) = tail.split_at(28); let mut _tail: [u8; 28] = [0; 28]; @@ -329,7 +329,7 @@ pub fn arp_handler ( packet_data: &[u8] ) -> ArpHeader { _tail[18..23].copy_from_slice(&_tha); - ArpHeader{ + Some(ArpHeader{ htype: arp_header.get_htype(), ptype: arp_header.get_ptype(), hlen: arp_header.get_hlen().into(), @@ -340,12 +340,34 @@ pub fn arp_handler ( packet_data: &[u8] ) -> ArpHeader { spa: IpAddr::V4(arp_header.get_spa_as_ip_addr()), tha: MacAddress::new(_tha as Eui48).to_hex_string(), tpa: IpAddr::V4(arp_header.get_tpa()), - } + }) } - + +/* udp */ +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub struct UdpHeader { + pub source_port: u16, + pub destination_port: u16, + pub length: u16, + pub checksum: u16, +} + +pub fn udp_handler ( ip_hlen: u32, packet_data: &[u8] ) -> Option { + let (_head, tail) = packet_data.split_at(ETHER_HDRLEN + ip_hlen as usize * 4 ); + let (raw_hdr, _) = tail.split_at(8); + let mut _tail: [u8; 8] = [0;8]; + _tail.copy_from_slice(raw_hdr); + + Some(UdpHeader{ + source_port: BigEndian::read_u16(&_tail[0..2]), + destination_port: BigEndian::read_u16(&_tail[2..4]), + length: BigEndian::read_u16(&_tail[4..6]), + checksum: BigEndian::read_u16(&_tail[6..8]), + }) +} + /* payload */ pub fn payload_handler ( ip_hlen: u32, data_offset: u32, packet_data : &[u8] ) -> Option> { let (_head, tail)= packet_data.split_at(ETHER_HDRLEN+ip_hlen as usize * 4+data_offset as usize * 4); Some(tail.to_vec()) } -