2020-05-29 01:05:53 +02:00
// Init of configuration files could also be done via Config crate.
// But at this point of development it seems like unjustified overhead.
extern crate serde_json ;
use std ::fs ::File ;
2020-06-06 16:48:40 +02:00
use byteorder ::{ ByteOrder , LittleEndian } ;
2020-06-01 20:55:11 +02:00
use std ::collections ::HashMap ;
use std ::fs ;
use std ::io ::prelude ::* ;
2020-06-04 21:13:48 +02:00
//use std::thread::{spawn, JoinHandle};
//use std::sync::mpsc::{channel, Receiver};
2020-06-01 20:55:11 +02:00
const PCAPNG_SIGNATURE : [ u8 ; 4 ] = [ 0x0a , 0x0d , 0x0d , 0x0a ] ;
2020-06-04 21:13:48 +02:00
const PCAP_SIGNATURE : [ u8 ; 4 ] = [ 0xd4 , 0xc3 , 0xb2 , 0xa1 ] ;
const PCAP_SIGNATURE_BE : [ u8 ; 4 ] = [ 0xa1 , 0xb2 , 0xc3 , 0xa1 ] ;
2020-05-29 01:05:53 +02:00
pub struct Config {
pub filter : String ,
2020-06-06 03:29:38 +02:00
pub regex_filter : String ,
2020-05-29 01:05:53 +02:00
pub insert_max : usize ,
pub pcap_file : String ,
pub connection : String ,
2020-05-31 00:44:47 +02:00
pub device : String ,
2020-05-29 01:05:53 +02:00
pub is_device : bool ,
pub pcap_dir : String ,
}
2020-06-06 16:48:40 +02:00
#[ 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 ( ) ,
}
}
}
2020-05-29 01:05:53 +02:00
pub fn from_json_file ( ) -> Option < Config > {
2020-05-31 00:44:47 +02:00
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 ( ) ;
Some ( Config {
filter : json . get ( " filter " ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_owned ( ) ,
2020-06-06 03:29:38 +02:00
regex_filter : json . get ( " regex_filter " ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_owned ( ) ,
2020-05-31 00:44:47 +02:00
insert_max : json . get ( " insert_max " ) . unwrap ( ) . as_u64 ( ) . unwrap ( ) as usize ,
pcap_file : json . get ( " pcap_file " ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_owned ( ) ,
connection : format ! (
" host={} user={} password={} " ,
json . get ( " database_host " ) . unwrap ( ) . as_str ( ) . unwrap ( ) ,
json . get ( " database_user " ) . unwrap ( ) . as_str ( ) . unwrap ( ) ,
json . get ( " database_password " ) . unwrap ( ) . as_str ( ) . unwrap ( ) ,
) ,
device : json
. get ( " parse_device " )
. unwrap ( )
. as_str ( )
. unwrap ( )
. to_owned ( ) ,
is_device : json . get ( " from_device " ) . unwrap ( ) . as_bool ( ) . unwrap ( ) ,
pcap_dir : json . get ( " pcap_dir " ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_owned ( ) ,
} )
2020-05-29 01:05:53 +02:00
}
2020-06-01 20:55:11 +02:00
2020-06-06 16:48:40 +02:00
/*
File signature and encapsulation type from file
See : https ://www.tcpdump.org/linktypes.html
* /
2020-06-07 23:56:53 +02:00
// Futher:file.len() is included in metadata() but only shows up if called explicitly. Maybe this is not needed at all in the end
2020-06-06 16:48:40 +02:00
// 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 > > {
2020-06-01 20:55:11 +02:00
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 ( ) {
2020-06-06 16:48:40 +02:00
let ( magic_number , enc_pcap , enc_pcapng ) = bytes_from_file ( entry . path ( ) ) . unwrap ( ) ;
2020-06-01 20:55:11 +02:00
match magic_number {
2020-06-06 16:48:40 +02:00
PCAPNG_SIGNATURE = > pcap_map . insert ( entry . path ( ) , FileInfo ::new ( entry . path ( ) , enc_pcapng ) ) ,
2020-06-07 23:56:53 +02:00
PCAP_SIGNATURE | PCAP_SIGNATURE_BE = > pcap_map . insert ( entry . path ( ) , FileInfo ::new ( entry . path ( ) , enc_pcap ) ) , // TEST: Endiannes for SIGNATURE_BE may be incorrect after introducing fn bytes_from_file()
2020-06-01 20:55:11 +02:00
_ = > None ,
} ;
// println!("{:?}", &entry.metadata().unwrap().modified());
}
} else {
println! ( " Couldn't get file type for {:?} " , entry . path ( ) ) ;
}
}
}
}
Some ( pcap_map )
}
2020-06-04 21:13:48 +02:00