Pong over ipv4 response
This commit is contained in:
parent
2b376a2239
commit
988f009913
@ -35,8 +35,8 @@ impl<A: Address> ServersContext<A> for Servers2NetworkCtxTestImpl<A> {
|
||||
);
|
||||
}
|
||||
|
||||
fn report_ping(&mut self, addr: A, id: u64, ping_ms: u64) {
|
||||
println!("{} {ping_ms}", addr.to_string())
|
||||
fn report_ping(&mut self, addr: A, id: u64, ping_ms: u128) {
|
||||
println!("{} {ping_ms} ms", addr.to_string())
|
||||
}
|
||||
|
||||
fn report_error(&mut self, addr: A, id: u64) {
|
||||
|
||||
@ -12,7 +12,7 @@ pub trait NetworkContext {
|
||||
pub trait ServersContext<A: Address> {
|
||||
fn start_measuring(&mut self) -> (u64, impl Iterator<Item = A>);
|
||||
|
||||
fn report_ping(&mut self, addr: A, id: u64, ping_ms: u64);
|
||||
fn report_ping(&mut self, addr: A, id: u64, ping_ms: u128);
|
||||
|
||||
fn report_error(&mut self, addr: A, id: u64);
|
||||
}
|
||||
|
||||
39
network/icmp/src/conversions.rs
Normal file
39
network/icmp/src/conversions.rs
Normal file
@ -0,0 +1,39 @@
|
||||
pub(crate) fn hton16(v: u16, b: &mut [u8]) {
|
||||
b[0] = (v >> 8) as u8;
|
||||
b[1] = (v & 0xFF) as u8;
|
||||
}
|
||||
|
||||
pub(crate) fn hton64(v: u64, b: &mut [u8]) {
|
||||
hton16((v >> 48) as u16, b);
|
||||
hton16(((v >> 32) & 0xFFFF) as u16, &mut b[2..4]);
|
||||
hton16(((v >> 16) & 0xFFFF) as u16, &mut b[4..6]);
|
||||
hton16((v & 0xFFFF) as u16, &mut b[6..8]);
|
||||
}
|
||||
|
||||
pub(crate) fn hton128(v: u128, b: &mut [u8]) {
|
||||
hton64((v >> 64) as u64, b);
|
||||
hton64((v & 0xFFFF_FFFF_FFFF_FFFF) as u64, &mut b[8..16]);
|
||||
}
|
||||
|
||||
pub(crate) fn ntoh16(b: &[u8]) -> u16 {
|
||||
let mut v = 0u16;
|
||||
v += (b[0] as u16) << 8;
|
||||
v += b[1] as u16;
|
||||
return v;
|
||||
}
|
||||
|
||||
pub(crate) fn ntoh64(b: &[u8]) -> u64 {
|
||||
let mut v = 0u64;
|
||||
v += (ntoh16(b) as u64) << 48;
|
||||
v += (ntoh16(&b[2..4]) as u64) << 32;
|
||||
v += (ntoh16(&b[4..6]) as u64) << 16;
|
||||
v += ntoh16(&b[6..8]) as u64;
|
||||
return v;
|
||||
}
|
||||
|
||||
pub(crate) fn ntoh128(b: &[u8]) -> u128 {
|
||||
let mut v = 0u128;
|
||||
v += (ntoh64(b) as u128) << 64;
|
||||
v += ntoh64(&b[8..16]) as u128;
|
||||
return v;
|
||||
}
|
||||
@ -1,23 +1,9 @@
|
||||
mod checksum;
|
||||
mod ping;
|
||||
mod pong;
|
||||
mod conversions;
|
||||
|
||||
use checksum::IPv4ChecksumAccumulator;
|
||||
|
||||
pub use ping::fmt_icmp_echo_req;
|
||||
|
||||
fn hton16(v: u16, b: &mut [u8]) {
|
||||
b[0] = (v >> 8) as u8;
|
||||
b[1] = (v & 0xFF) as u8;
|
||||
}
|
||||
|
||||
fn hton64(v: u64, b: &mut [u8]) {
|
||||
hton16((v >> 48) as u16, b);
|
||||
hton16(((v >> 32) & 0xFFFF) as u16, &mut b[2..4]);
|
||||
hton16(((v >> 16) & 0xFFFF) as u16, &mut b[4..6]);
|
||||
hton16((v & 0xFFFF) as u16, &mut b[6..8]);
|
||||
}
|
||||
|
||||
fn hton128(v: u128, b: &mut [u8]) {
|
||||
hton64((v >> 64) as u64, b);
|
||||
hton64((v & 0xFFFF_FFFF_FFFF_FFFF) as u64, &mut b[8..16]);
|
||||
}
|
||||
pub use pong::{parse_icmp_echo_res, IcmpPong};
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::checksum::IPv4ChecksumAccumulator;
|
||||
use crate::{hton128, hton16, hton64};
|
||||
use crate::conversions::{hton128, hton16, hton64};
|
||||
|
||||
pub fn fmt_icmp_echo_req(buff: &mut [u8], seq_no: u16, req_id: u64, timestamp: u128) -> usize{
|
||||
buff[0] = 8;
|
||||
|
||||
24
network/icmp/src/pong.rs
Normal file
24
network/icmp/src/pong.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::checksum::IPv4ChecksumAccumulator;
|
||||
use crate::conversions::{hton16, hton64, hton128, ntoh16, ntoh64, ntoh128};
|
||||
|
||||
pub enum IcmpPong {
|
||||
WrongChecksum,
|
||||
Success { req_id: u64, timestamp: u128 },
|
||||
}
|
||||
|
||||
pub fn parse_icmp_echo_res(buff: &[u8]) -> IcmpPong {
|
||||
let expected_checksum = ntoh16(&buff[2..4]);
|
||||
let mut checksum = IPv4ChecksumAccumulator::new();
|
||||
checksum.add_first_byte(buff[0]);
|
||||
checksum.add_second_byte(buff[1]);
|
||||
checksum.add_trailing_data(&buff[4..32]);
|
||||
let actual_checksum = checksum.snapshot();
|
||||
if actual_checksum != expected_checksum {
|
||||
return IcmpPong::WrongChecksum;
|
||||
}
|
||||
|
||||
return IcmpPong::Success {
|
||||
req_id: ntoh64(&buff[8..16]),
|
||||
timestamp: ntoh128(&buff[16..32]),
|
||||
};
|
||||
}
|
||||
@ -12,10 +12,10 @@ use allocator::Allocator;
|
||||
use bgtu_networks_2_network_abstract::{Address, ServersContext};
|
||||
use std::ptr::NonNull;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use windows::Win32::Networking::WinSock::{WSAEACCES, WSA_ERROR};
|
||||
use windows::Win32::Networking::WinSock::{AF_INET, AF_INET6, WSAEACCES, WSA_ERROR};
|
||||
use windows::Win32::System::SystemInformation::GetTickCount;
|
||||
use windows::Win32::System::Threading::SleepEx;
|
||||
use bgtu_networks_2_network_icmp::fmt_icmp_echo_req;
|
||||
use bgtu_networks_2_network_icmp::{fmt_icmp_echo_req, parse_icmp_echo_res, IcmpPong};
|
||||
|
||||
pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut Ctx) {
|
||||
let heap = Allocator::new();
|
||||
@ -86,6 +86,29 @@ impl<'s, Ctx: ServersContext<WindowsAddressKnown>> RecvCallback<'_, Ctx> {
|
||||
unsafe {
|
||||
let this = this_ptr.cast::<Self>().as_ref();
|
||||
this.bind_callback();
|
||||
|
||||
let buffer_no_ip_header;
|
||||
match addr.any.native.ss_family {
|
||||
AF_INET => {
|
||||
let ipv4_len = ((buffer[0] & 0x0F) as usize) * 4;
|
||||
buffer_no_ip_header = &buffer[ipv4_len..buffer.len()];
|
||||
}
|
||||
AF_INET6 => {
|
||||
buffer_no_ip_header = &buffer[40..buffer.len()];
|
||||
// todo extra headers
|
||||
}
|
||||
_ => panic!("Unsupported L4 header")
|
||||
}
|
||||
|
||||
match parse_icmp_echo_res(buffer_no_ip_header) {
|
||||
IcmpPong::WrongChecksum => {
|
||||
println!("Wrong checksum")
|
||||
}
|
||||
IcmpPong::Success { req_id, timestamp } => {
|
||||
let delta = get_timestamp() - timestamp;
|
||||
NonNull::new_unchecked(this.ctx).as_mut().report_ping(addr, req_id, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Received from addr {} data {:02X?}", addr.to_string(), buffer);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user