Run `cargo fmt`

main
link2xt 2 years ago
parent 8f22d88792
commit e2e7032ffa
  1. 6
      examples/default_gateway.rs
  2. 10
      examples/default_interface.rs
  3. 6
      examples/list_interfaces.rs
  4. 39
      src/bpf/binding.rs
  5. 9
      src/bpf/mod.rs
  6. 11
      src/bpf/unix.rs
  7. 8
      src/gateway/linux.rs
  8. 18
      src/gateway/mod.rs
  9. 18
      src/gateway/unix.rs
  10. 10
      src/interface/linux.rs
  11. 8
      src/interface/macos.rs
  12. 65
      src/interface/mod.rs
  13. 24
      src/interface/types.rs
  14. 122
      src/interface/unix.rs
  15. 80
      src/interface/windows.rs
  16. 8
      src/ip.rs
  17. 30
      src/lib.rs
  18. 31
      src/socket/mod.rs
  19. 26
      src/socket/packet.rs
  20. 4
      src/sys/mod.rs
  21. 5
      src/sys/unix.rs

@ -1,14 +1,14 @@
use default_net; use default_net;
fn main(){ fn main() {
match default_net::get_default_gateway() { match default_net::get_default_gateway() {
Ok(gateway) => { Ok(gateway) => {
println!("Default Gateway"); println!("Default Gateway");
println!("\tMAC: {}", gateway.mac_addr); println!("\tMAC: {}", gateway.mac_addr);
println!("\tIP: {}", gateway.ip_addr); println!("\tIP: {}", gateway.ip_addr);
}, }
Err(e) => { Err(e) => {
println!("{}", e); println!("{}", e);
}, }
} }
} }

@ -1,6 +1,6 @@
use default_net; use default_net;
fn main(){ fn main() {
match default_net::get_default_interface() { match default_net::get_default_interface() {
Ok(default_interface) => { Ok(default_interface) => {
println!("Default Interface"); println!("Default Interface");
@ -11,7 +11,7 @@ fn main(){
println!("\tType: {}", default_interface.if_type.name()); println!("\tType: {}", default_interface.if_type.name());
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 {
println!("\tMAC: (Failed to get mac address)"); println!("\tMAC: (Failed to get mac address)");
} }
println!("\tIPv4: {:?}", default_interface.ipv4); println!("\tIPv4: {:?}", default_interface.ipv4);
@ -23,12 +23,12 @@ fn main(){
println!("Default Gateway"); println!("Default Gateway");
println!("\tMAC: {}", gateway.mac_addr); println!("\tMAC: {}", gateway.mac_addr);
println!("\tIP: {}", gateway.ip_addr); println!("\tIP: {}", gateway.ip_addr);
}else { } else {
println!("Default Gateway: (Not found)"); println!("Default Gateway: (Not found)");
} }
}, }
Err(e) => { Err(e) => {
println!("{}", e); println!("{}", e);
}, }
} }
} }

@ -1,6 +1,6 @@
use default_net; use default_net;
fn main(){ fn main() {
let interfaces = default_net::get_interfaces(); let interfaces = default_net::get_interfaces();
for interface in interfaces { for interface in interfaces {
println!("Interface"); println!("Interface");
@ -11,7 +11,7 @@ fn main(){
println!("\tType: {}", interface.if_type.name()); println!("\tType: {}", interface.if_type.name());
if let Some(mac_addr) = interface.mac_addr { if let Some(mac_addr) = interface.mac_addr {
println!("\tMAC: {}", mac_addr); println!("\tMAC: {}", mac_addr);
}else{ } else {
println!("\tMAC: (Failed to get mac address)"); println!("\tMAC: (Failed to get mac address)");
} }
println!("\tIPv4: {:?}", interface.ipv4); println!("\tIPv4: {:?}", interface.ipv4);
@ -23,7 +23,7 @@ fn main(){
println!("Gateway"); println!("Gateway");
println!("\tMAC: {}", gateway.mac_addr); println!("\tMAC: {}", gateway.mac_addr);
println!("\tIP: {}", gateway.ip_addr); println!("\tIP: {}", gateway.ip_addr);
}else { } else {
println!("Gateway: (Not found)"); println!("Gateway: (Not found)");
} }
println!(); println!();

@ -20,17 +20,24 @@ const SIZEOF_C_UINT: libc::c_ulong = 4;
#[cfg(any(target_os = "freebsd", target_os = "netbsd"))] #[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
const SIZEOF_C_LONG: libc::c_int = 8; const SIZEOF_C_LONG: libc::c_int = 8;
pub const BIOCSETIF: libc::c_ulong = IOC_IN | ((SIZEOF_IFREQ & IOCPARM_MASK) << 16usize) | (('B' as libc::c_ulong) << 8usize) | 108; pub const BIOCSETIF: libc::c_ulong =
pub const BIOCIMMEDIATE: libc::c_ulong = IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 112; IOC_IN | ((SIZEOF_IFREQ & IOCPARM_MASK) << 16usize) | (('B' as libc::c_ulong) << 8usize) | 108;
pub const BIOCGDLT: libc::c_ulong = IOC_OUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 106; pub const BIOCIMMEDIATE: libc::c_ulong =
pub const BIOCSBLEN: libc::c_ulong = IOC_INOUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 102; IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 112;
pub const BIOCSHDRCMPLT: libc::c_ulong = IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 117; pub const BIOCGDLT: libc::c_ulong =
IOC_OUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 106;
pub const BIOCSBLEN: libc::c_ulong =
IOC_INOUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 102;
pub const BIOCSHDRCMPLT: libc::c_ulong =
IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 117;
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
pub const BIOCFEEDBACK: libc::c_ulong = IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 124; pub const BIOCFEEDBACK: libc::c_ulong =
IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 124;
#[cfg(target_os = "netbsd")] #[cfg(target_os = "netbsd")]
pub const BIOCFEEDBACK: libc::c_ulong = IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 125; pub const BIOCFEEDBACK: libc::c_ulong =
IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 125;
pub const DLT_NULL: libc::c_uint = 0; pub const DLT_NULL: libc::c_uint = 0;
@ -50,7 +57,13 @@ pub struct ifreq {
pub ifru_addr: SockAddr, pub ifru_addr: SockAddr,
} }
#[cfg(any(target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "macos", target_os = "ios"))] #[cfg(any(
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "macos",
target_os = "ios"
))]
pub struct sockaddr_dl { pub struct sockaddr_dl {
pub sdl_len: libc::c_uchar, pub sdl_len: libc::c_uchar,
pub sdl_family: libc::c_uchar, pub sdl_family: libc::c_uchar,
@ -65,7 +78,10 @@ pub struct sockaddr_dl {
#[cfg(any( #[cfg(any(
target_os = "freebsd", target_os = "freebsd",
target_os = "netbsd", target_os = "netbsd",
all(any(target_os = "macos", target_os = "ios"), target_pointer_width = "32"), all(
any(target_os = "macos", target_os = "ios"),
target_pointer_width = "32"
),
windows windows
))] ))]
#[repr(C)] #[repr(C)]
@ -83,7 +99,10 @@ pub struct timeval32 {
#[cfg(any( #[cfg(any(
target_os = "openbsd", target_os = "openbsd",
all(any(target_os = "macos", target_os = "ios"), target_pointer_width = "64") all(
any(target_os = "macos", target_os = "ios"),
target_pointer_width = "64"
)
))] ))]
#[repr(C)] #[repr(C)]
pub struct bpf_hdr { pub struct bpf_hdr {

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

@ -1,6 +1,6 @@
use super::binding; use super::binding;
use crate::socket::{DataLinkReceiver, DataLinkSender};
use crate::interface::Interface; use crate::interface::Interface;
use crate::socket::{DataLinkReceiver, DataLinkSender};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::ffi::CString; use std::ffi::CString;
@ -200,9 +200,7 @@ pub fn channel(interface_name: String, config: Config) -> io::Result<crate::sock
fd_set: unsafe { mem::zeroed() }, fd_set: unsafe { mem::zeroed() },
write_buffer: vec![0; config.write_buffer_size], write_buffer: vec![0; config.write_buffer_size],
loopback: loopback, loopback: loopback,
timeout: config timeout: config.write_timeout.map(|to| duration_to_timespec(to)),
.write_timeout
.map(|to| duration_to_timespec(to)),
}); });
unsafe { unsafe {
libc::FD_ZERO(&mut sender.fd_set as *mut libc::fd_set); libc::FD_ZERO(&mut sender.fd_set as *mut libc::fd_set);
@ -213,9 +211,7 @@ pub fn channel(interface_name: String, config: Config) -> io::Result<crate::sock
fd_set: unsafe { mem::zeroed() }, fd_set: unsafe { mem::zeroed() },
read_buffer: vec![0; allocated_read_buffer_size], read_buffer: vec![0; allocated_read_buffer_size],
loopback: loopback, loopback: loopback,
timeout: config timeout: config.read_timeout.map(|to| duration_to_timespec(to)),
.read_timeout
.map(|to| duration_to_timespec(to)),
packets: VecDeque::with_capacity(allocated_read_buffer_size / 64), packets: VecDeque::with_capacity(allocated_read_buffer_size / 64),
}); });
unsafe { unsafe {
@ -245,7 +241,6 @@ impl DataLinkSender for DataLinkSenderImpl {
if len >= self.write_buffer.len() { if len >= self.write_buffer.len() {
None None
} else { } else {
let offset = if self.loopback { let offset = if self.loopback {
ETHERNET_HEADER_SIZE ETHERNET_HEADER_SIZE
} else { } else {

@ -1,7 +1,7 @@
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::fs::read_to_string;
use crate::interface::MacAddr;
use super::Gateway; use super::Gateway;
use crate::interface::MacAddr;
use std::fs::read_to_string;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
const PATH_PROC_NET_ROUTE: &str = "/proc/net/route"; const PATH_PROC_NET_ROUTE: &str = "/proc/net/route";
const PATH_PROC_NET_ARP: &str = "/proc/net/arp"; const PATH_PROC_NET_ARP: &str = "/proc/net/arp";
@ -35,7 +35,7 @@ fn convert_hex_ipv6(hex_ip: &str) -> Ipv6Addr {
pub fn get_default_gateway(interface_name: String) -> Result<Gateway, String> { pub fn get_default_gateway(interface_name: String) -> Result<Gateway, String> {
match super::send_udp_packet() { match super::send_udp_packet() {
Ok(_) => {}, Ok(_) => {}
Err(e) => return Err(format!("Failed to send UDP packet {}", e)), Err(e) => return Err(format!("Failed to send UDP packet {}", e)),
} }
let route_data = read_to_string(PATH_PROC_NET_ROUTE); let route_data = read_to_string(PATH_PROC_NET_ROUTE);

@ -1,11 +1,17 @@
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "ios"))] #[cfg(any(
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios"
))]
pub(crate) mod unix; pub(crate) mod unix;
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) mod linux; pub(crate) mod linux;
use crate::interface::{self, Interface, MacAddr};
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use crate::interface::{self, MacAddr, Interface};
/// Structure of default Gateway information /// Structure of default Gateway information
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -28,7 +34,7 @@ impl Gateway {
/// Get default Gateway /// Get default Gateway
pub fn get_default_gateway() -> Result<Gateway, String> { pub fn get_default_gateway() -> Result<Gateway, String> {
let local_ip: IpAddr = match interface::get_local_ipaddr(){ let local_ip: IpAddr = match interface::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")),
}; };
@ -41,20 +47,20 @@ pub fn get_default_gateway() -> Result<Gateway, String> {
return Ok(gateway); return Ok(gateway);
} }
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
if let Some(gateway) = iface.gateway { if let Some(gateway) = iface.gateway {
return Ok(gateway); return Ok(gateway);
} }
} }
}, }
} }
} }
Err(String::from("Default Gateway not found")) Err(String::from("Default Gateway not found"))
} }
#[cfg(not(target_os="windows"))] #[cfg(not(target_os = "windows"))]
fn send_udp_packet() -> Result<(), String> { fn send_udp_packet() -> Result<(), String> {
use std::net::UdpSocket; use std::net::UdpSocket;
let buf = [0u8; 0]; let buf = [0u8; 0];

@ -1,6 +1,6 @@
use std::time::{Duration, Instant};
use crate::socket;
use super::Gateway; use super::Gateway;
use crate::socket;
use std::time::{Duration, Instant};
const TIMEOUT: u64 = 3000; const TIMEOUT: u64 = 3000;
@ -21,7 +21,7 @@ pub fn get_default_gateway(interface_name: String) -> Result<Gateway, String> {
Ok(socket::Channel::Ethernet(etx, erx)) => { Ok(socket::Channel::Ethernet(etx, erx)) => {
_tx = etx; _tx = etx;
rx = erx; rx = erx;
}, }
Err(e) => return Err(format!("Failed to create channel {}", e)), Err(e) => return Err(format!("Failed to create channel {}", e)),
} }
match super::send_udp_packet() { match super::send_udp_packet() {
@ -30,19 +30,17 @@ pub fn get_default_gateway(interface_name: String) -> Result<Gateway, String> {
} }
loop { loop {
match rx.next() { match rx.next() {
Ok(frame) => { Ok(frame) => match socket::packet::parse_frame(frame) {
match socket::packet::parse_frame(frame){ Ok(gateway) => {
Ok(gateway) => { return Ok(gateway);
return Ok(gateway);
},
Err(_) => {},
} }
Err(_) => {}
}, },
Err(_) => {} Err(_) => {}
} }
if Instant::now().duration_since(start_time) > timeout { if Instant::now().duration_since(start_time) > timeout {
return Err(String::from("Recieve timeout")); return Err(String::from("Recieve timeout"));
}else{ } else {
match super::send_udp_packet() { match super::send_udp_packet() {
Ok(_) => (), Ok(_) => (),
Err(e) => return Err(format!("Failed to send UDP packet {}", e)), Err(e) => return Err(format!("Failed to send UDP packet {}", e)),

@ -1,6 +1,6 @@
use crate::interface::InterfaceType;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fs::read_to_string; use std::fs::read_to_string;
use crate::interface::InterfaceType;
pub fn get_interface_type(if_name: String) -> InterfaceType { pub fn get_interface_type(if_name: String) -> InterfaceType {
let if_type_path: String = format!("/sys/class/net/{}/type", if_name); let if_type_path: String = format!("/sys/class/net/{}/type", if_name);
@ -11,12 +11,12 @@ pub fn get_interface_type(if_name: String) -> InterfaceType {
match if_type_string.parse::<u32>() { match if_type_string.parse::<u32>() {
Ok(if_type) => { Ok(if_type) => {
return InterfaceType::try_from(if_type).unwrap_or(InterfaceType::Unknown); return InterfaceType::try_from(if_type).unwrap_or(InterfaceType::Unknown);
}, }
Err(_) => { Err(_) => {
return InterfaceType::Unknown; return InterfaceType::Unknown;
} }
} }
}, }
Err(_) => { Err(_) => {
return InterfaceType::Unknown; return InterfaceType::Unknown;
} }
@ -33,12 +33,12 @@ pub fn get_interface_speed(if_name: String) -> Option<u64> {
Ok(if_speed) => { Ok(if_speed) => {
// Convert Mbps to bps // Convert Mbps to bps
return Some(if_speed * 1000000); return Some(if_speed * 1000000);
}, }
Err(_) => { Err(_) => {
return None; return None;
} }
} }
}, }
Err(_) => { Err(_) => {
return None; return None;
} }

@ -1,6 +1,6 @@
use crate::interface::InterfaceType;
use std::collections::HashMap; use std::collections::HashMap;
use system_configuration::network_configuration; use system_configuration::network_configuration;
use crate::interface::InterfaceType;
fn get_if_type_from_id(type_id: String) -> InterfaceType { fn get_if_type_from_id(type_id: String) -> InterfaceType {
match type_id.as_str() { match type_id.as_str() {
@ -11,18 +11,18 @@ fn get_if_type_from_id(type_id: String) -> InterfaceType {
} }
} }
pub fn get_if_type_map() -> HashMap<String, InterfaceType> { pub fn get_if_type_map() -> HashMap<String, InterfaceType> {
let mut map: HashMap<String, InterfaceType> = HashMap::new(); let mut map: HashMap<String, InterfaceType> = HashMap::new();
let interfaces = network_configuration::get_interfaces(); let interfaces = network_configuration::get_interfaces();
for interface in &interfaces { for interface in &interfaces {
let if_name: String = if let Some(bsd_name) = interface.bsd_name() { let if_name: String = if let Some(bsd_name) = interface.bsd_name() {
bsd_name.to_string() bsd_name.to_string()
}else{ } else {
continue; continue;
}; };
let type_id: String = if let Some(type_string) = interface.interface_type_string() { let type_id: String = if let Some(type_string) = interface.interface_type_string() {
type_string.to_string() type_string.to_string()
}else{ } else {
continue; continue;
}; };
map.insert(if_name, get_if_type_from_id(type_id)); map.insert(if_name, get_if_type_from_id(type_id));

@ -4,9 +4,25 @@ pub use self::shared::*;
mod types; mod types;
pub use self::types::*; pub use self::types::*;
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "ios", target_os = "android"))] #[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios",
target_os = "android"
))]
mod unix; mod unix;
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "ios", target_os = "android"))] #[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios",
target_os = "android"
))]
use self::unix::*; use self::unix::*;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -20,9 +36,9 @@ mod linux;
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]
mod macos; mod macos;
use std::net::IpAddr; use crate::gateway::Gateway;
use crate::ip::{Ipv4Net, Ipv6Net}; use crate::ip::{Ipv4Net, Ipv6Net};
use crate::gateway::{Gateway}; use std::net::IpAddr;
/// Structure of MAC address /// Structure of MAC address
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -31,24 +47,29 @@ pub struct MacAddr(u8, u8, u8, u8, u8, u8);
impl MacAddr { impl MacAddr {
/// Construct a new MacAddr instance from the given octets /// Construct a new MacAddr instance from the given octets
pub fn new(octets: [u8; 6]) -> MacAddr { pub fn new(octets: [u8; 6]) -> MacAddr {
MacAddr(octets[0], octets[1], octets[2], octets[3], octets[4], octets[5]) MacAddr(
octets[0], octets[1], octets[2], octets[3], octets[4], octets[5],
)
} }
/// Returns an array of MAC address octets /// Returns an array of MAC address octets
pub fn octets(&self) -> [u8; 6] { pub fn octets(&self) -> [u8; 6] {
[self.0,self.1,self.2,self.3,self.4,self.5] [self.0, self.1, self.2, self.3, self.4, self.5]
} }
/// Return a formatted string of MAC address /// Return a formatted string of MAC address
pub fn address(&self) -> String { pub fn address(&self) -> String {
format!("{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", self.0,self.1,self.2,self.3,self.4,self.5) format!(
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
self.0, self.1, self.2, self.3, self.4, self.5
)
} }
/// Construct an all-zero MacAddr instance /// Construct an all-zero MacAddr instance
pub fn zero() -> MacAddr { pub fn zero() -> MacAddr {
MacAddr(0,0,0,0,0,0) MacAddr(0, 0, 0, 0, 0, 0)
} }
/// Construct a new MacAddr instance from a colon-separated string of hex format /// Construct a new MacAddr instance from a colon-separated string of hex format
pub fn from_hex_format(hex_mac_addr: &str) -> MacAddr { pub fn from_hex_format(hex_mac_addr: &str) -> MacAddr {
if hex_mac_addr.len() != 17 { if hex_mac_addr.len() != 17 {
return MacAddr(0,0,0,0,0,0) return MacAddr(0, 0, 0, 0, 0, 0);
} }
let fields: Vec<&str> = hex_mac_addr.split(":").collect(); let fields: Vec<&str> = hex_mac_addr.split(":").collect();
let o1: u8 = u8::from_str_radix(&fields[0], 0x10).unwrap_or(0); let o1: u8 = u8::from_str_radix(&fields[0], 0x10).unwrap_or(0);
@ -63,7 +84,11 @@ impl MacAddr {
impl std::fmt::Display for MacAddr { impl std::fmt::Display for MacAddr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let _ = write!(f,"{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}",self.0,self.1,self.2,self.3,self.4,self.5); let _ = write!(
f,
"{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}",
self.0, self.1, self.2, self.3, self.4, self.5
);
Ok(()) Ok(())
} }
} }
@ -76,7 +101,7 @@ pub struct Interface {
/// Name of network interface /// Name of network interface
pub name: String, pub name: String,
/// Friendly Name of network interface /// Friendly Name of network interface
pub friendly_name : Option<String>, pub friendly_name: Option<String>,
/// Description of the network interface /// Description of the network interface
pub description: Option<String>, pub description: Option<String>,
/// Interface Type /// Interface Type
@ -99,7 +124,7 @@ pub struct Interface {
/// Get default Network Interface /// 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 get_local_ipaddr(){ let local_ip: IpAddr = match 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")),
}; };
@ -110,12 +135,12 @@ pub fn get_default_interface() -> Result<Interface, String> {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) { if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Ok(iface); return Ok(iface);
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Ok(iface); return Ok(iface);
} }
}, }
} }
} }
Err(String::from("Default Interface not found")) Err(String::from("Default Interface not found"))
@ -123,7 +148,7 @@ pub fn get_default_interface() -> Result<Interface, String> {
/// Get default Network Interface index /// Get default Network Interface index
pub fn get_default_interface_index() -> Option<u32> { pub fn get_default_interface_index() -> Option<u32> {
let local_ip: IpAddr = match get_local_ipaddr(){ let local_ip: IpAddr = match get_local_ipaddr() {
Some(local_ip) => local_ip, Some(local_ip) => local_ip,
None => return None, None => return None,
}; };
@ -134,12 +159,12 @@ pub fn get_default_interface_index() -> Option<u32> {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) { if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Some(iface.index); return Some(iface.index);
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Some(iface.index); return Some(iface.index);
} }
}, }
} }
} }
None None
@ -147,7 +172,7 @@ pub fn get_default_interface_index() -> Option<u32> {
/// Get default Network Interface name /// Get default Network Interface name
pub fn get_default_interface_name() -> Option<String> { pub fn get_default_interface_name() -> Option<String> {
let local_ip: IpAddr = match get_local_ipaddr(){ let local_ip: IpAddr = match get_local_ipaddr() {
Some(local_ip) => local_ip, Some(local_ip) => local_ip,
None => return None, None => return None,
}; };
@ -158,12 +183,12 @@ pub fn get_default_interface_name() -> Option<String> {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) { if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Some(iface.name); return Some(iface.name);
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Some(iface.name); return Some(iface.name);
} }
}, }
} }
} }
None None

@ -114,7 +114,13 @@ impl InterfaceType {
} }
} }
/// Returns OS-specific value of InterfaceType /// Returns OS-specific value of InterfaceType
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "ios"))] #[cfg(any(
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios"
))]
pub fn value(&self) -> u32 { pub fn value(&self) -> u32 {
// TODO // TODO
match *self { match *self {
@ -168,7 +174,9 @@ impl TryFrom<u32> for InterfaceType {
x if x == InterfaceType::PrimaryIsdn.value() => Ok(InterfaceType::PrimaryIsdn), x if x == InterfaceType::PrimaryIsdn.value() => Ok(InterfaceType::PrimaryIsdn),
x if x == InterfaceType::Ppp.value() => Ok(InterfaceType::Ppp), x if x == InterfaceType::Ppp.value() => Ok(InterfaceType::Ppp),
x if x == InterfaceType::Loopback.value() => Ok(InterfaceType::Loopback), x if x == InterfaceType::Loopback.value() => Ok(InterfaceType::Loopback),
x if x == InterfaceType::Ethernet3Megabit.value() => Ok(InterfaceType::Ethernet3Megabit), x if x == InterfaceType::Ethernet3Megabit.value() => {
Ok(InterfaceType::Ethernet3Megabit)
}
x if x == InterfaceType::Slip.value() => Ok(InterfaceType::Slip), x if x == InterfaceType::Slip.value() => Ok(InterfaceType::Slip),
x if x == InterfaceType::Atm.value() => Ok(InterfaceType::Atm), x if x == InterfaceType::Atm.value() => Ok(InterfaceType::Atm),
x if x == InterfaceType::GenericModem.value() => Ok(InterfaceType::GenericModem), x if x == InterfaceType::GenericModem.value() => Ok(InterfaceType::GenericModem),
@ -179,12 +187,18 @@ impl TryFrom<u32> for InterfaceType {
x if x == InterfaceType::AsymmetricDsl.value() => Ok(InterfaceType::AsymmetricDsl), x if x == InterfaceType::AsymmetricDsl.value() => Ok(InterfaceType::AsymmetricDsl),
x if x == InterfaceType::RateAdaptDsl.value() => Ok(InterfaceType::RateAdaptDsl), x if x == InterfaceType::RateAdaptDsl.value() => Ok(InterfaceType::RateAdaptDsl),
x if x == InterfaceType::SymmetricDsl.value() => Ok(InterfaceType::SymmetricDsl), x if x == InterfaceType::SymmetricDsl.value() => Ok(InterfaceType::SymmetricDsl),
x if x == InterfaceType::VeryHighSpeedDsl.value() => Ok(InterfaceType::VeryHighSpeedDsl), x if x == InterfaceType::VeryHighSpeedDsl.value() => {
Ok(InterfaceType::VeryHighSpeedDsl)
}
x if x == InterfaceType::IPOverAtm.value() => Ok(InterfaceType::IPOverAtm), x if x == InterfaceType::IPOverAtm.value() => Ok(InterfaceType::IPOverAtm),
x if x == InterfaceType::GigabitEthernet.value() => Ok(InterfaceType::GigabitEthernet), x if x == InterfaceType::GigabitEthernet.value() => Ok(InterfaceType::GigabitEthernet),
x if x == InterfaceType::Tunnel.value() => Ok(InterfaceType::Tunnel), x if x == InterfaceType::Tunnel.value() => Ok(InterfaceType::Tunnel),
x if x == InterfaceType::MultiRateSymmetricDsl.value() => Ok(InterfaceType::MultiRateSymmetricDsl), x if x == InterfaceType::MultiRateSymmetricDsl.value() => {
x if x == InterfaceType::HighPerformanceSerialBus.value() => Ok(InterfaceType::HighPerformanceSerialBus), Ok(InterfaceType::MultiRateSymmetricDsl)
}
x if x == InterfaceType::HighPerformanceSerialBus.value() => {
Ok(InterfaceType::HighPerformanceSerialBus)
}
x if x == InterfaceType::Wman.value() => Ok(InterfaceType::Wman), x if x == InterfaceType::Wman.value() => Ok(InterfaceType::Wman),
x if x == InterfaceType::Wwanpp.value() => Ok(InterfaceType::Wwanpp), x if x == InterfaceType::Wwanpp.value() => Ok(InterfaceType::Wwanpp),
x if x == InterfaceType::Wwanpp2.value() => Ok(InterfaceType::Wwanpp2), x if x == InterfaceType::Wwanpp2.value() => Ok(InterfaceType::Wwanpp2),

@ -1,21 +1,21 @@
use super::Interface; use super::Interface;
use super::MacAddr; use super::MacAddr;
use crate::sys;
use crate::gateway; use crate::gateway;
use crate::ip::{Ipv4Net, Ipv6Net}; use crate::ip::{Ipv4Net, Ipv6Net};
use crate::sys;
use crate::interface::InterfaceType;
use libc; use libc;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::mem::{self, MaybeUninit}; use std::mem::{self, MaybeUninit};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::os::raw::c_char; use std::os::raw::c_char;
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use crate::interface::InterfaceType;
#[cfg(any(target_os = "openbsd", target_os = "freebsd", target_os = "netbsd"))] #[cfg(any(target_os = "openbsd", target_os = "freebsd", target_os = "netbsd"))]
pub fn interfaces() -> Vec<Interface> { pub fn interfaces() -> Vec<Interface> {
let mut interfaces: Vec<Interface> = unix_interfaces(); let mut interfaces: Vec<Interface> = unix_interfaces();
let local_ip: IpAddr = match super::get_local_ipaddr(){ let local_ip: IpAddr = match super::get_local_ipaddr() {
Some(local_ip) => local_ip, Some(local_ip) => local_ip,
None => return interfaces, None => return interfaces,
}; };
@ -26,21 +26,21 @@ pub fn interfaces() -> Vec<Interface> {
match gateway::unix::get_default_gateway(iface.name.clone()) { match gateway::unix::get_default_gateway(iface.name.clone()) {
Ok(gateway) => { Ok(gateway) => {
iface.gateway = Some(gateway); iface.gateway = Some(gateway);
}, }
Err(_) => {}, Err(_) => {}
} }
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
match gateway::unix::get_default_gateway(iface.name.clone()) { match gateway::unix::get_default_gateway(iface.name.clone()) {
Ok(gateway) => { Ok(gateway) => {
iface.gateway = Some(gateway); iface.gateway = Some(gateway);
}, }
Err(_) => {}, Err(_) => {}
} }
} }
}, }
} }
} }
interfaces interfaces
@ -52,7 +52,7 @@ pub fn interfaces() -> Vec<Interface> {
let type_map = macos::get_if_type_map(); let type_map = macos::get_if_type_map();
let mut interfaces: Vec<Interface> = unix_interfaces(); let mut interfaces: Vec<Interface> = unix_interfaces();
let local_ip: IpAddr = match super::get_local_ipaddr(){ let local_ip: IpAddr = match super::get_local_ipaddr() {
Some(local_ip) => local_ip, Some(local_ip) => local_ip,
None => return interfaces, None => return interfaces,
}; };
@ -64,21 +64,21 @@ pub fn interfaces() -> Vec<Interface> {
match gateway::unix::get_default_gateway(iface.name.clone()) { match gateway::unix::get_default_gateway(iface.name.clone()) {
Ok(gateway) => { Ok(gateway) => {
iface.gateway = Some(gateway); iface.gateway = Some(gateway);
}, }
Err(_) => {}, Err(_) => {}
} }
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
match gateway::unix::get_default_gateway(iface.name.clone()) { match gateway::unix::get_default_gateway(iface.name.clone()) {
Ok(gateway) => { Ok(gateway) => {
iface.gateway = Some(gateway); iface.gateway = Some(gateway);
}, }
Err(_) => {}, Err(_) => {}
} }
} }
}, }
} }
} }
interfaces interfaces
@ -89,7 +89,7 @@ pub fn interfaces() -> Vec<Interface> {
use super::linux; use super::linux;
let mut interfaces: Vec<Interface> = unix_interfaces(); let mut interfaces: Vec<Interface> = unix_interfaces();
let local_ip: IpAddr = match super::get_local_ipaddr(){ let local_ip: IpAddr = match super::get_local_ipaddr() {
Some(local_ip) => local_ip, Some(local_ip) => local_ip,
None => return interfaces, None => return interfaces,
}; };
@ -104,21 +104,21 @@ pub fn interfaces() -> Vec<Interface> {
match gateway::linux::get_default_gateway(iface.name.clone()) { match gateway::linux::get_default_gateway(iface.name.clone()) {
Ok(gateway) => { Ok(gateway) => {
iface.gateway = Some(gateway); iface.gateway = Some(gateway);
}, }
Err(_) => {}, Err(_) => {}
} }
} }
}, }
IpAddr::V6(local_ipv6) => { IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) { if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
match gateway::linux::get_default_gateway(iface.name.clone()) { match gateway::linux::get_default_gateway(iface.name.clone()) {
Ok(gateway) => { Ok(gateway) => {
iface.gateway = Some(gateway); iface.gateway = Some(gateway);
}, }
Err(_) => {}, Err(_) => {}
} }
} }
}, }
} }
} }
interfaces interfaces
@ -144,10 +144,8 @@ fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option<MacAddr>, Opti
(Some(mac), None) (Some(mac), None)
} else { } else {
let addr = sys::sockaddr_to_addr( let addr =
mem::transmute(sa), sys::sockaddr_to_addr(mem::transmute(sa), mem::size_of::<libc::sockaddr_storage>());
mem::size_of::<libc::sockaddr_storage>(),
);
match addr { match addr {
Ok(SocketAddr::V4(sa)) => (None, Some(IpAddr::V4(*sa.ip()))), Ok(SocketAddr::V4(sa)) => (None, Some(IpAddr::V4(*sa.ip()))),
@ -158,7 +156,13 @@ fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option<MacAddr>, Opti
} }
} }
#[cfg(any(target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "macos", target_os = "ios"))] #[cfg(any(
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "macos",
target_os = "ios"
))]
fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option<MacAddr>, Option<IpAddr>) { fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option<MacAddr>, Option<IpAddr>) {
use crate::bpf; use crate::bpf;
use std::net::SocketAddr; use std::net::SocketAddr;
@ -180,10 +184,8 @@ fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option<MacAddr>, Opti
(Some(mac), None) (Some(mac), None)
} else { } else {
let addr = sys::sockaddr_to_addr( let addr =
mem::transmute(sa), sys::sockaddr_to_addr(mem::transmute(sa), mem::size_of::<libc::sockaddr_storage>());
mem::size_of::<libc::sockaddr_storage>(),
);
match addr { match addr {
Ok(SocketAddr::V4(sa)) => (None, Some(IpAddr::V4(*sa.ip()))), Ok(SocketAddr::V4(sa)) => (None, Some(IpAddr::V4(*sa.ip()))),
@ -203,10 +205,10 @@ pub fn unix_interfaces() -> Vec<Interface> {
let addrs = unsafe { addrs.assume_init() }; let addrs = unsafe { addrs.assume_init() };
let mut addr = addrs; let mut addr = addrs;
while !addr.is_null() { while !addr.is_null() {
let addr_ref: &libc::ifaddrs = unsafe {&*addr}; let addr_ref: &libc::ifaddrs = unsafe { &*addr };
let c_str = addr_ref.ifa_name as *const c_char; let c_str = addr_ref.ifa_name as *const c_char;
let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() }; let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };
let name = unsafe {from_utf8_unchecked(bytes).to_owned() }; let name = unsafe { from_utf8_unchecked(bytes).to_owned() };
let (mac, ip) = sockaddr_to_network_addr(addr_ref.ifa_addr as *const libc::sockaddr); let (mac, ip) = sockaddr_to_network_addr(addr_ref.ifa_addr as *const libc::sockaddr);
let (_, netmask) = sockaddr_to_network_addr(addr_ref.ifa_netmask as *const libc::sockaddr); let (_, netmask) = sockaddr_to_network_addr(addr_ref.ifa_netmask as *const libc::sockaddr);
let mut ini_ipv4: Vec<Ipv4Net> = vec![]; let mut ini_ipv4: Vec<Ipv4Net> = vec![];
@ -215,33 +217,29 @@ pub fn unix_interfaces() -> Vec<Interface> {
match ip { match ip {
IpAddr::V4(ipv4) => { IpAddr::V4(ipv4) => {
let netmask: Ipv4Addr = match netmask { let netmask: Ipv4Addr = match netmask {
Some(netmask) => { Some(netmask) => match netmask {
match netmask { IpAddr::V4(netmask) => netmask,
IpAddr::V4(netmask) => netmask, IpAddr::V6(_) => Ipv4Addr::UNSPECIFIED,
IpAddr::V6(_) => Ipv4Addr::UNSPECIFIED,
}
}, },
None => Ipv4Addr::UNSPECIFIED, None => Ipv4Addr::UNSPECIFIED,
}; };
let ipv4_net: Ipv4Net = Ipv4Net::new_with_netmask(ipv4, netmask); let ipv4_net: Ipv4Net = Ipv4Net::new_with_netmask(ipv4, netmask);
ini_ipv4.push(ipv4_net); ini_ipv4.push(ipv4_net);
}, }
IpAddr::V6(ipv6) => { IpAddr::V6(ipv6) => {
let netmask: Ipv6Addr = match netmask { let netmask: Ipv6Addr = match netmask {
Some(netmask) => { Some(netmask) => match netmask {
match netmask { IpAddr::V4(_) => Ipv6Addr::UNSPECIFIED,
IpAddr::V4(_) => Ipv6Addr::UNSPECIFIED, IpAddr::V6(netmask) => netmask,
IpAddr::V6(netmask) => netmask,
}
}, },
None => Ipv6Addr::UNSPECIFIED, None => Ipv6Addr::UNSPECIFIED,
}; };
let ipv6_net: Ipv6Net = Ipv6Net::new_with_netmask(ipv6, netmask); let ipv6_net: Ipv6Net = Ipv6Net::new_with_netmask(ipv6, netmask);
ini_ipv6.push(ipv6_net); ini_ipv6.push(ipv6_net);
}, }
} }
} }
let interface: Interface = Interface{ let interface: Interface = Interface {
index: 0, index: 0,
name: name.clone(), name: name.clone(),
friendly_name: None, friendly_name: None,
@ -265,30 +263,26 @@ pub fn unix_interfaces() -> Vec<Interface> {
match ip { match ip {
IpAddr::V4(ipv4) => { IpAddr::V4(ipv4) => {
let netmask: Ipv4Addr = match netmask { let netmask: Ipv4Addr = match netmask {
Some(netmask) => { Some(netmask) => match netmask {
match netmask { IpAddr::V4(netmask) => netmask,
IpAddr::V4(netmask) => netmask, IpAddr::V6(_) => Ipv4Addr::UNSPECIFIED,
IpAddr::V6(_) => Ipv4Addr::UNSPECIFIED,
}
}, },
None => Ipv4Addr::UNSPECIFIED, None => Ipv4Addr::UNSPECIFIED,
}; };
let ipv4_net: Ipv4Net = Ipv4Net::new_with_netmask(ipv4, netmask); let ipv4_net: Ipv4Net = Ipv4Net::new_with_netmask(ipv4, netmask);
iface.ipv4.push(ipv4_net); iface.ipv4.push(ipv4_net);
}, }
IpAddr::V6(ipv6) => { IpAddr::V6(ipv6) => {
let netmask: Ipv6Addr = match netmask { let netmask: Ipv6Addr = match netmask {
Some(netmask) => { Some(netmask) => match netmask {
match netmask { IpAddr::V4(_) => Ipv6Addr::UNSPECIFIED,
IpAddr::V4(_) => Ipv6Addr::UNSPECIFIED, IpAddr::V6(netmask) => netmask,
IpAddr::V6(netmask) => netmask,
}
}, },
None => Ipv6Addr::UNSPECIFIED, None => Ipv6Addr::UNSPECIFIED,
}; };
let ipv6_net: Ipv6Net = Ipv6Net::new_with_netmask(ipv6, netmask); let ipv6_net: Ipv6Net = Ipv6Net::new_with_netmask(ipv6, netmask);
iface.ipv6.push(ipv6_net); iface.ipv6.push(ipv6_net);
}, }
} }
} }
found = true; found = true;
@ -299,10 +293,14 @@ pub fn unix_interfaces() -> Vec<Interface> {
} }
addr = addr_ref.ifa_next; addr = addr_ref.ifa_next;
} }
unsafe{ libc::freeifaddrs(addrs); } unsafe {
libc::freeifaddrs(addrs);
}
for iface in &mut ifaces { for iface in &mut ifaces {
let name = CString::new(iface.name.as_bytes()).unwrap(); let name = CString::new(iface.name.as_bytes()).unwrap();
unsafe { iface.index = libc::if_nametoindex(name.as_ptr()); } unsafe {
iface.index = libc::if_nametoindex(name.as_ptr());
}
} }
ifaces ifaces
} }

@ -1,40 +1,50 @@
use windows::Win32::Foundation::{ERROR_BUFFER_OVERFLOW, NO_ERROR};
use windows::Win32::Networking::WinSock::{SOCKADDR_IN, SOCKADDR_IN6};
use windows::Win32::NetworkManagement::IpHelper::{GetAdaptersAddresses, AF_UNSPEC, AF_INET, AF_INET6, GAA_FLAG_INCLUDE_GATEWAYS, IP_ADAPTER_ADDRESSES_LH, SendARP};
use std::convert::TryInto;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::convert::TryFrom;
use core::ffi::c_void; use core::ffi::c_void;
use libc::{c_char, strlen, wchar_t, wcslen}; use libc::{c_char, strlen, wchar_t, wcslen};
use memalloc::{allocate, deallocate}; use memalloc::{allocate, deallocate};
use std::convert::TryFrom;
use std::convert::TryInto;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use windows::Win32::Foundation::{ERROR_BUFFER_OVERFLOW, NO_ERROR};
use windows::Win32::NetworkManagement::IpHelper::{
GetAdaptersAddresses, SendARP, AF_INET, AF_INET6, AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS,
IP_ADAPTER_ADDRESSES_LH,
};
use windows::Win32::Networking::WinSock::{SOCKADDR_IN, SOCKADDR_IN6};
use crate::ip::{Ipv4Net, Ipv6Net};
use crate::interface::{Interface, MacAddr,InterfaceType};
use crate::gateway::Gateway; use crate::gateway::Gateway;
use crate::interface::{Interface, InterfaceType, MacAddr};
use crate::ip::{Ipv4Net, Ipv6Net};
#[cfg(target_endian = "little")] #[cfg(target_endian = "little")]
fn htonl(val : u32) -> u32 { fn htonl(val: u32) -> u32 {
let o3 = (val >> 24) as u8; let o3 = (val >> 24) as u8;
let o2 = (val >> 16) as u8; let o2 = (val >> 16) as u8;
let o1 = (val >> 8) as u8; let o1 = (val >> 8) as u8;
let o0 = val as u8; let o0 = val as u8;
(o0 as u32) << 24 | (o1 as u32) << 16 | (o2 as u32) << 8 | (o3 as u32) (o0 as u32) << 24 | (o1 as u32) << 16 | (o2 as u32) << 8 | (o3 as u32)
} }
#[cfg(target_endian = "big")] #[cfg(target_endian = "big")]
fn htonl(val : u32) -> u32 { fn htonl(val: u32) -> u32 {
val val
} }
fn get_mac_through_arp(src_ip: Ipv4Addr, dst_ip: Ipv4Addr) -> MacAddr { fn get_mac_through_arp(src_ip: Ipv4Addr, dst_ip: Ipv4Addr) -> MacAddr {
let src_ip_int: u32 = htonl(u32::from(src_ip)); let src_ip_int: u32 = htonl(u32::from(src_ip));
let dst_ip_int: u32 = htonl(u32::from(dst_ip)); let dst_ip_int: u32 = htonl(u32::from(dst_ip));
let mut out_buf_len : u32 = 6; let mut out_buf_len: u32 = 6;
let mut target_mac_addr: [u8; 6] = [0; 6]; let mut target_mac_addr: [u8; 6] = [0; 6];
let res = unsafe { SendARP(dst_ip_int, src_ip_int, target_mac_addr.as_mut_ptr() as *mut c_void, &mut out_buf_len) }; let res = unsafe {
SendARP(
dst_ip_int,
src_ip_int,
target_mac_addr.as_mut_ptr() as *mut c_void,
&mut out_buf_len,
)
};
if res == NO_ERROR.0 { if res == NO_ERROR.0 {
MacAddr::new(target_mac_addr) MacAddr::new(target_mac_addr)
}else{ } else {
MacAddr::zero() MacAddr::zero()
} }
} }
@ -49,7 +59,15 @@ pub fn interfaces() -> Vec<Interface> {
let mut ret_val; let mut ret_val;
loop { loop {
let old_size = dwsize as usize; let old_size = dwsize as usize;
ret_val = unsafe { GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS, std::ptr::null_mut::<std::ffi::c_void>(), mem, &mut dwsize) }; ret_val = unsafe {
GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_GATEWAYS,
std::ptr::null_mut::<std::ffi::c_void>(),
mem,
&mut dwsize,
)
};
if ret_val != ERROR_BUFFER_OVERFLOW.0 || retries <= 0 { if ret_val != ERROR_BUFFER_OVERFLOW.0 || retries <= 0 {
break; break;
} }
@ -61,17 +79,17 @@ pub fn interfaces() -> Vec<Interface> {
// Enumerate all adapters // Enumerate all adapters
let mut cur = mem; let mut cur = mem;
while !cur.is_null() { while !cur.is_null() {
let if_type: u32 = unsafe{ (*cur).IfType }; let if_type: u32 = unsafe { (*cur).IfType };
match InterfaceType::try_from(if_type) { match InterfaceType::try_from(if_type) {
Ok(_) => {}, Ok(_) => {}
Err(_) => { Err(_) => {
cur = unsafe { (*cur).Next }; cur = unsafe { (*cur).Next };
continue; continue;
}, }
} }
// Index // Index
let anon1 = unsafe { (*cur).Anonymous1 }; let anon1 = unsafe { (*cur).Anonymous1 };
let anon = unsafe { anon1.Anonymous}; let anon = unsafe { anon1.Anonymous };
let index = anon.IfIndex; let index = anon.IfIndex;
// Flags // Flags
let anon2 = unsafe { (*cur).Anonymous2 }; let anon2 = unsafe { (*cur).Anonymous2 };
@ -87,26 +105,28 @@ pub fn interfaces() -> Vec<Interface> {
let fname_slice = unsafe { std::slice::from_raw_parts(p_fname, fname_len) }; let fname_slice = unsafe { std::slice::from_raw_parts(p_fname, fname_len) };
let friendly_name = String::from_utf16(fname_slice).unwrap(); let friendly_name = String::from_utf16(fname_slice).unwrap();
// Description // Description
let p_desc = unsafe { (*cur).Description.0}; let p_desc = unsafe { (*cur).Description.0 };
let desc_len = unsafe { wcslen(p_desc as *const wchar_t) }; let desc_len = unsafe { wcslen(p_desc as *const wchar_t) };
let desc_slice = unsafe { std::slice::from_raw_parts(p_desc, desc_len) }; let desc_slice = unsafe { std::slice::from_raw_parts(p_desc, desc_len) };
let description = String::from_utf16(desc_slice).unwrap(); let description = String::from_utf16(desc_slice).unwrap();
// MAC address // MAC address
let mac_addr_arr: [u8; 6] = unsafe { (*cur).PhysicalAddress }[..6].try_into().unwrap_or([0, 0, 0, 0, 0, 0]); let mac_addr_arr: [u8; 6] = unsafe { (*cur).PhysicalAddress }[..6]
.try_into()
.unwrap_or([0, 0, 0, 0, 0, 0]);
let mac_addr: MacAddr = MacAddr::new(mac_addr_arr); let mac_addr: MacAddr = MacAddr::new(mac_addr_arr);
// TransmitLinkSpeed (bits per second) // TransmitLinkSpeed (bits per second)
let transmit_speed = unsafe { (*cur).TransmitLinkSpeed}; let transmit_speed = unsafe { (*cur).TransmitLinkSpeed };
// ReceiveLinkSpeed (bits per second) // ReceiveLinkSpeed (bits per second)
let receive_speed = unsafe { (*cur).ReceiveLinkSpeed}; let receive_speed = unsafe { (*cur).ReceiveLinkSpeed };
let mut ipv4_vec: Vec<Ipv4Net> = vec![]; let mut ipv4_vec: Vec<Ipv4Net> = vec![];
let mut ipv6_vec: Vec<Ipv6Net> = vec![]; let mut ipv6_vec: Vec<Ipv6Net> = vec![];
// Enumerate all IPs // Enumerate all IPs
let mut cur_a = unsafe { (*cur).FirstUnicastAddress }; let mut cur_a = unsafe { (*cur).FirstUnicastAddress };
while !cur_a.is_null() { while !cur_a.is_null() {
let addr = unsafe { (*cur_a).Address }; let addr = unsafe { (*cur_a).Address };
let prefix_len = unsafe{ (*cur_a).OnLinkPrefixLength }; let prefix_len = unsafe { (*cur_a).OnLinkPrefixLength };
let sockaddr = unsafe { *addr.lpSockaddr }; let sockaddr = unsafe { *addr.lpSockaddr };
if sockaddr.sa_family == AF_INET.0 as u16{ if sockaddr.sa_family == AF_INET.0 as u16 {
let sockaddr: *mut SOCKADDR_IN = addr.lpSockaddr as *mut SOCKADDR_IN; let sockaddr: *mut SOCKADDR_IN = addr.lpSockaddr as *mut SOCKADDR_IN;
let a = unsafe { (*sockaddr).sin_addr.S_un.S_addr }; let a = unsafe { (*sockaddr).sin_addr.S_un.S_addr };
let ipv4 = if cfg!(target_endian = "little") { let ipv4 = if cfg!(target_endian = "little") {
@ -153,13 +173,13 @@ pub fn interfaces() -> Vec<Interface> {
ip_addr: IpAddr::V4(*gateway_ip), ip_addr: IpAddr::V4(*gateway_ip),
}; };
Some(gateway) Some(gateway)
}else{ } else {
None None
} }
}, }
None => None, None => None,
}; };
let interface: Interface = Interface{ let interface: Interface = Interface {
index: index, index: index,
name: adapter_name, name: adapter_name,
friendly_name: Some(friendly_name), friendly_name: Some(friendly_name),

@ -97,11 +97,15 @@ fn ipv6_netmask_to_prefix(netmask: Ipv6Addr) -> u8 {
} }
fn prefix_to_ipv4_netmask(prefix_len: u8) -> Ipv4Addr { fn prefix_to_ipv4_netmask(prefix_len: u8) -> Ipv4Addr {
let netmask_u32: u32 = u32::max_value().checked_shl(32 - prefix_len as u32).unwrap_or(0); let netmask_u32: u32 = u32::max_value()
.checked_shl(32 - prefix_len as u32)
.unwrap_or(0);
Ipv4Addr::from(netmask_u32) Ipv4Addr::from(netmask_u32)
} }
fn prefix_to_ipv6_netmask(prefix_len: u8) -> Ipv6Addr { fn prefix_to_ipv6_netmask(prefix_len: u8) -> Ipv6Addr {
let netmask_u128: u128 = u128::max_value().checked_shl((128 - prefix_len) as u32).unwrap_or(u128::min_value()); let netmask_u128: u128 = u128::max_value()
.checked_shl((128 - prefix_len) as u32)
.unwrap_or(u128::min_value());
Ipv6Addr::from(netmask_u128) Ipv6Addr::from(netmask_u128)
} }

@ -1,16 +1,28 @@
#[cfg(not(target_os="windows"))] #[cfg(any(
mod sys; target_os = "macos",
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "ios"))] target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios"
))]
mod bpf; mod bpf;
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "freebsd", target_os = "netbsd", target_os = "ios"))] #[cfg(any(
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios"
))]
mod socket; mod socket;
#[cfg(not(target_os = "windows"))]
mod sys;
pub mod ip;
pub mod interface;
pub mod gateway; pub mod gateway;
pub mod interface;
pub mod ip;
pub use interface::Interface; pub use gateway::get_default_gateway;
pub use gateway::Gateway;
pub use interface::get_default_interface; pub use interface::get_default_interface;
pub use interface::get_interfaces; pub use interface::get_interfaces;
pub use gateway::Gateway; pub use interface::Interface;
pub use gateway::get_default_gateway;

@ -1,8 +1,8 @@
pub mod packet; pub mod packet;
#[cfg(not(target_os="windows"))] #[cfg(not(target_os = "windows"))]
mod unix; mod unix;
#[cfg(not(target_os="windows"))] #[cfg(not(target_os = "windows"))]
pub use self::unix::*; pub use self::unix::*;
#[cfg(test)] #[cfg(test)]
@ -16,7 +16,7 @@ mod tests {
Err(e) => { Err(e) => {
println!("Failed to create UDP socket {}", e); println!("Failed to create UDP socket {}", e);
return; return;
}, }
}; };
let dst: &str = "1.1.1.1:80"; let dst: &str = "1.1.1.1:80";
match socket.set_ttl(1) { match socket.set_ttl(1) {
@ -24,14 +24,14 @@ mod tests {
Err(e) => { Err(e) => {
println!("Failed to set TTL {}", e); println!("Failed to set TTL {}", e);
return; return;
}, }
} }
match socket.send_to(&buf, dst) { match socket.send_to(&buf, dst) {
Ok(_) => (), Ok(_) => (),
Err(e) => { Err(e) => {
println!("Failed to send data {}", e); println!("Failed to send data {}", e);
return; return;
}, }
} }
} }
#[test] #[test]
@ -55,17 +55,15 @@ mod tests {
loop { loop {
match rx.next() { match rx.next() {
Ok(frame) => { Ok(frame) => match packet::parse_frame(frame) {
match packet::parse_frame(frame){ Ok(gateway) => {
Ok(gateway) => { println!("Default Gateway:");
println!("Default Gateway:"); println!("{}", gateway.mac_addr);
println!("{}", gateway.mac_addr); println!("{}", gateway.ip_addr);
println!("{}", gateway.ip_addr); return;
return; }
}, Err(_) => {
Err(_) => { println!("Parse Error");
println!("Parse Error");
},
} }
}, },
Err(e) => { Err(e) => {
@ -76,4 +74,3 @@ mod tests {
} }
} }
} }

@ -1,6 +1,6 @@
use std::convert::TryInto;
use crate::gateway::Gateway; use crate::gateway::Gateway;
use crate::interface::MacAddr; use crate::interface::MacAddr;
use std::convert::TryInto;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::u16; use std::u16;
@ -76,11 +76,18 @@ fn convert_ipv6_bytes(bytes: [u8; 16]) -> Ipv6Addr {
} }
pub fn parse_frame(frame: &[u8]) -> Result<Gateway, ()> { pub fn parse_frame(frame: &[u8]) -> Result<Gateway, ()> {
let src_mac: [u8; 6] = frame[Frame::SrcMacAddr.start_index()..Frame::SrcMacAddr.end_index()].try_into().unwrap(); let src_mac: [u8; 6] = frame[Frame::SrcMacAddr.start_index()..Frame::SrcMacAddr.end_index()]
let ether_type: [u8; 2] = frame[Frame::EtherType.start_index()..Frame::EtherType.end_index()].try_into().unwrap(); .try_into()
.unwrap();
let ether_type: [u8; 2] = frame[Frame::EtherType.start_index()..Frame::EtherType.end_index()]
.try_into()
.unwrap();
match ether_type { match ether_type {
ETHER_TYPE_IPV4 => { ETHER_TYPE_IPV4 => {
let src_ip: [u8; 4] = frame[Frame::SrcIpv4Addr.start_index()..Frame::SrcIpv4Addr.end_index()].try_into().unwrap(); let src_ip: [u8; 4] = frame
[Frame::SrcIpv4Addr.start_index()..Frame::SrcIpv4Addr.end_index()]
.try_into()
.unwrap();
let next_header_protocol: u8 = frame[Frame::NextHeaderProtocolIpv4.start_index()]; let next_header_protocol: u8 = frame[Frame::NextHeaderProtocolIpv4.start_index()];
if next_header_protocol == NEXT_HEADER_ICMP { if next_header_protocol == NEXT_HEADER_ICMP {
let icmp_type: u8 = frame[Frame::IcmpType.start_index()]; let icmp_type: u8 = frame[Frame::IcmpType.start_index()];
@ -92,9 +99,12 @@ pub fn parse_frame(frame: &[u8]) -> Result<Gateway, ()> {
return Ok(gateway); return Ok(gateway);
} }
} }
}, }
ETHER_TYPE_IPV6 => { ETHER_TYPE_IPV6 => {
let src_ip: [u8; 16] = frame[Frame::SrcIpv6Addr.start_index()..Frame::SrcIpv6Addr.end_index()].try_into().unwrap(); let src_ip: [u8; 16] = frame
[Frame::SrcIpv6Addr.start_index()..Frame::SrcIpv6Addr.end_index()]
.try_into()
.unwrap();
let next_header_protocol: u8 = frame[Frame::NextHeaderProtocolIpv6.start_index()]; let next_header_protocol: u8 = frame[Frame::NextHeaderProtocolIpv6.start_index()];
if next_header_protocol == NEXT_HEADER_ICMPV6 { if next_header_protocol == NEXT_HEADER_ICMPV6 {
let icmp_type: u8 = frame[Frame::Icmpv6Type.start_index()]; let icmp_type: u8 = frame[Frame::Icmpv6Type.start_index()];
@ -109,8 +119,8 @@ pub fn parse_frame(frame: &[u8]) -> Result<Gateway, ()> {
} }
} }
} }
}, }
_ => {}, _ => {}
} }
Err(()) Err(())
} }

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

@ -27,7 +27,8 @@ pub fn sockaddr_to_addr(storage: &SockAddrStorage, len: usize) -> io::Result<Soc
let o2 = (ip >> 16) as u8; let o2 = (ip >> 16) as u8;
let o3 = (ip >> 8) as u8; let o3 = (ip >> 8) as u8;
let o4 = ip as u8; let o4 = ip as u8;
let sockaddrv4 = SocketAddrV4::new(Ipv4Addr::new(o1, o2, o3, o4), ntohs(storage.sin_port)); let sockaddrv4 =
SocketAddrV4::new(Ipv4Addr::new(o1, o2, o3, o4), ntohs(storage.sin_port));
Ok(SocketAddr::V4(sockaddrv4)) Ok(SocketAddr::V4(sockaddrv4))
} }
AF_INET6 => { AF_INET6 => {
@ -51,7 +52,7 @@ pub fn sockaddr_to_addr(storage: &SockAddrStorage, len: usize) -> io::Result<Soc
storage.sin6_scope_id, storage.sin6_scope_id,
))) )))
} }
_ => Err(io::Error::new(io::ErrorKind::InvalidData, "Not supported",)), _ => Err(io::Error::new(io::ErrorKind::InvalidData, "Not supported")),
} }
} }

Loading…
Cancel
Save