diff --git a/Cargo.lock b/Cargo.lock index 66cb53b..e438c5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -719,12 +719,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "managed" @@ -1219,11 +1216,10 @@ checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "simple_logger" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78beb34673091ccf96a8816fce8bfd30d1292c7621ca2bcb5f2ba0fae4f558d" +checksum = "2230cd5c29b815c9b699fb610b49a5ed65588f3509d9f0108be3a885da629333" dependencies = [ - "atty", "colored", "log", "time", @@ -1419,10 +1415,12 @@ version = "0.1.0" dependencies = [ "anyhow", "libc", + "log", "nl-sys", "packets", "pcap-sys", "rand 0.8.5", + "simple_logger", "smoltcp", "tokio", "tokio-stream", diff --git a/tcp-test/client/Cargo.toml b/tcp-test/client/Cargo.toml index f28ac47..853cbcb 100644 --- a/tcp-test/client/Cargo.toml +++ b/tcp-test/client/Cargo.toml @@ -13,5 +13,7 @@ rand = "0.8.5" tokio = { version = "1.32.0", features = ["full"] } anyhow = "1.0.75" tokio-stream = { version = "0.1.14", features = ["full"] } -smoltcp = { version = "0.10.0", features = ["socket-tcp", "phy-raw_socket", "std", "async", "medium-ethernet", "proto-ipv4", "reassembly-buffer-size-65536", "fragmentation-buffer-size-65536", "proto-ipv4-fragmentation"] } +smoltcp = { version = "0.10", features = ["socket-tcp", "phy-raw_socket", "std", "async", "medium-ethernet", "proto-ipv4", "reassembly-buffer-size-65536", "fragmentation-buffer-size-65536", "proto-ipv4-fragmentation", "log", "verbose"] } libc = "0.2.148" +log = "0.4.20" +simple_logger = "4.2.0" diff --git a/tcp-test/client/src/main.rs b/tcp-test/client/src/main.rs index 0aa1e8d..d4084d7 100644 --- a/tcp-test/client/src/main.rs +++ b/tcp-test/client/src/main.rs @@ -2,11 +2,12 @@ use std::{net::Ipv4Addr, os::fd::AsRawFd, sync::Arc}; use anyhow::anyhow; +use log::{debug, info, trace}; use nl_sys::{netlink, route}; use smoltcp::{ iface::{Config, Interface, Route, SocketSet}, - phy::{wait as phy_wait, Medium, RawSocket}, + phy::{wait as phy_wait, Device, Medium, RawSocket}, socket::tcp, time::Instant, wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address}, @@ -15,6 +16,11 @@ use tokio::io::{unix::AsyncFd, Interest}; #[tokio::main] async fn main() -> anyhow::Result<()> { + simple_logger::SimpleLogger::new() + .with_level(log::LevelFilter::Trace) + .with_module_level("tcp_test", log::LevelFilter::Trace) + .init()?; + let ip = std::env::args() .skip(1) .next() @@ -45,6 +51,11 @@ async fn main() -> anyhow::Result<()> { let mut iface = Interface::new(config, &mut device, Instant::now()); iface.update_ip_addrs(|ip_addrs| { let o = srcip.octets(); + debug!( + "source network ip: {}.{}.{}.{}/{src_snmask}", + o[0], o[1], o[2], o[3] + ); + ip_addrs .push(IpCidr::new( IpAddress::v4(o[0], o[1], o[2], o[3]), @@ -55,36 +66,85 @@ async fn main() -> anyhow::Result<()> { for route in routes.iter() { let Some(dst) = route.dst() else { + trace!("failed to get route destination"); continue; }; let Some(hop) = route.hop_iter().next() else { + trace!("no next hop existed for {dst:?}"); continue; }; if hop.ifindex() != ifindex { + trace!("hop doesn't match ifindex {ifindex}"); continue; } let Some(laddr) = hop.gateway() else { + trace!("couldn't get gateway address for {dst:?}"); continue; }; if laddr.atype() != Some(libc::AF_INET) { - continue; - } - let Some(raddr) = route.dst() else { - continue; - }; - if raddr.atype() != Some(libc::AF_INET) { + trace!("unable to load IP info for {dst:?}"); continue; } if dst.cidrlen() == 0 { + info!("setting default route via {:?}", &laddr); iface .routes_mut() .add_default_ipv4_route(Ipv4Address::from_bytes(&laddr.hw_address()))?; - } else { + iface.routes_mut().update(|routes| { let lip = laddr.hw_address(); - let rip = raddr.hw_address(); + _ = routes.push(Route { + cidr: IpCidr::new(IpAddress::v4(10, 0, 0, 0), 8), + via_router: IpAddress::v4(lip[0], lip[1], lip[2], lip[3]), + expires_at: None, + preferred_until: None, + }); + _ = routes.push(Route { + cidr: IpCidr::new(IpAddress::v4(172, 16, 0, 0), 12), + via_router: IpAddress::v4(lip[0], lip[1], lip[2], lip[3]), + expires_at: None, + preferred_until: None, + }); + }); + } else { + let Some(raddr) = route.dst() else { + continue; + }; + if raddr.atype() != Some(libc::AF_INET) { + continue; + } + + let lip = laddr.hw_address(); + let rip = raddr.hw_address(); + + info!( + "queueing adding {}.{}.{}.{}/{} via {}.{}.{}.{}", + rip[0], + rip[1], + rip[2], + rip[3], + dst.cidrlen(), + lip[0], + lip[1], + lip[2], + lip[3] + ); + + iface.routes_mut().update(|routes| { + info!( + "adding {}.{}.{}.{}/{} via {}.{}.{}.{}", + rip[0], + rip[1], + rip[2], + rip[3], + dst.cidrlen(), + lip[0], + lip[1], + lip[2], + lip[3] + ); _ = routes.push(Route { cidr: IpCidr::new( @@ -99,8 +159,15 @@ async fn main() -> anyhow::Result<()> { } } - let tcp_rx_buffer = tcp::SocketBuffer::new(vec![0; 1500]); - let tcp_tx_buffer = tcp::SocketBuffer::new(vec![0; 1500]); + debug!("routes added:"); + iface.routes_mut().update(|r| { + for r in r { + debug!("\t{r:?}"); + } + }); + + let tcp_rx_buffer = tcp::SocketBuffer::new(vec![0; 65536]); + let tcp_tx_buffer = tcp::SocketBuffer::new(vec![0; 65536]); let tcp_socket = tcp::Socket::new(tcp_rx_buffer, tcp_tx_buffer); let mut sockets = SocketSet::new(vec![]); let tcp_handle = sockets.add(tcp_socket); @@ -117,15 +184,13 @@ async fn main() -> anyhow::Result<()> { socket.connect(iface.context(), (ip, 54248), port)?; let fd = device.as_raw_fd(); - let interest = Interest::WRITABLE + /*let interest = Interest::WRITABLE .add(Interest::READABLE) .add(Interest::ERROR) .add(Interest::PRIORITY); - let afd = AsyncFd::with_interest(fd, interest)?; + let afd = AsyncFd::with_interest(fd, interest)?;*/ let mut tcp_active = false; - let mut tcp_data_sent = false; - let mut tcp_data_recvd = false; loop { let timestamp = Instant::now(); @@ -133,32 +198,36 @@ async fn main() -> anyhow::Result<()> { let socket = sockets.get_mut::(tcp_handle); if socket.is_active() && !tcp_active { - println!("connected!"); + info!("connected!"); + tcp_active = true; } else if !socket.is_active() && tcp_active { - println!("disconnected"); - break Ok(()); + info!("disconnected"); + tcp_active = false; } tcp_active = socket.is_active(); - if !tcp_data_sent && socket.can_send() { - socket.send_slice(b"ping")?; - tcp_data_sent = true; + if !socket.is_active() && !tcp_active { + socket.connect(iface.context(), (ip, 54248), port)?; + info!("connecting..."); } - if !tcp_data_recvd && socket.may_recv() { + + if socket.can_send() { + socket.send_slice(b"ping")?; + info!("sent data!"); + } else if socket.may_recv() { socket.recv(|data| { if !data.is_empty() { match std::str::from_utf8(&data) { - Ok(s) => println!("Data received: {}", s), - Err(_) => println!("Data received: {:?}", data), + Ok(s) => info!("Data received: {}", s), + Err(_) => info!("Data received: {:?}", data), } } (data.len(), data) })?; - tcp_data_recvd = true; } - // phy_wait(fd, iface.poll_delay(timestamp, &sockets))?; + phy_wait(fd, iface.poll_delay(timestamp, &sockets))?; - drop(afd.ready(interest).await?); + // drop(afd.ready(interest).await?); } }