mod link;
pub use link::*;
pub use nix::sys::socket::{
SockaddrIn as Inet4Addr, SockaddrIn6 as Inet6Addr, SockaddrStorage as NetAddr, UnixAddr,
};
pub use std::net::{Ipv4Addr, Ipv6Addr};
pub const UNSPECIFIED6: Ipv6Addr = Ipv6Addr::UNSPECIFIED;
pub const UNSPECIFIED4: Ipv4Addr = Ipv4Addr::UNSPECIFIED;
pub const ALL_NODES: Ipv6Addr = Ipv6Addr::new(
0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
);
pub const ALL_ROUTERS: Ipv6Addr = Ipv6Addr::new(
0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002,
);
pub trait ToNetAddr {
fn to_net_addr(&self) -> NetAddr;
}
impl<X: nix::sys::socket::SockaddrLike> ToNetAddr for X {
fn to_net_addr(&self) -> NetAddr {
use nix::sys::socket::SockaddrLike;
unsafe {
NetAddr::from_raw(<Self as SockaddrLike>::as_ptr(self), Some(self.len())).unwrap()
}
}
}
pub fn tokio_to_unixaddr(src: &tokio::net::unix::SocketAddr) -> UnixAddr {
if let Some(path) = src.as_pathname() {
UnixAddr::new(path).unwrap()
} else {
unimplemented!()
}
}
pub fn to_net_addr<X: ToNetAddr>(x: X) -> NetAddr {
x.to_net_addr()
}
pub trait WithPort {
fn with_port(&self, port: u16) -> NetAddr;
}
impl WithPort for std::net::Ipv4Addr {
fn with_port(&self, port: u16) -> NetAddr {
Inet4Addr::from(std::net::SocketAddrV4::new(*self, port)).to_net_addr()
}
}
impl WithPort for std::net::Ipv6Addr {
fn with_port(&self, port: u16) -> NetAddr {
Inet6Addr::from(std::net::SocketAddrV6::new(*self, port, 0, 0)).to_net_addr()
}
}
impl WithPort for std::net::IpAddr {
fn with_port(&self, port: u16) -> NetAddr {
match self {
Self::V4(ip) => ip.with_port(port),
Self::V6(ip) => ip.with_port(port),
}
}
}
pub trait NetAddrExt {
fn to_std_socket_addr(&self) -> Option<std::net::SocketAddr>;
fn ip(&self) -> Option<std::net::IpAddr>;
fn port(&self) -> Option<u16>;
}
impl NetAddrExt for NetAddr {
fn to_std_socket_addr(&self) -> Option<std::net::SocketAddr> {
if let Some(&v4) = self.as_sockaddr_in() {
Some(std::net::SocketAddrV4::from(v4).into())
} else if let Some(&v6) = self.as_sockaddr_in6() {
Some(std::net::SocketAddrV6::from(v6).into())
} else {
None
}
}
fn ip(&self) -> Option<std::net::IpAddr> {
if let Some(&v4) = self.as_sockaddr_in() {
Some(v4.ip().into())
} else if let Some(&v6) = self.as_sockaddr_in6() {
Some(v6.ip().into())
} else {
None
}
}
fn port(&self) -> Option<u16> {
if let Some(&v4) = self.as_sockaddr_in() {
Some(v4.port())
} else if let Some(&v6) = self.as_sockaddr_in6() {
Some(v6.port())
} else {
None
}
}
}