added Fileinfo struct, including file size, metadata and pcap encapsulation type
This commit is contained in:
parent
2930cdd2ac
commit
16a2253f23
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
@ -24,6 +25,25 @@ pub struct Config {
|
||||||
pub pcap_dir: String,
|
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> {
|
pub fn from_json_file() -> Option<Config> {
|
||||||
let config_file = File::open("parser.json").expect("file should open read only");
|
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();
|
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();
|
let mut pcap_map = HashMap::new();
|
||||||
if let Ok(entries) = fs::read_dir(pcap_dir) {
|
if let Ok(entries) = fs::read_dir(pcap_dir) {
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
if let Ok(entry) = entry {
|
if let Ok(entry) = entry {
|
||||||
if let Ok(_file_type) = entry.file_type() {
|
if let Ok(_file_type) = entry.file_type() {
|
||||||
if entry.metadata().unwrap().is_file() {
|
if entry.metadata().unwrap().is_file() {
|
||||||
let mut magic_number: [u8; 4] = [0; 4];
|
let (magic_number, enc_pcap, enc_pcapng) = bytes_from_file(entry.path()).unwrap();
|
||||||
let _signature = File::open(entry.path().to_owned())
|
|
||||||
.unwrap()
|
|
||||||
.read_exact(&mut magic_number)
|
|
||||||
.unwrap();
|
|
||||||
match magic_number {
|
match magic_number {
|
||||||
PCAPNG_SIGNATURE => 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(), entry.metadata().unwrap()),
|
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,
|
_ => None,
|
||||||
};
|
};
|
||||||
// println!("{:?}", &entry.metadata().unwrap().modified());
|
// println!("{:?}", &entry.metadata().unwrap().modified());
|
||||||
|
|
|
@ -33,7 +33,7 @@ async fn main() -> Result<(), Error> {
|
||||||
// This db table should include UUIDs so it can be joined effectively
|
// This db table should include UUIDs so it can be joined effectively
|
||||||
let pcap_map = configure::map_pcap_dir( &config.pcap_dir ).unwrap();
|
let pcap_map = configure::map_pcap_dir( &config.pcap_dir ).unwrap();
|
||||||
|
|
||||||
// println!("{:?}", pcap_map.iter());
|
println!("{:?}", pcap_map.iter());
|
||||||
|
|
||||||
/* db connection */
|
/* db connection */
|
||||||
let (client, connection) = tokio_postgres::connect(&config.connection, NoTls).await?;
|
let (client, connection) = tokio_postgres::connect(&config.connection, NoTls).await?;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"insert_max": 20000,
|
"insert_max": 20000,
|
||||||
"filter": "!vlan && !ip6 && tcp",
|
"filter": " !ip6 && tcp",
|
||||||
"regex_filter": "192.168.0.13",
|
"regex_filter": "192.168.0.13",
|
||||||
"from_device": false,
|
"from_device": false,
|
||||||
"parse_device": "enp7s0",
|
"parse_device": "enp7s0",
|
||||||
|
|
|
@ -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 */
|
/* tcp */
|
||||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||||
pub struct TcpHeader {
|
pub struct TcpHeader {
|
||||||
|
@ -264,70 +217,6 @@ pub fn tcp_handler(ip_hlen: u32, packet_data: &[u8]) -> Option<TcpHeader> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arp */
|
/* 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)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
pub struct ArpHeader {
|
pub struct ArpHeader {
|
||||||
pub htype: u16,
|
pub htype: u16,
|
||||||
|
|
Loading…
Reference in New Issue