Skip to content

Commit

Permalink
Support ip boardcasting with sync/async stream
Browse files Browse the repository at this point in the history
formatter and dependency

check point

check point

get network interface

Support ip boardcasting with sync/async stream
  • Loading branch information
irvingoujAtDevolution committed Jan 10, 2024
1 parent 322ed68 commit 2dd2da5
Show file tree
Hide file tree
Showing 13 changed files with 411 additions and 1 deletion.
4 changes: 4 additions & 0 deletions crates/network-scanner-net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ publish = false

[dependencies]
anyhow = "1.0.79"
etherparse = "0.13.0"
socket2 = { version = "0.5.5", features = ["all"] }
tokio = { version = "1.35.1", features = ["io-util","rt","sync"] }
tracing = "0.1.40"

[dev-dependencies]
network-scanner-proto = { path = "../network-scanner-proto" }
41 changes: 41 additions & 0 deletions crates/network-scanner-net/examples/block_raw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use etherparse::{icmpv4, IcmpEchoHeader, Icmpv4Header};
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use std::{
io::{self, Write},
mem::MaybeUninit,
net::SocketAddr,
thread,
};

#[derive(Debug)]
#[repr(u8)]
pub enum IpProtocol {
Icmp = 1,
Igmp = 2,
Tcp = 6,
Udp = 17,
Ipv6 = 41,
Icmpv6 = 58,
UdpLite = 136,
}

fn main() -> io::Result<()> {
let socket = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::ICMPV4))?;

let buf = [8, 0, 246, 78, 0, 0, 0, 0, 0, 0, 0, 0, 101, 157, 156, 19];
let addr = socket2::SockAddr::from(SocketAddr::from(([127, 0, 0, 1], 0)));
socket.send_to(&buf, &addr).unwrap();

let mut buf = [MaybeUninit::<u8>::uninit(); 8096];
let (size, addr) = socket.recv_from(&mut buf)?;

let inited_buf = buf[..size].as_ref();
let buffer = inited_buf
.iter()
.map(|u| unsafe { u.assume_init() })
.collect::<Vec<u8>>();
println!("Received {} bytes from write socket", size);
println!("{:?}", buffer);

Ok(())
}
51 changes: 51 additions & 0 deletions crates/network-scanner-net/examples/send_all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use etherparse::{icmpv4, IcmpEchoHeader, Icmpv4Header};
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use std::{
io::{self, Write},
mem::MaybeUninit,
net::SocketAddr,
thread,
};

#[derive(Debug)]
#[repr(u8)]
pub enum IpProtocol {
Icmp = 1,
Igmp = 2,
Tcp = 6,
Udp = 17,
Ipv6 = 41,
Icmpv6 = 58,
UdpLite = 136,
}

fn main() -> io::Result<()> {
println!("Sending packet");
let send_socket = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::ICMPV4))?;
let addr = SocketAddr::from(([192, 168, 1, 255], 1));

let time = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();

send_socket.set_broadcast(true)?;
// send_socket.connect(&addr.into()).expect("Failed to connect");
let echo_message = network_scanner_proto::icmp_v4::Icmpv4Message::Echo {
identifier: 0,
sequence: 0,
payload: time.to_be_bytes().to_vec(),
};

let packet = network_scanner_proto::icmp_v4::Icmpv4Packet::from_message(echo_message);
// send_socket.write(&packet.to_bytes(true)).expect("Failed to write");
send_socket
.send_to(&packet.to_bytes(true), &SockAddr::from(addr))
.unwrap();
println!("packet sent");
let mut buf = [MaybeUninit::<u8>::uninit(); 8096];
let res = send_socket.recv(&mut buf).expect("Failed to receive");
println!("Received {} bytes from write socket", res);

Ok(())
}
11 changes: 11 additions & 0 deletions crates/network-scanner-net/src/broadcast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// pub struct ResultStream{

// }

// impl tokio_stream::Stream for ResultStream{
// type Item = &[u8];

// }

// pub async fn boardcast(ip: Ipv4Addr) -> std::io::Result<()>{
// }
1 change: 1 addition & 0 deletions crates/network-scanner-net/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod broadcast;
pub mod tokio_raw_socket;
1 change: 0 additions & 1 deletion crates/network-scanner-net/src/tokio_raw_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ impl TokioRawSocket {
ty: socket2::Type,
protocol: Option<socket2::Protocol>,
) -> std::io::Result<TokioRawSocket> {

let socket = socket2::Socket::new(domain, ty, protocol)?;
let socket = Arc::new(Mutex::new(socket));
Ok(TokioRawSocket { socket })
Expand Down
3 changes: 3 additions & 0 deletions crates/network-scanner-proto/src/icmp_v4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub enum Icmpv4MessageType {
InformationReply = 16,
}

#[derive(Debug)]
pub enum Icmpv4Message {
EchoReply {
// type 0
Expand Down Expand Up @@ -213,6 +214,8 @@ impl Icmpv4Message {
bytes
}
}

#[derive(Debug)]
pub struct Icmpv4Packet {
pub code: u8,
pub checksum: u16,
Expand Down
2 changes: 2 additions & 0 deletions crates/network-scanner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ publish = false

[dependencies]
anyhow = "1.0.79"
get_if_addrs = "0.5.3"
network-scanner-net ={ path = "../network-scanner-net" }
network-scanner-proto ={ path = "../network-scanner-proto" }
socket2 = "0.5.5"
tokio = { version = "1.35.1", features = ["io-util"] }
tokio-stream = "0.1.14"
tracing = "0.1.40"

[dev-dependencies]
Expand Down
36 changes: 36 additions & 0 deletions crates/network-scanner/examples/block_boardcast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use std::{process::exit, time::Duration};

use network_scanner::boardcast::block_broadcast;

pub fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::SubscriberBuilder::default()
.with_max_level(tracing::Level::TRACE)
.init();

let ip = std::net::Ipv4Addr::new(192, 168, 1, 255);

let iterator = block_broadcast(ip, Some(Duration::from_secs(1)))?;

for result in iterator {
match result {
Ok(ping_res) => {
println!("received result {:?}", &ping_res);
}
Err(e) => match e.downcast_ref::<std::io::Error>() {
Some(e) => match e.kind() {
std::io::ErrorKind::TimedOut => {
tracing::info!("Timed out");
exit(0);
}
_ => {
tracing::error!("Failed to receive broadcast packet: {}", e);
break;
}
},
None => break,
},
}
}

Ok(())
}
10 changes: 10 additions & 0 deletions crates/network-scanner/examples/block_ping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use network_scanner::ping::block_ping;

pub fn main() {
tracing_subscriber::fmt::SubscriberBuilder::default()
.with_max_level(tracing::Level::TRACE)
.init();

let ip = std::net::Ipv4Addr::new(127, 0, 0, 1);
block_ping(ip).expect("Failed to ping");
}
35 changes: 35 additions & 0 deletions crates/network-scanner/examples/boardcast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::{process::exit, time::Duration};

use network_scanner::boardcast::boardcast;
use tokio_stream::StreamExt;

#[tokio::main]
pub async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::SubscriberBuilder::default()
.with_max_level(tracing::Level::TRACE)
.init();

let ip = std::net::Ipv4Addr::new(192, 168, 1, 255);

let mut iterator = boardcast(ip, Some(Duration::from_secs(1))).await?;

while let Some(result) = iterator.next().await {
match result {
Ok(res) => {
tracing::info!("received result {:?}", &res)
}
Err(e) => {
if let Some(e) = e.downcast_ref::<std::io::Error>() {
// if is timeout, say timeout then break
if let std::io::ErrorKind::TimedOut = e.kind() {
tracing::info!("timed out");
exit(0)
}
}
return Err(e);
}
}
}

Ok(())
}
Loading

0 comments on commit 2dd2da5

Please sign in to comment.