implemented data_link() for device_parse(), implemented serializable MacAddress, clean up
This commit is contained in:
parent
7aff006aed
commit
faddf64307
|
@ -2,8 +2,7 @@ extern crate bitfield;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate eui48;
|
extern crate eui48;
|
||||||
mod packet_handler;
|
mod packet_handler;
|
||||||
use eui48::{MacAddress};
|
use pcap::{Capture, Linktype};
|
||||||
use pcap::Capture;
|
|
||||||
use regex::bytes::Regex;
|
use regex::bytes::Regex;
|
||||||
use std::str;
|
use std::str;
|
||||||
//use std::thread::{spawn, JoinHandle};
|
//use std::thread::{spawn, JoinHandle};
|
||||||
|
@ -18,14 +17,6 @@ const UDP: usize = 0x11;
|
||||||
const ETH_P_ARP: usize = 0x0608;
|
const ETH_P_ARP: usize = 0x0608;
|
||||||
const ETH_P_RARP: usize = 0x3580;
|
const ETH_P_RARP: usize = 0x3580;
|
||||||
|
|
||||||
fn build_ether() -> packet_handler::EtherHeader {
|
|
||||||
packet_handler::EtherHeader {
|
|
||||||
ether_dhost: MacAddress::new([0;6]),
|
|
||||||
ether_shost: MacAddress::new([0;6]),
|
|
||||||
ether_type: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
QryData could be written in the sense of QryData{ ... frame: .., packet: .., segment:.. }
|
QryData could be written in the sense of QryData{ ... frame: .., packet: .., segment:.. }
|
||||||
On the one hand, only the actual type of frame/packet/segment would be contained in the resulting struct.
|
On the one hand, only the actual type of frame/packet/segment would be contained in the resulting struct.
|
||||||
|
@ -40,7 +31,7 @@ pub struct QryData {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub time: f64,
|
pub time: f64,
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
pub ether_header: packet_handler::EtherHeader,
|
pub ether_header: Option<packet_handler::EtherHeader>,
|
||||||
pub ipv4_header: Option<packet_handler::IpV4Header>,
|
pub ipv4_header: Option<packet_handler::IpV4Header>,
|
||||||
pub ipv6_header: Option<packet_handler::IpV6Header>,
|
pub ipv6_header: Option<packet_handler::IpV6Header>,
|
||||||
pub tcp_header: Option<packet_handler::TcpHeader>,
|
pub tcp_header: Option<packet_handler::TcpHeader>,
|
||||||
|
@ -50,12 +41,11 @@ pub struct QryData {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_qrydata( ) -> Result<QryData, core::fmt::Error> {
|
fn init_qrydata( ) -> Result<QryData, core::fmt::Error> {
|
||||||
let ether_init = build_ether();
|
|
||||||
Ok(QryData {
|
Ok(QryData {
|
||||||
id: 0,
|
id: 0,
|
||||||
time: 0.0,
|
time: 0.0,
|
||||||
data: None,
|
data: None,
|
||||||
ether_header: ether_init,
|
ether_header: None::<packet_handler::EtherHeader>,
|
||||||
ipv4_header: None::<packet_handler::IpV4Header>,
|
ipv4_header: None::<packet_handler::IpV4Header>,
|
||||||
ipv6_header: None::<packet_handler::IpV6Header>,
|
ipv6_header: None::<packet_handler::IpV6Header>,
|
||||||
tcp_header: None::<packet_handler::TcpHeader>,
|
tcp_header: None::<packet_handler::TcpHeader>,
|
||||||
|
@ -66,9 +56,9 @@ fn init_qrydata( ) -> Result<QryData, core::fmt::Error> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum EncapsulationType {
|
enum EncapsulationType { // pcap::Linktype::get_name() is unsafe.
|
||||||
ETHER = 1,
|
EN10MB = 1, // See: https://docs.rs/pcap/0.7.0/src/pcap/lib.rs.html#247-261
|
||||||
RAWIP = 107,
|
RAW = 101, // Would this be an issue?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QryData {
|
impl QryData {
|
||||||
|
@ -76,14 +66,12 @@ impl QryData {
|
||||||
// This will get modularized into subfunctions
|
// This will get modularized into subfunctions
|
||||||
fn encap_ether( packet_data: &[u8] ) -> Option<QryData> {
|
fn encap_ether( packet_data: &[u8] ) -> Option<QryData> {
|
||||||
let mut pkg: QryData = init_qrydata().unwrap();
|
let mut pkg: QryData = init_qrydata().unwrap();
|
||||||
pkg.ether_header = packet_handler::ethernet_handler(packet_data);
|
pkg.ether_header = Some(packet_handler::ethernet_handler(packet_data)).unwrap();
|
||||||
match pkg.ether_header.ether_type as usize {
|
match pkg.ether_header.unwrap().ether_type as usize {
|
||||||
ETH_P_IP => {
|
ETH_P_IP => {
|
||||||
//pkg.ipv6_header = None::<packet_handler::IpV6Header>;
|
|
||||||
pkg.ipv4_header = Some(packet_handler::ip_handler(packet_data)).unwrap();
|
pkg.ipv4_header = Some(packet_handler::ip_handler(packet_data)).unwrap();
|
||||||
match pkg.ipv4_header.unwrap().ip_protocol as usize {
|
match pkg.ipv4_header.unwrap().ip_protocol as usize {
|
||||||
TCP => {
|
TCP => {
|
||||||
// pkg.udp_header = None::<packet_handler::UdpHeader>;
|
|
||||||
pkg.tcp_header = Some(packet_handler::tcp_handler(
|
pkg.tcp_header = Some(packet_handler::tcp_handler(
|
||||||
pkg.ipv4_header.unwrap().ip_ihl,
|
pkg.ipv4_header.unwrap().ip_ihl,
|
||||||
packet_data,
|
packet_data,
|
||||||
|
@ -96,7 +84,6 @@ impl QryData {
|
||||||
)).unwrap();
|
)).unwrap();
|
||||||
}
|
}
|
||||||
UDP => {
|
UDP => {
|
||||||
// pkg.tcp_header = None::<packet_handler::TcpHeader>;
|
|
||||||
pkg.udp_header = Some(packet_handler::udp_handler(
|
pkg.udp_header = Some(packet_handler::udp_handler(
|
||||||
pkg.ipv4_header.unwrap().ip_ihl,
|
pkg.ipv4_header.unwrap().ip_ihl,
|
||||||
packet_data,
|
packet_data,
|
||||||
|
@ -112,11 +99,9 @@ impl QryData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ETH_P_IPV6 => {
|
ETH_P_IPV6 => {
|
||||||
//pkg.ipv4_header = None::<packet_handler::IpV4Header>;
|
|
||||||
pkg.ipv6_header = Some(packet_handler::ipv6_handler(packet_data)).unwrap();
|
pkg.ipv6_header = Some(packet_handler::ipv6_handler(packet_data)).unwrap();
|
||||||
match pkg.ipv6_header.unwrap().next_header as usize {
|
match pkg.ipv6_header.unwrap().next_header as usize {
|
||||||
TCP => {
|
TCP => {
|
||||||
// pkg.udp_header = None::<packet_handler::UdpHeader>;
|
|
||||||
pkg.tcp_header = Some(packet_handler::tcp_handler(10, packet_data)).unwrap();
|
pkg.tcp_header = Some(packet_handler::tcp_handler(10, packet_data)).unwrap();
|
||||||
pkg.data = Some(packet_handler::payload_handler(
|
pkg.data = Some(packet_handler::payload_handler(
|
||||||
10,
|
10,
|
||||||
|
@ -125,7 +110,6 @@ impl QryData {
|
||||||
)).unwrap();
|
)).unwrap();
|
||||||
}
|
}
|
||||||
UDP => {
|
UDP => {
|
||||||
// pkg.tcp_header = None::<packet_handler::TcpHeader>;
|
|
||||||
pkg.udp_header = Some(packet_handler::udp_handler(10, packet_data)).unwrap();
|
pkg.udp_header = Some(packet_handler::udp_handler(10, packet_data)).unwrap();
|
||||||
pkg.data = Some(packet_handler::payload_handler(10, 7, packet_data)).unwrap();
|
pkg.data = Some(packet_handler::payload_handler(10, 7, packet_data)).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +118,6 @@ impl QryData {
|
||||||
}
|
}
|
||||||
ETH_P_ARP | ETH_P_RARP => {
|
ETH_P_ARP | ETH_P_RARP => {
|
||||||
pkg.arp_header = Some(packet_handler::arp_handler(packet_data)).unwrap();
|
pkg.arp_header = Some(packet_handler::arp_handler(packet_data)).unwrap();
|
||||||
pkg.data = None;
|
|
||||||
}
|
}
|
||||||
_ => println!("Network protocol not implemented"),
|
_ => println!("Network protocol not implemented"),
|
||||||
}
|
}
|
||||||
|
@ -143,12 +126,9 @@ impl QryData {
|
||||||
|
|
||||||
fn encap_rawip ( packet_data: &[u8] ) -> Option<QryData> {
|
fn encap_rawip ( packet_data: &[u8] ) -> Option<QryData> {
|
||||||
let mut pkg: QryData = init_qrydata().unwrap();
|
let mut pkg: QryData = init_qrydata().unwrap();
|
||||||
//pkg.ether_header = None::<packet_handler::EtherHeader>;
|
|
||||||
//pkg.ipv6_header = None::<packet_handler::IpV6Header>;
|
|
||||||
pkg.ipv4_header = Some(packet_handler::ip_handler(packet_data)).unwrap();
|
pkg.ipv4_header = Some(packet_handler::ip_handler(packet_data)).unwrap();
|
||||||
match pkg.ipv4_header.unwrap().ip_protocol as usize {
|
match pkg.ipv4_header.unwrap().ip_protocol as usize {
|
||||||
TCP => {
|
TCP => {
|
||||||
pkg.udp_header = None::<packet_handler::UdpHeader>;
|
|
||||||
pkg.tcp_header = Some(packet_handler::tcp_handler(
|
pkg.tcp_header = Some(packet_handler::tcp_handler(
|
||||||
pkg.ipv4_header.unwrap().ip_ihl,
|
pkg.ipv4_header.unwrap().ip_ihl,
|
||||||
packet_data,
|
packet_data,
|
||||||
|
@ -160,8 +140,7 @@ impl QryData {
|
||||||
packet_data,
|
packet_data,
|
||||||
)).unwrap();
|
)).unwrap();
|
||||||
}
|
}
|
||||||
UDP => {
|
UDP => {
|
||||||
pkg.tcp_header = None::<packet_handler::TcpHeader>;
|
|
||||||
pkg.udp_header = Some(packet_handler::udp_handler(
|
pkg.udp_header = Some(packet_handler::udp_handler(
|
||||||
pkg.ipv4_header.unwrap().ip_ihl,
|
pkg.ipv4_header.unwrap().ip_ihl,
|
||||||
packet_data,
|
packet_data,
|
||||||
|
@ -207,8 +186,8 @@ pub fn parse(parse_file: &std::path::Path, filter_str: &str, regex_filter: &str,
|
||||||
|
|
||||||
match encap {
|
match encap {
|
||||||
// Syntax is clunky, but no num_derive + num_traits dependencies.
|
// Syntax is clunky, but no num_derive + num_traits dependencies.
|
||||||
encap if encap == EncapsulationType::ETHER as u16 => me = QryData::encap_ether(packet.data).unwrap(),
|
encap if encap == EncapsulationType::EN10MB as u16 => me = QryData::encap_ether(packet.data).unwrap(),
|
||||||
encap if encap == EncapsulationType::RAWIP as u16 => me = QryData::encap_rawip(packet.data).unwrap(),
|
encap if encap == EncapsulationType::RAW as u16 => me = QryData::encap_rawip(packet.data).unwrap(),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,83 +206,20 @@ pub fn parse_device(parse_device: &str, filter_str: &str, insert_max: &usize, re
|
||||||
let mut v: Vec<QryData> = Vec::new();
|
let mut v: Vec<QryData> = Vec::new();
|
||||||
let mut cap = Capture::from_device(parse_device).unwrap().open().unwrap();
|
let mut cap = Capture::from_device(parse_device).unwrap().open().unwrap();
|
||||||
Capture::filter(&mut cap, &filter_str).unwrap();
|
Capture::filter(&mut cap, &filter_str).unwrap();
|
||||||
|
let linktype = cap.get_datalink();
|
||||||
let re = Regex::new(regex_filter).unwrap();
|
let re = Regex::new(regex_filter).unwrap();
|
||||||
'parse: while let Ok(packet) = cap.next() {
|
'parse: while let Ok(packet) = cap.next() {
|
||||||
me.time = (packet.header.ts.tv_usec as f64 / 1000000.0) + packet.header.ts.tv_sec as f64;
|
match linktype {
|
||||||
me.data = Some(packet.data.to_vec());
|
Linktype(1) => me = QryData::encap_ether(packet.data).unwrap(),
|
||||||
me.reg_res = flag_carnage(&re, packet.data);
|
Linktype(101) => me = QryData::encap_rawip(packet.data).unwrap(),
|
||||||
me.ether_header = packet_handler::ethernet_handler(packet.data);
|
_ => (),
|
||||||
match me.ether_header.ether_type as usize {
|
|
||||||
ETH_P_IP => {
|
|
||||||
me.ipv6_header = None::<packet_handler::IpV6Header>;
|
|
||||||
me.ipv4_header = Some(packet_handler::ip_handler(packet.data)).unwrap();
|
|
||||||
match me.ipv4_header.unwrap().ip_protocol as usize {
|
|
||||||
TCP => {
|
|
||||||
me.tcp_header = Some(packet_handler::tcp_handler(
|
|
||||||
me.ipv4_header.unwrap().ip_ihl,
|
|
||||||
packet.data,
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
me.data = Some(packet_handler::payload_handler(
|
|
||||||
me.ipv4_header.unwrap().ip_ihl,
|
|
||||||
me.tcp_header.unwrap().data_offset,
|
|
||||||
packet.data,
|
|
||||||
)).unwrap();
|
|
||||||
}
|
|
||||||
UDP => {
|
|
||||||
me.udp_header = Some(packet_handler::udp_handler(
|
|
||||||
me.ipv4_header.unwrap().ip_ihl,
|
|
||||||
packet.data,
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
me.data = Some(packet_handler::payload_handler(
|
|
||||||
me.ipv4_header.unwrap().ip_ihl,
|
|
||||||
7,
|
|
||||||
packet.data,
|
|
||||||
)).unwrap();
|
|
||||||
}
|
|
||||||
_ => println!("network protocol not implemented"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ETH_P_IPV6 => {
|
|
||||||
me.ipv4_header = None::<packet_handler::IpV4Header>;
|
|
||||||
me.ipv6_header = Some(packet_handler::ipv6_handler(packet.data)).unwrap();
|
|
||||||
match me.ipv6_header.unwrap().next_header as usize {
|
|
||||||
TCP => {
|
|
||||||
me.tcp_header = Some(packet_handler::tcp_handler(10, packet.data)).unwrap();
|
|
||||||
me.data = Some(packet_handler::payload_handler(
|
|
||||||
10,
|
|
||||||
me.tcp_header.unwrap().data_offset,
|
|
||||||
packet.data,
|
|
||||||
)).unwrap();
|
|
||||||
}
|
|
||||||
UDP => {
|
|
||||||
me.udp_header = Some(packet_handler::udp_handler(10, packet.data)).unwrap();
|
|
||||||
me.data = Some(packet_handler::payload_handler(10, 7, packet.data)).unwrap();
|
|
||||||
}
|
|
||||||
_ => println!("network protocol not implemented"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ETH_P_ARP | ETH_P_RARP => {
|
|
||||||
me.arp_header = Some(packet_handler::arp_handler(packet.data)).unwrap();
|
|
||||||
me.data = None;
|
|
||||||
}
|
|
||||||
_ => println!("network protocol not implemented"),
|
|
||||||
}
|
}
|
||||||
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,
|
|
||||||
udp_header: me.udp_header,
|
|
||||||
arp_header: me.arp_header,
|
|
||||||
reg_res: me.reg_res,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
me.time = (packet.header.ts.tv_usec as f64 / 1000000.0) + packet.header.ts.tv_sec as f64;
|
||||||
|
me.reg_res = flag_carnage(&re, packet.data);
|
||||||
|
|
||||||
|
v.push(me.clone());
|
||||||
|
|
||||||
if &v.len() >= insert_max {
|
if &v.len() >= insert_max {
|
||||||
break 'parse;
|
break 'parse;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ const ETH_TLEN: usize = 2;
|
||||||
const ETHER_HDRLEN: usize = 14;
|
const ETHER_HDRLEN: usize = 14;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy,Serialize, Deserialize)]
|
||||||
pub struct EtherHeader {
|
pub struct EtherHeader {
|
||||||
pub ether_dhost: MacAddress,
|
pub ether_dhost: MacAddress,
|
||||||
pub ether_shost: MacAddress,
|
pub ether_shost: MacAddress,
|
||||||
|
@ -24,7 +24,7 @@ pub struct EtherHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement optional ethernet vlan shim header fields
|
// TODO: implement optional ethernet vlan shim header fields
|
||||||
pub fn ethernet_handler(packet_data: &[u8]) -> EtherHeader {
|
pub fn ethernet_handler(packet_data: &[u8]) -> Option<EtherHeader> {
|
||||||
let mut _ether_dhost: [u8; ETH_ALEN] = [0; ETH_ALEN];
|
let mut _ether_dhost: [u8; ETH_ALEN] = [0; ETH_ALEN];
|
||||||
let mut _ether_shost: [u8; ETH_ALEN] = [0; ETH_ALEN];
|
let mut _ether_shost: [u8; ETH_ALEN] = [0; ETH_ALEN];
|
||||||
let mut _ether_type: u16 = 0;
|
let mut _ether_type: u16 = 0;
|
||||||
|
@ -33,11 +33,11 @@ pub fn ethernet_handler(packet_data: &[u8]) -> EtherHeader {
|
||||||
_ether_shost.clone_from_slice(&packet_data[ETH_ALEN..ETH_ALEN * 2]);
|
_ether_shost.clone_from_slice(&packet_data[ETH_ALEN..ETH_ALEN * 2]);
|
||||||
_ether_type = LittleEndian::read_u16(&packet_data[ETH_ALEN * 2..(ETH_ALEN * 2) + ETH_TLEN]);
|
_ether_type = LittleEndian::read_u16(&packet_data[ETH_ALEN * 2..(ETH_ALEN * 2) + ETH_TLEN]);
|
||||||
|
|
||||||
EtherHeader {
|
Some(EtherHeader {
|
||||||
ether_dhost: (MacAddress::new(_ether_dhost as Eui48)),
|
ether_dhost: (MacAddress::new(_ether_dhost as Eui48)),
|
||||||
ether_shost: (MacAddress::new(_ether_shost as Eui48)),
|
ether_shost: (MacAddress::new(_ether_shost as Eui48)),
|
||||||
ether_type: _ether_type as i32,
|
ether_type: _ether_type as i32,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ip */
|
/* ip */
|
||||||
|
@ -224,9 +224,9 @@ pub struct ArpHeader {
|
||||||
pub hlen: u8,
|
pub hlen: u8,
|
||||||
pub plen: u8,
|
pub plen: u8,
|
||||||
pub oper: u16,
|
pub oper: u16,
|
||||||
pub sha: Eui48,
|
pub sha: MacAddress,
|
||||||
pub spa: IpAddr,
|
pub spa: IpAddr,
|
||||||
pub tha: Eui48,
|
pub tha: MacAddress,
|
||||||
pub tpa: IpAddr,
|
pub tpa: IpAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,12 +248,10 @@ pub fn arp_handler(packet_data: &[u8]) -> Option<ArpHeader> {
|
||||||
hlen: raw_hdr[4],
|
hlen: raw_hdr[4],
|
||||||
plen: raw_hdr[5],
|
plen: raw_hdr[5],
|
||||||
oper: BigEndian::read_u16(&raw_hdr[6..8]),
|
oper: BigEndian::read_u16(&raw_hdr[6..8]),
|
||||||
//sha: MacAddress::new(_sha as Eui48).to_hex_string().to_owned(),
|
sha: MacAddress::new(_sha as Eui48),
|
||||||
sha: _sha,
|
|
||||||
spa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[14..18]))),
|
spa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[14..18]))),
|
||||||
//tha: MacAddress::new( _tha as Eui48 ).to_hex_string().to_owned(),
|
tha: MacAddress::new( _tha as Eui48 ),
|
||||||
tha: _tha,
|
tpa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[24..28]))),
|
||||||
tpa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[24..28]))),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,7 @@ impl Serialize for parser::QryData {
|
||||||
{
|
{
|
||||||
let mut state = serializer.serialize_struct("parser::QryData", 11)?;
|
let mut state = serializer.serialize_struct("parser::QryData", 11)?;
|
||||||
state.serialize_field("time", &self.time)?;
|
state.serialize_field("time", &self.time)?;
|
||||||
state.serialize_field("ether_header.ether_dhost", &self.ether_header.ether_dhost.to_hex_string())?;
|
state.serialize_field("ether_header", &self.ether_header)?;
|
||||||
state.serialize_field("ether_header.ether_shost", &self.ether_header.ether_shost.to_hex_string())?;
|
|
||||||
state.serialize_field("ether_header.ether_type", &self.ether_header.ether_type)?;
|
|
||||||
state.serialize_field("ipv4_header", &self.ipv4_header)?;
|
state.serialize_field("ipv4_header", &self.ipv4_header)?;
|
||||||
state.serialize_field("ipv6_header", &self.ipv6_header)?;
|
state.serialize_field("ipv6_header", &self.ipv6_header)?;
|
||||||
state.serialize_field("tcp_header", &self.tcp_header)?;
|
state.serialize_field("tcp_header", &self.tcp_header)?;
|
||||||
|
|
Loading…
Reference in New Issue