• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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`.
ip_mask_to_prefix(mask: IpAddr) -> Result<u8, PrefixLenError>11 pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, PrefixLenError> {
12     match mask {
13         IpAddr::V4(mask) => ipv4_mask_to_prefix(mask),
14         IpAddr::V6(mask) => ipv6_mask_to_prefix(mask),
15     }
16 }
17 
18 /// Converts a `Ipv4Addr` network mask into a prefix.
19 ///
20 /// # Errors
21 /// If the mask is invalid this will return an `PrefixLenError`.
ipv4_mask_to_prefix(mask: Ipv4Addr) -> Result<u8, PrefixLenError>22 pub fn ipv4_mask_to_prefix(mask: Ipv4Addr) -> Result<u8, PrefixLenError> {
23     let mask = u32::from(mask);
24 
25     let prefix = mask.leading_ones();
26     if mask.checked_shl(prefix).unwrap_or(0) == 0 {
27         Ok(prefix as u8)
28     } else {
29         Err(PrefixLenError)
30     }
31 }
32 
33 /// Converts a `Ipv6Addr` network mask into a prefix.
34 ///
35 /// # Errors
36 /// If the mask is invalid this will return an `PrefixLenError`.
ipv6_mask_to_prefix(mask: Ipv6Addr) -> Result<u8, PrefixLenError>37 pub fn ipv6_mask_to_prefix(mask: Ipv6Addr) -> Result<u8, PrefixLenError> {
38     let mask = u128::from(mask);
39 
40     let prefix = mask.leading_ones();
41     if mask.checked_shl(prefix).unwrap_or(0) == 0 {
42         Ok(prefix as u8)
43     } else {
44         Err(PrefixLenError)
45     }
46 }
47 
48 #[cfg(test)]
49 mod tests {
50     use super::*;
51     use crate::{Ipv4Net, Ipv6Net};
52 
53     #[test]
v4_mask_to_prefix()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]
v4_mask_to_prefix_max()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]
invalid_v4_mask_to_prefix()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]
ipv4net_with_netmask()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]
v6_mask_to_prefix()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]
v6_mask_to_prefix_max()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]
invalid_v6_mask_to_prefix()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]
ipv6net_with_netmask()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 }
132