Impl interface for windows

main
shellrow 2 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
.DS_Store
# debug
/.vscode/

@ -1,6 +1,7 @@
use std::net::UdpSocket;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use crate::gateway::{self, Gateway};
use crate::os;
/// Struct of MAC address
#[derive(Clone, Debug)]
@ -43,6 +44,31 @@ pub struct Interface {
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
pub fn get_default_interface() -> Result<Interface, String> {
let local_ip = get_local_ipaddr();

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

Loading…
Cancel
Save