Impl interface for windows

main
shellrow 3 years ago
parent 60feaff4be
commit 07c74649d1
  1. 3
      .gitignore
  2. 26
      src/interface.rs
  3. 1
      src/lib.rs
  4. 12
      src/os/mod.rs
  5. 18
      src/os/shared.rs
  6. 6
      src/os/unix.rs
  7. 165
      src/os/windows.rs

3
.gitignore vendored

@ -11,3 +11,6 @@ Cargo.lock
# mac # mac
.DS_Store .DS_Store
# debug
/.vscode/

@ -1,6 +1,7 @@
use std::net::UdpSocket; use std::net::UdpSocket;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use crate::gateway::{self, Gateway}; use crate::gateway::{self, Gateway};
use crate::os;
/// Struct of MAC address /// Struct of MAC address
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -43,6 +44,31 @@ pub struct Interface {
pub gateway: Option<Gateway>, pub gateway: Option<Gateway>,
} }
#[cfg(target_os = "windows")]
pub fn get_default_interface() -> Result<Interface, String> {
let local_ip: IpAddr = match os::get_local_ipaddr(){
Some(local_ip) => local_ip,
None => return Err(String::from("Local IP address not found")),
};
let interfaces: Vec<Interface> = os::get_interfaces();
for iface in interfaces {
match local_ip {
IpAddr::V4(local_ipv4) => {
if iface.ipv4.contains(&local_ipv4) {
return Ok(iface);
}
},
IpAddr::V6(local_ipv6) => {
if iface.ipv6.contains(&local_ipv6) {
return Ok(iface);
}
},
}
}
Err(String::from("Default Interface not found"))
}
#[cfg(not(target_os="windows"))]
/// Get default Interface /// Get default Interface
pub fn get_default_interface() -> Result<Interface, String> { pub fn get_default_interface() -> Result<Interface, String> {
let local_ip = get_local_ipaddr(); let local_ip = get_local_ipaddr();

@ -6,3 +6,4 @@ pub use interface::Interface;
pub use interface::get_default_interface; pub use interface::get_default_interface;
pub use gateway::Gateway; pub use gateway::Gateway;
pub use gateway::get_default_gateway; pub use gateway::get_default_gateway;
pub use os::get_interfaces;

@ -1,2 +1,12 @@
mod shared;
pub use self::shared::*;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub mod windows; mod windows;
#[cfg(target_os = "windows")]
pub use self::windows::*;
#[cfg(not(target_os="windows"))]
mod unix;
#[cfg(not(target_os="windows"))]
use self::unix::*;

@ -0,0 +1,18 @@
use std::net::{IpAddr, UdpSocket};
pub fn get_local_ipaddr() -> Option<IpAddr> {
let socket = match UdpSocket::bind("0.0.0.0:0") {
Ok(s) => s,
Err(_) => return None,
};
match socket.connect("1.1.1.1:80") {
Ok(()) => (),
Err(_) => return None,
};
match socket.local_addr() {
Ok(addr) => return Some(addr.ip()),
Err(_) => return None,
};
}

@ -0,0 +1,6 @@
use crate::interface::{Interface, MacAddr};
pub fn get_interfaces() -> Vec<Interface> {
let interfaces: Vec<Interface> = vec![];
return interfaces;
}

@ -9,7 +9,8 @@ use core::ffi::c_void;
use crate::interface::{Interface, MacAddr}; use crate::interface::{Interface, MacAddr};
use crate::gateway::Gateway; use crate::gateway::Gateway;
pub const EXCEPTION_INTERFACE_INDEX: u32 = 0; const EXCEPTION_INTERFACE_INDEX: u32 = 0;
const EXCEPTION_INTERFACE_COMBOINDEX: u32 = 4928;
// Convert C string to Rust string without trailing null bytes // Convert C string to Rust string without trailing null bytes
fn bytes_to_string(bytes: &[u8]) -> String { fn bytes_to_string(bytes: &[u8]) -> String {
@ -76,92 +77,90 @@ pub fn get_interfaces() -> Vec<Interface> {
//Enumerate all adapters //Enumerate all adapters
p_adaptor = unsafe { mem::transmute(&raw_adaptor_mem) }; p_adaptor = unsafe { mem::transmute(&raw_adaptor_mem) };
while p_adaptor as u64 != 0 { while p_adaptor as u64 != 0 {
unsafe { let adapter: IP_ADAPTER_INFO = unsafe { *p_adaptor };
let adapter: IP_ADAPTER_INFO = *p_adaptor; if adapter.Index == EXCEPTION_INTERFACE_INDEX || adapter.ComboIndex == EXCEPTION_INTERFACE_COMBOINDEX{
if adapter.Index == EXCEPTION_INTERFACE_INDEX{ unsafe { p_adaptor = (*p_adaptor).Next; }
p_adaptor = (*p_adaptor).Next; continue;
continue; }
} let adapter_name: String = bytes_to_string(&adapter.AdapterName);
let adapter_name: String = bytes_to_string(&adapter.AdapterName); let adapter_desc: String = bytes_to_string(&adapter.Description);
let adapter_desc: String = bytes_to_string(&adapter.Description); let mac_addr:[u8; 6] = adapter.Address[..6].try_into().unwrap_or([0, 0, 0, 0, 0, 0]);
let mac_addr:[u8; 6] = adapter.Address[..6].try_into().unwrap_or([0, 0, 0, 0, 0, 0]); //Enumerate all IPs
//Enumerate all IPs let mut ipv4_vec: Vec<Ipv4Addr> = vec![];
let mut ipv4_vec: Vec<Ipv4Addr> = vec![]; let mut ipv6_vec: Vec<Ipv6Addr> = vec![];
let mut ipv6_vec: Vec<Ipv6Addr> = vec![]; let mut p_ip_addr: *mut IP_ADDR_STRING;
let mut p_ip_addr: *mut IP_ADDR_STRING; p_ip_addr = unsafe { mem::transmute(&(*p_adaptor).IpAddressList) };
p_ip_addr = mem::transmute(&(*p_adaptor).IpAddressList); while p_ip_addr as u64 != 0 {
while p_ip_addr as u64 != 0 { let ip_addr_string: IP_ADDR_STRING = unsafe{ *p_ip_addr };
let ip_addr_string: IP_ADDR_STRING = *p_ip_addr; let ip_addr: String = bytes_to_string(&ip_addr_string.IpAddress.String);
let ip_addr: String = bytes_to_string(&ip_addr_string.IpAddress.String); match ip_addr.parse::<IpAddr>() {
match ip_addr.parse::<IpAddr>() { Ok(ip_addr) => {
Ok(ip_addr) => { match ip_addr {
match ip_addr { IpAddr::V4(ipv4_addr) => {
IpAddr::V4(ipv4_addr) => { ipv4_vec.push(ipv4_addr);
ipv4_vec.push(ipv4_addr); },
}, IpAddr::V6(ipv6_addr) => {
IpAddr::V6(ipv6_addr) => { ipv6_vec.push(ipv6_addr);
ipv6_vec.push(ipv6_addr);
}
} }
}, }
Err(_) => {}, },
} Err(_) => {},
p_ip_addr = (*p_ip_addr).Next;
} }
//Enumerate all gateways unsafe { p_ip_addr = (*p_ip_addr).Next; }
let mut gateway_ips: Vec<IpAddr> = vec![]; }
let mut p_gateway_addr: *mut IP_ADDR_STRING; //Enumerate all gateways
p_gateway_addr = mem::transmute(&(*p_adaptor).GatewayList); let mut gateway_ips: Vec<IpAddr> = vec![];
while p_gateway_addr as u64 != 0 { let mut p_gateway_addr: *mut IP_ADDR_STRING;
let gateway_addr_string: IP_ADDR_STRING = *p_gateway_addr; p_gateway_addr = unsafe { mem::transmute(&(*p_adaptor).GatewayList) };
let gateway_addr: String = bytes_to_string(&gateway_addr_string.IpAddress.String); while p_gateway_addr as u64 != 0 {
match gateway_addr.parse::<IpAddr>() { let gateway_addr_string: IP_ADDR_STRING = unsafe { *p_gateway_addr };
Ok(ip_addr) => { let gateway_addr: String = bytes_to_string(&gateway_addr_string.IpAddress.String);
gateway_ips.push(ip_addr); match gateway_addr.parse::<IpAddr>() {
}, Ok(ip_addr) => {
Err(_) => {}, gateway_ips.push(ip_addr);
} },
p_gateway_addr = (*p_gateway_addr).Next; Err(_) => {},
} }
let default_gateway: Option<Gateway> = match gateway_ips.get(0) { unsafe { p_gateway_addr = (*p_gateway_addr).Next; }
Some(gateway_ip) => { }
let gateway_ip: IpAddr = *gateway_ip; let default_gateway: Option<Gateway> = match gateway_ips.get(0) {
let default_gateway: Option<Gateway> = if gateway_ip != IpAddr::V4(Ipv4Addr::UNSPECIFIED) { Some(gateway_ip) => {
match gateway_ip { let gateway_ip: IpAddr = *gateway_ip;
IpAddr::V4(dst_ip) => { let default_gateway: Option<Gateway> = if gateway_ip != IpAddr::V4(Ipv4Addr::UNSPECIFIED) {
if let Some(src_ip) = ipv4_vec.get(0) { match gateway_ip {
let mac_addr = get_mac_through_arp(*src_ip, dst_ip); IpAddr::V4(dst_ip) => {
let gateway = Gateway { if let Some(src_ip) = ipv4_vec.get(0) {
mac_addr: mac_addr, let mac_addr = get_mac_through_arp(*src_ip, dst_ip);
ip_addr: IpAddr::V4(dst_ip), let gateway = Gateway {
}; mac_addr: mac_addr,
Some(gateway) ip_addr: IpAddr::V4(dst_ip),
}else{ };
None Some(gateway)
} }else{
},
IpAddr::V6(_dst_ip) => {
None None
}, }
} },
}else{ IpAddr::V6(_dst_ip) => {
None None
}; },
default_gateway }
}, }else{
None => None, None
}; };
let interface: Interface = Interface{ default_gateway
index: adapter.Index, },
name: adapter_name, None => None,
description: Some(adapter_desc), };
mac_addr: Some(MacAddr::new(mac_addr)), let interface: Interface = Interface{
ipv4: ipv4_vec, index: adapter.Index,
ipv6: ipv6_vec, name: adapter_name,
gateway: default_gateway, description: Some(adapter_desc),
}; mac_addr: Some(MacAddr::new(mac_addr)),
interfaces.push(interface); ipv4: ipv4_vec,
} ipv6: ipv6_vec,
gateway: default_gateway,
};
interfaces.push(interface);
unsafe { p_adaptor = (*p_adaptor).Next; } unsafe { p_adaptor = (*p_adaptor).Next; }
} }
return interfaces; return interfaces;

Loading…
Cancel
Save