/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ipnet-2.11.0/src/mask.rs
Line | Count | Source |
1 | | use crate::PrefixLenError; |
2 | | #[cfg(not(feature = "std"))] |
3 | | use core::net::{IpAddr, Ipv4Addr, Ipv6Addr}; |
4 | | #[cfg(feature = "std")] |
5 | | use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; |
6 | | |
7 | | /// Converts a `IpAddr` network mask into a prefix. |
8 | | /// |
9 | | /// # Errors |
10 | | /// If the mask is invalid this will return an `PrefixLenError`. |
11 | 0 | pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, PrefixLenError> { |
12 | 0 | match mask { |
13 | 0 | IpAddr::V4(mask) => ipv4_mask_to_prefix(mask), |
14 | 0 | IpAddr::V6(mask) => ipv6_mask_to_prefix(mask), |
15 | | } |
16 | 0 | } |
17 | | |
18 | | /// Converts a `Ipv4Addr` network mask into a prefix. |
19 | | /// |
20 | | /// # Errors |
21 | | /// If the mask is invalid this will return an `PrefixLenError`. |
22 | 0 | pub fn ipv4_mask_to_prefix(mask: Ipv4Addr) -> Result<u8, PrefixLenError> { |
23 | 0 | let mask = u32::from(mask); |
24 | | |
25 | 0 | let prefix = mask.leading_ones(); |
26 | 0 | if mask.checked_shl(prefix).unwrap_or(0) == 0 { |
27 | 0 | Ok(prefix as u8) |
28 | | } else { |
29 | 0 | Err(PrefixLenError) |
30 | | } |
31 | 0 | } |
32 | | |
33 | | /// Converts a `Ipv6Addr` network mask into a prefix. |
34 | | /// |
35 | | /// # Errors |
36 | | /// If the mask is invalid this will return an `PrefixLenError`. |
37 | 0 | pub fn ipv6_mask_to_prefix(mask: Ipv6Addr) -> Result<u8, PrefixLenError> { |
38 | 0 | let mask = u128::from(mask); |
39 | | |
40 | 0 | let prefix = mask.leading_ones(); |
41 | 0 | if mask.checked_shl(prefix).unwrap_or(0) == 0 { |
42 | 0 | Ok(prefix as u8) |
43 | | } else { |
44 | 0 | Err(PrefixLenError) |
45 | | } |
46 | 0 | } |
47 | | |
48 | | #[cfg(test)] |
49 | | mod tests { |
50 | | use super::*; |
51 | | use crate::{Ipv4Net, Ipv6Net}; |
52 | | |
53 | | #[test] |
54 | | fn v4_mask_to_prefix() { |
55 | | let mask = Ipv4Addr::new(255, 255, 255, 128); |
56 | | let prefix = ipv4_mask_to_prefix(mask); |
57 | | assert_eq!(prefix, Ok(25)); |
58 | | } |
59 | | |
60 | | #[test] |
61 | | fn v4_mask_to_prefix_max() { |
62 | | let mask = Ipv4Addr::from(u32::MAX); |
63 | | let prefix = ipv4_mask_to_prefix(mask); |
64 | | assert_eq!(prefix, Ok(32)); |
65 | | } |
66 | | |
67 | | #[test] |
68 | | fn invalid_v4_mask_to_prefix() { |
69 | | let mask = Ipv4Addr::new(255, 0, 255, 0); |
70 | | let prefix = ipv4_mask_to_prefix(mask); |
71 | | assert!(prefix.is_err()); |
72 | | } |
73 | | |
74 | | #[test] |
75 | | fn ipv4net_with_netmask() { |
76 | | { |
77 | | // Positive test-case. |
78 | | let addr = Ipv4Addr::new(127, 0, 0, 1); |
79 | | let mask = Ipv4Addr::new(255, 0, 0, 0); |
80 | | let net = Ipv4Net::with_netmask(addr, mask).unwrap(); |
81 | | let expected = Ipv4Net::new(Ipv4Addr::new(127, 0, 0, 1), 8).unwrap(); |
82 | | assert_eq!(net, expected); |
83 | | } |
84 | | { |
85 | | // Negative test-case. |
86 | | let addr = Ipv4Addr::new(127, 0, 0, 1); |
87 | | let mask = Ipv4Addr::new(255, 0, 255, 0); |
88 | | Ipv4Net::with_netmask(addr, mask).unwrap_err(); |
89 | | } |
90 | | } |
91 | | |
92 | | #[test] |
93 | | fn v6_mask_to_prefix() { |
94 | | let mask = Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0); |
95 | | let prefix = ipv6_mask_to_prefix(mask); |
96 | | assert_eq!(prefix, Ok(48)); |
97 | | } |
98 | | |
99 | | #[test] |
100 | | fn v6_mask_to_prefix_max() { |
101 | | let mask = Ipv6Addr::from(u128::MAX); |
102 | | let prefix = ipv6_mask_to_prefix(mask); |
103 | | assert_eq!(prefix, Ok(128)); |
104 | | } |
105 | | |
106 | | #[test] |
107 | | fn invalid_v6_mask_to_prefix() { |
108 | | let mask = Ipv6Addr::new(0, 0, 0xffff, 0xffff, 0, 0, 0, 0); |
109 | | let prefix = ipv6_mask_to_prefix(mask); |
110 | | assert!(prefix.is_err()); |
111 | | } |
112 | | |
113 | | #[test] |
114 | | fn ipv6net_with_netmask() { |
115 | | { |
116 | | // Positive test-case. |
117 | | let addr = Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2); |
118 | | let mask = Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0); |
119 | | let net = Ipv6Net::with_netmask(addr, mask).unwrap(); |
120 | | let expected = |
121 | | Ipv6Net::new(Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2), 48).unwrap(); |
122 | | assert_eq!(net, expected); |
123 | | } |
124 | | { |
125 | | // Negative test-case. |
126 | | let addr = Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2); |
127 | | let mask = Ipv6Addr::new(0, 0, 0xffff, 0xffff, 0, 0, 0, 0); |
128 | | Ipv6Net::with_netmask(addr, mask).unwrap_err(); |
129 | | } |
130 | | } |
131 | | } |