1pub mod icmp;
17pub mod tcp;
18pub mod udp;
19
20use std::io;
21use std::net::{IpAddr, SocketAddr};
22
23#[cfg(any(
24 target_os = "android",
25 target_os = "dragonfly",
26 target_os = "freebsd",
27 target_os = "fuchsia",
28 target_os = "linux",
29 target_os = "macos",
30 target_os = "netbsd",
31 target_os = "openbsd"
32))]
33pub(crate) fn apply_tclass_v6(socket: &socket2::Socket, tclass: Option<u32>) -> io::Result<()> {
34 if let Some(tclass) = tclass {
35 socket.set_tclass_v6(tclass)?;
36 }
37 Ok(())
38}
39
40#[cfg(not(any(
41 target_os = "android",
42 target_os = "dragonfly",
43 target_os = "freebsd",
44 target_os = "fuchsia",
45 target_os = "linux",
46 target_os = "macos",
47 target_os = "netbsd",
48 target_os = "openbsd"
49)))]
50pub(crate) fn apply_tclass_v6(_socket: &socket2::Socket, tclass: Option<u32>) -> io::Result<()> {
51 if tclass.is_some() {
52 return Err(io::Error::new(
53 io::ErrorKind::Unsupported,
54 "IPv6 traffic class is not supported on this platform",
55 ));
56 }
57 Ok(())
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62#[non_exhaustive]
63pub enum SocketFamily {
64 IPV4,
65 IPV6,
66}
67
68impl SocketFamily {
69 pub fn from_ip(ip: &IpAddr) -> Self {
71 match ip {
72 IpAddr::V4(_) => SocketFamily::IPV4,
73 IpAddr::V6(_) => SocketFamily::IPV6,
74 }
75 }
76
77 pub fn from_socket_addr(addr: &SocketAddr) -> Self {
79 match addr {
80 SocketAddr::V4(_) => SocketFamily::IPV4,
81 SocketAddr::V6(_) => SocketFamily::IPV6,
82 }
83 }
84
85 pub fn is_v4(&self) -> bool {
87 matches!(self, SocketFamily::IPV4)
88 }
89
90 pub fn is_v6(&self) -> bool {
92 matches!(self, SocketFamily::IPV6)
93 }
94
95 pub(crate) fn to_domain(self) -> socket2::Domain {
97 match self {
98 SocketFamily::IPV4 => socket2::Domain::IPV4,
99 SocketFamily::IPV6 => socket2::Domain::IPV6,
100 }
101 }
102}