made osi Layer 3+4 optional, table layout will be dynamic

This commit is contained in:
gurkenhabicht 2020-05-19 18:28:32 +02:00
parent a2d6ebe535
commit a324836a90
4 changed files with 99 additions and 132 deletions

View File

@ -3,77 +3,40 @@ extern crate serde_json;
extern crate tokio;
use rayon::prelude::*;
use serde::ser::{Serialize, Serializer, SerializeStruct};
mod parser;
use std::fs::File;
use serde_json::json;
mod parser;
use tokio_postgres::types::ToSql;
//use futures::{TryStreamExt};
use tokio_postgres::{NoTls, Error};
impl Serialize for parser::QryData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// 34 is the number of fields in the struct.
// 34 (42) is the number of fields in the struct.
let mut state = serializer.serialize_struct("parser::QryData", 34)?;
state.serialize_field("time", &self.time)?;
state.serialize_field("ether_header.ether_dhost", &self.ether_header.ether_dhost)?;
state.serialize_field("ether_header.ether_shost", &self.ether_header.ether_shost)?;
state.serialize_field("ether_header.ether_type", &self.ether_header.ether_type)?;
state.serialize_field("ipv4_header.ip_version", &self.ipv4_header.ip_version)?;
state.serialize_field("ipv4_header.ip_ihl", &self.ipv4_header.ip_ihl)?;
state.serialize_field("ipv4_header.ip_dscp", &self.ipv4_header.ip_dscp)?;
state.serialize_field("ipv4_header.ip_ecn", &self.ipv4_header.ip_ecn)?;
state.serialize_field("ipv4_header.ip_total_length", &self.ipv4_header.ip_total_length)?;
state.serialize_field("ipv4_header.ip_identification", &self.ipv4_header.ip_identification)?;
state.serialize_field("ipv4_header.ip_df", &self.ipv4_header.ip_df)?;
state.serialize_field("ipv4_header.ip_mf", &self.ipv4_header.ip_mf)?;
state.serialize_field("ipv4_header.ip_fragment_offset", &self.ipv4_header.ip_fragment_offset)?;
state.serialize_field("ipv4_header.ip_source_address", &self.ipv4_header.ip_source_address)?;
state.serialize_field("ipv4_header.ip_destination_address", &self.ipv4_header.ip_destination_address)?;
state.serialize_field("ipv6_header.version", &self.ipv6_header.version)?;
state.serialize_field("ipv6_header.traffic_class", &self.ipv6_header.traffic_class)?;
state.serialize_field("ipv6_header.flow_label" , &self.ipv6_header.flow_label)?;
state.serialize_field("ipv6_header.payload_length" , &self.ipv6_header.payload_length)?;
state.serialize_field("ipv6_header.next_header" , &self.ipv6_header.next_header)?;
state.serialize_field("ipv6_header.hop_limit" , &self.ipv6_header.hop_limit)?;
state.serialize_field("ipv6_header.source_address" , &self.ipv6_header.source_address)?;
state.serialize_field("ipv6_header.destination_address" , &self.ipv6_header.destination_address)?;
state.serialize_field("tcp_header.source_port", &self.tcp_header.source_port)?;
state.serialize_field("tcp_header.destination_port", &self.tcp_header.destination_port)?;
state.serialize_field("tcp_header.seq_num", &self.tcp_header.seq_num)?;
state.serialize_field("tcp_header.ack_num", &self.tcp_header.ack_num)?;
state.serialize_field("tcp_header.data_offset", &self.tcp_header.data_offset)?;
state.serialize_field("tcp_header.reserved", &self.tcp_header.reserved)?;
state.serialize_field("tcp_header.ns", &self.tcp_header.ns)?;
state.serialize_field("tcp_header.cwr", &self.tcp_header.cwr)?;
state.serialize_field("tcp_header.ece", &self.tcp_header.ece)?;
state.serialize_field("tcp_header.urg", &self.tcp_header.urg)?;
state.serialize_field("tcp_header.ack", &self.tcp_header.ack)?;
state.serialize_field("tcp_header.psh", &self.tcp_header.psh)?;
state.serialize_field("tcp_header.rst", &self.tcp_header.rst)?;
state.serialize_field("tcp_header.syn", &self.tcp_header.syn)?;
state.serialize_field("tcp_header.fin", &self.tcp_header.fin)?;
state.serialize_field("tcp_header.window_size", &self.tcp_header.window_size)?;
state.serialize_field("tcp_header.checksum", &self.tcp_header.checksum)?;
state.serialize_field("tcp_header.urgent_pointer", &self.tcp_header.urgent_pointer)?;
state.serialize_field("ipv4_header", &self.ipv4_header)?;
state.serialize_field("ipv6_header", &self.ipv6_header)?;
state.serialize_field("tcp_header", &self.tcp_header)?;
state.serialize_field("data", &self.data)?;
state.end()
}
}
fn serialize_packets ( v: Vec<parser::QryData> ) -> Vec<serde_json::Value> {
let mut packets_serialized: Vec<_> = Vec::new();
// let mut packets_serialized: Vec<_> = Vec::new();
// for packet in v.iter() {
// // packets_serialized.push(json!(&packet));
// }
/* rayon parallelized */
packets_serialized = v.par_iter().map( |x| json!(x) ).collect();
let packets_serialized = v.par_iter().map( |x| json!(x) ).collect();
packets_serialized
}

View File

@ -1,7 +1,7 @@
{
"insert_max": 80,
"insert_max": 20000,
"filter": "tcp && !ip6",
"from_device": true,
"from_device": false,
"parse_device": "enp7s0",
"pcap_file": "../target/wohnung2.pcapng",
"database_user": "postgres",

View File

@ -4,7 +4,7 @@ extern crate eui48;
mod packet_handler;
use pcap::Capture;
use eui48::MacAddress;
use std::net::{IpAddr, Ipv4Addr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::str;
fn build_ether () -> packet_handler::EtherHeader {
@ -15,47 +15,6 @@ fn build_ether () -> packet_handler::EtherHeader {
}
}
fn build_ipv4 () -> packet_handler::IpV4Header {
packet_handler::IpV4Header {
ip_version: 0,
ip_ihl: 0,
ip_dscp: 0,
ip_ecn: 0,
ip_total_length: 0,
ip_identification: 0,
ip_df: 0,
ip_mf: 0,
ip_fragment_offset: 0,
ip_time_to_live: 0,
ip_protocol: 0,
ip_header_checksum: 0,
ip_source_address: IpAddr::V4(Ipv4Addr::new(0,0,0,0)),
ip_destination_address: IpAddr::V4(Ipv4Addr::new(0,0,0,0)),
}
}
fn build_tcp () -> packet_handler::TcpHeader {
packet_handler::TcpHeader {
source_port: 0,
destination_port: 0,
seq_num: 0,
ack_num: 0,
data_offset: 0,
reserved: 0,
ns: 0,
cwr: 0,
ece: 0,
urg: 0,
ack: 0,
psh: 0,
rst: 0,
syn: 0,
fin: 0,
window_size: 0,
checksum: 0,
urgent_pointer: 0,
}
}
// TODO: wrap packet_handler types inside Option<T>
#[derive(Debug, Clone)]
@ -64,22 +23,23 @@ pub struct QryData{
pub time: f64,
pub data: Option<Vec<u8>>,
pub ether_header: packet_handler::EtherHeader,
pub ipv4_header: packet_handler::IpV4Header,
pub tcp_header: packet_handler::TcpHeader,
pub ipv4_header: Option<packet_handler::IpV4Header>,
pub ipv6_header: Option<packet_handler::IpV6Header>,
pub tcp_header: Option<packet_handler::TcpHeader>,
}
pub fn parse (parse_file: &str, filter_str: &str) -> Vec<QryData> {
let ether_init = build_ether();
let ipv4_init = build_ipv4();
let tcp_init = build_tcp();
let mut me = QryData {
id: 0,
time: 0.0,
data: None,
ether_header: ether_init,
ipv4_header: ipv4_init,
tcp_header: tcp_init,
ipv4_header: None::<packet_handler::IpV4Header>,
ipv6_header: None::<packet_handler::IpV6Header>,
tcp_header: None::<packet_handler::TcpHeader>,
};
let mut v: Vec<QryData> = Vec::new();
@ -96,15 +56,24 @@ pub fn parse (parse_file: &str, filter_str: &str) -> Vec<QryData> {
me.data = Some(packet.data.to_vec());
me.ether_header = packet_handler::ethernet_handler( packet.data );
if 8 == me.ether_header.ether_type {
me.ipv4_header = packet_handler::ip_handler( packet.data );
if 6 == me.ipv4_header.ip_protocol {
me.tcp_header = packet_handler::tcp_handler( me.ipv4_header.ip_ihl, packet.data );
me.data= packet_handler::payload_handler( me.ipv4_header.ip_ihl, me.tcp_header.data_offset, packet.data);
me.ipv6_header = None::<packet_handler::IpV6Header>;
me.ipv4_header = Some(packet_handler::ip_handler( packet.data )).unwrap();
if 6 == me.ipv4_header.unwrap().ip_protocol {
me.tcp_header = Some(packet_handler::tcp_handler( me.ipv4_header.unwrap().ip_ihl, packet.data )).unwrap();
me.data= packet_handler::payload_handler( me.ipv4_header.unwrap().ip_ihl, me.tcp_header.unwrap().data_offset, packet.data);
}
}
if 56710 == me.ether_header.ether_type{
me.ipv4_header = None::<packet_handler::IpV4Header>;
me.ipv6_header = Some(packet_handler::ipv6_handler( packet.data )).unwrap();
if 6 == me.ipv6_header.unwrap().next_header{
me.tcp_header = Some(packet_handler::tcp_handler( 10, packet.data )).unwrap();
me.data = packet_handler::payload_handler( 10, 0, packet.data);
}
}
v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, tcp_header: me.tcp_header});
v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, ipv6_header: me.ipv6_header, tcp_header: me.tcp_header});
}
v
@ -113,15 +82,17 @@ pub fn parse (parse_file: &str, filter_str: &str) -> Vec<QryData> {
pub fn parse_device (parse_device: &str, filter_str: &str, insert_max: &usize) -> Vec<QryData> {
let ether_init = build_ether();
let ipv4_init = build_ipv4();
let tcp_init = build_tcp();
let ipv6_init = build_ipv6();
//let tcp_init = build_tcp();
let mut me = QryData {
id: 0,
time: 0.0,
data: None,
ether_header: ether_init,
ipv4_header: ipv4_init,
tcp_header: tcp_init,
ipv4_header: None::<packet_handler::IpV4Header>,
ipv6_header: None::<packet_handler::IpV6Header>,
tcp_header: None::<packet_handler::TcpHeader>,
};
let mut v: Vec<QryData> = Vec::new();
let mut cap = Capture::from_device(parse_device).unwrap().open().unwrap();
@ -132,15 +103,26 @@ pub fn parse_device (parse_device: &str, filter_str: &str, insert_max: &usize) -
me.data = Some(packet.data.to_vec());
me.ether_header = packet_handler::ethernet_handler( packet.data );
if 8 == me.ether_header.ether_type {
me.ipv4_header = packet_handler::ip_handler( packet.data );
if 6 == me.ipv4_header.ip_protocol {
me.tcp_header = packet_handler::tcp_handler( me.ipv4_header.ip_ihl, packet.data );
me.data= packet_handler::payload_handler( me.ipv4_header.ip_ihl, me.tcp_header.data_offset, packet.data);
me.ipv6_header = None::<packet_handler::IpV6Header>;
me.ipv4_header = Some(packet_handler::ip_handler( packet.data )).unwrap();
if 6 == me.ipv4_header.unwrap().ip_protocol {
me.tcp_header = Some(packet_handler::tcp_handler( me.ipv4_header.unwrap().ip_ihl, packet.data )).unwrap();
me.data= packet_handler::payload_handler( me.ipv4_header.unwrap().ip_ihl, me.tcp_header.unwrap().data_offset, packet.data);
}
}
if 56710 == me.ether_header.ether_type{
me.ipv4_header = None::<packet_handler::IpV4Header>;
me.ipv6_header = Some(packet_handler::ipv6_handler( packet.data)).unwrap();
if 6 == me.ipv6_header.unwrap().next_header{
me.tcp_header = Some(packet_handler::tcp_handler( 10, packet.data )).unwrap();
me.data = packet_handler::payload_handler( 10, 0, packet.data);
}
}
v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, ipv6_header: me.ipv6_header, tcp_header: me.tcp_header});
v.push(QryData{id:0, time:me.time, data: me.data, ether_header:me.ether_header, ipv4_header: me.ipv4_header, tcp_header: me.tcp_header});
if &v.len() >= insert_max {
break 'parse;
}

View File

@ -1,12 +1,12 @@
extern crate eui48;
extern crate byteorder;
extern crate bitfield;
use byteorder::{ByteOrder, BigEndian, LittleEndian, ReadBytesExt};
extern crate serde;
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use eui48::{MacAddress, Eui48};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use bitfield::{bitfield, BitRange};
use std::io::Cursor;
use bitfield::{bitfield};
use serde::{Serialize, Deserialize};
/* ethernet */
const ETH_ALEN: usize = 6;
@ -42,7 +42,7 @@ pub fn ethernet_handler ( packet_data: &[u8] ) -> EtherHeader {
}
/* ip */
#[derive(Debug,Copy, Clone)]
#[derive(Debug,Copy, Clone, Serialize, Deserialize)]
pub struct IpV4Header {
pub ip_version: u32,
pub ip_ihl: u32,
@ -91,7 +91,7 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> BitfieldIpV4Header<T> {
}
}
pub fn ip_handler ( packet_data: &[u8] ) -> IpV4Header {
pub fn ip_handler ( packet_data: &[u8] ) -> Option<IpV4Header> {
let (_head, tail) = packet_data.split_at(ETHER_HDRLEN);
let (raw_hdr, _) = tail.split_at(20);
let mut _tail: [u8; 20] = [0; 20];
@ -99,7 +99,7 @@ pub fn ip_handler ( packet_data: &[u8] ) -> IpV4Header {
let ip_header = BitfieldIpV4Header(_tail);
IpV4Header {
Some(IpV4Header {
ip_version: ip_header.get_version(),
ip_ihl: ip_header.get_ihl(),
ip_dscp: ip_header.get_dscp(),
@ -114,11 +114,11 @@ pub fn ip_handler ( packet_data: &[u8] ) -> IpV4Header {
ip_header_checksum: ip_header.get_header_checksum(),
ip_source_address: IpAddr::V4(ip_header.get_source_as_ip_addr()),
ip_destination_address: IpAddr::V4(ip_header.get_destination_address()),
}
})
}
/* ipv6 */
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct IpV6Header {
pub version: u8,
pub traffic_class: u8,
@ -130,7 +130,7 @@ pub struct IpV6Header {
pub destination_address: IpAddr,
}
pub fn ipv6_handler ( packet_data: &[u8] ) -> IpV6Header {
pub fn ipv6_handler ( packet_data: &[u8] ) -> Option<IpV6Header> {
let (_head, tail) = packet_data.split_at(ETHER_HDRLEN);
let (raw_hdr, _) = tail.split_at(40);
let mut _tail: [u8; 40] = [0; 40];
@ -139,16 +139,16 @@ pub fn ipv6_handler ( packet_data: &[u8] ) -> IpV6Header {
IpV6Header {
Some(IpV6Header {
version: (&raw_hdr[0] & 0xf0) >> 4,
traffic_class: ((&raw_hdr[0] & 0x0f) >> 4)| ((&raw_hdr[1] & 0xf0 <<4)) ,
flow_label: BigEndian::read_u32( &[0x00 ,(&_tail[1] &0x0f) , _tail[2] , _tail[3]]),
payload_length: BigEndian::read_u16(&[_tail[4], _tail[5]]),
next_header: _tail[6],
hop_limit: _tail[7],
source_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[8..24]))),
destination_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[24..40]))),
}
source_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[8..24]))), // Results in correct addresses, but interval range is not default [incl..excl]. Watch out!
destination_address: IpAddr::V6(Ipv6Addr::from(BigEndian::read_u128(&_tail[24..40]))), // Must be byteorder crate !?
})
}
/* I ve got no glue how this bitfield macro syntax works with impl and bitranges involved, if you do plz enlighten me */
@ -199,7 +199,7 @@ pub fn ipv6_handler( packet_data: &[u8] ) -> IpV6Header {
*/
/* tcp */
#[derive(Debug,Copy,Clone)]
#[derive(Debug,Copy,Clone, Serialize, Deserialize)]
pub struct TcpHeader {
pub source_port: u32,
pub destination_port: u32,
@ -245,14 +245,14 @@ bitfield! {
get_urgent_pointer, _: 159,144;
}
pub fn tcp_handler ( ip_hlen: u32, packet_data: &[u8] ) ->TcpHeader {
pub fn tcp_handler ( ip_hlen: u32, packet_data: &[u8] ) -> Option<TcpHeader> {
let (_head, tail) = packet_data.split_at(ETHER_HDRLEN+ip_hlen as usize * 4);
let (raw_hdr, _) = tail.split_at(20);
let mut _tail: [u8; 20] = [0; 20];
_tail.copy_from_slice(raw_hdr);
let tcp_header = BitfieldTcpHeader(_tail);
TcpHeader {
Some(TcpHeader {
source_port: tcp_header.get_source_port(),
destination_port: tcp_header.get_destination_port(),
seq_num: tcp_header.get_seq_num(),
@ -271,13 +271,13 @@ pub fn tcp_handler ( ip_hlen: u32, packet_data: &[u8] ) ->TcpHeader {
window_size: tcp_header.get_window_size(),
checksum: tcp_header.get_checksum(),
urgent_pointer: tcp_header.get_urgent_pointer(),
}
})
}
/* arp */
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArpHeader {
pub htype: u32,
pub ptype: u32,
@ -317,7 +317,7 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> BitfieldArpHeader<T> {
}
}
pub fn arp_handler ( packet_data: &[u8] ) -> ArpHeader {
pub fn arp_handler ( packet_data: &[u8] ) -> Option<ArpHeader> {
let (_head, tail) = packet_data.split_at(ETHER_HDRLEN);
let (raw_hdr, _) = tail.split_at(28);
let mut _tail: [u8; 28] = [0; 28];
@ -329,7 +329,7 @@ pub fn arp_handler ( packet_data: &[u8] ) -> ArpHeader {
_tail[18..23].copy_from_slice(&_tha);
ArpHeader{
Some(ArpHeader{
htype: arp_header.get_htype(),
ptype: arp_header.get_ptype(),
hlen: arp_header.get_hlen().into(),
@ -340,7 +340,30 @@ pub fn arp_handler ( packet_data: &[u8] ) -> ArpHeader {
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()),
}
})
}
/* udp */
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct UdpHeader {
pub source_port: u16,
pub destination_port: u16,
pub length: u16,
pub checksum: u16,
}
pub fn udp_handler ( ip_hlen: u32, packet_data: &[u8] ) -> Option<UdpHeader> {
let (_head, tail) = packet_data.split_at(ETHER_HDRLEN + ip_hlen as usize * 4 );
let (raw_hdr, _) = tail.split_at(8);
let mut _tail: [u8; 8] = [0;8];
_tail.copy_from_slice(raw_hdr);
Some(UdpHeader{
source_port: BigEndian::read_u16(&_tail[0..2]),
destination_port: BigEndian::read_u16(&_tail[2..4]),
length: BigEndian::read_u16(&_tail[4..6]),
checksum: BigEndian::read_u16(&_tail[6..8]),
})
}
/* payload */
@ -348,4 +371,3 @@ pub fn payload_handler ( ip_hlen: u32, data_offset: u32, packet_data : &[u8] ) -
let (_head, tail)= packet_data.split_at(ETHER_HDRLEN+ip_hlen as usize * 4+data_offset as usize * 4);
Some(tail.to_vec())
}