1use std::net::{
2 IpAddr,
3 Ipv4Addr,
4 Ipv6Addr,
5};
6
7use crate::num::NumberOfAddresses;
8
9pub trait PrivUnspecAddress: Sized {
11 type _Tools;
12}
13
14pub trait PrivCidr {}
16
17pub trait PrivInet {}
19
20pub trait PrivInetPair {
22 fn _covered_addresses(&self) -> NumberOfAddresses;
23 fn _inc_first(&mut self) -> bool;
24 fn _dec_second(&mut self) -> bool;
25}
26
27#[derive(Clone, Copy)]
28struct Ipv4OverflowingOp {
29 address: u32,
30 net_mask: u32,
31 host_mask: u32,
32}
33
34impl Ipv4OverflowingOp {
35 const fn new(address: Ipv4Addr, prefix_len: u8) -> Self {
36 let host_mask = Ipv4AddrTools::native_host_mask(prefix_len);
37 let net_mask = !host_mask;
38 let address: u32 = Ipv4AddrTools::to_native(address);
39 Self {
40 address,
41 net_mask,
42 host_mask,
43 }
44 }
45
46 const fn handle_result(self, (mut res, mut overflow): (u32, bool)) -> (Ipv4Addr, bool) {
47 let net_address = self.address & self.net_mask;
48 if res & self.net_mask != net_address {
49 res = (res & self.host_mask) | net_address;
51 overflow = true
52 }
53 (Ipv4AddrTools::from_native(res), overflow)
54 }
55}
56
57pub struct Ipv4AddrTools(());
58
59impl Ipv4AddrTools {
60 pub(crate) const fn to_native(ip: Ipv4Addr) -> u32 {
61 u32::from_be_bytes(ip.octets())
63 }
64
65 pub(crate) const fn from_native(ip: u32) -> Ipv4Addr {
66 let ip = ip.to_be_bytes();
68 Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3])
69 }
70
71 pub(crate) const fn native_host_mask(prefix_len: u8) -> u32 {
72 if let Some(mask) = (!0u32).checked_shr(prefix_len as u32) {
74 mask
75 } else {
76 0
77 }
78 }
79
80 pub(crate) const fn _has_zero_host_part(address: Ipv4Addr, prefix_len: u8) -> bool {
81 let host_mask: u32 = Self::native_host_mask(prefix_len);
82 let addr_num = Self::to_native(address);
83 (addr_num & host_mask) == 0
84 }
85
86 pub(crate) const fn _overflowing_next(address: Ipv4Addr, prefix_len: u8) -> (Ipv4Addr, bool) {
87 let op = Ipv4OverflowingOp::new(address, prefix_len);
88 op.handle_result(op.address.overflowing_add(1))
89 }
90
91 pub(crate) const fn _overflowing_inc_u32(
92 address: Ipv4Addr,
93 prefix_len: u8,
94 step_u32: u32,
95 ) -> (Ipv4Addr, bool) {
96 let op = Ipv4OverflowingOp::new(address, prefix_len);
97 let (res, overflow) = op.handle_result(op.address.overflowing_add(step_u32));
98 (res, overflow)
99 }
100
101 pub(crate) const fn _overflowing_inc(
102 address: Ipv4Addr,
103 prefix_len: u8,
104 step: u128,
105 ) -> (Ipv4Addr, bool) {
106 let step_u32 = step as u32;
107 let step_overflow = step_u32 as u128 != step;
108 let (res, overflow) = Self::_overflowing_inc_u32(address, prefix_len, step_u32);
109 (res, overflow || step_overflow)
110 }
111
112 pub(crate) const fn _overflowing_prev(address: Ipv4Addr, prefix_len: u8) -> (Ipv4Addr, bool) {
113 let op = Ipv4OverflowingOp::new(address, prefix_len);
114 op.handle_result(op.address.overflowing_sub(1))
115 }
116
117 pub(crate) const fn _overflowing_dec_u32(
118 address: Ipv4Addr,
119 prefix_len: u8,
120 step_u32: u32,
121 ) -> (Ipv4Addr, bool) {
122 let op = Ipv4OverflowingOp::new(address, prefix_len);
123 let (res, overflow) = op.handle_result(op.address.overflowing_sub(step_u32));
124 (res, overflow)
125 }
126
127 pub(crate) const fn _overflowing_dec(
128 address: Ipv4Addr,
129 prefix_len: u8,
130 step: u128,
131 ) -> (Ipv4Addr, bool) {
132 let step_u32 = step as u32;
133 let step_overflow = step_u32 as u128 != step;
134 let (res, overflow) = Self::_overflowing_dec_u32(address, prefix_len, step_u32);
135 (res, overflow || step_overflow)
136 }
137
138 pub(crate) const fn _prefix_match(address: Ipv4Addr, other: Ipv4Addr, prefix_len: u8) -> bool {
146 let net_mask: u32 = !Self::native_host_mask(prefix_len);
147 (Self::to_native(address) & net_mask) == (Self::to_native(other) & net_mask)
148 }
149
150 pub(crate) const fn _network_address(address: Ipv4Addr, prefix_len: u8) -> Ipv4Addr {
151 let net_mask: u32 = !Self::native_host_mask(prefix_len);
152 Self::from_native(Self::to_native(address) & net_mask)
153 }
154
155 pub(crate) const fn _last_address(address: Ipv4Addr, prefix_len: u8) -> Ipv4Addr {
156 let host_mask: u32 = Self::native_host_mask(prefix_len);
157 Self::from_native(Self::to_native(address) | host_mask)
158 }
159
160 pub(crate) const fn _network_mask(prefix_len: u8) -> Ipv4Addr {
161 Self::from_native(!Self::native_host_mask(prefix_len))
162 }
163}
164
165impl PrivUnspecAddress for Ipv4Addr {
166 type _Tools = Ipv4AddrTools;
167}
168
169#[derive(Clone, Copy)]
170struct Ipv6OverflowingOp {
171 address: u128,
172 net_mask: u128,
173 host_mask: u128,
174}
175
176impl Ipv6OverflowingOp {
177 const fn new(address: Ipv6Addr, prefix_len: u8) -> Self {
178 let host_mask = Ipv6AddrTools::native_host_mask(prefix_len);
179 let net_mask = !host_mask;
180 let address: u128 = u128::from_be_bytes(address.octets());
181 Self {
182 address,
183 net_mask,
184 host_mask,
185 }
186 }
187
188 const fn handle_result(self, (mut res, mut overflow): (u128, bool)) -> (Ipv6Addr, bool) {
189 let net_address = self.address & self.net_mask;
190 if res & self.net_mask != net_address {
191 res = (res & self.host_mask) | net_address;
193 overflow = true
194 }
195 (Ipv6AddrTools::from_native(res), overflow)
196 }
197}
198
199pub struct Ipv6AddrTools(());
200
201impl Ipv6AddrTools {
202 pub(crate) const fn to_native(ip: Ipv6Addr) -> u128 {
203 u128::from_be_bytes(ip.octets())
205 }
206
207 pub(crate) const fn from_native(ip: u128) -> Ipv6Addr {
208 let ip = ip.to_be_bytes();
210 #[cfg(not(feature = "no_unsafe"))]
211 {
212 unsafe { std::mem::transmute(ip) }
220 }
221 #[cfg(feature = "no_unsafe")]
222 {
223 Ipv6Addr::new(
225 u16::from_be_bytes([ip[0], ip[1]]),
226 u16::from_be_bytes([ip[2], ip[3]]),
227 u16::from_be_bytes([ip[4], ip[5]]),
228 u16::from_be_bytes([ip[6], ip[7]]),
229 u16::from_be_bytes([ip[8], ip[9]]),
230 u16::from_be_bytes([ip[10], ip[11]]),
231 u16::from_be_bytes([ip[12], ip[13]]),
232 u16::from_be_bytes([ip[14], ip[15]]),
233 )
234 }
235 }
236
237 pub(crate) const fn native_host_mask(prefix_len: u8) -> u128 {
238 if let Some(mask) = (!0u128).checked_shr(prefix_len as u32) {
240 mask
241 } else {
242 0
243 }
244 }
245
246 pub(crate) const fn _has_zero_host_part(address: Ipv6Addr, prefix_len: u8) -> bool {
247 let host_mask: u128 = Self::native_host_mask(prefix_len);
248 let addr_num = Self::to_native(address);
249 (addr_num & host_mask) == 0
250 }
251
252 pub(crate) const fn _overflowing_next(address: Ipv6Addr, prefix_len: u8) -> (Ipv6Addr, bool) {
253 let op = Ipv6OverflowingOp::new(address, prefix_len);
254 op.handle_result(op.address.overflowing_add(1))
255 }
256
257 pub(crate) const fn _overflowing_inc(
258 address: Ipv6Addr,
259 prefix_len: u8,
260 step: u128,
261 ) -> (Ipv6Addr, bool) {
262 let op = Ipv6OverflowingOp::new(address, prefix_len);
263 op.handle_result(op.address.overflowing_add(step))
264 }
265
266 pub(crate) const fn _overflowing_prev(address: Ipv6Addr, prefix_len: u8) -> (Ipv6Addr, bool) {
267 let op = Ipv6OverflowingOp::new(address, prefix_len);
268 op.handle_result(op.address.overflowing_sub(1))
269 }
270
271 pub(crate) const fn _overflowing_dec(
272 address: Ipv6Addr,
273 prefix_len: u8,
274 step: u128,
275 ) -> (Ipv6Addr, bool) {
276 let op = Ipv6OverflowingOp::new(address, prefix_len);
277 op.handle_result(op.address.overflowing_sub(step))
278 }
279
280 pub(crate) const fn _prefix_match(address: Ipv6Addr, other: Ipv6Addr, prefix_len: u8) -> bool {
287 let net_mask: u128 = !Self::native_host_mask(prefix_len);
288 (Self::to_native(address) & net_mask) == (Self::to_native(other) & net_mask)
289 }
290
291 pub(crate) const fn _network_address(address: Ipv6Addr, prefix_len: u8) -> Ipv6Addr {
292 let net_mask: u128 = !Self::native_host_mask(prefix_len);
293 Self::from_native(Self::to_native(address) & net_mask)
294 }
295
296 pub(crate) const fn _last_address(address: Ipv6Addr, prefix_len: u8) -> Ipv6Addr {
297 let host_mask: u128 = Self::native_host_mask(prefix_len);
298 Self::from_native(Self::to_native(address) | host_mask)
299 }
300
301 pub(crate) const fn _network_mask(prefix_len: u8) -> Ipv6Addr {
302 Self::from_native(!Self::native_host_mask(prefix_len))
303 }
304}
305
306impl PrivUnspecAddress for Ipv6Addr {
307 type _Tools = Ipv6AddrTools;
308}
309
310pub struct IpAddrTools(());
311
312impl IpAddrTools {
314 }
413
414impl PrivUnspecAddress for IpAddr {
415 type _Tools = IpAddrTools;
416}