Skip to content

Commit

Permalink
Sockaddr (meh#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssrlive authored Apr 14, 2024
1 parent 00f0f16 commit d73452b
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 192 deletions.
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ protocol = "sparse"
# target = ["aarch64-apple-ios"]
# target = ["x86_64-pc-windows-msvc"]
# target = ["x86_64-apple-darwin"]
# target = ["x86_64-unknown-freebsd"]
8 changes: 8 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ env:
jobs:
build_n_test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]

Expand All @@ -17,10 +18,17 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: rustfmt
if: ${{ !cancelled() }}
run: cargo fmt --all -- --check
- name: check
if: ${{ !cancelled() }}
run: cargo check --verbose
- name: clippy
if: ${{ !cancelled() }}
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Build
if: ${{ !cancelled() }}
run: cargo build --verbose --examples --tests --all-features --features="async tokio/rt-multi-thread"
- name: Abort on error
if: ${{ failure() }}
run: echo "Some of jobs failed" && false
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ crate-type = ["staticlib", "cdylib", "lib"]
bytes = { version = "1" }
cfg-if = "1.0"
futures-core = { version = "0.3", optional = true }
libc = { version="0.2", features=["extra_traits"] }
libc = { version = "0.2", features = ["extra_traits"] }
log = "0.4"
thiserror = "1"
tokio = { version = "1", features = [
Expand Down
37 changes: 13 additions & 24 deletions src/platform/freebsd/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{
device::AbstractDevice,
error::{Error, Result},
platform::freebsd::sys::*,
platform::posix::{self, Fd, SockAddr, Tun},
platform::posix::{self, sockaddr_to_rs_addr, Fd, Tun},
};

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -164,9 +164,9 @@ impl Device {
self.tun_name.len(),
);

req.addr = SockAddr::from(addr).into();
req.dstaddr = SockAddr::from(dest).into();
req.mask = SockAddr::from(mask).into();
req.addr = posix::rs_addr_to_sockaddr((addr, 0).into()).addr;
req.dstaddr = posix::rs_addr_to_sockaddr((dest, 0).into()).addr;
req.mask = posix::rs_addr_to_sockaddr((mask, 0).into()).addr;

if let Err(err) = siocaifaddr(ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
Expand Down Expand Up @@ -321,14 +321,11 @@ impl AbstractDevice for Device {
fn address(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifaddr(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_addr).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_addr as *const _ as *const posix::sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

Expand All @@ -351,14 +348,11 @@ impl AbstractDevice for Device {
fn destination(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_dstaddr).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_dstaddr as *const _ as *const posix::sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

Expand All @@ -381,14 +375,11 @@ impl AbstractDevice for Device {
fn broadcast(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_broadaddr).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_broadaddr as *const _ as *const posix::sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

Expand All @@ -399,14 +390,12 @@ impl AbstractDevice for Device {
fn netmask(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifnetmask(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_addr).map(Into::into)?,
))
// NOTE: Here should be `ifru_netmask` instead of `ifru_addr`, but `ifreq` does not define it.
let sa = &req.ifr_ifru.ifru_addr as *const _ as *const posix::sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

Expand Down
60 changes: 15 additions & 45 deletions src/platform/linux/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ use crate::{
device::AbstractDevice,
error::{Error, Result},
platform::linux::sys::*,
platform::posix::{self, Fd, SockAddr, Tun},
platform::posix::{self, ipaddr_to_sockaddr, sockaddr_to_rs_addr, sockaddr_union, Fd, Tun},
};

const OVERWRITE_SIZE: usize = std::mem::size_of::<libc::__c_anonymous_ifr_ifru>();

/// A TUN device using the TUN/TAP Linux driver.
pub struct Device {
tun_name: String,
Expand Down Expand Up @@ -261,119 +263,87 @@ impl AbstractDevice for Device {
fn address(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifaddr(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_addr).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_addr as *const _ as *const sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

fn set_address(&mut self, value: IpAddr) -> Result<()> {
let IpAddr::V4(value) = value else {
unimplemented!("do not support IPv6 yet")
};
unsafe {
let mut req = self.request();
req.ifr_ifru.ifru_addr = SockAddr::from(value).into();

ipaddr_to_sockaddr(value, 0, &mut req.ifr_ifru.ifru_addr, OVERWRITE_SIZE);
if let Err(err) = siocsifaddr(self.ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
}

Ok(())
}
}

fn destination(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_dstaddr).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_dstaddr as *const _ as *const sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

fn set_destination(&mut self, value: IpAddr) -> Result<()> {
let IpAddr::V4(value) = value else {
unimplemented!("do not support IPv6 yet")
};
unsafe {
let mut req = self.request();
req.ifr_ifru.ifru_dstaddr = SockAddr::from(value).into();

ipaddr_to_sockaddr(value, 0, &mut req.ifr_ifru.ifru_dstaddr, OVERWRITE_SIZE);
if let Err(err) = siocsifdstaddr(self.ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
}

Ok(())
}
}

fn broadcast(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_broadaddr).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_broadaddr as *const _ as *const sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

fn set_broadcast(&mut self, value: IpAddr) -> Result<()> {
let IpAddr::V4(value) = value else {
unimplemented!("do not support IPv6 yet")
};
unsafe {
let mut req = self.request();
req.ifr_ifru.ifru_broadaddr = SockAddr::from(value).into();

ipaddr_to_sockaddr(value, 0, &mut req.ifr_ifru.ifru_broadaddr, OVERWRITE_SIZE);
if let Err(err) = siocsifbrdaddr(self.ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
}

Ok(())
}
}

fn netmask(&self) -> Result<IpAddr> {
unsafe {
let mut req = self.request();

if let Err(err) = siocgifnetmask(self.ctl.as_raw_fd(), &mut req) {
return Err(io::Error::from(err).into());
}

Ok(IpAddr::V4(
SockAddr::new(&req.ifr_ifru.ifru_netmask).map(Into::into)?,
))
let sa = &req.ifr_ifru.ifru_netmask as *const _ as *const sockaddr_union;
Ok(sockaddr_to_rs_addr(&*sa).ok_or(Error::InvalidAddress)?.ip())
}
}

fn set_netmask(&mut self, value: IpAddr) -> Result<()> {
let IpAddr::V4(value) = value else {
unimplemented!("do not support IPv6 yet")
};
unsafe {
let mut req = self.request();
req.ifr_ifru.ifru_netmask = SockAddr::from(value).into();

ipaddr_to_sockaddr(value, 0, &mut req.ifr_ifru.ifru_netmask, OVERWRITE_SIZE);
if let Err(err) = siocsifnetmask(self.ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
}

Ok(())
}
}
Expand Down
Loading

0 comments on commit d73452b

Please sign in to comment.