1use netdev::mac::MacAddr;
17use std::{
18 fmt,
19 net::{Ipv4Addr, Ipv6Addr},
20};
21
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24
25#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31pub enum Protocol {
32 Mac(MacAddr),
34 Ip4(Ipv4Addr),
36 Ip6(Ipv6Addr),
38 Dns(String),
40 Dns4(String),
42 Dns6(String),
44 Tcp(u16),
46 Udp(u16),
48 Tls,
50 Quic,
52 Http,
54 Https,
56 Ws(u16),
58 Wss(u16),
60 WebTransport(u16),
62 WebRTC,
64 Onion(String),
66 Custom(String),
68}
69
70impl fmt::Display for Protocol {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 use Protocol::*;
73 match self {
74 Ip4(addr) => write!(f, "/ip4/{}", addr),
75 Ip6(addr) => write!(f, "/ip6/{}", addr),
76 Dns(name) => write!(f, "/dns/{}", name),
77 Dns4(name) => write!(f, "/dns4/{}", name),
78 Dns6(name) => write!(f, "/dns6/{}", name),
79 Mac(addr) => write!(f, "/mac/{}", addr),
80 Tcp(port) => write!(f, "/tcp/{}", port),
81 Udp(port) => write!(f, "/udp/{}", port),
82 Tls => write!(f, "/tls"),
83 Quic => write!(f, "/quic"),
84 Http => write!(f, "/http"),
85 Https => write!(f, "/https"),
86 Ws(port) => write!(f, "/ws/{}", port),
87 Wss(port) => write!(f, "/wss/{}", port),
88 WebTransport(port) => write!(f, "/wtr/{}", port),
89 WebRTC => write!(f, "/webrtc"),
90 Onion(addr) => write!(f, "/onion/{}", addr),
91 Custom(name) => write!(f, "/custom/{}", name),
92 }
93 }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
97#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
98pub enum TransportProtocol {
99 Tcp(u16),
101 Udp(u16),
103 TlsOverTcp(u16),
105 Quic(u16),
107 Ws(u16),
109 Wss(u16),
111 WebTransport(u16),
113}
114
115impl TransportProtocol {
116 pub fn port(&self) -> u16 {
118 match self {
119 TransportProtocol::Tcp(p)
120 | TransportProtocol::Udp(p)
121 | TransportProtocol::TlsOverTcp(p)
122 | TransportProtocol::Quic(p)
123 | TransportProtocol::Ws(p)
124 | TransportProtocol::Wss(p)
125 | TransportProtocol::WebTransport(p) => *p,
126 }
127 }
128 pub fn is_secure(&self) -> bool {
130 matches!(
131 self,
132 TransportProtocol::TlsOverTcp(_)
133 | TransportProtocol::Quic(_)
134 | TransportProtocol::Wss(_)
135 | TransportProtocol::WebTransport(_)
136 )
137 }
138}
139
140impl fmt::Display for TransportProtocol {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 use TransportProtocol::*;
143 match self {
144 Tcp(port) => write!(f, "tcp/{}", port),
145 Udp(port) => write!(f, "udp/{}", port),
146 TlsOverTcp(port) => write!(f, "tls/tcp/{}", port),
147 Quic(port) => write!(f, "quic/{}", port),
148 Ws(port) => write!(f, "ws/{}", port),
149 Wss(port) => write!(f, "wss/{}", port),
150 WebTransport(port) => write!(f, "wtr/{}", port),
151 }
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 fn test_display_macaddr() {
161 use netdev::mac::MacAddr;
162 let mac = MacAddr::new(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff);
163 let proto = vec![
164 Protocol::Mac(mac),
165 Protocol::Ip4("192.168.10.10".parse().unwrap()),
166 ];
167 let text = proto.iter().map(|p| p.to_string()).collect::<String>();
168 assert_eq!(text, "/mac/aa:bb:cc:dd:ee:ff/ip4/192.168.10.10");
169 }
170
171 #[test]
172 fn test_display_ip4_quic() {
173 let proto = vec![
174 Protocol::Ip4("127.0.0.1".parse().unwrap()),
175 Protocol::Udp(4433),
176 Protocol::Quic,
177 ];
178 let text = proto.iter().map(|p| p.to_string()).collect::<String>();
179 assert_eq!(text, "/ip4/127.0.0.1/udp/4433/quic");
180 }
181
182 #[test]
183 fn test_display_ip6_tcp_https() {
184 let proto = vec![
185 Protocol::Ip6("::1".parse().unwrap()),
186 Protocol::Tcp(443),
187 Protocol::Https,
188 ];
189 let text = proto.iter().map(|p| p.to_string()).collect::<String>();
190 assert_eq!(text, "/ip6/::1/tcp/443/https");
191 }
192}