Skip to content

Commit a569b35

Browse files
committed
Add BSD support by reusing Linux code
1 parent 86978f6 commit a569b35

File tree

4 files changed

+60
-8
lines changed

4 files changed

+60
-8
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ readme = "README.md"
1616
serde = { version = "1.0.183", features = ["derive"], optional = true}
1717
thiserror = "1.0"
1818

19-
[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies]
19+
[target.'cfg(any(target_os = "android", target_os = "linux", target_os = "netbsd", target_os = "freebsd"))'.dependencies]
2020
libc = "0.2.101"
2121

2222
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]

src/target/linux.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use std::collections::HashMap;
33
use std::net::{Ipv4Addr, Ipv6Addr};
44
use std::slice::from_raw_parts;
55

6-
use libc::{
7-
sockaddr_in, sockaddr_in6, strlen, AF_INET, AF_INET6, if_nametoindex, sockaddr_ll, AF_PACKET,
8-
};
6+
use libc::{sockaddr_in, sockaddr_in6, strlen, AF_INET, AF_INET6, if_nametoindex};
97

108
use crate::target::getifaddrs;
119
use crate::{Error, NetworkInterface, NetworkInterfaceConfig, Result};
@@ -24,7 +22,8 @@ impl NetworkInterfaceConfig for NetworkInterface {
2422
};
2523

2624
let mut network_interface = match netifa_family {
27-
AF_PACKET => {
25+
#[cfg(target_os = "linux")]
26+
libc::AF_PACKET => {
2827
let name = make_netifa_name(&netifa)?;
2928
let mac = make_mac_addrs(&netifa);
3029
let index = netifa_index(&netifa);
@@ -35,6 +34,19 @@ impl NetworkInterfaceConfig for NetworkInterface {
3534
index,
3635
}
3736
}
37+
#[cfg(any(target_os = "netbsd", target_os = "freebsd"))]
38+
libc::AF_LINK => {
39+
let name = make_netifa_name(&netifa)?;
40+
let mac = make_mac_addrs(&netifa);
41+
let index = netifa_index(&netifa);
42+
43+
NetworkInterface {
44+
name,
45+
addr: Vec::new(),
46+
mac_addr: Some(mac),
47+
index,
48+
}
49+
}
3850
AF_INET => {
3951
let socket_addr = netifa_addr as *mut sockaddr_in;
4052
let internet_address = unsafe { (*socket_addr).sin_addr };
@@ -87,7 +99,10 @@ fn make_netifa_name(netifa: &libc::ifaddrs) -> Result<String> {
8799
///
88100
/// https://man7.org/linux/man-pages/man3/getifaddrs.3.html
89101
fn make_ipv4_broadcast_addr(netifa: &libc::ifaddrs) -> Result<Option<Ipv4Addr>> {
102+
#[cfg(target_os = "linux")]
90103
let ifa_dstaddr = netifa.ifa_ifu;
104+
#[cfg(not(target_os = "linux"))]
105+
let ifa_dstaddr = netifa.ifa_dstaddr;
91106

92107
if ifa_dstaddr.is_null() {
93108
return Ok(None);
@@ -107,7 +122,10 @@ fn make_ipv4_broadcast_addr(netifa: &libc::ifaddrs) -> Result<Option<Ipv4Addr>>
107122
///
108123
/// https://man7.org/linux/man-pages/man3/getifaddrs.3.html
109124
fn make_ipv6_broadcast_addr(netifa: &libc::ifaddrs) -> Result<Option<Ipv6Addr>> {
125+
#[cfg(target_os = "linux")]
110126
let ifa_dstaddr = netifa.ifa_ifu;
127+
#[cfg(not(target_os = "linux"))]
128+
let ifa_dstaddr = netifa.ifa_dstaddr;
111129

112130
if ifa_dstaddr.is_null() {
113131
return Ok(None);
@@ -120,9 +138,10 @@ fn make_ipv6_broadcast_addr(netifa: &libc::ifaddrs) -> Result<Option<Ipv6Addr>>
120138
Ok(Some(addr))
121139
}
122140

141+
#[cfg(target_os = "linux")]
123142
fn make_mac_addrs(netifa: &libc::ifaddrs) -> String {
124143
let netifa_addr = netifa.ifa_addr;
125-
let socket_addr = netifa_addr as *mut sockaddr_ll;
144+
let socket_addr = netifa_addr as *mut libc::sockaddr_ll;
126145
let mac_array = unsafe { (*socket_addr).sll_addr };
127146
let addr_len = unsafe { (*socket_addr).sll_halen };
128147
let real_addr_len = std::cmp::min(addr_len as usize, mac_array.len());
@@ -135,6 +154,25 @@ fn make_mac_addrs(netifa: &libc::ifaddrs) -> String {
135154
.join(":")
136155
}
137156

157+
#[cfg(not(target_os = "linux"))]
158+
fn make_mac_addrs(netifa: &libc::ifaddrs) -> String {
159+
let netifa_addr = netifa.ifa_addr;
160+
let socket_addr = netifa_addr as *mut libc::sockaddr_dl;
161+
let mac_array = unsafe { (*socket_addr).sdl_data };
162+
let addr_len = unsafe { (*socket_addr).sdl_alen } as usize;
163+
let name_len = unsafe { (*socket_addr).sdl_nlen } as usize;
164+
//let sel_len = unsafe { (*socket_addr).sdl_slen } as usize;
165+
//let real_addr_len = std::cmp::min(addr_len as usize, mac_array.len());
166+
let data_slice = unsafe { std::slice::from_raw_parts(mac_array.as_ptr(), name_len + addr_len) };
167+
let mac_slice = &data_slice[name_len..];
168+
169+
mac_slice
170+
.iter()
171+
.map(|x| format!("{:02x}", x))
172+
.collect::<Vec<_>>()
173+
.join(":")
174+
}
175+
138176
/// Retreives the name for the the network interface provided
139177
///
140178
/// ## References

src/target/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
#[cfg(any(target_os = "android", target_os = "linux"))]
1+
#[cfg(any(
2+
target_os = "android",
3+
target_os = "linux",
4+
target_os = "freebsd",
5+
target_os = "netbsd"
6+
))]
27
mod linux;
38

4-
#[cfg(any(target_os = "android", target_os = "linux"))]
9+
#[cfg(any(
10+
target_os = "android",
11+
target_os = "linux",
12+
target_os = "freebsd",
13+
target_os = "netbsd"
14+
))]
515
pub use linux::*;
616

717
#[cfg(any(target_os = "macos", target_os = "ios"))]

src/utils/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ pub mod hex;
33
#[cfg(any(
44
target_os = "android",
55
target_os = "linux",
6+
target_os = "netbsd",
7+
target_os = "freebsd",
68
target_os = "ios",
79
target_os = "macos"
810
))]
@@ -11,6 +13,8 @@ mod unix;
1113
#[cfg(any(
1214
target_os = "android",
1315
target_os = "linux",
16+
target_os = "netbsd",
17+
target_os = "freebsd",
1418
target_os = "ios",
1519
target_os = "macos"
1620
))]

0 commit comments

Comments
 (0)