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 eui48;
|
||||
mod packet_handler;
|
||||
use eui48::{MacAddress};
|
||||
use pcap::Capture;
|
||||
use pcap::{Capture, Linktype};
|
||||
use regex::bytes::Regex;
|
||||
use std::str;
|
||||
//use std::thread::{spawn, JoinHandle};
|
||||
|
@ -18,14 +17,6 @@ const UDP: usize = 0x11;
|
|||
const ETH_P_ARP: usize = 0x0608;
|
||||
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:.. }
|
||||
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 time: f64,
|
||||
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 ipv6_header: Option<packet_handler::IpV6Header>,
|
||||
pub tcp_header: Option<packet_handler::TcpHeader>,
|
||||
|
@ -50,12 +41,11 @@ pub struct QryData {
|
|||
}
|
||||
|
||||
fn init_qrydata( ) -> Result<QryData, core::fmt::Error> {
|
||||
let ether_init = build_ether();
|
||||
Ok(QryData {
|
||||
id: 0,
|
||||
time: 0.0,
|
||||
data: None,
|
||||
ether_header: ether_init,
|
||||
ether_header: None::<packet_handler::EtherHeader>,
|
||||
ipv4_header: None::<packet_handler::IpV4Header>,
|
||||
ipv6_header: None::<packet_handler::IpV6Header>,
|
||||
tcp_header: None::<packet_handler::TcpHeader>,
|
||||
|
@ -66,9 +56,9 @@ fn init_qrydata( ) -> Result<QryData, core::fmt::Error> {
|
|||
|
||||
}
|
||||
|
||||
enum EncapsulationType {
|
||||
ETHER = 1,
|
||||
RAWIP = 107,
|
||||
enum EncapsulationType { // pcap::Linktype::get_name() is unsafe.
|
||||
EN10MB = 1, // See: https://docs.rs/pcap/0.7.0/src/pcap/lib.rs.html#247-261
|
||||
RAW = 101, // Would this be an issue?
|
||||
}
|
||||
|
||||
impl QryData {
|
||||
|
@ -76,14 +66,12 @@ impl QryData {
|
|||
// This will get modularized into subfunctions
|
||||
fn encap_ether( packet_data: &[u8] ) -> Option<QryData> {
|
||||
let mut pkg: QryData = init_qrydata().unwrap();
|
||||
pkg.ether_header = packet_handler::ethernet_handler(packet_data);
|
||||
match pkg.ether_header.ether_type as usize {
|
||||
pkg.ether_header = Some(packet_handler::ethernet_handler(packet_data)).unwrap();
|
||||
match pkg.ether_header.unwrap().ether_type as usize {
|
||||
ETH_P_IP => {
|
||||
//pkg.ipv6_header = None::<packet_handler::IpV6Header>;
|
||||
pkg.ipv4_header = Some(packet_handler::ip_handler(packet_data)).unwrap();
|
||||
match pkg.ipv4_header.unwrap().ip_protocol as usize {
|
||||
TCP => {
|
||||
// pkg.udp_header = None::<packet_handler::UdpHeader>;
|
||||
pkg.tcp_header = Some(packet_handler::tcp_handler(
|
||||
pkg.ipv4_header.unwrap().ip_ihl,
|
||||
packet_data,
|
||||
|
@ -96,7 +84,6 @@ impl QryData {
|
|||
)).unwrap();
|
||||
}
|
||||
UDP => {
|
||||
// pkg.tcp_header = None::<packet_handler::TcpHeader>;
|
||||
pkg.udp_header = Some(packet_handler::udp_handler(
|
||||
pkg.ipv4_header.unwrap().ip_ihl,
|
||||
packet_data,
|
||||
|
@ -112,11 +99,9 @@ impl QryData {
|
|||
}
|
||||
}
|
||||
ETH_P_IPV6 => {
|
||||
//pkg.ipv4_header = None::<packet_handler::IpV4Header>;
|
||||
pkg.ipv6_header = Some(packet_handler::ipv6_handler(packet_data)).unwrap();
|
||||
match pkg.ipv6_header.unwrap().next_header as usize {
|
||||
TCP => {
|
||||
// pkg.udp_header = None::<packet_handler::UdpHeader>;
|
||||
pkg.tcp_header = Some(packet_handler::tcp_handler(10, packet_data)).unwrap();
|
||||
pkg.data = Some(packet_handler::payload_handler(
|
||||
10,
|
||||
|
@ -125,7 +110,6 @@ impl QryData {
|
|||
)).unwrap();
|
||||
}
|
||||
UDP => {
|
||||
// pkg.tcp_header = None::<packet_handler::TcpHeader>;
|
||||
pkg.udp_header = Some(packet_handler::udp_handler(10, 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 => {
|
||||
pkg.arp_header = Some(packet_handler::arp_handler(packet_data)).unwrap();
|
||||
pkg.data = None;
|
||||
}
|
||||
_ => println!("Network protocol not implemented"),
|
||||
}
|
||||
|
@ -143,12 +126,9 @@ impl QryData {
|
|||
|
||||
fn encap_rawip ( packet_data: &[u8] ) -> Option<QryData> {
|
||||
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();
|
||||
match pkg.ipv4_header.unwrap().ip_protocol as usize {
|
||||
TCP => {
|
||||
pkg.udp_header = None::<packet_handler::UdpHeader>;
|
||||
pkg.tcp_header = Some(packet_handler::tcp_handler(
|
||||
pkg.ipv4_header.unwrap().ip_ihl,
|
||||
packet_data,
|
||||
|
@ -161,7 +141,6 @@ impl QryData {
|
|||
)).unwrap();
|
||||
}
|
||||
UDP => {
|
||||
pkg.tcp_header = None::<packet_handler::TcpHeader>;
|
||||
pkg.udp_header = Some(packet_handler::udp_handler(
|
||||
pkg.ipv4_header.unwrap().ip_ihl,
|
||||
packet_data,
|
||||
|
@ -207,8 +186,8 @@ pub fn parse(parse_file: &std::path::Path, filter_str: &str, regex_filter: &str,
|
|||
|
||||
match encap {
|
||||
// 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::RAWIP as u16 => me = QryData::encap_rawip(packet.data).unwrap(),
|
||||
encap if encap == EncapsulationType::EN10MB as u16 => me = QryData::encap_ether(packet.data).unwrap(),
|
||||
encap if encap == EncapsulationType::RAW as u16 => me = QryData::encap_rawip(packet.data).unwrap(),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
|
@ -227,82 +206,19 @@ pub fn parse_device(parse_device: &str, filter_str: &str, insert_max: &usize, re
|
|||
let mut v: Vec<QryData> = Vec::new();
|
||||
let mut cap = Capture::from_device(parse_device).unwrap().open().unwrap();
|
||||
Capture::filter(&mut cap, &filter_str).unwrap();
|
||||
|
||||
let linktype = cap.get_datalink();
|
||||
let re = Regex::new(regex_filter).unwrap();
|
||||
'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;
|
||||
me.data = Some(packet.data.to_vec());
|
||||
me.reg_res = flag_carnage(&re, packet.data);
|
||||
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"),
|
||||
match linktype {
|
||||
Linktype(1) => me = QryData::encap_ether(packet.data).unwrap(),
|
||||
Linktype(101) => me = QryData::encap_rawip(packet.data).unwrap(),
|
||||
_ => (),
|
||||
}
|
||||
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 {
|
||||
break 'parse;
|
||||
|
|
|
@ -16,7 +16,7 @@ const ETH_TLEN: usize = 2;
|
|||
const ETHER_HDRLEN: usize = 14;
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy,Serialize, Deserialize)]
|
||||
pub struct EtherHeader {
|
||||
pub ether_dhost: MacAddress,
|
||||
pub ether_shost: MacAddress,
|
||||
|
@ -24,7 +24,7 @@ pub struct EtherHeader {
|
|||
}
|
||||
|
||||
// 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_shost: [u8; ETH_ALEN] = [0; ETH_ALEN];
|
||||
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_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_shost: (MacAddress::new(_ether_shost as Eui48)),
|
||||
ether_type: _ether_type as i32,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* ip */
|
||||
|
@ -224,9 +224,9 @@ pub struct ArpHeader {
|
|||
pub hlen: u8,
|
||||
pub plen: u8,
|
||||
pub oper: u16,
|
||||
pub sha: Eui48,
|
||||
pub sha: MacAddress,
|
||||
pub spa: IpAddr,
|
||||
pub tha: Eui48,
|
||||
pub tha: MacAddress,
|
||||
pub tpa: IpAddr,
|
||||
}
|
||||
|
||||
|
@ -248,12 +248,10 @@ pub fn arp_handler(packet_data: &[u8]) -> Option<ArpHeader> {
|
|||
hlen: raw_hdr[4],
|
||||
plen: raw_hdr[5],
|
||||
oper: BigEndian::read_u16(&raw_hdr[6..8]),
|
||||
//sha: MacAddress::new(_sha as Eui48).to_hex_string().to_owned(),
|
||||
sha: _sha,
|
||||
sha: MacAddress::new(_sha as Eui48),
|
||||
spa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[14..18]))),
|
||||
//tha: MacAddress::new( _tha as Eui48 ).to_hex_string().to_owned(),
|
||||
tha: _tha,
|
||||
tpa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[24..28]))),
|
||||
tha: MacAddress::new( _tha as Eui48 ),
|
||||
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)?;
|
||||
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.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("ether_header", &self.ether_header)?;
|
||||
state.serialize_field("ipv4_header", &self.ipv4_header)?;
|
||||
state.serialize_field("ipv6_header", &self.ipv6_header)?;
|
||||
state.serialize_field("tcp_header", &self.tcp_header)?;
|
||||
|
|
Loading…
Reference in New Issue