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]]
|
[[package]]
|
||||||
name = "num-bigint-dig"
|
name = "num-bigint-dig"
|
||||||
version = "0.8.4"
|
version = "0.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
|
checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libm",
|
"libm",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@ -2092,9 +2091,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.8"
|
version = "0.9.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
|
checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"digest",
|
"digest",
|
||||||
|
|||||||
@ -9,12 +9,14 @@ use std::{
|
|||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use once_cell::sync::OnceCell;
|
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::{
|
use tokio::sync::{
|
||||||
mpsc::{channel, Receiver, Sender},
|
mpsc::{channel, Receiver, Sender},
|
||||||
oneshot,
|
oneshot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::network::tun::DNS_IP;
|
||||||
|
|
||||||
use super::{get_edge, get_route_table, init_arp_wait_list, init_route};
|
use super::{get_edge, get_route_table, init_arp_wait_list, init_route};
|
||||||
|
|
||||||
static GLOBAL_ARP: OnceCell<ArpActor> = OnceCell::new();
|
static GLOBAL_ARP: OnceCell<ArpActor> = OnceCell::new();
|
||||||
@ -168,9 +170,9 @@ pub struct ArpInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
if ip == BROADCAST_IPADDR {
|
||||||
return (BROADCAST_MAC, ip, false);
|
return Some((BROADCAST_MAC, ip, false));
|
||||||
}
|
}
|
||||||
let edge = get_edge();
|
let edge = get_edge();
|
||||||
let netbit = edge.device_config.get_net_bit();
|
let netbit = edge.device_config.get_net_bit();
|
||||||
@ -178,7 +180,7 @@ impl ArpInfo {
|
|||||||
let host_netmask_reverse = !host_netmask;
|
let host_netmask_reverse = !host_netmask;
|
||||||
|
|
||||||
if (ip & host_netmask_reverse) == host_netmask_reverse {
|
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;
|
let first_ip = (ip >> 24) as u8 & 0xff;
|
||||||
@ -187,7 +189,7 @@ impl ArpInfo {
|
|||||||
multi[3] = (ip >> 16) as u8 & 0x7f;
|
multi[3] = (ip >> 16) as u8 & 0x7f;
|
||||||
multi[4] = (ip >> 8) as u8 & 0xff;
|
multi[4] = (ip >> 8) as u8 & 0xff;
|
||||||
multi[5] = (ip) as u8 & 0xff;
|
multi[5] = (ip) as u8 & 0xff;
|
||||||
return (multi, ip, false);
|
return Some((multi, ip, false));
|
||||||
}
|
}
|
||||||
let mut target_ip = 0;
|
let mut target_ip = 0;
|
||||||
|
|
||||||
@ -204,10 +206,11 @@ impl ArpInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if target_ip == 0 {
|
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) {
|
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 {
|
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) {
|
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 {
|
if let Some(d) = data {
|
||||||
match d.req {
|
match d.req {
|
||||||
ArpRequestInfo::Lookup{ip} => {
|
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 {
|
if let Err(e) = d.tx.send(ArpResponse::LookupResp {
|
||||||
mac: mac.0, ip: mac.1, do_arp_request: mac.2 }
|
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(0x08);
|
||||||
packet.push(0x00);
|
packet.push(0x00);
|
||||||
packet.extend_from_slice(&reply);
|
packet.extend_from_slice(&reply);
|
||||||
|
|
||||||
|
/// TODO: check the packet should
|
||||||
if let Err(_e) = eee.device.handle_packet_from_net(&packet, &Vec::new()).await {
|
if let Err(_e) = eee.device.handle_packet_from_net(&packet, &Vec::new()).await {
|
||||||
error!("failed to write dns packet to device");
|
error!("failed to write dns packet to device");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ use crate::tcp::PacketType;
|
|||||||
use super::device::{DeviceConfig, Mode};
|
use super::device::{DeviceConfig, Mode};
|
||||||
use super::TunTapPacketHandler;
|
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: &'static str = "/etc/resolv.conf";
|
||||||
const RESOLV_FILE_BACKUP: &'static str = "/etc/resolv.conf.punchnet.bak";
|
const RESOLV_FILE_BACKUP: &'static str = "/etc/resolv.conf.punchnet.bak";
|
||||||
@ -274,9 +274,16 @@ impl TunTapPacketHandler for Iface {
|
|||||||
impl TunTapPacketHandler for Iface {
|
impl TunTapPacketHandler for Iface {
|
||||||
async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()> {
|
async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()> {
|
||||||
debug!("in tun mode");
|
debug!("in tun mode");
|
||||||
|
|
||||||
|
if key.len() == 0 {
|
||||||
|
// got layer2 packet, just write to interface;
|
||||||
|
}
|
||||||
// got layer 2 frame
|
// got layer 2 frame
|
||||||
match Ethernet2Header::from_slice(&data) {
|
match Ethernet2Header::from_slice(&data) {
|
||||||
Ok((hdr, rest)) => {
|
Ok((hdr, rest)) => {
|
||||||
|
use etherparse::ether_type::ARP;
|
||||||
|
use sdlan_sn_rs::utils::is_multi_broadcast;
|
||||||
|
|
||||||
if rest.len() < 4 {
|
if rest.len() < 4 {
|
||||||
error!("payload length error");
|
error!("payload length error");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -294,6 +301,8 @@ impl TunTapPacketHandler for Iface {
|
|||||||
let self_mac = edge.device_config.get_mac();
|
let self_mac = edge.device_config.get_mac();
|
||||||
|
|
||||||
if hdr.destination != self_mac && !is_multi_broadcast(&hdr.destination) {
|
if hdr.destination != self_mac && !is_multi_broadcast(&hdr.destination) {
|
||||||
|
use sdlan_sn_rs::utils::mac_to_string;
|
||||||
|
|
||||||
error!(
|
error!(
|
||||||
"packet to [{:?}] not direct to us",
|
"packet to [{:?}] not direct to us",
|
||||||
mac_to_string(&hdr.destination)
|
mac_to_string(&hdr.destination)
|
||||||
@ -302,6 +311,8 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hdr.ether_type == ARP {
|
if hdr.ether_type == ARP {
|
||||||
|
use crate::network::ArpHdr;
|
||||||
|
|
||||||
let mut arp = ArpHdr::from_slice(&data);
|
let mut arp = ArpHdr::from_slice(&data);
|
||||||
let self_ip = edge.device_config.get_ip();
|
let self_ip = edge.device_config.get_ip();
|
||||||
|
|
||||||
@ -320,6 +331,10 @@ impl TunTapPacketHandler for Iface {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if dest_ip == self_ip {
|
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 {
|
send_arp_request(ArpRequestInfo::Set {
|
||||||
ip: from_ip,
|
ip: from_ip,
|
||||||
mac: arp.shwaddr,
|
mac: arp.shwaddr,
|
||||||
@ -369,6 +384,8 @@ impl TunTapPacketHandler for Iface {
|
|||||||
|
|
||||||
debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes());
|
debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes());
|
||||||
if dest_ip == self_ip {
|
if dest_ip == self_ip {
|
||||||
|
use crate::network::{ArpRequestInfo, arp_arrived, send_arp_request};
|
||||||
|
|
||||||
send_arp_request(ArpRequestInfo::Set {
|
send_arp_request(ArpRequestInfo::Set {
|
||||||
ip: from_ip,
|
ip: from_ip,
|
||||||
mac: arp.shwaddr,
|
mac: arp.shwaddr,
|
||||||
@ -382,6 +399,8 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
use etherparse::IpHeaders;
|
||||||
|
|
||||||
match IpHeaders::from_slice(rest) {
|
match IpHeaders::from_slice(rest) {
|
||||||
Ok((iphdr, _)) => {
|
Ok((iphdr, _)) => {
|
||||||
let Some(ipv4) = iphdr.ipv4() else {
|
let Some(ipv4) = iphdr.ipv4() else {
|
||||||
@ -391,6 +410,8 @@ impl TunTapPacketHandler for Iface {
|
|||||||
let ip = u32::from_be_bytes(ipv4.0.source);
|
let ip = u32::from_be_bytes(ipv4.0.source);
|
||||||
let mac = hdr.source;
|
let mac = hdr.source;
|
||||||
if !is_multi_broadcast(&mac) {
|
if !is_multi_broadcast(&mac) {
|
||||||
|
use crate::network::{ArpRequestInfo, send_arp_request};
|
||||||
|
|
||||||
send_arp_request(ArpRequestInfo::Set { ip, mac }).await;
|
send_arp_request(ArpRequestInfo::Set { ip, mac }).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -427,12 +448,16 @@ impl TunTapPacketHandler for Iface {
|
|||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
encrypt_key: &[u8],
|
encrypt_key: &[u8],
|
||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
|
use etherparse::IpHeaders;
|
||||||
|
|
||||||
let eee = get_edge();
|
let eee = get_edge();
|
||||||
|
|
||||||
let src_mac = eee.device_config.get_mac();
|
let src_mac = eee.device_config.get_mac();
|
||||||
|
|
||||||
match IpHeaders::from_slice(&data) {
|
match IpHeaders::from_slice(&data) {
|
||||||
Ok((iphdr, _payload)) => {
|
Ok((iphdr, _payload)) => {
|
||||||
|
use crate::network::{ArpRequestInfo, ArpResponse, send_arp_request};
|
||||||
|
|
||||||
let Some(ipv4hdr) = iphdr.ipv4() else {
|
let Some(ipv4hdr) = iphdr.ipv4() else {
|
||||||
debug!("ipv6 packet ignored");
|
debug!("ipv6 packet ignored");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -451,13 +476,29 @@ impl TunTapPacketHandler for Iface {
|
|||||||
debug!("drop tun packet due to not authed");
|
debug!("drop tun packet due to not authed");
|
||||||
return Ok(());
|
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 {
|
match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await {
|
||||||
ArpResponse::LookupResp {
|
ArpResponse::LookupResp {
|
||||||
mac,
|
mac,
|
||||||
ip,
|
ip,
|
||||||
do_arp_request,
|
do_arp_request,
|
||||||
} => {
|
} => {
|
||||||
|
use crate::utils::caculate_crc;
|
||||||
|
|
||||||
if do_arp_request {
|
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);
|
add_to_arp_wait_list(dstip, data);
|
||||||
debug!(
|
debug!(
|
||||||
"find ip: {:?} => {:?}",
|
"find ip: {:?} => {:?}",
|
||||||
|
|||||||
@ -58,7 +58,7 @@ impl Iface {
|
|||||||
Ok(content.len())
|
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 netbit = device_config.get_net_bit();
|
||||||
let ip = device_config.get_ip();
|
let ip = device_config.get_ip();
|
||||||
if netbit == 0 || ip == 0 {
|
if netbit == 0 || ip == 0 {
|
||||||
@ -113,6 +113,13 @@ impl Iface {
|
|||||||
error!("failed to run netsh2: {}", e.to_string());
|
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 {
|
pub fn get_install_channel() -> String {
|
||||||
"windows".to_owned()
|
"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