115 lines
4.5 KiB
Rust
115 lines
4.5 KiB
Rust
// 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;
|
|
use byteorder::{ByteOrder, LittleEndian};
|
|
use std::collections::HashMap;
|
|
use std::fs;
|
|
use std::io::prelude::*;
|
|
//use std::thread::{spawn, JoinHandle};
|
|
//use std::sync::mpsc::{channel, Receiver};
|
|
|
|
const PCAPNG_SIGNATURE: [u8; 4] = [0x0a, 0x0d, 0x0d, 0x0a];
|
|
const PCAP_SIGNATURE: [u8; 4] = [0xd4, 0xc3, 0xb2, 0xa1];
|
|
const PCAP_SIGNATURE_BE: [u8; 4] = [0xa1, 0xb2, 0xc3, 0xa1];
|
|
|
|
pub struct Config {
|
|
pub filter: String,
|
|
pub regex_filter: String,
|
|
pub insert_max: usize,
|
|
pub pcap_file: String,
|
|
pub connection: String,
|
|
pub device: String,
|
|
pub is_device: bool,
|
|
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();
|
|
Some(Config {
|
|
filter: json.get("filter").unwrap().as_str().unwrap().to_owned(),
|
|
regex_filter: json.get("regex_filter").unwrap().as_str().unwrap().to_owned(),
|
|
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(),
|
|
})
|
|
}
|
|
|
|
/*
|
|
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. Maybe this is not needed at all in the end
|
|
// 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 (magic_number, enc_pcap, enc_pcapng) = bytes_from_file(entry.path()).unwrap();
|
|
match magic_number {
|
|
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 incorrect after introducing fn bytes_from_file()
|
|
_ => None,
|
|
};
|
|
// println!("{:?}", &entry.metadata().unwrap().modified());
|
|
}
|
|
} else {
|
|
println!("Couldn't get file type for {:?}", entry.path());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Some(pcap_map)
|
|
}
|
|
|
|
|