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. 23
      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,10 +77,9 @@ 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);
@ -89,9 +89,9 @@ pub fn get_interfaces() -> Vec<Interface> {
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 = mem::transmute(&(*p_adaptor).IpAddressList); p_ip_addr = unsafe { 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 = *p_ip_addr; let ip_addr_string: IP_ADDR_STRING = unsafe{ *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) => {
@ -106,14 +106,14 @@ pub fn get_interfaces() -> Vec<Interface> {
}, },
Err(_) => {}, Err(_) => {},
} }
p_ip_addr = (*p_ip_addr).Next; unsafe { p_ip_addr = (*p_ip_addr).Next; }
} }
//Enumerate all gateways //Enumerate all gateways
let mut gateway_ips: Vec<IpAddr> = vec![]; let mut gateway_ips: Vec<IpAddr> = vec![];
let mut p_gateway_addr: *mut IP_ADDR_STRING; let mut p_gateway_addr: *mut IP_ADDR_STRING;
p_gateway_addr = mem::transmute(&(*p_adaptor).GatewayList); p_gateway_addr = unsafe { mem::transmute(&(*p_adaptor).GatewayList) };
while p_gateway_addr as u64 != 0 { while p_gateway_addr as u64 != 0 {
let gateway_addr_string: IP_ADDR_STRING = *p_gateway_addr; let gateway_addr_string: IP_ADDR_STRING = unsafe { *p_gateway_addr };
let gateway_addr: String = bytes_to_string(&gateway_addr_string.IpAddress.String); let gateway_addr: String = bytes_to_string(&gateway_addr_string.IpAddress.String);
match gateway_addr.parse::<IpAddr>() { match gateway_addr.parse::<IpAddr>() {
Ok(ip_addr) => { Ok(ip_addr) => {
@ -121,7 +121,7 @@ pub fn get_interfaces() -> Vec<Interface> {
}, },
Err(_) => {}, Err(_) => {},
} }
p_gateway_addr = (*p_gateway_addr).Next; unsafe { p_gateway_addr = (*p_gateway_addr).Next; }
} }
let default_gateway: Option<Gateway> = match gateway_ips.get(0) { let default_gateway: Option<Gateway> = match gateway_ips.get(0) {
Some(gateway_ip) => { Some(gateway_ip) => {
@ -161,7 +161,6 @@ pub fn get_interfaces() -> Vec<Interface> {
gateway: default_gateway, gateway: default_gateway,
}; };
interfaces.push(interface); interfaces.push(interface);
}
unsafe { p_adaptor = (*p_adaptor).Next; } unsafe { p_adaptor = (*p_adaptor).Next; }
} }
return interfaces; return interfaces;

Loading…
Cancel
Save