posix_socket/address/
inet4.rs

1use crate::SpecificSocketAddress;
2
3/// IPv4 socket address.
4///
5/// This includes an IPv4 address and a 16-bit port number.
6#[derive(Clone)]
7#[repr(C)]
8pub struct Inet4SocketAddress {
9	/// The inner C-compatible socket address.
10	inner: libc::sockaddr_in,
11}
12
13impl Inet4SocketAddress {
14	/// Create an IPv4 socket address from an IP address and a port number.
15	pub fn new(ip: &std::net::Ipv4Addr, port: u16) -> Self {
16		unsafe {
17			let ip : u32 = std::mem::transmute(ip.octets());
18			let inner = libc::sockaddr_in {
19				sin_family: Self::static_family(),
20				sin_addr: libc::in_addr { s_addr: ip },
21				sin_port: port.to_be(),
22				..std::mem::zeroed()
23			};
24			Self::from_raw(inner)
25		}
26	}
27
28	/// Create an IPv4 socket address from a [`libc::sockaddr_in`].
29	pub fn from_raw(inner: libc::sockaddr_in) -> Self {
30		Self { inner }
31	}
32
33	/// Convert the [`SocketAddress`] into raw [`libc`] parts.
34	pub fn into_raw(self) -> libc::sockaddr_in {
35		self.inner
36	}
37
38	/// Get the IP address associated with the socket address.
39	pub fn ip(&self) -> std::net::Ipv4Addr {
40		unsafe {
41			let ip: [u8; 4] = std::mem::transmute(self.inner.sin_addr.s_addr);
42			ip.into()
43		}
44	}
45
46	/// Set the IP address associated with the socket address.
47	pub fn set_ip(&mut self, ip: std::net::Ipv4Addr) {
48		unsafe {
49			let ip: u32 = std::mem::transmute(ip.octets());
50			self.inner.sin_addr.s_addr = ip;
51		}
52	}
53
54	/// Get the port number associated with the socket address.
55	pub fn port(&self) -> u16 {
56		u16::from_be(self.inner.sin_port)
57	}
58
59	/// Set the port number associated with the socket address.
60	pub fn set_port(&mut self, port: u16) {
61		self.inner.sin_port = port.to_be();
62	}
63}
64
65impl SpecificSocketAddress for Inet4SocketAddress {
66	fn static_family() -> libc::sa_family_t {
67		libc::AF_INET as libc::sa_family_t
68	}
69}
70
71unsafe impl crate::AsSocketAddress for Inet4SocketAddress {
72	fn as_sockaddr(&self) -> *const libc::sockaddr {
73		&self.inner as *const _ as *const _
74	}
75
76	fn as_sockaddr_mut(address: &mut std::mem::MaybeUninit<Self>) -> *mut libc::sockaddr {
77		unsafe { &mut address.as_mut_ptr().as_mut().unwrap().inner as *mut _ as *mut _ }
78	}
79
80	fn len(&self) -> libc::socklen_t {
81		Self::max_len()
82	}
83
84	fn finalize(address: std::mem::MaybeUninit<Self>, len: libc::socklen_t) -> std::io::Result<Self> {
85		unsafe {
86			let address = address.assume_init();
87			if address.family() != Self::static_family() {
88				return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "wrong address family, expected AF_INET"));
89			}
90			if len != Self::max_len() {
91				return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "wrong address size"));
92			}
93			Ok(address)
94		}
95	}
96
97	fn max_len() -> libc::socklen_t {
98		std::mem::size_of::<libc::sockaddr_in>() as libc::socklen_t
99	}
100}
101
102impl From<Inet4SocketAddress> for crate::SocketAddress {
103	fn from(other: Inet4SocketAddress) -> Self {
104		Self::from(&other)
105	}
106}
107
108impl From<&Inet4SocketAddress> for crate::SocketAddress {
109	fn from(other: &Inet4SocketAddress) -> Self {
110		Self::from_other(other)
111	}
112}
113
114impl From<std::net::SocketAddrV4> for Inet4SocketAddress {
115	fn from(other: std::net::SocketAddrV4) -> Self {
116		Self::from(&other)
117	}
118}
119
120impl From<&std::net::SocketAddrV4> for Inet4SocketAddress {
121	fn from(other: &std::net::SocketAddrV4) -> Self {
122		Self::new(other.ip(), other.port())
123	}
124}
125
126impl From<Inet4SocketAddress> for std::net::SocketAddrV4 {
127	fn from(other: Inet4SocketAddress) -> Self {
128		Self::from(&other)
129	}
130}
131
132impl From<&Inet4SocketAddress> for std::net::SocketAddrV4 {
133	fn from(other: &Inet4SocketAddress) -> Self {
134		Self::new(other.ip(), other.port())
135	}
136}