linux is ok for tun and tap
This commit is contained in:
parent
0300eb9ade
commit
2096c3faac
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.cargo.target": null,
|
||||
"rust-analyzer.cargo.features": ["tun"]
|
||||
}
|
||||
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -1524,11 +1524,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.4"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
|
||||
checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"lazy_static",
|
||||
"libm",
|
||||
"num-integer",
|
||||
@ -2092,9 +2091,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.8"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
|
||||
checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
|
||||
@ -9,12 +9,14 @@ use std::{
|
||||
use tracing::error;
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use sdlan_sn_rs::utils::{net_bit_len_to_mask, Mac, BROADCAST_MAC, MULTICAST_MAC};
|
||||
use sdlan_sn_rs::utils::{BROADCAST_MAC, MULTICAST_MAC, Mac, ip_to_string, net_bit_len_to_mask};
|
||||
use tokio::sync::{
|
||||
mpsc::{channel, Receiver, Sender},
|
||||
oneshot,
|
||||
};
|
||||
|
||||
use crate::network::tun::DNS_IP;
|
||||
|
||||
use super::{get_edge, get_route_table, init_arp_wait_list, init_route};
|
||||
|
||||
static GLOBAL_ARP: OnceCell<ArpActor> = OnceCell::new();
|
||||
@ -168,9 +170,9 @@ pub struct ArpInfo {
|
||||
}
|
||||
|
||||
impl ArpInfo {
|
||||
fn lookup_ip_mac(&self, ip: u32) -> ([u8; 6], u32, bool) {
|
||||
fn lookup_ip_mac(&self, ip: u32) -> Option<([u8; 6], u32, bool)> {
|
||||
if ip == BROADCAST_IPADDR {
|
||||
return (BROADCAST_MAC, ip, false);
|
||||
return Some((BROADCAST_MAC, ip, false));
|
||||
}
|
||||
let edge = get_edge();
|
||||
let netbit = edge.device_config.get_net_bit();
|
||||
@ -178,7 +180,7 @@ impl ArpInfo {
|
||||
let host_netmask_reverse = !host_netmask;
|
||||
|
||||
if (ip & host_netmask_reverse) == host_netmask_reverse {
|
||||
return (BROADCAST_MAC, ip, false);
|
||||
return Some((BROADCAST_MAC, ip, false));
|
||||
}
|
||||
|
||||
let first_ip = (ip >> 24) as u8 & 0xff;
|
||||
@ -187,7 +189,7 @@ impl ArpInfo {
|
||||
multi[3] = (ip >> 16) as u8 & 0x7f;
|
||||
multi[4] = (ip >> 8) as u8 & 0xff;
|
||||
multi[5] = (ip) as u8 & 0xff;
|
||||
return (multi, ip, false);
|
||||
return Some((multi, ip, false));
|
||||
}
|
||||
let mut target_ip = 0;
|
||||
|
||||
@ -204,10 +206,11 @@ impl ArpInfo {
|
||||
}
|
||||
}
|
||||
if target_ip == 0 {
|
||||
panic!("target should not route to me");
|
||||
error!("target should not route to me: ip = {}", ip_to_string(&ip));
|
||||
return None;
|
||||
}
|
||||
if let Some(entry) = self.entry.get(&target_ip) {
|
||||
return (entry.hw_addr, target_ip, false);
|
||||
return Some((entry.hw_addr, target_ip, false));
|
||||
}
|
||||
/*
|
||||
for i in 0..ARP_TABLE_SIZE {
|
||||
@ -217,7 +220,7 @@ impl ArpInfo {
|
||||
}
|
||||
}
|
||||
*/
|
||||
return (BROADCAST_MAC, target_ip, true);
|
||||
return Some((BROADCAST_MAC, target_ip, true));
|
||||
}
|
||||
|
||||
fn set_arp(&mut self, mac: [u8; 6], ip: u32) {
|
||||
@ -352,7 +355,9 @@ async fn loop_arp_info(mut rx: Receiver<ArpRequest>) {
|
||||
if let Some(d) = data {
|
||||
match d.req {
|
||||
ArpRequestInfo::Lookup{ip} => {
|
||||
let mac = arp.lookup_ip_mac(ip);
|
||||
let Some(mac) = arp.lookup_ip_mac(ip) else {
|
||||
continue;
|
||||
};
|
||||
if let Err(e) = d.tx.send(ArpResponse::LookupResp {
|
||||
mac: mac.0, ip: mac.1, do_arp_request: mac.2 }
|
||||
) {
|
||||
|
||||
@ -578,6 +578,8 @@ async fn loop_tap(eee: &'static Node, cancel: CancellationToken) {
|
||||
packet.push(0x08);
|
||||
packet.push(0x00);
|
||||
packet.extend_from_slice(&reply);
|
||||
|
||||
/// TODO: check the packet should
|
||||
if let Err(_e) = eee.device.handle_packet_from_net(&packet, &Vec::new()).await {
|
||||
error!("failed to write dns packet to device");
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ use crate::tcp::PacketType;
|
||||
use super::device::{DeviceConfig, Mode};
|
||||
use super::TunTapPacketHandler;
|
||||
|
||||
const DNS_IP: u32 = (100<<24) + (100<<16) + (100<<8) + 100;
|
||||
pub const DNS_IP: u32 = (100<<24) + (100<<16) + (100<<8) + 100;
|
||||
|
||||
const RESOLV_FILE: &'static str = "/etc/resolv.conf";
|
||||
const RESOLV_FILE_BACKUP: &'static str = "/etc/resolv.conf.punchnet.bak";
|
||||
@ -274,9 +274,16 @@ impl TunTapPacketHandler for Iface {
|
||||
impl TunTapPacketHandler for Iface {
|
||||
async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()> {
|
||||
debug!("in tun mode");
|
||||
|
||||
if key.len() == 0 {
|
||||
// got layer2 packet, just write to interface;
|
||||
}
|
||||
// got layer 2 frame
|
||||
match Ethernet2Header::from_slice(&data) {
|
||||
Ok((hdr, rest)) => {
|
||||
use etherparse::ether_type::ARP;
|
||||
use sdlan_sn_rs::utils::is_multi_broadcast;
|
||||
|
||||
if rest.len() < 4 {
|
||||
error!("payload length error");
|
||||
return Ok(());
|
||||
@ -294,6 +301,8 @@ impl TunTapPacketHandler for Iface {
|
||||
let self_mac = edge.device_config.get_mac();
|
||||
|
||||
if hdr.destination != self_mac && !is_multi_broadcast(&hdr.destination) {
|
||||
use sdlan_sn_rs::utils::mac_to_string;
|
||||
|
||||
error!(
|
||||
"packet to [{:?}] not direct to us",
|
||||
mac_to_string(&hdr.destination)
|
||||
@ -302,6 +311,8 @@ impl TunTapPacketHandler for Iface {
|
||||
}
|
||||
|
||||
if hdr.ether_type == ARP {
|
||||
use crate::network::ArpHdr;
|
||||
|
||||
let mut arp = ArpHdr::from_slice(&data);
|
||||
let self_ip = edge.device_config.get_ip();
|
||||
|
||||
@ -320,6 +331,10 @@ impl TunTapPacketHandler for Iface {
|
||||
return Ok(());
|
||||
}
|
||||
if dest_ip == self_ip {
|
||||
use sdlan_sn_rs::utils::mac_to_string;
|
||||
|
||||
use crate::network::{ARP_REPLY, ArpRequestInfo, send_arp_request};
|
||||
|
||||
send_arp_request(ArpRequestInfo::Set {
|
||||
ip: from_ip,
|
||||
mac: arp.shwaddr,
|
||||
@ -369,6 +384,8 @@ impl TunTapPacketHandler for Iface {
|
||||
|
||||
debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes());
|
||||
if dest_ip == self_ip {
|
||||
use crate::network::{ArpRequestInfo, arp_arrived, send_arp_request};
|
||||
|
||||
send_arp_request(ArpRequestInfo::Set {
|
||||
ip: from_ip,
|
||||
mac: arp.shwaddr,
|
||||
@ -382,6 +399,8 @@ impl TunTapPacketHandler for Iface {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
use etherparse::IpHeaders;
|
||||
|
||||
match IpHeaders::from_slice(rest) {
|
||||
Ok((iphdr, _)) => {
|
||||
let Some(ipv4) = iphdr.ipv4() else {
|
||||
@ -391,6 +410,8 @@ impl TunTapPacketHandler for Iface {
|
||||
let ip = u32::from_be_bytes(ipv4.0.source);
|
||||
let mac = hdr.source;
|
||||
if !is_multi_broadcast(&mac) {
|
||||
use crate::network::{ArpRequestInfo, send_arp_request};
|
||||
|
||||
send_arp_request(ArpRequestInfo::Set { ip, mac }).await;
|
||||
}
|
||||
}
|
||||
@ -427,12 +448,16 @@ impl TunTapPacketHandler for Iface {
|
||||
data: Vec<u8>,
|
||||
encrypt_key: &[u8],
|
||||
) -> std::io::Result<()> {
|
||||
use etherparse::IpHeaders;
|
||||
|
||||
let eee = get_edge();
|
||||
|
||||
let src_mac = eee.device_config.get_mac();
|
||||
|
||||
match IpHeaders::from_slice(&data) {
|
||||
Ok((iphdr, _payload)) => {
|
||||
use crate::network::{ArpRequestInfo, ArpResponse, send_arp_request};
|
||||
|
||||
let Some(ipv4hdr) = iphdr.ipv4() else {
|
||||
debug!("ipv6 packet ignored");
|
||||
return Ok(());
|
||||
@ -451,13 +476,29 @@ impl TunTapPacketHandler for Iface {
|
||||
debug!("drop tun packet due to not authed");
|
||||
return Ok(());
|
||||
}
|
||||
if dstip == DNS_IP {
|
||||
// should do the dns request
|
||||
println!("request for dns");
|
||||
let addr = format!("{}:15353", eee.server_ip);
|
||||
println!("send dns to {}", addr);
|
||||
if let Err(e) = eee.udp_sock_for_dns.send_to(&data, &addr).await {
|
||||
error!("failed to send request to 15353: {}", e);
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await {
|
||||
ArpResponse::LookupResp {
|
||||
mac,
|
||||
ip,
|
||||
do_arp_request,
|
||||
} => {
|
||||
use crate::utils::caculate_crc;
|
||||
|
||||
if do_arp_request {
|
||||
use sdlan_sn_rs::utils::BROADCAST_MAC;
|
||||
|
||||
use crate::network::{add_to_arp_wait_list, generate_arp_request};
|
||||
|
||||
add_to_arp_wait_list(dstip, data);
|
||||
debug!(
|
||||
"find ip: {:?} => {:?}",
|
||||
|
||||
@ -58,7 +58,7 @@ impl Iface {
|
||||
Ok(content.len())
|
||||
}
|
||||
|
||||
pub fn reload_config(&self, device_config: &DeviceConfig) {
|
||||
pub fn reload_config(&self, device_config: &DeviceConfig, network_domain: &str) {
|
||||
let netbit = device_config.get_net_bit();
|
||||
let ip = device_config.get_ip();
|
||||
if netbit == 0 || ip == 0 {
|
||||
@ -113,6 +113,13 @@ impl Iface {
|
||||
error!("failed to run netsh2: {}", e.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if let Err(e) = set_dns(&self.name, network_domain) {
|
||||
println!("failed to set dns: {:?}", e);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,3 +412,29 @@ pub fn new_iface(name: &str, _mode: Mode) -> Iface {
|
||||
pub fn get_install_channel() -> String {
|
||||
"windows".to_owned()
|
||||
}
|
||||
|
||||
pub fn set_dns(name: &str, network_domain: &str) -> std::io::Result<()>{
|
||||
Command::new("netsh")
|
||||
.arg("dnsclient")
|
||||
.arg("set")
|
||||
.arg("dnsserver")
|
||||
.arg(&format!("name=\"{}\"", name))
|
||||
.arg("source=static")
|
||||
.arg("address=100.100.100.100")
|
||||
.arg("validate=yes").output()?;
|
||||
|
||||
Command::new("netsh")
|
||||
.arg("interface")
|
||||
.arg("ipv4")
|
||||
.arg("set")
|
||||
.arg("dns")
|
||||
.arg("suffix")
|
||||
.arg(&format!("name=\"{}\"", name))
|
||||
.arg(&format!("suffix=\"{}\"", network_domain))
|
||||
.output()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn restore_dns() {
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user