From cf847e32419270ecf09acbad5857b4cee4a8a328 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 15 Apr 2026 11:53:04 +0800 Subject: [PATCH] tun_win is set in dns --- .vscode/settings.json | 4 +- src/bin/punchnet/main.rs | 5 -- src/network/tun_linux.rs | 4 +- src/network/tun_win.rs | 147 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 147 insertions(+), 13 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 442c566..9eb94d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { - // "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu", - "rust-analyzer.cargo.features": ["tun"] + "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu", + // "rust-analyzer.cargo.features": ["tun"] } \ No newline at end of file diff --git a/src/bin/punchnet/main.rs b/src/bin/punchnet/main.rs index 00b7a9d..9c02d07 100755 --- a/src/bin/punchnet/main.rs +++ b/src/bin/punchnet/main.rs @@ -429,7 +429,6 @@ fn main() { #[cfg(target_os = "windows")] run_it(cmd, client_id, allow_routing, mac, system, version); - } fn run_it(cmd: CommandLineInput2, client_id: String, allow_routing: bool, mac: Mac, system: &str, version: &str) { @@ -442,9 +441,7 @@ fn run_it(cmd: CommandLineInput2, client_id: String, allow_routing: bool, mac: M eprintln!("not logged in, should login with user/pass or token first"); process::exit(-2); } - let remembered = remembered_token.unwrap(); - let connect_info = parse_connect_result( connect(TEST_PREFIX, &client_id, &remembered.access_token).await ); @@ -483,8 +480,6 @@ fn run_it(cmd: CommandLineInput2, client_id: String, allow_routing: bool, mac: M process::exit(-1); } } - - } pub fn delete_pid_file() { diff --git a/src/network/tun_linux.rs b/src/network/tun_linux.rs index 301a655..4c9d323 100755 --- a/src/network/tun_linux.rs +++ b/src/network/tun_linux.rs @@ -757,11 +757,9 @@ impl TunTapPacketHandler for Iface { if let Some(transport) = sliced_packet.transport { match transport { TransportSlice::Tcp(tcp) => { - + // just fall back } TransportSlice::Udp(udp) => { - // - if dstip == DNS_IP { // should do the dns request // println!("request for dns"); diff --git a/src/network/tun_win.rs b/src/network/tun_win.rs index 745ef9b..0fe3e24 100755 --- a/src/network/tun_win.rs +++ b/src/network/tun_win.rs @@ -1,6 +1,6 @@ use bytes::{Bytes, BytesMut}; use etherparse::ether_type::ARP; -use etherparse::{Ethernet2Header, IpHeaders}; +use etherparse::{Ethernet2Header, IpHeaders, NetSlice, SlicedPacket, TransportSlice}; use ipnet::Ipv4Net; use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL; use sdlan_sn_rs::utils::{ @@ -17,7 +17,7 @@ use wintun; use crate::{caculate_crc, get_edge}; use crate::network::{ - ARP_REPLY, ARP_REQUEST, ArpHdr, DNS_IP, Node, form_ethernet_packet, generate_arp_request, send_packet_to_net + ARP_REPLY, ARP_REQUEST, ArpHdr, DNS_IP, Node, form_ethernet_packet, generate_arp_request, parse_dns_payload, send_packet_to_net }; use crate::pb::{SdlArpResponse, SdlData, encode_to_udp_message}; use crate::tcp::PacketType; @@ -450,6 +450,147 @@ impl TunTapPacketHandler for Iface { // Ok(()) // } + async fn handle_packet_from_device( + &self, + mut header: BytesMut, + ) -> std::io::Result<()> { + use etherparse::IpHeaders; + + let eee = get_edge(); + + let src_mac = eee.device_config.get_mac(); + + let data = header.split_off(14); + + let Ok(sliced_packet) = SlicedPacket::from_ip(&data) else { + error!("failed to parse ip packet"); + return Ok(()); + }; + let Some(net) = sliced_packet.net else { + error!("failed to get ip packet"); + return Ok(()); + }; + + + match net { + NetSlice::Ipv4(ipv4) => { + + let dstip = u32::from_be_bytes(ipv4.header().destination()); + // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); + debug!("packet dst ip: {:?}", ip_to_string(&dstip)); + let src = u32::from_be_bytes(ipv4.header().source()); + //let src = u32::from_be_bytes(ipv4hdr.0.source); + debug!("packet src ip: {:?}", ip_to_string(&src)); + // packet should be sent to dev + debug!("got {} bytes from tun", data.len()); + if (!eee.config.allow_routing.load(Ordering::Relaxed)) && (src != eee.device_config.get_ip()) { + info!("dropping routed packet"); + return Ok(()); + } + if !eee.is_authorized() { + debug!("drop tun packet due to not authed"); + return Ok(()); + } + + if let Some(transport) = sliced_packet.transport { + match transport { + TransportSlice::Tcp(tcp) => { + // just fall back + } + TransportSlice::Udp(udp) => { + if dstip == DNS_IP { + // should do the dns request + // println!("request for dns"); + + parse_dns_payload(eee, udp.payload(), &data, src, udp.source_port()).await; + // edge.udp_sock_for_dns.send_to() + return Ok(()); + } + } + _other => { + + } + } + + match eee.arp_table.get(dstip) { + Some(mac) => { + let pkt_size = data.len() + 14; + let mut etherheader = Ethernet2Header::default(); + etherheader.destination = mac; + etherheader.ether_type = etherparse::EtherType::IPV4; + etherheader.source = src_mac; + // let mut packet = Vec::with_capacity(14 + data.len() + 4); + + header.copy_from_slice(ðerheader.to_bytes()[..]); + + let crc = caculate_crc(&data); + header.unsplit(data); + + + // packet.extend_from_slice(ðerheader.to_bytes()[..]); + // packet.extend_from_slice(&data); + header.extend_from_slice(&crc.to_be_bytes()); + // packet.extend_from_slice(&crc.to_be_bytes()); + + // let pkt_size = packet.len(); + // println!("sending data with mac"); + + // let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else { + let Ok(encrypted) = eee.encryptor.load().encrypt(&header) else { + error!("failed to encrypt packet request"); + return Ok(()); + }; + + let data = SdlData { + is_p2p: true, + network_id: eee.network_id.load(Ordering::Relaxed), + ttl: SDLAN_DEFAULT_TTL as u32, + src_mac: Vec::from(src_mac), + dst_mac: Vec::from(mac), + data: Bytes::from(encrypted), + session_token: eee.session_token.get(), + identity_id: eee.identity_id.load(), + }; + let msg = + encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + let size = msg.len(); + send_packet_to_net(eee, mac, &msg, pkt_size as u64).await; + } + None => { + header.unsplit(data); + eee.arp_table.add_to_arp_wait_list(dstip, header); + debug!( + "find ip: {:?} => {:?}", + src.to_be_bytes(), + dstip.to_be_bytes() + ); + debug!("no mac found for ip {:?}, sending arp request", dstip.to_be_bytes()); + // let _ = eee.send_arp_request(dstip, dstip).await; + + if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) { + let _ = eee.send_arp_request(dstip, dstip).await; + } else { + if let Some((_, real_ip)) = eee.route_table.lookup(dstip) { + let real_ip = u32::from_be_bytes(real_ip.octets()); + let _ = eee.send_arp_request(dstip, real_ip).await; + } + } + + } + } + + } + } + NetSlice::Ipv6(ipv6) => { + + } + } + Ok(()) + } + + + + /* async fn handle_packet_from_device( &self, mut header: BytesMut, @@ -569,7 +710,7 @@ impl TunTapPacketHandler for Iface { } } Ok(()) - } + }*/ } fn create_wintun(path: &str, name: &str) -> Iface {