1#[derive(Clone, Copy, Debug)]
3#[repr(C, align(8))]
4pub struct SockAddrIpv4 {
5 sin_family: linux_unsafe::sa_family_t,
6 sin_port: u16, sin_addr: Ipv4Addr,
8
9 sin_zero: [u8; 8],
13}
14
15impl SockAddrIpv4 {
16 #[inline]
22 pub const fn new(host_addr: Ipv4Addr, port: u16) -> Self {
23 Self {
24 sin_family: AF_INET,
25 sin_port: port.to_be(),
26 sin_addr: host_addr,
27 sin_zero: [0; 8],
28 }
29 }
30
31 #[inline(always)]
33 pub const fn host_address(&self) -> Ipv4Addr {
34 self.sin_addr
35 }
36
37 #[inline(always)]
39 pub const fn port(&self) -> u16 {
40 self.sin_port.to_be() }
42}
43
44#[derive(Clone, Copy, Debug)]
49#[repr(C)]
50pub struct Ipv4Addr {
51 s_addr: u32, }
53
54impl Ipv4Addr {
55 pub const ANY: Self = Self { s_addr: 0x00000000 };
57
58 pub const NONE: Self = Self { s_addr: 0xffffffff };
60
61 pub const BROADCAST: Self = Self { s_addr: 0xffffffff };
63
64 pub const DUMMY: Self = Self {
66 s_addr: 0xc0000008_u32.to_be(),
67 };
68
69 pub const LOOPBACK: Self = Self {
71 s_addr: 0x7f000001_u32.to_be(),
72 };
73
74 pub const UNSPEC_GROUP: Self = Self {
76 s_addr: 0xe0000000_u32.to_be(),
77 };
78 pub const ALLHOSTS_GROUP: Self = Self {
80 s_addr: 0xe0000001_u32.to_be(),
81 };
82 pub const ALLRTRS_GROUP: Self = Self {
84 s_addr: 0xe0000002_u32.to_be(),
85 };
86 pub const ALLSNOOPERS_GROUP: Self = Self {
88 s_addr: 0xe000006a_u32.to_be(),
89 };
90
91 #[inline(always)]
99 pub const fn from_u32(raw: u32) -> Self {
100 Self {
101 s_addr: raw.to_be(),
102 }
103 }
104
105 #[inline(always)]
110 pub const fn from_octets(raw: [u8; 4]) -> Self {
111 Self::from_u32(u32::from_be_bytes(raw))
114 }
115
116 #[inline(always)]
118 pub const fn as_u32(&self) -> u32 {
119 self.s_addr.to_be() }
121
122 #[inline(always)]
124 pub const fn as_octets(&self) -> [u8; 4] {
125 self.as_u32().to_be_bytes()
126 }
127
128 pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
130 let our_octets = self.as_octets();
131 let mut new_octets = [0_u8; 16];
132 new_octets[10] = 0xff;
133 new_octets[11] = 0xff;
134 new_octets[12] = our_octets[0];
135 new_octets[13] = our_octets[1];
136 new_octets[14] = our_octets[2];
137 new_octets[15] = our_octets[3];
138 Ipv6Addr::from_octets(new_octets)
139 }
140}
141
142#[derive(Clone, Copy, Debug)]
144#[repr(C, align(8))]
145pub struct SockAddrIpv6 {
146 sin6_family: linux_unsafe::sa_family_t,
147 sin6_port: u16, sin6_flowinfo: u32,
149 sin6_addr: Ipv6Addr,
150 sin6_scope_id: u32,
151}
152
153impl SockAddrIpv6 {
154 #[inline]
160 pub const fn new(host_addr: Ipv6Addr, port: u16) -> Self {
161 Self {
162 sin6_family: AF_INET6,
163 sin6_port: port.to_be(),
164 sin6_addr: host_addr,
165
166 sin6_flowinfo: 0,
167 sin6_scope_id: 0,
168 }
169 }
170
171 #[inline]
177 pub const fn new_with_scope(host_addr: Ipv6Addr, port: u16, scope_id: u32) -> Self {
178 Self {
179 sin6_family: AF_INET6,
180 sin6_port: port.to_be(),
181 sin6_addr: host_addr,
182
183 sin6_flowinfo: 0,
184 sin6_scope_id: scope_id,
185 }
186 }
187
188 #[inline(always)]
190 pub const fn host_address(&self) -> Ipv6Addr {
191 self.sin6_addr
192 }
193
194 #[inline(always)]
196 pub const fn port(&self) -> u16 {
197 self.sin6_port.to_be() }
199
200 #[inline(always)]
202 pub const fn scope_id(&self) -> u32 {
203 self.sin6_scope_id
204 }
205}
206
207#[derive(Clone, Copy, Debug)]
212#[repr(C)]
213pub struct Ipv6Addr {
214 s6_addr: [u8; 16],
215}
216
217impl Ipv6Addr {
218 pub const ANY: Self = Self {
220 s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
221 };
222
223 pub const LOOPBACK: Self = Self {
225 s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
226 };
227
228 pub const LINKLOCAL_ALLNODES: Self = Self {
230 s6_addr: [0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
231 };
232
233 pub const LINKLOCAL_ALLROUTERS: Self = Self {
235 s6_addr: [0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
236 };
237
238 pub const INTERFACELOCAL_ALLNODES: Self = Self {
240 s6_addr: [0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
241 };
242
243 pub const INTERFACELOCAL_ALLROUTERS: Self = Self {
245 s6_addr: [0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
246 };
247
248 pub const SITELOCAL_ALLROUTERS: Self = Self {
250 s6_addr: [0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
251 };
252
253 #[inline(always)]
258 pub const fn from_octets(raw: [u8; 16]) -> Self {
259 Self { s6_addr: raw }
262 }
263
264 #[inline(always)]
266 pub const fn as_octets(&self) -> [u8; 16] {
267 self.s6_addr
268 }
269}
270
271#[derive(Clone, Copy)]
274#[repr(transparent)]
275pub struct SockAddrIp(SockAddrIpInner);
276
277#[derive(Clone, Copy)]
278#[repr(C, align(8))]
279union SockAddrIpInner {
280 jt: SockAddrJustTag,
284
285 v4: SockAddrIpv4,
288 v6: SockAddrIpv6,
289}
290
291#[derive(Clone, Copy, Debug)]
292#[repr(C, align(8))]
293struct SockAddrJustTag {
294 family: linux_unsafe::sa_family_t,
295}
296
297impl SockAddrIp {
298 pub fn new(host_address: impl Into<IpAddr>, port: u16) -> Self {
299 let host_address = host_address.into();
300 match host_address {
301 IpAddr::V4(addr) => Self(SockAddrIpInner {
302 v4: SockAddrIpv4::new(addr, port),
303 }),
304 IpAddr::V6(addr) => Self(SockAddrIpInner {
305 v6: SockAddrIpv6::new(addr, port),
306 }),
307 }
308 }
309
310 pub const fn address_family(&self) -> linux_unsafe::sa_family_t {
314 unsafe { self.0.jt.family }
318 }
319
320 pub const fn host_address(&self) -> IpAddr {
325 match self.address_family() {
326 AF_INET => IpAddr::V4(unsafe { self.0.v4 }.host_address()),
327 AF_INET6 => IpAddr::V6(unsafe { self.0.v6 }.host_address()),
328 _ => unreachable!(),
329 }
330 }
331
332 #[inline(always)]
334 pub const fn port(&self) -> u16 {
335 match self.address_family() {
336 AF_INET => unsafe { self.0.v4 }.port(),
337 AF_INET6 => unsafe { self.0.v6 }.port(),
338 _ => unreachable!(),
339 }
340 }
341}
342
343impl core::fmt::Debug for SockAddrIp {
344 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
345 match self.address_family() {
346 AF_INET => unsafe { self.0.v4 }.fmt(f),
347 AF_INET6 => unsafe { self.0.v6 }.fmt(f),
348 _ => unreachable!(),
349 }
350 }
351}
352
353#[derive(Clone, Copy, Debug)]
356pub enum IpAddr {
357 V4(Ipv4Addr),
358 V6(Ipv6Addr),
359}
360
361impl IpAddr {
362 pub const fn to_ipv6_mapped(self) -> Ipv6Addr {
369 match self {
370 IpAddr::V4(addr) => addr.to_ipv6_mapped(),
371 IpAddr::V6(addr) => addr,
372 }
373 }
374}
375
376pub const AF_INET: linux_unsafe::sa_family_t = 2;
378
379pub const AF_INET6: linux_unsafe::sa_family_t = 10;
381
382pub const IPPROTO_TCP: super::SocketProtocolFixed<tcp::TcpSocketDevice> =
383 unsafe { super::socket_protocol(6) };
384
385pub const IPPROTO_ICMP: linux_unsafe::int = 1;
386pub const IPPROTO_IGMP: linux_unsafe::int = 4;
387pub const IPPROTO_EGP: linux_unsafe::int = 8;
388pub const IPPROTO_PUP: linux_unsafe::int = 12;
389pub const IPPROTO_UDP: linux_unsafe::int = 17;
390pub const IPPROTO_IDP: linux_unsafe::int = 22;
391pub const IPPROTO_TP: linux_unsafe::int = 29;
392pub const IPPROTO_DCCP: linux_unsafe::int = 33;
393pub const IPPROTO_IPV6: linux_unsafe::int = 41;
394pub const IPPROTO_RSVP: linux_unsafe::int = 46;
395pub const IPPROTO_GRE: linux_unsafe::int = 47;
396pub const IPPROTO_ESP: linux_unsafe::int = 50;
397pub const IPPROTO_AH: linux_unsafe::int = 51;
398pub const IPPROTO_MTP: linux_unsafe::int = 92;
399pub const IPPROTO_ENCAP: linux_unsafe::int = 98;
400pub const IPPROTO_PIM: linux_unsafe::int = 103;
401pub const IPPROTO_COMP: linux_unsafe::int = 108;
402pub const IPPROTO_L2TP: linux_unsafe::int = 115;
403pub const IPPROTO_SCTP: linux_unsafe::int = 132;
404pub const IPPROTO_UDPLITE: linux_unsafe::int = 136;
405pub const IPPROTO_MPLS: linux_unsafe::int = 137;
406pub const IPPROTO_ETHERNET: linux_unsafe::int = 143;
407pub const IPPROTO_RAW: linux_unsafe::int = 255;
408pub const IPPROTO_MPTCP: linux_unsafe::int = 262;
409
410unsafe impl super::SockAddr for SockAddrIpv4 {
411 #[inline(always)]
412 unsafe fn sockaddr_raw_const(
413 &self,
414 ) -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
415 (
416 self as *const Self as *const _,
417 core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
418 )
419 }
420
421 #[inline(always)]
422 unsafe fn sockaddr_raw_mut(
423 &mut self,
424 ) -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
425 (
426 self as *mut Self as *mut _,
427 core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
428 )
429 }
430}
431
432unsafe impl super::SockAddr for SockAddrIpv6 {
433 #[inline(always)]
434 unsafe fn sockaddr_raw_const(
435 &self,
436 ) -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
437 (
438 self as *const Self as *const _,
439 core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
440 )
441 }
442
443 #[inline(always)]
444 unsafe fn sockaddr_raw_mut(
445 &mut self,
446 ) -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
447 (
448 self as *mut Self as *mut _,
449 core::mem::size_of::<Self>() as linux_unsafe::socklen_t,
450 )
451 }
452}
453
454unsafe impl super::SockAddr for SockAddrIp {
455 #[inline(always)]
456 unsafe fn sockaddr_raw_const(
457 &self,
458 ) -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
459 match self.address_family() {
463 AF_INET => self.0.v4.sockaddr_raw_const(),
464 AF_INET6 => self.0.v6.sockaddr_raw_const(),
465 _ => unreachable!(), }
467 }
468
469 #[inline(always)]
470 unsafe fn sockaddr_raw_mut(
471 &mut self,
472 ) -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t) {
473 match self.address_family() {
477 AF_INET => self.0.v4.sockaddr_raw_mut(),
478 AF_INET6 => self.0.v6.sockaddr_raw_mut(),
479 _ => unreachable!(), }
481 }
482}
483
484impl From<Ipv4Addr> for IpAddr {
485 fn from(value: Ipv4Addr) -> Self {
486 IpAddr::V4(value)
487 }
488}
489
490impl From<Ipv6Addr> for IpAddr {
491 fn from(value: Ipv6Addr) -> Self {
492 IpAddr::V6(value)
493 }
494}
495
496#[cfg(feature = "std")]
497extern crate std;
498
499#[cfg(feature = "std")]
502impl Ipv4Addr {
503 #[inline]
506 pub const fn from_std(addr: std::net::Ipv4Addr) -> Self {
507 Self::from_octets(addr.octets())
508 }
509}
510
511#[cfg(feature = "std")]
512impl From<std::net::Ipv4Addr> for Ipv4Addr {
513 fn from(value: std::net::Ipv4Addr) -> Self {
514 Self::from_std(value)
515 }
516}
517
518#[cfg(feature = "std")]
521impl Ipv6Addr {
522 #[inline]
525 pub const fn from_std(addr: std::net::Ipv6Addr) -> Self {
526 Self::from_octets(addr.octets())
527 }
528}
529
530#[cfg(feature = "std")]
531impl From<std::net::Ipv6Addr> for Ipv6Addr {
532 fn from(value: std::net::Ipv6Addr) -> Self {
533 Self::from_std(value)
534 }
535}
536
537#[cfg(feature = "std")]
540impl IpAddr {
541 #[inline]
544 pub const fn from_std(addr: std::net::IpAddr) -> Self {
545 match addr {
546 std::net::IpAddr::V4(addr) => Self::V4(Ipv4Addr::from_octets(addr.octets())),
547 std::net::IpAddr::V6(addr) => Self::V6(Ipv6Addr::from_octets(addr.octets())),
548 }
549 }
550}
551
552#[cfg(feature = "std")]
553impl From<std::net::IpAddr> for IpAddr {
554 fn from(value: std::net::IpAddr) -> Self {
555 Self::from_std(value)
556 }
557}
558
559#[derive(Clone, Copy)]
561pub struct Ipv4SocketDevice;
562
563impl crate::fd::ioctl::IoDevice for Ipv4SocketDevice {}
564unsafe impl crate::fd::ioctl::SubDevice<super::SocketDevice> for Ipv4SocketDevice {}
565
566#[derive(Clone, Copy)]
568pub struct Ipv6SocketDevice;
569
570impl crate::fd::ioctl::IoDevice for Ipv6SocketDevice {}
571unsafe impl crate::fd::ioctl::SubDevice<super::SocketDevice> for Ipv6SocketDevice {}
572
573pub mod tcp;