Successfully sent ICMP ping packets
This commit is contained in:
parent
7f8187a43e
commit
2b376a2239
@ -2,6 +2,7 @@
|
|||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = [
|
members = [
|
||||||
"app",
|
"app",
|
||||||
|
"network/icmp",
|
||||||
"network/abstract",
|
"network/abstract",
|
||||||
"network/windows"
|
"network/windows"
|
||||||
]
|
]
|
||||||
|
|||||||
7
network/icmp/Cargo.toml
Normal file
7
network/icmp/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "bgtu-networks-2-network-icmp"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
44
network/icmp/src/checksum.rs
Normal file
44
network/icmp/src/checksum.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
pub(crate) struct IPv4ChecksumAccumulator {
|
||||||
|
acc: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IPv4ChecksumAccumulator {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
return Self { acc: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_first_byte(&mut self, b: u8) {
|
||||||
|
self.acc += (b as u32) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_second_byte(&mut self, b: u8) {
|
||||||
|
self.acc += b as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_last_byte(&mut self, b: u8) {
|
||||||
|
self.acc += b as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_word(&mut self, b: u16) {
|
||||||
|
self.acc += b as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_trailing_data(&mut self, data: &[u8]) {
|
||||||
|
for i in (0..(data.len() / 2)).into_iter().map(|i| i * 2) {
|
||||||
|
self.add_first_byte(data[i]);
|
||||||
|
self.add_second_byte(data[i + 1]);
|
||||||
|
}
|
||||||
|
if data.len() % 2 != 0 {
|
||||||
|
self.add_last_byte(data[data.len() - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn snapshot(&self) -> u16 {
|
||||||
|
let mut out = self.acc;
|
||||||
|
while out > 0x0000FFFFu32 {
|
||||||
|
out = (out & 0x0000FFFFu32) + (out >> 16);
|
||||||
|
}
|
||||||
|
return !(out as u16);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
network/icmp/src/lib.rs
Normal file
23
network/icmp/src/lib.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
mod checksum;
|
||||||
|
mod ping;
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
19
network/icmp/src/ping.rs
Normal file
19
network/icmp/src/ping.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::checksum::IPv4ChecksumAccumulator;
|
||||||
|
use crate::{hton128, hton16, hton64};
|
||||||
|
|
||||||
|
pub fn fmt_icmp_echo_req(buff: &mut [u8], seq_no: u16, req_id: u64, timestamp: u128) -> usize{
|
||||||
|
buff[0] = 8;
|
||||||
|
buff[1] = 0;
|
||||||
|
hton16(0, &mut buff[4..6]);
|
||||||
|
hton16(seq_no, &mut buff[6..8]);
|
||||||
|
hton64(req_id, &mut buff[8..16]);
|
||||||
|
hton128(timestamp, &mut buff[16..32]);
|
||||||
|
|
||||||
|
let mut checksum = IPv4ChecksumAccumulator::new();
|
||||||
|
checksum.add_first_byte(buff[0]);
|
||||||
|
checksum.add_second_byte(buff[1]);
|
||||||
|
checksum.add_trailing_data(&buff[4..32]);
|
||||||
|
hton16(checksum.snapshot(), &mut buff[2..4]);
|
||||||
|
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bgtu-networks-2-network-abstract = { path = "../abstract" }
|
bgtu-networks-2-network-abstract = { path = "../abstract" }
|
||||||
|
bgtu-networks-2-network-icmp = { path = "../icmp" }
|
||||||
|
|
||||||
[dependencies.windows]
|
[dependencies.windows]
|
||||||
version = ">=0.41.0, <=0.62.2"
|
version = ">=0.41.0, <=0.62.2"
|
||||||
|
|||||||
@ -9,10 +9,13 @@ use std::ffi::c_void;
|
|||||||
use crate::address::WindowsAddressKnown;
|
use crate::address::WindowsAddressKnown;
|
||||||
use crate::errors::format_windows_err_code;
|
use crate::errors::format_windows_err_code;
|
||||||
use allocator::Allocator;
|
use allocator::Allocator;
|
||||||
use bgtu_networks_2_network_abstract::ServersContext;
|
use bgtu_networks_2_network_abstract::{Address, ServersContext};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
use windows::Win32::Networking::WinSock::{WSAEACCES, WSA_ERROR};
|
||||||
use windows::Win32::System::SystemInformation::GetTickCount;
|
use windows::Win32::System::SystemInformation::GetTickCount;
|
||||||
use windows::Win32::System::Threading::SleepEx;
|
use windows::Win32::System::Threading::SleepEx;
|
||||||
|
use bgtu_networks_2_network_icmp::fmt_icmp_echo_req;
|
||||||
|
|
||||||
pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut Ctx) {
|
pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut Ctx) {
|
||||||
let heap = Allocator::new();
|
let heap = Allocator::new();
|
||||||
@ -25,15 +28,17 @@ pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut
|
|||||||
ctx,
|
ctx,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut seq_no = 0u16;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (id, it) = (*ctx).start_measuring();
|
let (round_id, addrs_it) = (*ctx).start_measuring();
|
||||||
|
|
||||||
let mut should_recv_being_enabled = false;
|
let mut should_recv_being_enabled = false;
|
||||||
for address in it {
|
for address in addrs_it {
|
||||||
socket.send(
|
socket.send(
|
||||||
address,
|
address,
|
||||||
|buff| {},
|
|buff| fmt_icmp_echo_req(buff, seq_no, round_id, get_timestamp()),
|
||||||
|err, _| println!("Otpravlena hujnya: {}", format_windows_err_code(err)),
|
send_callback,
|
||||||
);
|
);
|
||||||
should_recv_being_enabled = true;
|
should_recv_being_enabled = true;
|
||||||
}
|
}
|
||||||
@ -61,6 +66,8 @@ pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seq_no = seq_no.wrapping_add(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +87,13 @@ impl<'s, Ctx: ServersContext<WindowsAddressKnown>> RecvCallback<'_, Ctx> {
|
|||||||
let this = this_ptr.cast::<Self>().as_ref();
|
let this = this_ptr.cast::<Self>().as_ref();
|
||||||
this.bind_callback();
|
this.bind_callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Received from addr {} data {:02X?}", addr.to_string(), buffer);
|
||||||
|
|
||||||
|
match WSA_ERROR(errcode.cast_signed()) {
|
||||||
|
WSA_ERROR(0) => {}
|
||||||
|
errcode => panic!("Unhandled exception on send: [{}] {}", errcode.0, format_windows_err_code(errcode))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// I <3 borrow checker
|
// I <3 borrow checker
|
||||||
@ -98,3 +112,19 @@ impl<'s, Ctx: ServersContext<WindowsAddressKnown>> RecvCallback<'_, Ctx> {
|
|||||||
Self::_bind_callback(self_ptr.cast(), self.sock, Self::_callback_body);
|
Self::_bind_callback(self_ptr.cast(), self.sock, Self::_callback_body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_callback(errcode: u32, addr: WindowsAddressKnown) {
|
||||||
|
match WSA_ERROR(errcode.cast_signed()) {
|
||||||
|
WSAEACCES => panic!("Need admin privileges to send ICMP"), // todo without panic,
|
||||||
|
WSA_ERROR(0) => {}
|
||||||
|
errcode => panic!("Unhandled exception on send: [{}] {}", errcode.0, format_windows_err_code(errcode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_timestamp() -> u128 {
|
||||||
|
let start = SystemTime::now();
|
||||||
|
let since_the_epoch = start
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("time should go forward");
|
||||||
|
return since_the_epoch.as_millis();
|
||||||
|
}
|
||||||
@ -2,19 +2,18 @@ use crate::address::WindowsAddressKnown;
|
|||||||
use crate::errors::throw_from_windows_err_code;
|
use crate::errors::throw_from_windows_err_code;
|
||||||
use crate::eventloop::allocator::Allocator;
|
use crate::eventloop::allocator::Allocator;
|
||||||
use crate::eventloop::task::IoTask;
|
use crate::eventloop::task::IoTask;
|
||||||
use bgtu_networks_2_network_abstract::ServersContext;
|
|
||||||
use std::mem::uninitialized;
|
use std::mem::uninitialized;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use windows::Win32::Networking::WinSock::{
|
use windows::Win32::Networking::WinSock::{
|
||||||
WSAGetLastError, WSARecvFrom, WSASendTo, WSASocketW, AF_UNSPEC,
|
AF_UNSPEC, IPPROTO_ICMP, LPWSAOVERLAPPED_COMPLETION_ROUTINE, SOCK_RAW, SOCKADDR,
|
||||||
IPPROTO_ICMP, LPWSAOVERLAPPED_COMPLETION_ROUTINE, SOCKADDR, SOCKADDR_STORAGE, SOCKET,
|
SOCKADDR_STORAGE, SOCKET, SOCKET_ERROR, WSA_FLAG_NO_HANDLE_INHERIT, WSA_FLAG_OVERLAPPED,
|
||||||
SOCKET_ERROR, SOCK_RAW, WSAEACCES, WSAEADDRNOTAVAIL, WSAEAFNOSUPPORT,
|
WSA_IO_PENDING, WSA_OPERATION_ABORTED, WSAEACCES, WSAEADDRNOTAVAIL, WSAEAFNOSUPPORT,
|
||||||
WSAECONNRESET, WSAEDESTADDRREQ, WSAEFAULT, WSAEHOSTUNREACH, WSAEINPROGRESS, WSAEINTR,
|
WSAECONNRESET, WSAEDESTADDRREQ, WSAEFAULT, WSAEHOSTUNREACH, WSAEINPROGRESS, WSAEINTR,
|
||||||
WSAEINVAL, WSAEMSGSIZE, WSAENETDOWN, WSAENETRESET, WSAENETUNREACH, WSAENOBUFS, WSAENOTCONN,
|
WSAEINVAL, WSAEMSGSIZE, WSAENETDOWN, WSAENETRESET, WSAENETUNREACH, WSAENOBUFS, WSAENOTCONN,
|
||||||
WSAENOTSOCK, WSAESHUTDOWN, WSAEWOULDBLOCK, WSANOTINITIALISED, WSA_FLAG_NO_HANDLE_INHERIT, WSA_FLAG_OVERLAPPED,
|
WSAENOTSOCK, WSAESHUTDOWN, WSAEWOULDBLOCK, WSAGetLastError, WSANOTINITIALISED, WSARecvFrom,
|
||||||
WSA_IO_PENDING, WSA_OPERATION_ABORTED,
|
WSASendTo, WSASocketW,
|
||||||
};
|
};
|
||||||
use windows::Win32::System::IO::OVERLAPPED;
|
use windows::Win32::System::IO::OVERLAPPED;
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ impl<'a> WindowsOverlappingIcmpSocket<'a> {
|
|||||||
pub unsafe fn send(
|
pub unsafe fn send(
|
||||||
&mut self,
|
&mut self,
|
||||||
addr: WindowsAddressKnown,
|
addr: WindowsAddressKnown,
|
||||||
init_data: impl FnOnce(&mut [u8]),
|
init_data: impl FnOnce(&mut [u8]) -> usize,
|
||||||
on_sent: impl FnOnce(u32, WindowsAddressKnown) + 'static,
|
on_sent: impl FnOnce(u32, WindowsAddressKnown) + 'static,
|
||||||
) {
|
) {
|
||||||
let task = self.heap.alloc(|p| {
|
let task = self.heap.alloc(|p| {
|
||||||
@ -91,7 +90,7 @@ impl<'a> WindowsOverlappingIcmpSocket<'a> {
|
|||||||
});
|
});
|
||||||
let task_p = task.get_unchecked_mut();
|
let task_p = task.get_unchecked_mut();
|
||||||
|
|
||||||
init_data(&mut task_p.buff);
|
task_p.buff_d[0].len = init_data(&mut task_p.buff) as u32;
|
||||||
|
|
||||||
let result = WSASendTo(
|
let result = WSASendTo(
|
||||||
self.socket,
|
self.socket,
|
||||||
@ -138,7 +137,6 @@ impl<'a> WindowsOverlappingIcmpSocket<'a> {
|
|||||||
&self,
|
&self,
|
||||||
on_received: impl for<'xx> FnOnce(u32, WindowsAddressKnown, &'xx [u8]) + 'static,
|
on_received: impl for<'xx> FnOnce(u32, WindowsAddressKnown, &'xx [u8]) + 'static,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
let task = self.heap.alloc(|p| {
|
let task = self.heap.alloc(|p| {
|
||||||
IoTask::init(
|
IoTask::init(
|
||||||
p,
|
p,
|
||||||
@ -149,7 +147,6 @@ impl<'a> WindowsOverlappingIcmpSocket<'a> {
|
|||||||
});
|
});
|
||||||
let task_p = task.get_unchecked_mut();
|
let task_p = task.get_unchecked_mut();
|
||||||
|
|
||||||
|
|
||||||
task_p._addr_size = size_of::<SOCKADDR_STORAGE>() as i32;
|
task_p._addr_size = size_of::<SOCKADDR_STORAGE>() as i32;
|
||||||
task_p._flags = 0;
|
task_p._flags = 0;
|
||||||
let result = WSARecvFrom(
|
let result = WSARecvFrom(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user