current state

This commit is contained in:
Nils Andreas Svee committed 2022-09-04 16:40:38 +02:00
1 parent 92d3e3370b
commit 27aa972fe6
5 files changed
+230 -9

No files matched your search

+105
View File
@@ -1,9 +1,12 @@
use bincode::{deserialize, serialize};
use std::error::Error;
use std::net::IpAddr;
use std::{thread, time};
use crate::pinger::{PingListener, PingSender};
use crate::Pinger;
use byteorder::*;
use neli::err::NlError;
use nix::sys::time::TimeValLike;
use nix::time::{clock_gettime, ClockId};
use pnet::packet::icmp::IcmpTypes::EchoReply;
@@ -12,6 +15,19 @@ use pnet::packet::*;
use pnet_transport::TransportChannelType::Layer4;
use pnet_transport::TransportProtocol::Ipv4;
use pnet_transport::*;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
//#[repr(C)]
pub struct ICMPEcho {
type_: u8,
code: u8,
checksum: u16,
identifier: u16,
sequence: u16,
#[serde(with = "serde_bytes")]
payload: Vec<u8>,
}
pub struct PingerICMPEcho {
id: u16,
@@ -20,6 +36,33 @@ pub struct PingerICMPEcho {
tx: TransportSender,
}
pub struct PingerICMPEchoListener {
id: u16,
reflectors: Vec<IpAddr>,
}
pub struct PingerICMPEchoSender {
id: u16,
reflectors: Vec<IpAddr>,
}
fn calculate_checksum(buffer: &mut [u8]) -> u16 {
let mut sum = 0u32;
for word in buffer.chunks(2) {
let mut part = u16::from(word[0]) << 8;
if word.len() > 1 {
part += u16::from(word[1]);
}
sum = sum.wrapping_add(u32::from(part));
}
while (sum >> 16) > 0 {
sum = (sum & 0xffff) + (sum >> 16);
}
!sum as u16
}
impl Pinger for PingerICMPEcho {
fn new(id: u16, reflectors: Vec<IpAddr>) -> Self {
let protocol = Layer4(Ipv4(IpNextHeaderProtocols::Icmp));
@@ -121,3 +164,65 @@ impl Pinger for PingerICMPEcho {
Ok(())
}
}
impl PingListener for PingerICMPEchoListener {
fn new(id: u16, reflectors: Vec<IpAddr>) -> Self {
PingerICMPEchoListener { id, reflectors }
}
fn get_id(&self) -> u16 {
self.id
}
fn get_reflectors(&self) -> Vec<IpAddr> {
self.reflectors.clone()
}
fn parse_packet(buf: &[u8], len: usize) -> Result<(i64, i64, i64), Box<dyn Error>> {
if len != 44 {
println!("len: {}", len);
return Err(Box::new(NlError::msg("Wrong length")));
}
let hdr: ICMPEcho = deserialize(buf).expect("Failed to parse ICMP packet");
todo!()
}
}
impl PingSender for PingerICMPEchoSender {
fn new(id: u16, reflectors: Vec<IpAddr>) -> Self {
PingerICMPEchoSender { id, reflectors }
}
fn get_id(&self) -> u16 {
self.id
}
fn get_reflectors(&self) -> Vec<IpAddr> {
self.reflectors.clone()
}
fn craft_packet(&self, seq: u16) -> Vec<u8> {
let time = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap();
let time_u64: u64 = time.num_milliseconds() as u64;
let mut hdr = ICMPEcho {
type_: 8,
code: 0,
checksum: 0,
identifier: self.get_id(),
sequence: seq,
payload: time_u64.to_ne_bytes().to_vec(),
};
println!("id: {}", hdr.identifier);
println!("seq: {}", hdr.sequence);
let mut tmp_buf_v = serialize(&hdr).unwrap();
let mut tmp_buf = tmp_buf_v.as_mut_slice();
hdr.checksum = calculate_checksum(tmp_buf).to_be();
serialize(&hdr).unwrap()
}
}