Refactoring for unix-like OS

main
shellrow 3 years ago
parent 94d26cb15d
commit b64c013a9b
  1. 4
      Cargo.toml
  2. 24
      README.md
  3. 26
      examples/list_interfaces.rs
  4. 166
      src/gateway.rs
  5. 127
      src/interface.rs
  6. 2
      src/lib.rs
  7. 2
      src/os/mod.rs
  8. 243
      src/os/unix.rs
  9. 2
      src/os/windows.rs

@ -10,12 +10,12 @@ keywords = ["network"]
categories = ["network-programming"] categories = ["network-programming"]
license = "MIT" license = "MIT"
[dependencies] [target.'cfg(not(windows))'.dependencies]
pnet_packet = "0.28" pnet_packet = "0.28"
pnet_datalink = "0.28" pnet_datalink = "0.28"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = [ "std" ] } winapi = { version = "0.3.9", features = [ "std" ] }
[dependencies.windows] [target.'cfg(windows)'.dependencies.windows]
version = "0.29.0" version = "0.29.0"
features = ["Win32_Foundation","Win32_NetworkManagement_IpHelper"] features = ["Win32_Foundation","Win32_NetworkManagement_IpHelper"]

@ -15,7 +15,7 @@ Get default network information
Add `default-net` to your dependencies Add `default-net` to your dependencies
```toml:Cargo.toml ```toml:Cargo.toml
[dependencies] [dependencies]
default-net = "0.5.0" default-net = "0.6.0"
``` ```
## Example ## Example
@ -28,6 +28,7 @@ fn main(){
println!("Default Interface"); println!("Default Interface");
println!("\tIndex: {}", default_interface.index); println!("\tIndex: {}", default_interface.index);
println!("\tName: {}", default_interface.name); println!("\tName: {}", default_interface.name);
println!("\tDescription: {:?}", default_interface.description);
if let Some(mac_addr) = default_interface.mac_addr { if let Some(mac_addr) = default_interface.mac_addr {
println!("\tMAC: {}", mac_addr); println!("\tMAC: {}", mac_addr);
}else{ }else{
@ -50,7 +51,17 @@ fn main(){
} }
``` ```
## Note for Windows users ## Tested on
- Linux
- Kali 2021.1 (VMware)
- Ubuntu 20.04
- macOS 11.6
- Windows 10 20H2
For more details, see [examples][examples-url] or doc.
## For Windows users using v0.5.0 or lower
To build [libpnet](https://github.com/libpnet/libpnet) on Windows, follow the instructions below. To build [libpnet](https://github.com/libpnet/libpnet) on Windows, follow the instructions below.
> ### Windows > ### Windows
> * You must use a version of Rust which uses the MSVC toolchain > * You must use a version of Rust which uses the MSVC toolchain
@ -62,12 +73,3 @@ To build [libpnet](https://github.com/libpnet/libpnet) on Windows, follow the in
> in `WpdPack/Lib/x64/Packet.lib`, for the 32 bit toolchain, it is in `WpdPack/Lib/Packet.lib`. > in `WpdPack/Lib/x64/Packet.lib`, for the 32 bit toolchain, it is in `WpdPack/Lib/Packet.lib`.
[Source](https://github.com/libpnet/libpnet/blob/master/README.md#windows "libpnet#windows") [Source](https://github.com/libpnet/libpnet/blob/master/README.md#windows "libpnet#windows")
## Tested on
- Linux
- Kali 2021.1 (VMware)
- Ubuntu 20.04
- macOS 11.6
- Windows 10 20H2
For more details, see [examples][examples-url] or doc.

@ -0,0 +1,26 @@
use default_net;
fn main(){
let interfaces = default_net::get_interfaces();
for interface in interfaces {
println!("Interface");
println!("\tIndex: {}", interface.index);
println!("\tName: {}", interface.name);
println!("\tDescription: {:?}", interface.description);
if let Some(mac_addr) = interface.mac_addr {
println!("\tMAC: {}", mac_addr);
}else{
println!("\tMAC: (Failed to get mac address)");
}
println!("\tIPv4: {:?}", interface.ipv4);
println!("\tIPv6: {:?}", interface.ipv6);
if let Some(gateway) = interface.gateway {
println!("Gateway");
println!("\tMAC: {}", gateway.mac_addr);
println!("\tIP: {}", gateway.ip_addr);
}else {
println!("Gateway: (Not found)");
}
println!();
}
}

@ -1,12 +1,8 @@
use std::net::UdpSocket; use std::net::IpAddr;
use std::time::{Duration, Instant}; use crate::interface::{MacAddr, Interface};
use std::net::{IpAddr}; use crate::os;
use pnet_packet::Packet;
use crate::interface::{self, MacAddr};
const TIMEOUT: u64 = 3000; /// Structure of default Gateway information
/// Struct of default Gateway information
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Gateway { pub struct Gateway {
pub mac_addr: MacAddr, pub mac_addr: MacAddr,
@ -15,151 +11,37 @@ pub struct Gateway {
/// Get default Gateway /// Get default Gateway
pub fn get_default_gateway() -> Result<Gateway, String> { pub fn get_default_gateway() -> Result<Gateway, String> {
let default_idx = match interface::get_default_interface_index() { let local_ip: IpAddr = match os::get_local_ipaddr(){
Some(idx) => idx, Some(local_ip) => local_ip,
None => return Err(String::from("Failed to get default interface")), None => return Err(String::from("Local IP address not found")),
};
let interfaces = pnet_datalink::interfaces();
let interface = interfaces.into_iter().filter(|interface: &pnet_datalink::NetworkInterface| interface.index == default_idx).next().expect("Failed to get Interface");
let config = pnet_datalink::Config {
write_buffer_size: 4096,
read_buffer_size: 4096,
read_timeout: None,
write_timeout: None,
channel_type: pnet_datalink::ChannelType::Layer2,
bpf_fd_attempts: 1000,
linux_fanout: None,
promiscuous: false,
};
let (mut _tx, mut rx) = match pnet_datalink::channel(&interface, config) {
Ok(pnet_datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unknown channel type"),
Err(e) => panic!("Error happened {}", e),
};
match send_udp_packet() {
Ok(_) => (),
Err(e) => return Err(format!("Failed to send UDP packet {}", e)),
}
receive_packets(&mut rx)
}
fn send_udp_packet() -> Result<(), String> {
let buf = [0u8; 0];
let socket = match UdpSocket::bind("0.0.0.0:0") {
Ok(s) => s,
Err(e) => return Err(format!("Failed to create UDP socket {}", e)),
};
let dest: &str = "1.1.1.1:80";
match socket.set_ttl(1) {
Ok(_) => (),
Err(e) => return Err(format!("Failed to set TTL {}", e)),
}
match socket.send_to(&buf, dest) {
Ok(_) => (),
Err(e) => return Err(format!("Failed to send data {}", e)),
}
Ok(())
}
fn receive_packets(rx: &mut Box<dyn pnet_datalink::DataLinkReceiver>) -> Result<Gateway, String>{
let timeout = Duration::from_millis(TIMEOUT);
let start_time = Instant::now();
loop {
match rx.next() {
Ok(frame) => {
let frame = match pnet_packet::ethernet::EthernetPacket::new(frame) {
Some(f) => f,
None => return Err(String::from("Failed to read packet")),
};
match frame.get_ethertype() {
pnet_packet::ethernet::EtherTypes::Ipv4 => {
if let Some(ip_addr) = ipv4_handler(&frame) {
let gateway = Gateway {
mac_addr: MacAddr::new(frame.get_source().octets()),
ip_addr: ip_addr,
}; };
let interfaces: Vec<Interface> = os::interfaces();
for iface in interfaces {
match local_ip {
IpAddr::V4(local_ipv4) => {
if iface.ipv4.contains(&local_ipv4) {
if let Some(gateway) = iface.gateway {
return Ok(gateway); return Ok(gateway);
} }
},
pnet_packet::ethernet::EtherTypes::Ipv6 => {
if let Some(ip_addr) = ipv6_handler(&frame) {
let gateway = Gateway {
mac_addr: MacAddr::new(frame.get_source().octets()),
ip_addr: ip_addr,
};
return Ok(gateway);
}
},
_ => {}
}
},
Err(e) => {
return Err(format!("An error occurred while reading: {}", e));
}
}
if Instant::now().duration_since(start_time) > timeout {
return Err(String::from("Recieve timeout"));
}else{
match send_udp_packet() {
Ok(_) => (),
Err(e) => return Err(format!("Failed to send UDP packet {}", e)),
}
} }
}
}
fn ipv4_handler(ethernet: &pnet_packet::ethernet::EthernetPacket) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::ipv4::Ipv4Packet::new(ethernet.payload()) {
match packet.get_next_level_protocol() {
pnet_packet::ip::IpNextHeaderProtocols::Icmp => {
return icmp_handler(&packet);
}, },
_ => { IpAddr::V6(local_ipv6) => {
None if iface.ipv6.contains(&local_ipv6) {
} if let Some(gateway) = iface.gateway {
} return Ok(gateway);
}else{
None
} }
} }
fn ipv6_handler(ethernet: &pnet_packet::ethernet::EthernetPacket) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::ipv6::Ipv6Packet::new(ethernet.payload()) {
match packet.get_next_header() {
pnet_packet::ip::IpNextHeaderProtocols::Icmpv6 => {
return icmpv6_handler(&packet);
}, },
_ => {
None
} }
} }
}else{ Err(String::from("Default Gateway not found"))
None
}
} }
fn icmp_handler(ip_packet: &pnet_packet::ipv4::Ipv4Packet) -> Option<IpAddr> { #[cfg(test)]
if let Some(packet) = pnet_packet::icmp::IcmpPacket::new(ip_packet.payload()) { mod tests {
if packet.get_icmp_type() == pnet_packet::icmp::IcmpTypes::TimeExceeded { use super::*;
let ipv4_addr = ip_packet.get_source(); #[test]
return Some(IpAddr::V4(ipv4_addr)) fn test_default_gateway() {
}else{ println!("{:?}", get_default_gateway());
None
}
}else{
None
}
}
fn icmpv6_handler(ip_packet: &pnet_packet::ipv6::Ipv6Packet) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::icmpv6::Icmpv6Packet::new(ip_packet.payload()) {
if packet.get_icmpv6_type() == pnet_packet::icmpv6::Icmpv6Types::TimeExceeded {
let ipv6_addr = ip_packet.get_source();
return Some(IpAddr::V6(ipv6_addr))
}else{
None
}
}else{
None
} }
} }

@ -1,9 +1,8 @@
use std::net::UdpSocket;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use crate::gateway::{self, Gateway}; use crate::gateway::{Gateway};
use crate::os; use crate::os;
/// Struct of MAC address /// Structure of MAC address
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MacAddr(u8, u8, u8, u8, u8, u8); pub struct MacAddr(u8, u8, u8, u8, u8, u8);
@ -32,7 +31,7 @@ impl std::fmt::Display for MacAddr {
} }
} }
/// Struct of default Network Interface information /// Structure of default Network Interface information
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Interface { pub struct Interface {
pub index: u32, pub index: u32,
@ -44,13 +43,13 @@ pub struct Interface {
pub gateway: Option<Gateway>, pub gateway: Option<Gateway>,
} }
#[cfg(target_os = "windows")] /// Get default Network Interface
pub fn get_default_interface() -> Result<Interface, String> { pub fn get_default_interface() -> Result<Interface, String> {
let local_ip: IpAddr = match os::get_local_ipaddr(){ let local_ip: IpAddr = match os::get_local_ipaddr(){
Some(local_ip) => local_ip, Some(local_ip) => local_ip,
None => return Err(String::from("Local IP address not found")), None => return Err(String::from("Local IP address not found")),
}; };
let interfaces: Vec<Interface> = os::get_interfaces(); let interfaces: Vec<Interface> = os::interfaces();
for iface in interfaces { for iface in interfaces {
match local_ip { match local_ip {
IpAddr::V4(local_ipv4) => { IpAddr::V4(local_ipv4) => {
@ -68,103 +67,41 @@ pub fn get_default_interface() -> Result<Interface, String> {
Err(String::from("Default Interface not found")) Err(String::from("Default Interface not found"))
} }
#[cfg(not(target_os="windows"))] /// Get default Network Interface index
/// Get default Interface
pub fn get_default_interface() -> Result<Interface, String> {
let local_ip = get_local_ipaddr();
let interfaces = pnet_datalink::interfaces();
if let Some(local_ip) = local_ip {
for iface in interfaces{
for ip in &iface.ips{
if local_ip == ip.ip().to_string() {
let mac_addr: Option<MacAddr> = match iface.mac {
Some(mac_addr) => Some(MacAddr::new(mac_addr.octets())),
None => None,
};
let mut ipv4_vec: Vec<Ipv4Addr> = vec![];
let mut ipv6_vec: Vec<Ipv6Addr> = vec![];
for ip in &iface.ips {
match ip.ip() {
IpAddr::V4(ipv4_addr) => {
ipv4_vec.push(ipv4_addr);
},
IpAddr::V6(ipv6_addr) => {
ipv6_vec.push(ipv6_addr);
},
}
}
let default_gateway: Option<Gateway> = match gateway::get_default_gateway() {
Ok(gateway) => Some(gateway),
Err(_) => None,
};
let interface: Interface = Interface{
index: iface.index,
name: iface.name,
description: None,
mac_addr: mac_addr,
ipv4: ipv4_vec,
ipv6: ipv6_vec,
gateway: default_gateway,
};
return Ok(interface);
}
}
}
return Err(String::from(""));
}else{
return Err(String::from(""));
}
}
/// Get default Interface index
pub fn get_default_interface_index() -> Option<u32> { pub fn get_default_interface_index() -> Option<u32> {
let local_ip = get_local_ipaddr(); os::default_interface_index()
let interfaces = pnet_datalink::interfaces();
if let Some(local_ip) = local_ip {
for iface in interfaces {
for ip in iface.ips {
if local_ip == ip.ip().to_string() {
return Some(iface.index)
}
} }
/// Get default Network Interface name
pub fn get_default_interface_name() -> Option<String> {
os::default_interface_name()
} }
return None;
}else{ /// Get a list of available Network Interfaces
return None; pub fn get_interfaces() -> Vec<Interface> {
} os::interfaces()
} }
/// Get default Interface name #[cfg(test)]
pub fn get_default_interface_name() -> Option<String> { mod tests {
let local_ip = get_local_ipaddr(); use super::*;
let interfaces = pnet_datalink::interfaces(); #[test]
if let Some(local_ip) = local_ip { fn test_interfaces() {
for iface in interfaces { let interfaces = get_interfaces();
for ip in iface.ips { for interface in interfaces {
if local_ip == ip.ip().to_string() { println!("{:#?}", interface);
return Some(iface.name)
} }
} }
#[test]
fn test_default_interface() {
println!("{:#?}", get_default_interface());
} }
return None; #[test]
}else{ fn test_default_interface_index() {
return None; println!("{:?}", get_default_interface_index());
} }
#[test]
fn test_default_interface_name() {
println!("{:?}", get_default_interface_name());
} }
fn get_local_ipaddr() -> Option<String> {
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().to_string()),
Err(_) => return None,
};
} }

@ -4,6 +4,6 @@ pub mod gateway;
pub use interface::Interface; pub use interface::Interface;
pub use interface::get_default_interface; pub use interface::get_default_interface;
pub use interface::get_interfaces;
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;

@ -9,4 +9,4 @@ pub use self::windows::*;
#[cfg(not(target_os="windows"))] #[cfg(not(target_os="windows"))]
mod unix; mod unix;
#[cfg(not(target_os="windows"))] #[cfg(not(target_os="windows"))]
use self::unix::*; pub use self::unix::*;

@ -1,6 +1,241 @@
use crate::interface::{Interface, MacAddr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::net::UdpSocket;
use std::time::{Duration, Instant};
use pnet_packet::Packet;
use crate::interface::{MacAddr, Interface};
use crate::gateway::Gateway;
pub fn get_interfaces() -> Vec<Interface> { const TIMEOUT: u64 = 3000;
let interfaces: Vec<Interface> = vec![];
return interfaces; fn get_default_gateway(interface_index: u32) -> Result<Gateway, String> {
let interfaces = pnet_datalink::interfaces();
let interface = interfaces.into_iter().filter(|interface: &pnet_datalink::NetworkInterface| interface.index == interface_index).next().expect("Failed to get Interface");
let config = pnet_datalink::Config {
write_buffer_size: 4096,
read_buffer_size: 4096,
read_timeout: None,
write_timeout: None,
channel_type: pnet_datalink::ChannelType::Layer2,
bpf_fd_attempts: 1000,
linux_fanout: None,
promiscuous: false,
};
let (mut _tx, mut rx) = match pnet_datalink::channel(&interface, config) {
Ok(pnet_datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unknown channel type"),
Err(e) => panic!("Error happened {}", e),
};
match send_udp_packet() {
Ok(_) => (),
Err(e) => return Err(format!("Failed to send UDP packet {}", e)),
}
receive_packets(&mut rx)
}
fn send_udp_packet() -> Result<(), String> {
let buf = [0u8; 0];
let socket = match UdpSocket::bind("0.0.0.0:0") {
Ok(s) => s,
Err(e) => return Err(format!("Failed to create UDP socket {}", e)),
};
let dst: &str = "1.1.1.1:80";
match socket.set_ttl(1) {
Ok(_) => (),
Err(e) => return Err(format!("Failed to set TTL {}", e)),
}
match socket.send_to(&buf, dst) {
Ok(_) => (),
Err(e) => return Err(format!("Failed to send data {}", e)),
}
Ok(())
}
fn receive_packets(rx: &mut Box<dyn pnet_datalink::DataLinkReceiver>) -> Result<Gateway, String>{
let timeout = Duration::from_millis(TIMEOUT);
let start_time = Instant::now();
loop {
match rx.next() {
Ok(frame) => {
let frame = match pnet_packet::ethernet::EthernetPacket::new(frame) {
Some(f) => f,
None => return Err(String::from("Failed to read packet")),
};
match frame.get_ethertype() {
pnet_packet::ethernet::EtherTypes::Ipv4 => {
if let Some(ip_addr) = ipv4_handler(&frame) {
let gateway = Gateway {
mac_addr: MacAddr::new(frame.get_source().octets()),
ip_addr: ip_addr,
};
return Ok(gateway);
}
},
pnet_packet::ethernet::EtherTypes::Ipv6 => {
if let Some(ip_addr) = ipv6_handler(&frame) {
let gateway = Gateway {
mac_addr: MacAddr::new(frame.get_source().octets()),
ip_addr: ip_addr,
};
return Ok(gateway);
}
},
_ => {}
}
},
Err(e) => {
return Err(format!("An error occurred while reading: {}", e));
}
}
if Instant::now().duration_since(start_time) > timeout {
return Err(String::from("Recieve timeout"));
}else{
match send_udp_packet() {
Ok(_) => (),
Err(e) => return Err(format!("Failed to send UDP packet {}", e)),
}
}
}
}
fn ipv4_handler(ethernet: &pnet_packet::ethernet::EthernetPacket) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::ipv4::Ipv4Packet::new(ethernet.payload()) {
match packet.get_next_level_protocol() {
pnet_packet::ip::IpNextHeaderProtocols::Icmp => {
return icmp_handler(&packet);
},
_ => {
None
}
}
}else{
None
}
}
fn ipv6_handler(ethernet: &pnet_packet::ethernet::EthernetPacket) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::ipv6::Ipv6Packet::new(ethernet.payload()) {
match packet.get_next_header() {
pnet_packet::ip::IpNextHeaderProtocols::Icmpv6 => {
return icmpv6_handler(&packet);
},
_ => {
None
}
}
}else{
None
}
}
fn icmp_handler(ip_packet: &pnet_packet::ipv4::Ipv4Packet) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::icmp::IcmpPacket::new(ip_packet.payload()) {
if packet.get_icmp_type() == pnet_packet::icmp::IcmpTypes::TimeExceeded {
let ipv4_addr = ip_packet.get_source();
return Some(IpAddr::V4(ipv4_addr))
}else{
None
}
}else{
None
}
}
fn icmpv6_handler(ip_packet: &pnet_packet::ipv6::Ipv6Packet) -> Option<IpAddr> {
if let Some(packet) = pnet_packet::icmpv6::Icmpv6Packet::new(ip_packet.payload()) {
if packet.get_icmpv6_type() == pnet_packet::icmpv6::Icmpv6Types::TimeExceeded {
let ipv6_addr = ip_packet.get_source();
return Some(IpAddr::V6(ipv6_addr))
}else{
None
}
}else{
None
}
}
pub fn interfaces() -> Vec<Interface> {
let mut result: Vec<Interface> = vec![];
let local_ip: IpAddr = match super::get_local_ipaddr(){
Some(local_ip) => local_ip,
None => return result,
};
let interfaces = pnet_datalink::interfaces();
for iface in interfaces{
let mac_addr: Option<MacAddr> = match iface.mac {
Some(mac_addr) => Some(MacAddr::new(mac_addr.octets())),
None => None,
};
let mut ipv4_vec: Vec<Ipv4Addr> = vec![];
let mut ipv6_vec: Vec<Ipv6Addr> = vec![];
let mut ips: Vec<IpAddr> = vec![];
for ip in &iface.ips {
match ip.ip() {
IpAddr::V4(ipv4_addr) => {
ipv4_vec.push(ipv4_addr);
},
IpAddr::V6(ipv6_addr) => {
ipv6_vec.push(ipv6_addr);
},
}
ips.push(ip.ip());
}
let default_gateway: Option<Gateway> = if ips.contains(&local_ip) {
match get_default_gateway(iface.index) {
Ok(default_gateway) => Some(default_gateway),
Err(_) => None,
}
} else{
None
};
let desc: Option<String> = if iface.description.is_empty() {
None
} else{
Some(iface.description)
};
let interface: Interface = Interface{
index: iface.index,
name: iface.name,
description: desc,
mac_addr: mac_addr,
ipv4: ipv4_vec,
ipv6: ipv6_vec,
gateway: default_gateway,
};
result.push(interface);
}
return result;
}
/// Get default Interface index
pub fn default_interface_index() -> Option<u32> {
let local_ip: IpAddr = match super::get_local_ipaddr(){
Some(local_ip) => local_ip,
None => return None,
};
let interfaces = pnet_datalink::interfaces();
for iface in interfaces {
for ip in iface.ips {
if local_ip == ip.ip() {
return Some(iface.index)
}
}
}
return None;
}
/// Get default Interface name
pub fn default_interface_name() -> Option<String> {
let local_ip: IpAddr = match super::get_local_ipaddr(){
Some(local_ip) => local_ip,
None => return None,
};
let interfaces = pnet_datalink::interfaces();
for iface in interfaces {
for ip in iface.ips {
if local_ip == ip.ip() {
return Some(iface.name)
}
}
}
return None;
} }

@ -58,7 +58,7 @@ fn get_mac_through_arp(src_ip: Ipv4Addr, dst_ip: Ipv4Addr) -> MacAddr {
// Get network interfaces using the IP Helper API // Get network interfaces using the IP Helper API
// TODO: Make more rusty ... // TODO: Make more rusty ...
// Reference: https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersinfo // Reference: https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersinfo
pub fn get_interfaces() -> Vec<Interface> { pub fn interfaces() -> Vec<Interface> {
let mut interfaces: Vec<Interface> = vec![]; let mut interfaces: Vec<Interface> = vec![];
let mut out_buf_len : u32 = mem::size_of::<IP_ADAPTER_INFO>().try_into().unwrap(); let mut out_buf_len : u32 = mem::size_of::<IP_ADAPTER_INFO>().try_into().unwrap();
let mut raw_adaptor_mem: Vec<u8> = Vec::with_capacity(out_buf_len as usize); let mut raw_adaptor_mem: Vec<u8> = Vec::with_capacity(out_buf_len as usize);

Loading…
Cancel
Save