From 16a2253f23b8195c54a1c53a6b3b29840d4d1823 Mon Sep 17 00:00:00 2001 From: gurkenhabicht Date: Sat, 6 Jun 2020 16:48:40 +0200 Subject: [PATCH] added Fileinfo struct, including file size, metadata and pcap encapsulation type --- src/configure/mod.rs | 50 +++++++++++++--- src/main.rs | 2 +- src/parser.json | 2 +- src/parser/packet_handler.rs | 111 ----------------------------------- 4 files changed, 44 insertions(+), 121 deletions(-) diff --git a/src/configure/mod.rs b/src/configure/mod.rs index bad5a2f..0b8c909 100644 --- a/src/configure/mod.rs +++ b/src/configure/mod.rs @@ -3,6 +3,7 @@ extern crate serde_json; use std::fs::File; +use byteorder::{ByteOrder, LittleEndian}; use std::collections::HashMap; use std::fs; use std::io::prelude::*; @@ -24,6 +25,25 @@ pub struct Config { pub pcap_dir: String, } +#[derive(Debug)] +pub struct FileInfo { + pub encapsulation_type: u16, + pub file_size: u64, + pub metadata: std::fs::Metadata, +} + +impl FileInfo { + fn new(file: std::path::PathBuf, encapsulation_type: u16) -> FileInfo { + FileInfo { + encapsulation_type: encapsulation_type, + file_size: fs::metadata(&file).unwrap().len(), + metadata: fs::metadata(&file).unwrap(), + } + } +} + + + pub fn from_json_file() -> Option { let config_file = File::open("parser.json").expect("file should open read only"); let json: serde_json::Value = serde_json::from_reader(config_file).unwrap(); @@ -49,21 +69,35 @@ pub fn from_json_file() -> Option { }) } -pub fn map_pcap_dir ( pcap_dir: &str ) -> Option> { +/* +File signature and encapsulation type from file + See: https://www.tcpdump.org/linktypes.html +*/ +// Futher:file.len() is included in metadata() but only shows up if called explicitly, so maybe this is not needed at all +// This would be needed for comparability over time. print metadata and you will see +fn bytes_from_file( entry: std::path::PathBuf ) -> Result<([u8;4], u16, u16), std::io::Error> { + let mut magic_number: [u8;4] = [0;4]; + let mut buffer: [u8;32] = [0;32]; + let mut _file = File::open(entry.to_owned())?; + _file.read_exact(&mut buffer)?; + magic_number.clone_from_slice(&buffer[0..4]); + let enc_pcap: u16 = LittleEndian::read_u16(&buffer[20..22]); + let enc_pcapng: u16 = LittleEndian::read_u16(&buffer[12..14]); + + Ok((magic_number, enc_pcap, enc_pcapng)) +} + +pub fn map_pcap_dir ( pcap_dir: &str ) -> Option> { let mut pcap_map = HashMap::new(); if let Ok(entries) = fs::read_dir(pcap_dir) { for entry in entries { if let Ok(entry) = entry { if let Ok(_file_type) = entry.file_type() { if entry.metadata().unwrap().is_file() { - let mut magic_number: [u8; 4] = [0; 4]; - let _signature = File::open(entry.path().to_owned()) - .unwrap() - .read_exact(&mut magic_number) - .unwrap(); + let (magic_number, enc_pcap, enc_pcapng) = bytes_from_file(entry.path()).unwrap(); match magic_number { - PCAPNG_SIGNATURE => pcap_map.insert(entry.path(), entry.metadata().unwrap()), - PCAP_SIGNATURE | PCAP_SIGNATURE_BE => pcap_map.insert(entry.path(), entry.metadata().unwrap()), + PCAPNG_SIGNATURE => pcap_map.insert(entry.path(), FileInfo::new(entry.path(), enc_pcapng) ), + PCAP_SIGNATURE | PCAP_SIGNATURE_BE => pcap_map.insert(entry.path(), FileInfo::new(entry.path(), enc_pcap)), // TEST: Endiannes for SIGNATURE_BE may be wrong now _ => None, }; // println!("{:?}", &entry.metadata().unwrap().modified()); diff --git a/src/main.rs b/src/main.rs index 717c680..1c55fcf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,7 @@ async fn main() -> Result<(), Error> { // This db table should include UUIDs so it can be joined effectively let pcap_map = configure::map_pcap_dir( &config.pcap_dir ).unwrap(); - // println!("{:?}", pcap_map.iter()); + println!("{:?}", pcap_map.iter()); /* db connection */ let (client, connection) = tokio_postgres::connect(&config.connection, NoTls).await?; diff --git a/src/parser.json b/src/parser.json index 13f0b44..eb28c9c 100644 --- a/src/parser.json +++ b/src/parser.json @@ -1,6 +1,6 @@ { "insert_max": 20000, - "filter": "!vlan && !ip6 && tcp", + "filter": " !ip6 && tcp", "regex_filter": "192.168.0.13", "from_device": false, "parse_device": "enp7s0", diff --git a/src/parser/packet_handler.rs b/src/parser/packet_handler.rs index 542cb3e..b8aa69b 100644 --- a/src/parser/packet_handler.rs +++ b/src/parser/packet_handler.rs @@ -141,53 +141,6 @@ pub fn ipv6_handler(packet_data: &[u8]) -> Option { }) } -/* I ve got no glue how this bitfield macro syntax works with impl and bitranges involved, if you do plz enlighten me */ -/*bitfield!{ - struct BitfieldIpV6Header (MSB0 [u8]); - impl Debug; - u32; - get_version, _: 3, 0; - get_traffic_class, _: 11, 4; - get_flow_label, _: 31, 12; - get_payload_length, _: 47, 32; - get_next_header, _: 55, 48; - get_hop_limit, _: 63, 56; - u8,get_source_address, _: 191, 64, 16; - u32,into Ipv6Addr, get_destination_address, _:319, 192; -} - -impl + AsMut<[u8]>> BitfieldIpV6Header { - fn get_source_as_ip_addr(&self) -> Ipv6Addr { - let mut src = [0; 16]; - for (i, src) in src.iter_mut().enumerate() { - *src = self.get_source_address(i); - } - src.into() - } -} - - -pub fn ipv6_handler( packet_data: &[u8] ) -> IpV6Header { - let (_head, tail) = packet_data.split_at(ETHER_HDRLEN); - let (raw_hdr, _) = tail.split_at(40); - let mut _tail: [u8; 40] = [0; 40]; - _tail.copy_from_slice(&raw_hdr); - - let v6_header = BitfieldIpV6Header(_tail); - - IpV6Header { - version: v6_header.get_version(), - traffic_class: v6_header.get_traffic_class(), - flow_label: v6_header.get_flow_label(), - payload_length: v6_header.get_payload_length(), - next_header: v6_header.get_next_header(), - hop_limit: v6_header.get_hop_limit(), - source_address: IpAddr::V6( v6_header.get_source_as_ip_addr() ), - destination_address: IpAddr::V6( v6_header.get_destination_address() ), - } -} -*/ - /* tcp */ #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct TcpHeader { @@ -264,70 +217,6 @@ pub fn tcp_handler(ip_hlen: u32, packet_data: &[u8]) -> Option { } /* arp */ -//#[derive(Debug, Clone, Serialize, Deserialize)] -//pub struct ArpHeader { -// pub htype: u32, -// pub ptype: u32, -// pub hlen: u32, -// pub plen: u32, -// pub oper: u32, -// pub sha: String, -// pub spa: IpAddr, -// pub tha: String, -// pub tpa: IpAddr, -//} -// u8, get_source_address, _: 103, 96, 4; -// u32, into Ipv4Addr, get_destination_address, _: 159, 128; - -//bitfield! { -// struct BitfieldArpHeader ( MSB0 [u8] ); -// impl Debug; -// u32; -// get_htype, _: 0, 1; -// get_ptype, _: 2, 3; -// get_hlen, _: 4; -// get_plen, _: 5; -// get_oper, _: 6, 7; -// get_sha, _: 8,13; -// get_tha, _: 18, 23; -// u8, get_spa, _: 17, 14, 4; -// u32, into Ipv4Addr, get_tpa, _: 28, 24; -//} -// -//impl + AsMut<[u8]>> BitfieldArpHeader { -// fn get_spa_as_ip_addr(&self) -> Ipv4Addr { -// let mut src = [0; 4]; -// for (i, src) in src.iter_mut().enumerate() { -// *src = self.get_spa(i); -// } -// src.into() -// } -//} -// TODO: Fix this crap -//pub fn arp_handler(packet_data: &[u8]) -> Option { -// let mut raw_hdr: [u8; 28] = [0; 28]; -// raw_hdr.copy_from_slice(&packet_data[ETHER_HDRLEN..ETHER_HDRLEN + 28]); -// -// let arp_header = BitfieldArpHeader(raw_hdr); -// let _sha: [u8; 6] = [0; 6]; -// let _tha: [u8; 6] = [0; 6]; -// raw_hdr[8..13].copy_from_slice(&_sha); -// raw_hdr[18..23].copy_from_slice(&_tha); -// -// Some(ArpHeader { -// htype: arp_header.get_htype(), -// ptype: arp_header.get_ptype(), -// hlen: arp_header.get_hlen().into(), -// plen: arp_header.get_plen().into(), -// oper: arp_header.get_oper(), -// sha: MacAddress::new(_sha as Eui48).to_hex_string(), -// //MacAddress::new(arp_header.get_sha() as Eui48).to_hex_string(), -// 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()), -// }) -//} - #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct ArpHeader { pub htype: u16,