implemented arp protocol
This commit is contained in:
parent
c7355fbcf8
commit
ac9cc64fbc
|
@ -0,0 +1,244 @@
|
||||||
|
extern crate bitfield;
|
||||||
|
extern crate byteorder;
|
||||||
|
extern crate eui48;
|
||||||
|
mod packet_handler;
|
||||||
|
use eui48::MacAddress;
|
||||||
|
use pcap::Capture;
|
||||||
|
use regex::bytes::Regex;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
/* protocol ids, LittleEndian */
|
||||||
|
const ETH_P_IPV6: usize = 0xDD86;
|
||||||
|
const ETH_P_IP: usize = 0x08;
|
||||||
|
const TCP: usize = 0x06;
|
||||||
|
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])).to_hex_string(),
|
||||||
|
ether_shost: (MacAddress::new([0; 6])).to_hex_string(),
|
||||||
|
ether_type: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct QryData {
|
||||||
|
pub id: i32,
|
||||||
|
pub time: f64,
|
||||||
|
pub data: Option<Vec<u8>>,
|
||||||
|
pub ether_header: packet_handler::EtherHeader,
|
||||||
|
pub ipv4_header: Option<packet_handler::IpV4Header>,
|
||||||
|
pub ipv6_header: Option<packet_handler::IpV6Header>,
|
||||||
|
pub tcp_header: Option<packet_handler::TcpHeader>,
|
||||||
|
pub udp_header: Option<packet_handler::UdpHeader>,
|
||||||
|
pub arp_header: Option<packet_handler::ArpHeader 'a>,
|
||||||
|
pub reg_res: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flag_carnage(re: &Regex, payload: &[u8]) -> Option<String> {
|
||||||
|
let mut flags: String = String::new();
|
||||||
|
for mat in re.find_iter(payload) {
|
||||||
|
flags.push_str(std::str::from_utf8(mat.as_bytes()).unwrap());
|
||||||
|
}
|
||||||
|
match 0 < flags.len() {
|
||||||
|
false => None,
|
||||||
|
true => Some(flags),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse <'a>(parse_file: &std::path::Path, filter_str: &str) -> Vec<QryData> {
|
||||||
|
let ether_init = build_ether();
|
||||||
|
|
||||||
|
let mut me = QryData {
|
||||||
|
id: 0,
|
||||||
|
time: 0.0,
|
||||||
|
data: None,
|
||||||
|
ether_header: ether_init,
|
||||||
|
ipv4_header: None::<packet_handler::IpV4Header>,
|
||||||
|
ipv6_header: None::<packet_handler::IpV6Header>,
|
||||||
|
tcp_header: None::<packet_handler::TcpHeader>,
|
||||||
|
udp_header: None::<packet_handler::UdpHeader>,
|
||||||
|
arp_header: None::<packet_handler::ArpHeader<'a>>,
|
||||||
|
reg_res: None::<String>,
|
||||||
|
};
|
||||||
|
let mut v: Vec<QryData> = Vec::new();
|
||||||
|
|
||||||
|
let mut cap = Capture::from_file(parse_file).unwrap();
|
||||||
|
Capture::filter(&mut cap, &filter_str).unwrap();
|
||||||
|
let re = Regex::new(r"(?:http|https):[[::punct::]]?").unwrap();
|
||||||
|
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 = packet_handler::payload_handler(
|
||||||
|
me.ipv4_header.unwrap().ip_ihl,
|
||||||
|
me.tcp_header.unwrap().data_offset,
|
||||||
|
packet.data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
UDP => {
|
||||||
|
me.udp_header = Some(packet_handler::udp_handler(
|
||||||
|
me.ipv4_header.unwrap().ip_ihl,
|
||||||
|
packet.data,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
me.data = packet_handler::payload_handler(
|
||||||
|
me.ipv4_header.unwrap().ip_ihl,
|
||||||
|
7,
|
||||||
|
packet.data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => 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 = packet_handler::payload_handler(
|
||||||
|
10,
|
||||||
|
me.tcp_header.unwrap().data_offset,
|
||||||
|
packet.data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
UDP => {
|
||||||
|
me.udp_header = Some(packet_handler::udp_handler(10, packet.data)).unwrap();
|
||||||
|
me.data = packet_handler::payload_handler(10, 7, packet.data);
|
||||||
|
}
|
||||||
|
_ => println!("network protocol not implemented"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ETH_P_ARP | ETH_P_RARP => {
|
||||||
|
me.arp_header = Some(packet_handler::arp_handler(packet.data)).unwrap();
|
||||||
|
}
|
||||||
|
_ => 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_device(parse_device: &str, filter_str: &str, insert_max: &usize) -> Vec<QryData> {
|
||||||
|
let ether_init = build_ether();
|
||||||
|
|
||||||
|
let mut me = QryData {
|
||||||
|
id: 0,
|
||||||
|
time: 0.0,
|
||||||
|
data: None,
|
||||||
|
ether_header: ether_init,
|
||||||
|
ipv4_header: None::<packet_handler::IpV4Header>,
|
||||||
|
ipv6_header: None::<packet_handler::IpV6Header>,
|
||||||
|
tcp_header: None::<packet_handler::TcpHeader>,
|
||||||
|
udp_header: None::<packet_handler::UdpHeader>,
|
||||||
|
arp_header: None::<packet_handler::ArpHeader>,
|
||||||
|
reg_res: None::<String>,
|
||||||
|
};
|
||||||
|
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 re = Regex::new(r"(?:http|https):[[::punct::]]").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 = packet_handler::payload_handler(
|
||||||
|
me.ipv4_header.unwrap().ip_ihl,
|
||||||
|
me.tcp_header.unwrap().data_offset,
|
||||||
|
packet.data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
UDP => {
|
||||||
|
me.udp_header = Some(packet_handler::udp_handler(
|
||||||
|
me.ipv4_header.unwrap().ip_ihl,
|
||||||
|
packet.data,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
me.data = packet_handler::payload_handler(
|
||||||
|
me.ipv4_header.unwrap().ip_ihl,
|
||||||
|
7,
|
||||||
|
packet.data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => 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 = packet_handler::payload_handler(
|
||||||
|
10,
|
||||||
|
me.tcp_header.unwrap().data_offset,
|
||||||
|
packet.data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
UDP => {
|
||||||
|
me.udp_header = Some(packet_handler::udp_handler(10, packet.data)).unwrap();
|
||||||
|
me.data = packet_handler::payload_handler(10, 7, packet.data);
|
||||||
|
}
|
||||||
|
_ => println!("network protocol not implemented"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => 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,
|
||||||
|
});
|
||||||
|
|
||||||
|
if &v.len() >= insert_max {
|
||||||
|
break 'parse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// Init of configuration files could also be done via Config crate.
|
// Init of configuration files could also be done via Config crate.
|
||||||
// But at this point of development it seems like unjustified overhead.
|
// But at this point of development it seems like unjustified overhead.
|
||||||
|
|
||||||
|
@ -10,27 +9,31 @@ pub struct Config {
|
||||||
pub insert_max: usize,
|
pub insert_max: usize,
|
||||||
pub pcap_file: String,
|
pub pcap_file: String,
|
||||||
pub connection: String,
|
pub connection: String,
|
||||||
pub device: String,
|
pub device: String,
|
||||||
pub is_device: bool,
|
pub is_device: bool,
|
||||||
pub pcap_dir: String,
|
pub pcap_dir: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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();
|
||||||
Some(Config {
|
Some(Config {
|
||||||
filter: json.get("filter").unwrap().as_str().unwrap().to_owned(),
|
filter: json.get("filter").unwrap().as_str().unwrap().to_owned(),
|
||||||
insert_max : json.get("insert_max").unwrap().as_u64().unwrap() as usize,
|
insert_max: json.get("insert_max").unwrap().as_u64().unwrap() as usize,
|
||||||
pcap_file : json.get("pcap_file").unwrap().as_str().unwrap().to_owned(),
|
pcap_file: json.get("pcap_file").unwrap().as_str().unwrap().to_owned(),
|
||||||
connection : format!("host={} user={} password={}",
|
connection: format!(
|
||||||
json.get("database_host").unwrap().as_str().unwrap(),
|
"host={} user={} password={}",
|
||||||
json.get("database_user").unwrap().as_str().unwrap(),
|
json.get("database_host").unwrap().as_str().unwrap(),
|
||||||
json.get("database_password").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(),
|
device: json
|
||||||
pcap_dir : json.get("pcap_dir").unwrap().as_str().unwrap().to_owned(),
|
.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(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -17,7 +17,7 @@ const PCAP_SIGNATURE: [u8; 4] = [0xed, 0xab, 0xee, 0xdb];
|
||||||
|
|
||||||
fn query_string(insert_max: &usize) -> String {
|
fn query_string(insert_max: &usize) -> String {
|
||||||
|
|
||||||
// Changed this to String with given capacity after stumbling on https://github.com/hoodie/concatenation_benchmarks-rs
|
// Changed this to String with given capacity after stumbling over https://github.com/hoodie/concatenation_benchmarks-rs
|
||||||
// Impressive performance increase!
|
// Impressive performance increase!
|
||||||
let mut insert_template = String::with_capacity(insert_max * 8 + 43);
|
let mut insert_template = String::with_capacity(insert_max * 8 + 43);
|
||||||
insert_template.push_str("INSERT INTO json_dump (packet) Values ");
|
insert_template.push_str("INSERT INTO json_dump (packet) Values ");
|
||||||
|
@ -30,6 +30,11 @@ fn query_string(insert_max: &usize) -> String {
|
||||||
insert_template
|
insert_template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn smallest_prime_divisor(remainder: usize ) -> usize {
|
||||||
|
let smallest_divisor: usize = (2..(remainder/2)).into_par_iter().find_first(|x| remainder % x == 0).unwrap();
|
||||||
|
smallest_divisor
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main(core_threads = 4)] // By default, tokio_postgres uses the tokio crate as its runtime.
|
#[tokio::main(core_threads = 4)] // By default, tokio_postgres uses the tokio crate as its runtime.
|
||||||
async fn main() -> Result<(), Error> {
|
async fn main() -> Result<(), Error> {
|
||||||
/* Init values from file */
|
/* Init values from file */
|
||||||
|
@ -88,8 +93,15 @@ async fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
match config.is_device {
|
match config.is_device {
|
||||||
false => for _pcap_file in pcap_map.keys() {
|
false => for _pcap_file in pcap_map.keys() {
|
||||||
|
|
||||||
|
// TODO: Tuning vector capacity according to actuarial excpectation, mean average & std dev of packet size
|
||||||
let v: Vec<parser::QryData> = parser::parse(&_pcap_file, &config.filter);
|
let v: Vec<parser::QryData> = parser::parse(&_pcap_file, &config.filter);
|
||||||
|
//let mut v = Vec::<parser::QryData>::with_capacity(35536);
|
||||||
|
//v.extend(parser::parse(&_pcap_file, &config.filter));
|
||||||
|
|
||||||
let packets_serialized = serializer::serialize_packets(v);
|
let packets_serialized = serializer::serialize_packets(v);
|
||||||
|
//let mut packets_serialized = Vec::<serde_json::Value>::with_capacity(35536);
|
||||||
|
//packets_serialized.extend(serializer::serialize_packets(v));
|
||||||
|
|
||||||
/* Query */
|
/* Query */
|
||||||
|
|
||||||
|
@ -111,7 +123,7 @@ async fn main() -> Result<(), Error> {
|
||||||
false => {
|
false => {
|
||||||
let insert_str = query_string(&config.insert_max);
|
let insert_str = query_string(&config.insert_max);
|
||||||
let statement = client.prepare(&insert_str).await?;
|
let statement = client.prepare(&insert_str).await?;
|
||||||
|
|
||||||
for _i in 0..chunk_count {
|
for _i in 0..chunk_count {
|
||||||
let (_input, _) = packets_serialized.split_at(config.insert_max);
|
let (_input, _) = packets_serialized.split_at(config.insert_max);
|
||||||
client
|
client
|
||||||
|
@ -123,7 +135,7 @@ async fn main() -> Result<(), Error> {
|
||||||
println!("Chunks, total:{}", chunk_count);
|
println!("Chunks, total:{}", chunk_count);
|
||||||
println!("Chunks, remainder:{}", remainder);
|
println!("Chunks, remainder:{}", remainder);
|
||||||
|
|
||||||
if remainder > 0 {
|
if remainder > 0 {
|
||||||
let rem_str = query_string(&remainder);
|
let rem_str = query_string(&remainder);
|
||||||
let statement_remainder = client.prepare(&rem_str).await?;
|
let statement_remainder = client.prepare(&rem_str).await?;
|
||||||
let (_garbage, _input) =
|
let (_garbage, _input) =
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"filter": "tcp && ip6",
|
"filter": "tcp && ip6",
|
||||||
"from_device": false,
|
"from_device": false,
|
||||||
"parse_device": "enp7s0",
|
"parse_device": "enp7s0",
|
||||||
"pcap_file": "../target/wohnung2.pcapng",
|
"pcap_file": "../target/arp_test.pcapng",
|
||||||
"pcap_dir": "../target",
|
"pcap_dir": "../target",
|
||||||
"database_user": "postgres",
|
"database_user": "postgres",
|
||||||
"database_host": "localhost",
|
"database_host": "localhost",
|
||||||
|
|
|
@ -12,6 +12,8 @@ const ETH_P_IPV6: usize = 0xDD86;
|
||||||
const ETH_P_IP: usize = 0x08;
|
const ETH_P_IP: usize = 0x08;
|
||||||
const TCP: usize = 0x06;
|
const TCP: usize = 0x06;
|
||||||
const UDP: usize = 0x11;
|
const UDP: usize = 0x11;
|
||||||
|
const ETH_P_ARP: usize = 0x0608;
|
||||||
|
const ETH_P_RARP: usize = 0x3580;
|
||||||
|
|
||||||
fn build_ether() -> packet_handler::EtherHeader {
|
fn build_ether() -> packet_handler::EtherHeader {
|
||||||
packet_handler::EtherHeader {
|
packet_handler::EtherHeader {
|
||||||
|
@ -31,6 +33,7 @@ pub struct QryData {
|
||||||
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>,
|
||||||
pub udp_header: Option<packet_handler::UdpHeader>,
|
pub udp_header: Option<packet_handler::UdpHeader>,
|
||||||
|
pub arp_header: Option<packet_handler::ArpHeader>,
|
||||||
pub reg_res: Option<String>,
|
pub reg_res: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +60,7 @@ pub fn parse(parse_file: &std::path::Path, filter_str: &str) -> Vec<QryData> {
|
||||||
ipv6_header: None::<packet_handler::IpV6Header>,
|
ipv6_header: None::<packet_handler::IpV6Header>,
|
||||||
tcp_header: None::<packet_handler::TcpHeader>,
|
tcp_header: None::<packet_handler::TcpHeader>,
|
||||||
udp_header: None::<packet_handler::UdpHeader>,
|
udp_header: None::<packet_handler::UdpHeader>,
|
||||||
|
arp_header: None::<packet_handler::ArpHeader>,
|
||||||
reg_res: None::<String>,
|
reg_res: None::<String>,
|
||||||
};
|
};
|
||||||
let mut v: Vec<QryData> = Vec::new();
|
let mut v: Vec<QryData> = Vec::new();
|
||||||
|
@ -120,6 +124,9 @@ pub fn parse(parse_file: &std::path::Path, filter_str: &str) -> Vec<QryData> {
|
||||||
_ => println!("network protocol not implemented"),
|
_ => println!("network protocol not implemented"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ETH_P_ARP | ETH_P_RARP => {
|
||||||
|
me.arp_header = Some(packet_handler::arp_handler(packet.data)).unwrap();
|
||||||
|
}
|
||||||
_ => println!("network protocol not implemented"),
|
_ => println!("network protocol not implemented"),
|
||||||
}
|
}
|
||||||
v.push(QryData {
|
v.push(QryData {
|
||||||
|
@ -131,6 +138,7 @@ pub fn parse(parse_file: &std::path::Path, filter_str: &str) -> Vec<QryData> {
|
||||||
ipv6_header: me.ipv6_header,
|
ipv6_header: me.ipv6_header,
|
||||||
tcp_header: me.tcp_header,
|
tcp_header: me.tcp_header,
|
||||||
udp_header: me.udp_header,
|
udp_header: me.udp_header,
|
||||||
|
arp_header: me.arp_header,
|
||||||
reg_res: me.reg_res,
|
reg_res: me.reg_res,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -149,6 +157,7 @@ pub fn parse_device(parse_device: &str, filter_str: &str, insert_max: &usize) ->
|
||||||
ipv6_header: None::<packet_handler::IpV6Header>,
|
ipv6_header: None::<packet_handler::IpV6Header>,
|
||||||
tcp_header: None::<packet_handler::TcpHeader>,
|
tcp_header: None::<packet_handler::TcpHeader>,
|
||||||
udp_header: None::<packet_handler::UdpHeader>,
|
udp_header: None::<packet_handler::UdpHeader>,
|
||||||
|
arp_header: None::<packet_handler::ArpHeader>,
|
||||||
reg_res: None::<String>,
|
reg_res: None::<String>,
|
||||||
};
|
};
|
||||||
let mut v: Vec<QryData> = Vec::new();
|
let mut v: Vec<QryData> = Vec::new();
|
||||||
|
@ -212,6 +221,9 @@ pub fn parse_device(parse_device: &str, filter_str: &str, insert_max: &usize) ->
|
||||||
_ => println!("network protocol not implemented"),
|
_ => println!("network protocol not implemented"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ETH_P_ARP | ETH_P_RARP => {
|
||||||
|
me.arp_header = Some(packet_handler::arp_handler(packet.data)).unwrap();
|
||||||
|
}
|
||||||
_ => println!("network protocol not implemented"),
|
_ => println!("network protocol not implemented"),
|
||||||
}
|
}
|
||||||
v.push(QryData {
|
v.push(QryData {
|
||||||
|
@ -223,6 +235,7 @@ pub fn parse_device(parse_device: &str, filter_str: &str, insert_max: &usize) ->
|
||||||
ipv6_header: me.ipv6_header,
|
ipv6_header: me.ipv6_header,
|
||||||
tcp_header: me.tcp_header,
|
tcp_header: me.tcp_header,
|
||||||
udp_header: me.udp_header,
|
udp_header: me.udp_header,
|
||||||
|
arp_header: me.arp_header,
|
||||||
reg_res: me.reg_res,
|
reg_res: me.reg_res,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,13 @@ pub struct EtherHeader {
|
||||||
pub ether_type: i32,
|
pub ether_type: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement 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]) -> 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;
|
||||||
|
|
||||||
_ether_dhost.clone_from_slice(&packet_data[0..ETH_ALEN]);
|
_ether_dhost.clone_from_slice(&packet_data[0..ETH_ALEN]);
|
||||||
|
|
||||||
//println!("{:?}", (&(_ether_dhost).to_owned()));
|
|
||||||
_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]);
|
||||||
|
|
||||||
|
@ -267,71 +265,110 @@ pub fn tcp_handler(ip_hlen: u32, packet_data: &[u8]) -> Option<TcpHeader> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arp */
|
/* arp */
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
//#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ArpHeader {
|
//pub struct ArpHeader {
|
||||||
pub htype: u32,
|
// pub htype: u32,
|
||||||
pub ptype: u32,
|
// pub ptype: u32,
|
||||||
pub hlen: u32,
|
// pub hlen: u32,
|
||||||
pub plen: u32,
|
// pub plen: u32,
|
||||||
pub oper: u32,
|
// pub oper: u32,
|
||||||
pub sha: String,
|
// pub sha: String,
|
||||||
pub spa: IpAddr,
|
// pub spa: IpAddr,
|
||||||
pub tha: String,
|
// pub tha: String,
|
||||||
pub tpa: IpAddr,
|
// pub tpa: IpAddr,
|
||||||
}
|
//}
|
||||||
// u8, get_source_address, _: 103, 96, 4;
|
// u8, get_source_address, _: 103, 96, 4;
|
||||||
// u32, into Ipv4Addr, get_destination_address, _: 159, 128;
|
// u32, into Ipv4Addr, get_destination_address, _: 159, 128;
|
||||||
|
|
||||||
bitfield! {
|
//bitfield! {
|
||||||
struct BitfieldArpHeader ( MSB0 [u8] );
|
// struct BitfieldArpHeader ( MSB0 [u8] );
|
||||||
impl Debug;
|
// impl Debug;
|
||||||
u32;
|
// u32;
|
||||||
get_htype, _: 0, 1;
|
// get_htype, _: 0, 1;
|
||||||
get_ptype, _: 2, 3;
|
// get_ptype, _: 2, 3;
|
||||||
get_hlen, _: 4;
|
// get_hlen, _: 4;
|
||||||
get_plen, _: 5;
|
// get_plen, _: 5;
|
||||||
get_oper, _: 6, 7;
|
// get_oper, _: 6, 7;
|
||||||
get_sha, _: 8,13;
|
// get_sha, _: 8,13;
|
||||||
get_tha, _: 18, 23;
|
// get_tha, _: 18, 23;
|
||||||
u8, get_spa, _: 17, 14, 4;
|
// u8, get_spa, _: 17, 14, 4;
|
||||||
u32, into Ipv4Addr, get_tpa, _: 28, 24;
|
// u32, into Ipv4Addr, get_tpa, _: 28, 24;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
impl<T: AsRef<[u8]> + AsMut<[u8]>> BitfieldArpHeader<T> {
|
//impl<T: AsRef<[u8]> + AsMut<[u8]>> BitfieldArpHeader<T> {
|
||||||
fn get_spa_as_ip_addr(&self) -> Ipv4Addr {
|
// fn get_spa_as_ip_addr(&self) -> Ipv4Addr {
|
||||||
let mut src = [0; 4];
|
// let mut src = [0; 4];
|
||||||
for (i, src) in src.iter_mut().enumerate() {
|
// for (i, src) in src.iter_mut().enumerate() {
|
||||||
*src = self.get_spa(i);
|
// *src = self.get_spa(i);
|
||||||
}
|
// }
|
||||||
src.into()
|
// src.into()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
// TODO: Fix this crap
|
// 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)]
|
||||||
|
pub struct ArpHeader {
|
||||||
|
pub htype: u16,
|
||||||
|
pub ptype: u16,
|
||||||
|
pub hlen: u8,
|
||||||
|
pub plen: u8,
|
||||||
|
pub oper: u16,
|
||||||
|
pub sha: Eui48,
|
||||||
|
pub spa: IpAddr,
|
||||||
|
pub tha: Eui48,
|
||||||
|
pub tpa: IpAddr,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn arp_handler(packet_data: &[u8]) -> Option<ArpHeader> {
|
pub fn arp_handler(packet_data: &[u8]) -> Option<ArpHeader> {
|
||||||
let mut raw_hdr: [u8; 28] = [0; 28];
|
let mut raw_hdr: [u8; 28] = [0; 28];
|
||||||
raw_hdr.copy_from_slice(&packet_data[ETHER_HDRLEN..ETHER_HDRLEN + 28]);
|
raw_hdr.copy_from_slice(
|
||||||
|
&packet_data[ETHER_HDRLEN .. ETHER_HDRLEN + 28]
|
||||||
|
);
|
||||||
|
|
||||||
let arp_header = BitfieldArpHeader(raw_hdr);
|
let mut _sha: [u8; 6] = [0; 6];
|
||||||
let _sha: [u8; 6] = [0; 6];
|
let mut _tha: [u8; 6] = [0; 6];
|
||||||
let _tha: [u8; 6] = [0; 6];
|
|
||||||
raw_hdr[8..13].copy_from_slice(&_sha);
|
_sha.clone_from_slice(&raw_hdr[8..14]);
|
||||||
raw_hdr[18..23].copy_from_slice(&_tha);
|
_tha.clone_from_slice(&raw_hdr[18..24]);
|
||||||
|
|
||||||
Some(ArpHeader {
|
Some(ArpHeader{
|
||||||
htype: arp_header.get_htype(),
|
htype: BigEndian::read_u16(&raw_hdr[0..2]),
|
||||||
ptype: arp_header.get_ptype(),
|
ptype: BigEndian::read_u16(&raw_hdr[2..4]),
|
||||||
hlen: arp_header.get_hlen().into(),
|
hlen: raw_hdr[4],
|
||||||
plen: arp_header.get_plen().into(),
|
plen: raw_hdr[5],
|
||||||
oper: arp_header.get_oper(),
|
oper: BigEndian::read_u16(&raw_hdr[6..8]),
|
||||||
sha: MacAddress::new(_sha as Eui48).to_hex_string(),
|
//sha: MacAddress::new(_sha as Eui48).to_hex_string().to_owned(),
|
||||||
//MacAddress::new(arp_header.get_sha() as Eui48).to_hex_string(),
|
sha: _sha,
|
||||||
spa: IpAddr::V4(arp_header.get_spa_as_ip_addr()),
|
spa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[14..18]))),
|
||||||
tha: MacAddress::new(_tha as Eui48).to_hex_string(),
|
//tha: MacAddress::new( _tha as Eui48 ).to_hex_string().to_owned(),
|
||||||
tpa: IpAddr::V4(arp_header.get_tpa()),
|
tha: _tha,
|
||||||
|
tpa: IpAddr::V4(Ipv4Addr::from(BigEndian::read_u32(&raw_hdr[24..28]))),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* udp */
|
/* udp */
|
||||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||||
pub struct UdpHeader {
|
pub struct UdpHeader {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
use crate::parser;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use serde::ser::{Serialize, SerializeStruct, Serializer};
|
use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use crate::parser;
|
|
||||||
|
|
||||||
impl Serialize for parser::QryData {
|
impl Serialize for parser::QryData {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -19,6 +19,7 @@ impl Serialize for parser::QryData {
|
||||||
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)?;
|
||||||
state.serialize_field("udp_header", &self.udp_header)?;
|
state.serialize_field("udp_header", &self.udp_header)?;
|
||||||
|
state.serialize_field("arp_header", &self.arp_header)?;
|
||||||
state.serialize_field("data", &self.data)?;
|
state.serialize_field("data", &self.data)?;
|
||||||
state.serialize_field("reg_res", &self.reg_res)?;
|
state.serialize_field("reg_res", &self.reg_res)?;
|
||||||
state.end()
|
state.end()
|
||||||
|
|
Loading…
Reference in New Issue