added Fileinfo struct, including file size, metadata and pcap encapsulation type

This commit is contained in:
gurkenhabicht 2020-06-06 16:48:40 +02:00
parent 2930cdd2ac
commit 16a2253f23
4 changed files with 44 additions and 121 deletions

View File

@ -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<Config> {
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<Config> {
})
}
pub fn map_pcap_dir ( pcap_dir: &str ) -> Option<std::collections::HashMap<std::path::PathBuf, std::fs::Metadata>> {
/*
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<std::collections::HashMap<std::path::PathBuf, FileInfo>> {
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());

View File

@ -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?;

View File

@ -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",

View File

@ -141,53 +141,6 @@ pub fn ipv6_handler(packet_data: &[u8]) -> Option<IpV6Header> {
})
}
/* 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<T: AsRef<[u8]> + AsMut<[u8]>> BitfieldIpV6Header<T> {
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<TcpHeader> {
}
/* 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<T: AsRef<[u8]> + AsMut<[u8]>> BitfieldArpHeader<T> {
// 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<ArpHeader> {
// 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,