Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
cba785b
feat: Obtain info via routing sockets
larseggert Oct 1, 2024
f3bd16f
Fixes
larseggert Oct 1, 2024
36d2c49
Fixes
larseggert Oct 1, 2024
3d3833c
Linux
larseggert Oct 1, 2024
b491400
Windows
larseggert Oct 1, 2024
44a1163
Fixes
larseggert Oct 1, 2024
89d1fe7
Clippy
larseggert Oct 1, 2024
ed1795f
Clippy
larseggert Oct 1, 2024
e95c38f
Update src/bsd.rs
larseggert Oct 2, 2024
f2444ce
Try and fix sanitizer issue
larseggert Oct 2, 2024
ee08c78
Rearrange Windows code
larseggert Oct 2, 2024
ff7fb82
Fixes
larseggert Oct 2, 2024
fa0cd57
Merge branch 'main' into feat-from-routing
larseggert Oct 2, 2024
356c669
Fixes
larseggert Oct 2, 2024
66fdaab
Omit win_bindings.rs from codecov (again)
larseggert Oct 2, 2024
4d0e274
Update docs
larseggert Oct 2, 2024
8e35eea
Read all socket responses to allow socket reuse
larseggert Oct 3, 2024
e8060db
Update README
larseggert Oct 3, 2024
71aa8de
Add .clippy.toml
larseggert Oct 3, 2024
6b700d6
Merge branch 'main' into feat-from-routing
larseggert Oct 7, 2024
a58dc65
Update src/windows/mod.rs
larseggert Oct 7, 2024
9c892c7
Drop neli
larseggert Oct 7, 2024
774d6ff
Cleanups
larseggert Oct 7, 2024
856d12b
Nit
larseggert Oct 7, 2024
2cfa562
Fixes
larseggert Oct 7, 2024
c5f0d1f
Fix
larseggert Oct 7, 2024
62de28c
Fix
larseggert Oct 7, 2024
4fda855
Simplify
larseggert Oct 7, 2024
f3336c5
Also install llvm-symbolizer for the sanitizer runs
larseggert Oct 8, 2024
a0816e6
Fixes
larseggert Oct 8, 2024
8fbcbfb
Fixes
larseggert Oct 8, 2024
7825347
Merge branch 'main' into feat-from-routing
larseggert Oct 8, 2024
87eb36c
README
larseggert Oct 8, 2024
9a8b72d
clippy
larseggert Oct 8, 2024
6aac56c
Tweaks
larseggert Oct 9, 2024
a0428ca
Misc improvements
larseggert Oct 10, 2024
cd3b4f3
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1
larseggert Oct 10, 2024
dab41d1
Suppress
larseggert Oct 10, 2024
7c51f5f
LSAN_OPTIONS
larseggert Oct 10, 2024
41d51bb
llvm
larseggert Oct 10, 2024
cfa9077
path
larseggert Oct 10, 2024
473fadc
Again
larseggert Oct 10, 2024
30444c3
Again
larseggert Oct 10, 2024
a69908d
Again
larseggert Oct 10, 2024
b80169d
Again
larseggert Oct 10, 2024
75e00c0
Again
larseggert Oct 10, 2024
20b2396
Again
larseggert Oct 10, 2024
86a592f
Again
larseggert Oct 10, 2024
6467f8b
Again
larseggert Oct 10, 2024
9e536ce
Again
larseggert Oct 10, 2024
d8d7dc1
Again
larseggert Oct 10, 2024
3f3fe9a
Again
larseggert Oct 10, 2024
a9b372c
Again
larseggert Oct 10, 2024
ee711fc
Again
larseggert Oct 10, 2024
4d43a3c
Again
larseggert Oct 10, 2024
c58eda9
Update src/linux.rs
larseggert Oct 11, 2024
5f57b4a
Use `OwnedFd`
larseggert Oct 11, 2024
248391b
Address code review
larseggert Oct 21, 2024
4a77574
BSDs and Windows
larseggert Oct 21, 2024
b00aebd
ifconfig
larseggert Oct 21, 2024
075f311
env
larseggert Oct 21, 2024
18a6938
rmx_filler
larseggert Oct 21, 2024
e571427
Debug
larseggert Oct 21, 2024
6942ecc
Debug
larseggert Oct 21, 2024
1eac2ee
send
larseggert Oct 21, 2024
a20ffea
recv
larseggert Oct 21, 2024
0901ad8
Again
larseggert Oct 21, 2024
546a452
Again
larseggert Oct 21, 2024
807116f
Again
larseggert Oct 21, 2024
1304c70
mtu
larseggert Oct 21, 2024
6b7d0f5
Fix cloudflare.com v6 address
larseggert Oct 22, 2024
813ae8d
Undo
larseggert Oct 22, 2024
789d964
rt_metrics
larseggert Oct 22, 2024
c2b27a9
More BSD
larseggert Oct 22, 2024
4691e18
RTAX_IFA
larseggert Oct 22, 2024
76d7eb9
All the BSDs are different, sigh
larseggert Oct 22, 2024
8f71dea
More
larseggert Oct 23, 2024
63ed25f
codecov
larseggert Oct 23, 2024
5155ee7
Again
larseggert Oct 23, 2024
33e9a9b
binstall
larseggert Oct 23, 2024
a873c43
cargo-llvm-cov
larseggert Oct 23, 2024
c9a8d5b
Again
larseggert Oct 23, 2024
b667a86
llvm
larseggert Oct 24, 2024
42b9747
Minimize conversions
larseggert Oct 24, 2024
fe78985
More
larseggert Oct 24, 2024
647308e
Merge branch 'main' into feat-from-routing
larseggert Oct 24, 2024
54c6435
Again
larseggert Oct 24, 2024
59f806b
Again
larseggert Oct 24, 2024
4c95881
Again
larseggert Oct 24, 2024
f9e5544
Again
larseggert Oct 24, 2024
4871a6b
Again
larseggert Oct 24, 2024
707f8ba
More
larseggert Oct 24, 2024
1dc568a
Again
larseggert Oct 24, 2024
ccdc7d5
Again
larseggert Oct 24, 2024
a080cff
Linux fix
larseggert Oct 24, 2024
858f344
More
larseggert Oct 24, 2024
bb96df8
stable
larseggert Oct 24, 2024
f7a9cc5
Simplify
larseggert Oct 25, 2024
fe9b4bd
More comments
larseggert Oct 25, 2024
9a89840
Merge branch 'main' into feat-from-routing
larseggert Oct 28, 2024
017dac4
Use bindgen
larseggert Oct 28, 2024
88a6363
Address code review
larseggert Oct 29, 2024
e02ccc2
Iterator
larseggert Nov 1, 2024
01ab445
Final fixes
larseggert Nov 1, 2024
e632413
Install llvm
larseggert Nov 1, 2024
cccc097
Workflow fixes
larseggert Nov 1, 2024
7f70fa9
Hack
larseggert Nov 1, 2024
acda937
Fix?
larseggert Nov 1, 2024
a0f8aac
CI
larseggert Nov 1, 2024
7aa1395
llvm-16.0.6p30
larseggert Nov 1, 2024
7601069
netbsd
larseggert Nov 1, 2024
cefe001
netbsd
larseggert Nov 1, 2024
a5b2795
clang
larseggert Nov 1, 2024
c372658
Remove unused code.
larseggert Nov 1, 2024
fc4793f
More helpers
larseggert Nov 1, 2024
91786da
Tweaks
larseggert Nov 2, 2024
6bb1324
Fix
larseggert Nov 2, 2024
15ccf0b
Address code review
larseggert Nov 8, 2024
f52f2d4
Merge branch 'main' into feat-from-routing
larseggert Nov 8, 2024
6b3dd15
Update .github/workflows/check.yml
larseggert Nov 11, 2024
fd20bfe
Update .github/workflows/check.yml
larseggert Nov 11, 2024
23867de
Update .github/workflows/check.yml
larseggert Nov 11, 2024
c27bbce
Update src/bsd.rs
larseggert Nov 12, 2024
226a16d
Update src/linux.rs
larseggert Nov 12, 2024
58f761b
Address first batch of comments from @martinthomson
larseggert Nov 12, 2024
a6f8773
Suppress shellcheck warning
larseggert Nov 12, 2024
26ea760
More suggestions from @martinthomson
larseggert Nov 12, 2024
269ff34
Use `std::io::Result`
larseggert Nov 12, 2024
dfdf14a
clippy
larseggert Nov 15, 2024
bd0305d
Nits
larseggert Nov 15, 2024
a3b2240
Merge branch 'main' into feat-from-routing
larseggert Nov 18, 2024
0a07c86
Suggestions from @martinthomson
larseggert Nov 21, 2024
766a075
Fix
larseggert Nov 21, 2024
bc104e9
Macro
larseggert Nov 21, 2024
0f1c742
Not Windows
larseggert Nov 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ rust-version = "1.76.0"
# Don't increase beyond what Firefox is currently using: https://searchfox.org/mozilla-central/source/Cargo.lock
libc = { version = "0.2", default-features = false }

[dev-dependencies]
rand = { version = "0.8", default-features = false, features = ["std", "std_rng"] }
[target.'cfg(target_os = "linux")'.dependencies]
neli = { version = "0.6", default-features = false }

[target."cfg(windows)".dependencies]
# Don't increase beyond what Firefox is currently using: https://searchfox.org/mozilla-central/source/Cargo.lock
Expand Down
144 changes: 144 additions & 0 deletions src/bsd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::{slice, str};
use std::{ffi::c_void, io::Error, mem, mem::size_of, net::IpAddr, ptr};

use libc::{
close, getpid, read, rt_msghdr, sockaddr_dl, sockaddr_in, sockaddr_in6, sockaddr_storage,
socket, write, AF_INET, AF_INET6, PF_ROUTE, RTAX_IFP, RTAX_MAX, RTA_DST, RTA_IFP, RTM_GET,
RTM_VERSION, SOCK_RAW,
};

use crate::default_err;

#[allow(clippy::too_many_lines)]
pub fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize), Error> {
// Open route socket.
let fd = unsafe { socket(PF_ROUTE, SOCK_RAW, 0) };
if fd == -1 {
return Err(Error::last_os_error());
}

// Prepare buffer with destination `sockaddr`.
#[allow(clippy::cast_possible_truncation)]
let dst: &[u8] = match remote {
IpAddr::V4(ip) => {
let mut sin: sockaddr_in = unsafe { mem::zeroed() };
sin.sin_len = size_of::<sockaddr_in>() as u8;
sin.sin_family = AF_INET as u8;
sin.sin_addr.s_addr = u32::from_ne_bytes(ip.octets());
unsafe {
slice::from_raw_parts(
ptr::from_ref::<sockaddr_in>(&sin).cast::<u8>(),
size_of::<sockaddr_in>(),
)
}
}
IpAddr::V6(ip) => {
let mut sin6: sockaddr_in6 = unsafe { mem::zeroed() };
sin6.sin6_len = size_of::<sockaddr_in6>() as u8;
sin6.sin6_family = AF_INET6 as u8;
sin6.sin6_addr.s6_addr = ip.octets();
unsafe {
slice::from_raw_parts(
ptr::from_ref::<sockaddr_in6>(&sin6).cast::<u8>(),
size_of::<sockaddr_in6>(),
)
}
}
};

// Prepare route message structure.
let mut rtm: rt_msghdr = unsafe { mem::zeroed() };
#[allow(clippy::cast_possible_truncation)]
{
rtm.rtm_msglen = (size_of::<rt_msghdr>() + dst.len()) as u16; // Length includes sockaddr
rtm.rtm_version = RTM_VERSION as u8;
rtm.rtm_type = RTM_GET as u8;
}
rtm.rtm_seq = fd; // Abuse file descriptor as sequence number, since it's unique
rtm.rtm_addrs = RTA_DST | RTA_IFP; // Query for destination and obtain interface info

// Copy route message and destination `sockaddr` into message buffer.
let mut msg: Vec<u8> = vec![0; rtm.rtm_msglen as usize];
unsafe {
ptr::copy_nonoverlapping(
ptr::from_ref::<rt_msghdr>(&rtm).cast::<u8>(),
msg.as_mut_ptr(),
size_of::<rt_msghdr>(),
);
ptr::copy_nonoverlapping(
dst.as_ptr(),
msg.as_mut_ptr().add(size_of::<rt_msghdr>()),
dst.len(),
);
}

// Send route message.
let res = unsafe { write(fd, msg.as_ptr().cast::<c_void>(), msg.len()) };
if res == -1 {
unsafe { close(fd) };
return Err(Error::last_os_error());
}

// Read route messages.
let mut buf = vec![
0u8;
size_of::<rt_msghdr>() +
// There will never be `RTAX_MAX` sockaddrs, but it's a safe upper bound
(RTAX_MAX as usize * size_of::<sockaddr_storage>())
];
let rtm = loop {
let len = unsafe { read(fd, buf.as_mut_ptr().cast::<c_void>(), buf.len()) };
if len <= 0 {
unsafe { close(fd) };
return Err(Error::last_os_error());
}
let rtm = unsafe { ptr::read_unaligned(buf.as_ptr().cast::<rt_msghdr>()) };
#[allow(clippy::cast_possible_truncation)]
if rtm.rtm_type == RTM_GET as u8 && rtm.rtm_pid == unsafe { getpid() } && rtm.rtm_seq == fd
{
// This is the response we are looking for.
break rtm;
}
};

// Close the route socket.
unsafe { close(fd) };

// Parse the route message for the interface name.
let mut sa = unsafe { buf.as_ptr().add(size_of::<rt_msghdr>()) };
for i in 0..RTAX_MAX {
let sdl = unsafe { ptr::read_unaligned(sa.cast::<sockaddr_dl>()) };
// Check if the address is present in the message
if rtm.rtm_addrs & (1 << i) != 0 {
// Check if the address is the interface address
if i == RTAX_IFP {
if let Ok(name) = unsafe {
str::from_utf8(std::slice::from_raw_parts(
sdl.sdl_data.as_ptr().cast::<u8>(),
sdl.sdl_nlen as usize,
))
} {
// We have our interface name.
return Ok((name.to_string(), rtm.rtm_rmx.rmx_mtu as usize));
}
}
// Advance to the next address. The length is always a multiple of 4, so we need to do
// some awkward manipulation.
sa = unsafe {
sa.add(if sdl.sdl_len == 0 {
4
} else {
((sdl.sdl_len - 1) | 3) + 1
} as usize)
};
}
}

Err(default_err())
}
Loading