Merge pull request #23 from link2xt/cargo-fmt

Run `cargo fmt` and add GitHub Actions check
main
shellrow 2 years ago committed by GitHub
commit 07a3fce1ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      .github/workflows/ci.yml
  2. 6
      examples/default_gateway.rs
  3. 10
      examples/default_interface.rs
  4. 6
      examples/list_interfaces.rs
  5. 41
      src/bpf/binding.rs
  6. 9
      src/bpf/mod.rs
  7. 11
      src/bpf/unix.rs
  8. 8
      src/gateway/linux.rs
  9. 18
      src/gateway/mod.rs
  10. 18
      src/gateway/unix.rs
  11. 14
      src/interface/linux.rs
  12. 8
      src/interface/macos.rs
  13. 67
      src/interface/mod.rs
  14. 24
      src/interface/types.rs
  15. 122
      src/interface/unix.rs
  16. 80
      src/interface/windows.rs
  17. 8
      src/ip.rs
  18. 30
      src/lib.rs
  19. 31
      src/socket/mod.rs
  20. 26
      src/socket/packet.rs
  21. 4
      src/sys/mod.rs
  22. 5
      src/sys/unix.rs

@ -0,0 +1,16 @@
name: CI
on:
pull_request:
push:
branches:
- main
jobs:
lint:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run rustfmt
run: cargo fmt --all --check

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

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

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

@ -20,17 +20,24 @@ const SIZEOF_C_UINT: libc::c_ulong = 4;
#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
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 BIOCIMMEDIATE: libc::c_ulong = IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 112;
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;
pub const BIOCSETIF: libc::c_ulong =
IOC_IN | ((SIZEOF_IFREQ & IOCPARM_MASK) << 16usize) | (('B' as libc::c_ulong) << 8usize) | 108;
pub const BIOCIMMEDIATE: libc::c_ulong =
IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 112;
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")]
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")]
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;
@ -47,10 +54,16 @@ pub fn BPF_WORDALIGN(x: isize) -> isize {
pub struct ifreq {
pub ifr_name: [libc::c_char; IFNAMSIZ],
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 sdl_len: libc::c_uchar,
pub sdl_family: libc::c_uchar,
@ -65,7 +78,10 @@ pub struct sockaddr_dl {
#[cfg(any(
target_os = "freebsd",
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
))]
#[repr(C)]
@ -83,7 +99,10 @@ pub struct timeval32 {
#[cfg(any(
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)]
pub struct bpf_hdr {

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

@ -1,6 +1,6 @@
use super::binding;
use crate::socket::{DataLinkReceiver, DataLinkSender};
use crate::interface::Interface;
use crate::socket::{DataLinkReceiver, DataLinkSender};
use std::collections::VecDeque;
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() },
write_buffer: vec![0; config.write_buffer_size],
loopback: loopback,
timeout: config
.write_timeout
.map(|to| duration_to_timespec(to)),
timeout: config.write_timeout.map(|to| duration_to_timespec(to)),
});
unsafe {
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() },
read_buffer: vec![0; allocated_read_buffer_size],
loopback: loopback,
timeout: config
.read_timeout
.map(|to| duration_to_timespec(to)),
timeout: config.read_timeout.map(|to| duration_to_timespec(to)),
packets: VecDeque::with_capacity(allocated_read_buffer_size / 64),
});
unsafe {
@ -245,7 +241,6 @@ impl DataLinkSender for DataLinkSenderImpl {
if len >= self.write_buffer.len() {
None
} else {
let offset = if self.loopback {
ETHERNET_HEADER_SIZE
} 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 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_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> {
match super::send_udp_packet() {
Ok(_) => {},
Ok(_) => {}
Err(e) => return Err(format!("Failed to send UDP packet {}", e)),
}
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;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) mod linux;
use crate::interface::{self, Interface, MacAddr};
use std::net::{IpAddr, Ipv4Addr};
use crate::interface::{self, MacAddr, Interface};
/// Structure of default Gateway information
#[derive(Clone, Debug)]
@ -28,7 +34,7 @@ impl Gateway {
/// Get default Gateway
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,
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);
}
}
},
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
if let Some(gateway) = iface.gateway {
return Ok(gateway);
}
}
},
}
}
}
Err(String::from("Default Gateway not found"))
}
#[cfg(not(target_os="windows"))]
#[cfg(not(target_os = "windows"))]
fn send_udp_packet() -> Result<(), String> {
use std::net::UdpSocket;
let buf = [0u8; 0];

@ -1,6 +1,6 @@
use std::time::{Duration, Instant};
use crate::socket;
use super::Gateway;
use crate::socket;
use std::time::{Duration, Instant};
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)) => {
_tx = etx;
rx = erx;
},
}
Err(e) => return Err(format!("Failed to create channel {}", e)),
}
match super::send_udp_packet() {
@ -30,19 +30,17 @@ pub fn get_default_gateway(interface_name: String) -> Result<Gateway, String> {
}
loop {
match rx.next() {
Ok(frame) => {
match socket::packet::parse_frame(frame){
Ok(gateway) => {
return Ok(gateway);
},
Err(_) => {},
Ok(frame) => match socket::packet::parse_frame(frame) {
Ok(gateway) => {
return Ok(gateway);
}
Err(_) => {}
},
Err(_) => {}
}
if Instant::now().duration_since(start_time) > timeout {
return Err(String::from("Recieve timeout"));
}else{
} else {
match super::send_udp_packet() {
Ok(_) => (),
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::fs::read_to_string;
use crate::interface::InterfaceType;
pub fn get_interface_type(if_name: String) -> InterfaceType {
let if_type_path: String = format!("/sys/class/net/{}/type", if_name);
@ -11,16 +11,16 @@ pub fn get_interface_type(if_name: String) -> InterfaceType {
match if_type_string.parse::<u32>() {
Ok(if_type) => {
return InterfaceType::try_from(if_type).unwrap_or(InterfaceType::Unknown);
},
}
Err(_) => {
return InterfaceType::Unknown;
}
}
},
}
Err(_) => {
return InterfaceType::Unknown;
}
};
};
}
pub fn get_interface_speed(if_name: String) -> Option<u64> {
@ -33,14 +33,14 @@ pub fn get_interface_speed(if_name: String) -> Option<u64> {
Ok(if_speed) => {
// Convert Mbps to bps
return Some(if_speed * 1000000);
},
}
Err(_) => {
return None;
}
}
},
}
Err(_) => {
return None;
}
};
};
}

@ -1,6 +1,6 @@
use crate::interface::InterfaceType;
use std::collections::HashMap;
use system_configuration::network_configuration;
use crate::interface::InterfaceType;
fn get_if_type_from_id(type_id: String) -> InterfaceType {
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 interfaces = network_configuration::get_interfaces();
for interface in &interfaces {
let if_name: String = if let Some(bsd_name) = interface.bsd_name() {
bsd_name.to_string()
}else{
} else {
continue;
};
let type_id: String = if let Some(type_string) = interface.interface_type_string() {
type_string.to_string()
}else{
} else {
continue;
};
map.insert(if_name, get_if_type_from_id(type_id));

@ -4,9 +4,25 @@ pub use self::shared::*;
mod 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;
#[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::*;
#[cfg(target_os = "windows")]
@ -20,9 +36,9 @@ mod linux;
#[cfg(any(target_os = "macos", target_os = "ios"))]
mod macos;
use std::net::IpAddr;
use crate::gateway::Gateway;
use crate::ip::{Ipv4Net, Ipv6Net};
use crate::gateway::{Gateway};
use std::net::IpAddr;
/// Structure of MAC address
#[derive(Clone, Debug)]
@ -31,24 +47,29 @@ pub struct MacAddr(u8, u8, u8, u8, u8, u8);
impl MacAddr {
/// Construct a new MacAddr instance from the given octets
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
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
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
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
pub fn from_hex_format(hex_mac_addr: &str) -> MacAddr {
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 o1: u8 = u8::from_str_radix(&fields[0], 0x10).unwrap_or(0);
@ -63,8 +84,12 @@ impl MacAddr {
impl std::fmt::Display for MacAddr {
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);
Ok(())
let _ = write!(
f,
"{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}",
self.0, self.1, self.2, self.3, self.4, self.5
);
Ok(())
}
}
@ -76,7 +101,7 @@ pub struct Interface {
/// Name of network interface
pub name: String,
/// Friendly Name of network interface
pub friendly_name : Option<String>,
pub friendly_name: Option<String>,
/// Description of the network interface
pub description: Option<String>,
/// Interface Type
@ -99,7 +124,7 @@ pub struct Interface {
/// Get default Network Interface
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,
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) {
return Ok(iface);
}
},
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Ok(iface);
}
},
}
}
}
Err(String::from("Default Interface not found"))
@ -123,7 +148,7 @@ pub fn get_default_interface() -> Result<Interface, String> {
/// Get default Network Interface index
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,
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) {
return Some(iface.index);
}
},
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Some(iface.index);
}
},
}
}
}
None
@ -147,7 +172,7 @@ pub fn get_default_interface_index() -> Option<u32> {
/// Get default Network Interface name
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,
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) {
return Some(iface.name);
}
},
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Some(iface.name);
}
},
}
}
}
None

@ -114,7 +114,13 @@ impl 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 {
// TODO
match *self {
@ -168,7 +174,9 @@ impl TryFrom<u32> for InterfaceType {
x if x == InterfaceType::PrimaryIsdn.value() => Ok(InterfaceType::PrimaryIsdn),
x if x == InterfaceType::Ppp.value() => Ok(InterfaceType::Ppp),
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::Atm.value() => Ok(InterfaceType::Atm),
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::RateAdaptDsl.value() => Ok(InterfaceType::RateAdaptDsl),
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::GigabitEthernet.value() => Ok(InterfaceType::GigabitEthernet),
x if x == InterfaceType::Tunnel.value() => Ok(InterfaceType::Tunnel),
x if x == InterfaceType::MultiRateSymmetricDsl.value() => Ok(InterfaceType::MultiRateSymmetricDsl),
x if x == InterfaceType::HighPerformanceSerialBus.value() => Ok(InterfaceType::HighPerformanceSerialBus),
x if x == InterfaceType::MultiRateSymmetricDsl.value() => {
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::Wwanpp.value() => Ok(InterfaceType::Wwanpp),
x if x == InterfaceType::Wwanpp2.value() => Ok(InterfaceType::Wwanpp2),

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

@ -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 libc::{c_char, strlen, wchar_t, wcslen};
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::interface::{Interface, InterfaceType, MacAddr};
use crate::ip::{Ipv4Net, Ipv6Net};
#[cfg(target_endian = "little")]
fn htonl(val : u32) -> u32 {
fn htonl(val: u32) -> u32 {
let o3 = (val >> 24) as u8;
let o2 = (val >> 16) as u8;
let o1 = (val >> 8) as u8;
let o0 = val as u8;
let o1 = (val >> 8) as u8;
let o0 = val as u8;
(o0 as u32) << 24 | (o1 as u32) << 16 | (o2 as u32) << 8 | (o3 as u32)
}
#[cfg(target_endian = "big")]
fn htonl(val : u32) -> u32 {
fn htonl(val: u32) -> u32 {
val
}
fn get_mac_through_arp(src_ip: Ipv4Addr, dst_ip: Ipv4Addr) -> MacAddr {
let src_ip_int: u32 = htonl(u32::from(src_ip));
let dst_ip_int: u32 = htonl(u32::from(dst_ip));
let mut out_buf_len : u32 = 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 mut out_buf_len: u32 = 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,
)
};
if res == NO_ERROR.0 {
MacAddr::new(target_mac_addr)
}else{
} else {
MacAddr::zero()
}
}
@ -49,7 +59,15 @@ pub fn interfaces() -> Vec<Interface> {
let mut ret_val;
loop {
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 {
break;
}
@ -61,17 +79,17 @@ pub fn interfaces() -> Vec<Interface> {
// Enumerate all adapters
let mut cur = mem;
while !cur.is_null() {
let if_type: u32 = unsafe{ (*cur).IfType };
let if_type: u32 = unsafe { (*cur).IfType };
match InterfaceType::try_from(if_type) {
Ok(_) => {},
Ok(_) => {}
Err(_) => {
cur = unsafe { (*cur).Next };
continue;
},
}
}
// Index
let anon1 = unsafe { (*cur).Anonymous1 };
let anon = unsafe { anon1.Anonymous};
let anon = unsafe { anon1.Anonymous };
let index = anon.IfIndex;
// Flags
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 friendly_name = String::from_utf16(fname_slice).unwrap();
// 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_slice = unsafe { std::slice::from_raw_parts(p_desc, desc_len) };
let description = String::from_utf16(desc_slice).unwrap();
// 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);
// TransmitLinkSpeed (bits per second)
let transmit_speed = unsafe { (*cur).TransmitLinkSpeed};
let transmit_speed = unsafe { (*cur).TransmitLinkSpeed };
// 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 ipv6_vec: Vec<Ipv6Net> = vec![];
// Enumerate all IPs
let mut cur_a = unsafe { (*cur).FirstUnicastAddress };
while !cur_a.is_null() {
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 };
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 a = unsafe { (*sockaddr).sin_addr.S_un.S_addr };
let ipv4 = if cfg!(target_endian = "little") {
@ -153,13 +173,13 @@ pub fn interfaces() -> Vec<Interface> {
ip_addr: IpAddr::V4(*gateway_ip),
};
Some(gateway)
}else{
} else {
None
}
},
}
None => None,
};
let interface: Interface = Interface{
let interface: Interface = Interface {
index: index,
name: adapter_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 {
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)
}
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)
}

@ -1,16 +1,28 @@
#[cfg(not(target_os="windows"))]
mod sys;
#[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 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;
#[cfg(not(target_os = "windows"))]
mod sys;
pub mod ip;
pub mod interface;
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_interfaces;
pub use gateway::Gateway;
pub use gateway::get_default_gateway;
pub use interface::Interface;

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

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

@ -1,4 +1,4 @@
#[cfg(not(target_os="windows"))]
#[cfg(not(target_os = "windows"))]
mod unix;
#[cfg(not(target_os="windows"))]
#[cfg(not(target_os = "windows"))]
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 o3 = (ip >> 8) 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))
}
AF_INET6 => {
@ -51,7 +52,7 @@ pub fn sockaddr_to_addr(storage: &SockAddrStorage, len: usize) -> io::Result<Soc
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