#[derive(Clone, Copy, Debug)]
#[repr(C, align(8))]
pub struct SockAddrIpv4 {
sin_family: linux_unsafe::sa_family_t,
sin_port: u16, sin_addr: Ipv4Addr,
sin_zero: [u8; 8],
}
impl SockAddrIpv4 {
#[inline]
pub const fn new(host_addr: Ipv4Addr, port: u16) -> Self {
Self {
sin_family: AF_INET,
sin_port: port.to_be(),
sin_addr: host_addr,
sin_zero: [0; 8],
}
}
#[inline(always)]
pub const fn host_address(&self) -> Ipv4Addr {
self.sin_addr
}
#[inline(always)]
pub const fn port(&self) -> u16 {
self.sin_port.to_be() }
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Ipv4Addr {
s_addr: u32, }
impl Ipv4Addr {
pub const ANY: Self = Self { s_addr: 0x00000000 };
pub const NONE: Self = Self { s_addr: 0xffffffff };
pub const BROADCAST: Self = Self { s_addr: 0xffffffff };
pub const DUMMY: Self = Self {
s_addr: 0xc0000008_u32.to_be(),
};
pub const LOOPBACK: Self = Self {
s_addr: 0x7f000001_u32.to_be(),
};
pub const UNSPEC_GROUP: Self = Self {
s_addr: 0xe0000000_u32.to_be(),
};
pub const ALLHOSTS_GROUP: Self = Self {
s_addr: 0xe0000001_u32.to_be(),
};
pub const ALLRTRS_GROUP: Self = Self {
s_addr: 0xe0000002_u32.to_be(),
};
pub const ALLSNOOPERS_GROUP: Self = Self {
s_addr: 0xe000006a_u32.to_be(),
};
#[inline(always)]
pub const fn from_u32(raw: u32) -> Self {
Self {
s_addr: raw.to_be(),
}
}
#[inline(always)]
pub const fn from_octets(raw: [u8; 4]) -> Self {
Self::from_u32(u32::from_be_bytes(raw))
}
#[inline(always)]
pub const fn as_u32(&self) -> u32 {
self.s_addr.to_be() }
#[inline(always)]
pub const fn as_octets(&self) -> [u8; 4] {
self.as_u32().to_be_bytes()
}
pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
let our_octets = self.as_octets();
let mut new_octets = [0_u8; 16];
new_octets[10] = 0xff;
new_octets[11] = 0xff;
new_octets[12] = our_octets[0];
new_octets[13] = our_octets[1];
new_octets[14] = our_octets[2];
new_octets[15] = our_octets[3];
Ipv6Addr::from_octets(new_octets)
}
}
#[derive(Clone, Copy, Debug)]
#[repr(C, align(8))]
pub struct SockAddrIpv6 {
sin6_family: linux_unsafe::sa_family_t,
sin6_port: u16, sin6_flowinfo: u32,
sin6_addr: Ipv6Addr,
sin6_scope_id: u32,
}
impl SockAddrIpv6 {
#[inline]
pub const fn new(host_addr: Ipv6Addr, port: u16) -> Self {
Self {
sin6_family: AF_INET6,
sin6_port: port.to_be(),
sin6_addr: host_addr,
sin6_flowinfo: 0,
sin6_scope_id: 0,
}
}
#[inline]
pub const fn new_with_scope(host_addr: Ipv6Addr, port: u16, scope_id: u32) -> Self {
Self {
sin6_family: AF_INET6,
sin6_port: port.to_be(),
sin6_addr: host_addr,
sin6_flowinfo: 0,
sin6_scope_id: scope_id,
}
}
#[inline(always)]
pub const fn host_address(&self) -> Ipv6Addr {
self.sin6_addr
}
#[inline(always)]
pub const fn port(&self) -> u16 {
self.sin6_port.to_be() }
#[inline(always)]
pub const fn scope_id(&self) -> u32 {
self.sin6_scope_id
}
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Ipv6Addr {
s6_addr: [u8; 16],
}
impl Ipv6Addr {
pub const ANY: Self = Self {
s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const LOOPBACK: Self = Self {
s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
};
pub const LINKLOCAL_ALLNODES: Self = Self {
s6_addr: [0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
};
pub const LINKLOCAL_ALLROUTERS: Self = Self {
s6_addr: [0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
};
pub const INTERFACELOCAL_ALLNODES: Self = Self {
s6_addr: [0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
};
pub const INTERFACELOCAL_ALLROUTERS: Self = Self {
s6_addr: [0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
};
pub const SITELOCAL_ALLROUTERS: Self = Self {
s6_addr: [0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
};
#[inline(always)]
pub const fn from_octets(raw: [u8; 16]) -> Self {
Self { s6_addr: raw }
}
#[inline(always)]
pub const fn as_octets(&self) -> [u8; 16] {
self.s6_addr
}
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct SockAddrIp(SockAddrIpInner);
#[derive(Clone, Copy)]
#[repr(C, align(8))]
union SockAddrIpInner {
jt: SockAddrJustTag,
v4: SockAddrIpv4,
v6: SockAddrIpv6,
}
#[derive(Clone, Copy, Debug)]
#[repr(C, align(8))]
struct SockAddrJustTag {
family: linux_unsafe::sa_family_t,
}
impl SockAddrIp {
pub fn new(host_address: impl Into<IpAddr>, port: u16) -> Self {
let host_address = host_address.into();
match host_address {
IpAddr::V4(addr) => Self(SockAddrIpInner {
v4: SockAddrIpv4::new(addr, port),
}),
IpAddr::V6(addr) => Self(SockAddrIpInner {
v6: SockAddrIpv6::new(addr, port),
}),
}
}
pub const fn address_family(&self) -> linux_unsafe::sa_family_t {
unsafe { self.0.jt.family }
}
pub const fn host_address(&self) -> IpAddr {
match self.address_family() {
AF_INET => IpAddr::V4(unsafe { self.0.v4 }.host_address()),
AF_INET6 => IpAddr::V6(unsafe { self.0.v6 }.host_address()),
_ => unreachable!(),
}
}
#[inline(always)]
pub const fn port(&self) -> u16 {
match self.address_family() {
AF_INET => unsafe { self.0.v4 }.port(),
AF_INET6 => unsafe { self.0.v6 }.port(),
_ => unreachable!(),
}
}
}
impl core::fmt::Debug for SockAddrIp {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.address_family() {
AF_INET => unsafe { self.0.v4 }.fmt(f),
AF_INET6 => unsafe { self.0.v6 }.fmt(f),
_ => unreachable!(),
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum IpAddr {
V4(Ipv4Addr),
V6(Ipv6Addr),
}
impl IpAddr {
pub const fn to_ipv6_mapped(self) -> Ipv6Addr {
match self {
IpAddr::V4(addr) => addr.to_ipv6_mapped(),
IpAddr::V6(addr) => addr,
}
}
}
pub const AF_INET: linux_unsafe::sa_family_t = 2;
pub const AF_INET6: linux_unsafe::sa_family_t = 10;
pub const IPPROTO_TCP: super::SocketProtocolFixed<tcp::TcpSocketDevice> =
unsafe { super::socket_protocol(6) };
pub const IPPROTO_ICMP: linux_unsafe::int = 1;
pub const IPPROTO_IGMP: linux_unsafe::int = 4;
pub const IPPROTO_EGP: linux_unsafe::int = 8;
pub const IPPROTO_PUP: linux_unsafe::int = 12;
pub const IPPROTO_UDP: linux_unsafe::int = 17;
pub const IPPROTO_IDP: linux_unsafe::int = 22;
pub const IPPROTO_TP: linux_unsafe::int = 29;
pub const IPPROTO_DCCP: linux_unsafe::int = 33;
pub const IPPROTO_IPV6: linux_unsafe::int = 41;
pub const IPPROTO_RSVP: linux_unsafe::int = 46;
pub const IPPROTO_GRE: linux_unsafe::int = 47;
pub const IPPROTO_ESP: linux_unsafe::int = 50;
pub const IPPROTO_AH: linux_unsafe::int = 51;
pub const IPPROTO_MTP: linux_unsafe::int = 92;
pub const IPPROTO_ENCAP: linux_unsafe::int = 98;
pub const IPPROTO_PIM: linux_unsafe::int = 103;
pub const IPPROTO_COMP: linux_unsafe::int = 108;
pub const IPPROTO_L2TP: linux_unsafe::int = 115;
pub const IPPROTO_SCTP: linux_unsafe::int = 132;
pub const IPPROTO_UDPLITE: linux_unsafe::int = 136;
pub const IPPROTO_MPLS: linux_unsafe::int = 137;
pub const IPPROTO_ETHERNET: linux_unsafe::int = 143;
pub const IPPROTO_RAW: linux_unsafe::int = 255;
pub const IPPROTO_MPTCP: linux_unsafe::int = 262;
unsafe impl super::SockAddr for SockAddrIpv4 {
#[inline(always)]
unsafe fn sockaddr_raw_const(
&self,
) -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
(
self as *const Self as *const _,
core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
)
}
#[inline(always)]
unsafe fn sockaddr_raw_mut(
&mut self,
) -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
(
self as *mut Self as *mut _,
core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
)
}
}
unsafe impl super::SockAddr for SockAddrIpv6 {
#[inline(always)]
unsafe fn sockaddr_raw_const(
&self,
) -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
(
self as *const Self as *const _,
core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
)
}
#[inline(always)]
unsafe fn sockaddr_raw_mut(
&mut self,
) -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
(
self as *mut Self as *mut _,
core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
)
}
}
unsafe impl super::SockAddr for SockAddrIp {
#[inline(always)]
unsafe fn sockaddr_raw_const(
&self,
) -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
match self.address_family() {
AF_INET => self.0.v4.sockaddr_raw_const(),
AF_INET6 => self.0.v6.sockaddr_raw_const(),
_ => unreachable!(), }
}
#[inline(always)]
unsafe fn sockaddr_raw_mut(
&mut self,
) -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
match self.address_family() {
AF_INET => self.0.v4.sockaddr_raw_mut(),
AF_INET6 => self.0.v6.sockaddr_raw_mut(),
_ => unreachable!(), }
}
}
impl From<Ipv4Addr> for IpAddr {
fn from(value: Ipv4Addr) -> Self {
IpAddr::V4(value)
}
}
impl From<Ipv6Addr> for IpAddr {
fn from(value: Ipv6Addr) -> Self {
IpAddr::V6(value)
}
}
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "std")]
impl Ipv4Addr {
#[inline]
pub const fn from_std(addr: std::net::Ipv4Addr) -> Self {
Self::from_octets(addr.octets())
}
}
#[cfg(feature = "std")]
impl From<std::net::Ipv4Addr> for Ipv4Addr {
fn from(value: std::net::Ipv4Addr) -> Self {
Self::from_std(value)
}
}
#[cfg(feature = "std")]
impl Ipv6Addr {
#[inline]
pub const fn from_std(addr: std::net::Ipv6Addr) -> Self {
Self::from_octets(addr.octets())
}
}
#[cfg(feature = "std")]
impl From<std::net::Ipv6Addr> for Ipv6Addr {
fn from(value: std::net::Ipv6Addr) -> Self {
Self::from_std(value)
}
}
#[cfg(feature = "std")]
impl IpAddr {
#[inline]
pub const fn from_std(addr: std::net::IpAddr) -> Self {
match addr {
std::net::IpAddr::V4(addr) => Self::V4(Ipv4Addr::from_octets(addr.octets())),
std::net::IpAddr::V6(addr) => Self::V6(Ipv6Addr::from_octets(addr.octets())),
}
}
}
#[cfg(feature = "std")]
impl From<std::net::IpAddr> for IpAddr {
fn from(value: std::net::IpAddr) -> Self {
Self::from_std(value)
}
}
#[derive(Clone, Copy)]
pub struct Ipv4SocketDevice;
impl crate::fd::ioctl::IoDevice for Ipv4SocketDevice {}
unsafe impl crate::fd::ioctl::SubDevice<super::SocketDevice> for Ipv4SocketDevice {}
#[derive(Clone, Copy)]
pub struct Ipv6SocketDevice;
impl crate::fd::ioctl::IoDevice for Ipv6SocketDevice {}
unsafe impl crate::fd::ioctl::SubDevice<super::SocketDevice> for Ipv6SocketDevice {}
pub mod tcp;