rust_p2p_core/extend/
addr.rs1use std::io;
2use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
3use tokio::net::UdpSocket;
4
5pub async fn local_ipv4() -> io::Result<Ipv4Addr> {
6 let socket = UdpSocket::bind("0.0.0.0:0").await?;
7 socket.connect("8.8.8.8:80").await?;
8 let addr = socket.local_addr()?;
9 match addr.ip() {
10 IpAddr::V4(ip) => Ok(ip),
11 IpAddr::V6(_) => Ok(Ipv4Addr::UNSPECIFIED),
12 }
13}
14pub async fn local_ipv6() -> io::Result<Ipv6Addr> {
15 let socket = UdpSocket::bind("[::]:0").await?;
16 socket
17 .connect("[2001:4860:4860:0000:0000:0000:0000:8888]:80")
18 .await?;
19 let addr = socket.local_addr()?;
20 match addr.ip() {
21 IpAddr::V4(_) => Ok(Ipv6Addr::UNSPECIFIED),
22 IpAddr::V6(ip) => Ok(ip),
23 }
24}
25
26pub const fn is_ipv4_global(ipv4: &Ipv4Addr) -> bool {
27 !(ipv4.octets()[0] == 0 || ipv4.is_private()
29 || ipv4.octets()[0] == 100 && (ipv4.octets()[1] & 0b1100_0000 == 0b0100_0000)|| ipv4.is_loopback()
31 || ipv4.is_link_local()
32 || (
35 ipv4.octets()[0] == 192 && ipv4.octets()[1] == 0 && ipv4.octets()[2] == 0
36 && ipv4.octets()[3] != 9 && ipv4.octets()[3] != 10
37 )
38 || ipv4.is_documentation()
39 || ipv4.octets()[0] == 198 && (ipv4.octets()[1] & 0xfe) == 18|| ipv4.octets()[0] & 240 == 240 && !ipv4.is_broadcast()|| ipv4.is_broadcast())
42}
43
44pub const fn is_ipv6_global(ipv6addr: &Ipv6Addr) -> bool {
45 !(ipv6addr.is_unspecified()
46 || ipv6addr.is_loopback()
47 || matches!(ipv6addr.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
49 || matches!(ipv6addr.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
51 || matches!(ipv6addr.segments(), [0x100, 0, 0, 0, _, _, _, _])
53 || (matches!(ipv6addr.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
55 && !(
56 u128::from_be_bytes(ipv6addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
58 || u128::from_be_bytes(ipv6addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
60 || matches!(ipv6addr.segments(), [0x2001, 3, _, _, _, _, _, _])
62 || matches!(ipv6addr.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
64 || matches!(ipv6addr.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
66 ))
67 || (ipv6addr.segments()[0] == 0x2001) && (ipv6addr.segments()[1] == 0xdb8)|| (ipv6addr.segments()[0] & 0xfe00) == 0xfc00|| (ipv6addr.segments()[0] & 0xffc0) == 0xfe80) }