1use core::net::IpAddr;
6
7pub const fn ip_is_local(ip: IpAddr) -> bool {
16 match ip {
17 IpAddr::V4(ip) => ip.is_loopback() || ip.is_private(),
18 IpAddr::V6(ip) => ip.is_loopback() || ip.is_unique_local() || ip.is_unicast_link_local(),
19 }
20}
21
22#[cfg(test)]
23mod test {
24 use core::net::{Ipv4Addr, Ipv6Addr};
25
26 use super::*;
27
28 #[test]
29 fn ip_local() {
30 for ipv4 in [
31 Ipv4Addr::LOCALHOST,
32 Ipv4Addr::new(10, 0, 0, 0),
33 Ipv4Addr::new(10, 0, 255, 255),
34 Ipv4Addr::new(172, 16, 0, 0),
35 Ipv4Addr::new(172, 16, 255, 255),
36 Ipv4Addr::new(192, 168, 0, 0),
37 Ipv4Addr::new(192, 168, 255, 255),
38 ] {
39 assert!(ip_is_local(ipv4.into()));
40 }
41
42 for ipv4 in [
43 Ipv4Addr::UNSPECIFIED,
44 Ipv4Addr::new(1, 1, 1, 1),
45 Ipv4Addr::new(176, 9, 0, 187),
46 Ipv4Addr::new(88, 198, 163, 90),
47 Ipv4Addr::new(66, 85, 74, 134),
48 Ipv4Addr::new(51, 79, 173, 165),
49 Ipv4Addr::new(192, 99, 8, 110),
50 Ipv4Addr::new(37, 187, 74, 171),
51 Ipv4Addr::new(77, 172, 183, 193),
52 ] {
53 assert!(!ip_is_local(ipv4.into()));
54 }
55
56 for ipv6 in [
57 Ipv6Addr::LOCALHOST,
58 Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0),
59 Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0),
60 Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0),
61 Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0),
62 ] {
63 assert!(ip_is_local(ipv6.into()));
64 }
65
66 for ipv6 in [
67 Ipv6Addr::UNSPECIFIED,
68 Ipv6Addr::new(1, 1, 1, 1, 1, 1, 1, 1),
69 Ipv6Addr::new(
70 0x1020, 0x3040, 0x5060, 0x7080, 0x90A0, 0xB0C0, 0xD0E0, 0xF00D,
71 ),
72 ] {
73 assert!(!ip_is_local(ipv6.into()));
74 }
75 }
76}