diff --git a/src/network/arp.rs b/src/network/arp.rs index d6c3063..344dc77 100644 --- a/src/network/arp.rs +++ b/src/network/arp.rs @@ -105,10 +105,10 @@ impl ArpHdr { result.extend_from_slice(&self.dhwaddr); result.extend_from_slice(&self.dipaddr[0].to_be_bytes()); result.extend_from_slice(&self.dipaddr[1].to_be_bytes()); - result.extend_from_slice(&[0; 18]); + // result.extend_from_slice(&[0; 18]); - let crc = CRC_HASH.checksum(&result).to_be_bytes(); - result.extend_from_slice(&crc); + // let crc = CRC_HASH.checksum(&result).to_be_bytes(); + // result.extend_from_slice(&crc); result } diff --git a/src/network/tun_win.rs b/src/network/tun_win.rs index 8b165e5..67c2e15 100644 --- a/src/network/tun_win.rs +++ b/src/network/tun_win.rs @@ -1,12 +1,28 @@ -use sdlan_sn_rs::utils::{ip_to_string, net_bit_len_to_mask}; +use etherparse::ether_type::ARP; +use etherparse::{Ethernet2Header, IpHeaders}; +use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL; +use sdlan_sn_rs::utils::{ + aes_encrypt, ip_to_string, is_multi_broadcast, net_bit_len_to_mask, BROADCAST_MAC, +}; use std::io::{Error, ErrorKind}; use std::os::windows::process::CommandExt; use std::process::Command; +use std::sync::atomic::Ordering; use std::sync::Arc; +use tracing::{debug, error, info}; use wintun; -use tracing::{error, debug}; -use super::device::{Mode, DeviceConfig}; +use crate::get_edge; +use crate::network::{ + generate_arp_request, send_arp_request, send_packet_to_net, ArpHdr, ArpRequestInfo, + ArpResponse, ARP_REPLY, +}; +use crate::pb::{encode_to_udp_message, SdlData}; +use crate::tcp::PacketType; +use crate::utils::{mac_to_string, CRC_HASH}; + +use super::device::{DeviceConfig, Mode}; +use super::TunTapPacketHandler; pub struct Iface { name: String, @@ -14,7 +30,7 @@ pub struct Iface { session: Arc, } -impl Iface { +impl Iface { pub fn recv(&self, buf: &mut [u8]) -> std::io::Result { let Ok(pkt) = self.session.receive_blocking() else { return Err(Error::new(ErrorKind::Other, "failed to receive")); @@ -77,7 +93,273 @@ impl Iface { } } -fn create_wintun(path: &str,name: &str) -> Iface { +impl TunTapPacketHandler for Iface { + async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()> { + // got layer 2 frame + match Ethernet2Header::from_slice(&data) { + Ok((hdr, rest)) => { + if rest.len() < 4 { + error!("payload length error"); + return Ok(()); + } + let crc_code = &rest[(rest.len() - 4)..rest.len()]; + + // let rest = &rest[..(rest.len() - 4)]; + + // let crc_hash: crc::Crc = crc::Crc::::new(&crc::CRC_32_CKSUM); + // let ck = CRC_HASH.checksum(&data[..(data.len()) - 4]); + // let sent_ck = u32::from_be_bytes(crc_code.try_into().unwrap()); + // debug!("ck = {}, sent_ck = {}", ck, sent_ck); + + debug!("ip size is {}", rest.len()); + let edge = get_edge(); + let self_mac = edge.device_config.get_mac(); + + /* + if hdr.destination != self_mac && hdr.destination != BROADCAST_MAC { + error!( + "packet to [{:?}] not direct to us", + mac_to_string(&hdr.destination) + ); + return; + } + */ + + if hdr.ether_type == ARP { + let mut arp = ArpHdr::from_slice(&data); + let self_ip = edge.device_config.get_ip(); + + println!("self_ip: {:?}", self_ip.to_be_bytes()); + let from_ip = ((arp.sipaddr[0] as u32) << 16) + arp.sipaddr[1] as u32; + println!("from_ip: {:?}", from_ip.to_be_bytes()); + let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32; + println!("dest_ip: {:?}", dest_ip.to_be_bytes()); + + match arp.opcode { + ARP_REQUEST => { + // handle ARP REQUEST + debug!("got ARP REQUEST"); + if arp.ethhdr.dest != [0xff; 6] { + println!("ARP REQUEST not broadcast"); + return Ok(()); + } + if dest_ip == self_ip { + send_arp_request(ArpRequestInfo::Set { + ip: from_ip, + mac: arp.shwaddr, + }) + .await; + // target to us + arp.opcode = ARP_REPLY; + arp.dhwaddr = arp.shwaddr; + arp.shwaddr = self_mac; + arp.ethhdr.src = self_mac; + arp.ethhdr.dest = arp.dhwaddr; + + arp.dipaddr = arp.sipaddr; + + arp.sipaddr = + [((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16]; + + let data = arp.marshal_to_bytes(); + let Ok(encrypted) = aes_encrypt(key, &data) else { + error!("failed to encrypt arp reply"); + return Ok(()); + }; + + let data = SdlData { + is_p2p: true, + ttl: 2, + network_id: edge.network_id.load(Ordering::Relaxed), + src_mac: Vec::from(self_mac), + dst_mac: Vec::from(arp.dhwaddr), + data: encrypted, + }; + + let v = encode_to_udp_message(Some(data), PacketType::Data as u8) + .unwrap(); + println!( + "xxxx send arp reply to [{}], selfmac=[{}]", + mac_to_string(&arp.dhwaddr), + mac_to_string(&self_mac) + ); + send_packet_to_net(edge, arp.dhwaddr, &v, 0).await; + // send_to_sock(edge, &v, from_sock); + // edge.sock.send(v).await; + } + } + ARP_REPLY => { + println!("got arp reply",); + + println!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes()); + if dest_ip == self_ip { + send_arp_request(ArpRequestInfo::Set { + ip: from_ip, + mac: arp.shwaddr, + }) + .await; + } + } + other => { + println!("unknown arp type info"); + } + } + } else { + match IpHeaders::from_slice(rest) { + Ok((iphdr, _)) => { + let Some(ipv4) = iphdr.ipv4() else { + error!("not ipv4, dropping"); + return Ok(()); + }; + let ip = u32::from_be_bytes(ipv4.0.source); + let mac = hdr.source; + if !is_multi_broadcast(&mac) { + send_arp_request(ArpRequestInfo::Set { ip, mac }).await; + } + } + Err(e) => { + error!("failed to parse ip header, dropping"); + return Ok(()); + } + } + + println!("got ip packet"); + println!("got data: {:?}", rest); + match edge.device.send(rest) { + Ok(size) => { + debug!("send to tun {} bytes", size); + } + Err(e) => { + error!("failed to send to device: {}", e.to_string()); + } + } + // edge.tun.send_data_to_tun(Vec::from(hdr.1)).await; + } + } + Err(e) => { + error!("failed to parse tap packet: {}", e); + return Ok(()); + } + } + + Ok(()) + } + + async fn handle_packet_from_device( + &self, + data: &[u8], + encrypt_key: &[u8], + ) -> std::io::Result<()> { + let eee = get_edge(); + + let src_mac = eee.device_config.get_mac(); + + match IpHeaders::from_slice(&data) { + Ok((iphdr, _payload)) => { + let Some(ipv4hdr) = iphdr.ipv4() else { + debug!("ipv6 packet ignored"); + return Ok(()); + }; + let dstip = u32::from_be_bytes(ipv4hdr.0.destination); + debug!("packet dst ip: {:?}", ipv4hdr.0.destination); + let src = u32::from_be_bytes(ipv4hdr.0.source); + debug!("packet src ip: {:?}", ipv4hdr.0.source); + // packet should be sent to dev + debug!("got {} bytes from tun", data.len()); + if (!eee.config.allow_routing) && (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(()); + } + match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await { + ArpResponse::LookupResp { + mac, + ip, + do_arp_request, + } => { + if do_arp_request { + println!( + "find ip: {:?} => {:?}", + src.to_be_bytes(), + dstip.to_be_bytes() + ); + let arp_msg = + generate_arp_request(src_mac, ip, eee.device_config.get_ip()); + let Ok(encrypted) = aes_encrypt(&encrypt_key, &arp_msg) else { + error!("failed to encrypt arp request"); + return Ok(()); + }; + // println!("arp_msg: {:?}", arp_msg); + let data = SdlData { + network_id: eee.network_id.load(Ordering::Relaxed), + src_mac: Vec::from(src_mac), + dst_mac: Vec::from([0xff; 6]), + is_p2p: true, + ttl: SDLAN_DEFAULT_TTL as u32, + data: encrypted, + }; + let data = + encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + debug!("sending arp"); + // let data = marshal_message(&data); + send_packet_to_net(eee, BROADCAST_MAC, &data, arp_msg.len() as u64) + .await; + // edge.sock.send(data).await; + // println!("should send arp"); + return Ok(()); + } + + // prepend the ether header + 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); + packet.extend_from_slice(ðerheader.to_bytes()[..]); + packet.extend_from_slice(&data); + // let crc = CRC_HASH.checksum(&packet); + // 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 { + 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: Vec::from(encrypted), + }; + 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; + // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); + println!( + "{:?} => {:?}, size={}", + ipv4hdr.0.source, ipv4hdr.0.destination, size + ); + } + _ => {} + } + } + Err(e) => { + error!("failed to parse ip packet: {}", e.to_string()); + } + } + Ok(()) + } +} + +fn create_wintun(path: &str, name: &str) -> Iface { let wt = unsafe { wintun::load_from_path(path) }.expect("failed to load wintun"); let adapter = match wintun::Adapter::open(&wt, name) { @@ -86,7 +368,11 @@ fn create_wintun(path: &str,name: &str) -> Iface { .expect("failed to create wintun adapter"), }; let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap()); - Iface { _adapter: adapter, session, name: name.to_owned()} + Iface { + _adapter: adapter, + session, + name: name.to_owned(), + } } pub fn new_iface(name: &str, _mode: Mode) -> Iface { @@ -96,4 +382,4 @@ pub fn new_iface(name: &str, _mode: Mode) -> Iface { pub fn get_install_channel() -> String { "windows".to_owned() -} \ No newline at end of file +}