支持tap网卡,优化tun网卡配置
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
use crate::tun_device::{TunReader, TunWriter};
|
||||
|
||||
pub type TapReader = TunReader;
|
||||
pub type TapWriter = TunWriter;
|
||||
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::Arc;
|
||||
use tun::Device;
|
||||
use parking_lot::Mutex;
|
||||
use std::io;
|
||||
|
||||
pub fn create_tap(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
) -> io::Result<(TunWriter, TunReader, [u8; 6])> {
|
||||
println!("========TAP网卡配置========");
|
||||
let mut config = tun::Configuration::default();
|
||||
|
||||
config
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.mtu(1420)
|
||||
.layer(tun::Layer::L2)
|
||||
// .queues(2) 用多个队列有兼容性问题
|
||||
.up();
|
||||
|
||||
let dev = tun::create(&config).unwrap();
|
||||
let name = dev.name();
|
||||
println!("name:{:?}", name);
|
||||
let packet_information = dev.has_packet_information();
|
||||
let queue = dev.queue(0).unwrap();
|
||||
let reader = queue.reader();
|
||||
let writer = queue.writer();
|
||||
let get_mac_cmd = format!("cat /sys/class/net/{}/address", name);
|
||||
let mac_out = std::process::Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(get_mac_cmd)
|
||||
.output()
|
||||
.expect("sh exec error!");
|
||||
if !mac_out.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("获取mac地址错误: {:?}", mac_out)));
|
||||
}
|
||||
let mac_str = String::from_utf8(mac_out.stdout).unwrap();
|
||||
let mut mac = [0; 6];
|
||||
let mut split = mac_str.split(":");
|
||||
for i in 0..6 {
|
||||
mac[i] = u8::from_str_radix(&split.next().unwrap()[..2], 16).unwrap();
|
||||
}
|
||||
println!("mac:{:?}", mac);
|
||||
println!("========TAP网卡配置========");
|
||||
Ok((
|
||||
TunWriter(writer, packet_information, Arc::new(Mutex::new(dev))),
|
||||
TunReader(reader, packet_information),
|
||||
mac
|
||||
))
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
use crate::tun_device::{TunReader, TunWriter};
|
||||
|
||||
pub type TapReader = TunReader;
|
||||
pub type TapWriter = TunWriter;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
pub fn create_tap(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
) -> crate::error::Result<(TapWriter, TapReader, [u8; 6])> {
|
||||
unimplemented!()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#[cfg(target_os = "windows")]
|
||||
mod windows;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
mod linux;
|
||||
#[cfg(target_os = "macos")]
|
||||
mod mac;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use mac::{TapWriter, TapReader};
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use mac::create_tap;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub use linux::{TapWriter, TapReader};
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub use linux::create_tap;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use windows::create_tap;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use windows::delete_tap;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use windows::{TapReader, TapWriter};
|
||||
@@ -0,0 +1,100 @@
|
||||
use std::io;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use win_tun_tap::{IFace, TapDevice};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TapWriter(Arc<TapDevice>, Arc<Mutex<()>>);
|
||||
|
||||
impl TapWriter {
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
pub fn change_ip(
|
||||
&self,
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
old_netmask: Ipv4Addr,
|
||||
old_gateway: Ipv4Addr,
|
||||
) -> io::Result<()> {
|
||||
if let Err(e) =
|
||||
self.0.delete_route(dest(old_gateway, old_gateway), old_netmask, old_gateway)
|
||||
{
|
||||
log::warn!("{:?}", e);
|
||||
}
|
||||
self.0.set_ip(address, netmask)?;
|
||||
self.0.add_route(dest(gateway, netmask), netmask, gateway)
|
||||
}
|
||||
pub fn close(&self) -> io::Result<()> {
|
||||
self.0.shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
fn dest(ip: Ipv4Addr, mask: Ipv4Addr) -> Ipv4Addr {
|
||||
let ip = ip.octets();
|
||||
let mask = mask.octets();
|
||||
Ipv4Addr::from([
|
||||
ip[0] & mask[0],
|
||||
ip[1] & mask[1],
|
||||
ip[2] & mask[2],
|
||||
ip[3] & mask[3],
|
||||
])
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TapReader(Arc<TapDevice>);
|
||||
|
||||
impl TapReader {
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub const TAP_INTERFACE_NAME: &str = "Switch-Tap-V1";
|
||||
|
||||
pub fn create_tap(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
) -> io::Result<(TapWriter, TapReader, [u8; 6])> {
|
||||
println!("========TAP网卡配置========");
|
||||
let tap_device = match TapDevice::open(TAP_INTERFACE_NAME) {
|
||||
Ok(tap_device) => tap_device,
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e);
|
||||
let tap_device = TapDevice::create()?;
|
||||
tap_device.set_name(TAP_INTERFACE_NAME)?;
|
||||
tap_device
|
||||
}
|
||||
};
|
||||
let mac = tap_device.get_mac()?;
|
||||
println!("name:{:?}", tap_device.get_name()?);
|
||||
println!("version:{:x?}", tap_device.get_version()?);
|
||||
println!("mac:{:x?}", mac);
|
||||
tap_device.set_ip(address, netmask)?;
|
||||
tap_device.set_mtu(1420)?;
|
||||
tap_device.set_status(true)?;
|
||||
tap_device.add_route(address, netmask, gateway)?;
|
||||
let tap = Arc::new(tap_device);
|
||||
println!("========TAP网卡配置========");
|
||||
Ok((
|
||||
TapWriter(tap.clone(), Arc::default()),
|
||||
TapReader(tap),
|
||||
mac
|
||||
))
|
||||
}
|
||||
|
||||
pub fn delete_tap() {
|
||||
let tap_device = match TapDevice::open(TAP_INTERFACE_NAME) {
|
||||
Ok(tap_device) => tap_device,
|
||||
Err(_) => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let _ = tap_device.delete();
|
||||
}
|
||||
Reference in New Issue
Block a user