Перечисление IpAddr
#![allow(unused)] fn main() { pub enum IpAddr { V4(Ipv4Addr), V6(Ipv6Addr), } }
IP-адрес, версия 4 или версия 6.
Этот enum может содержать либо адрес IPv4, либо адрес IPv6, с их соответствующими типами. Для представления любого IP-адреса, который может быть либо IPv4, либо IPv6, следует использовать этот тип.
Варианты
V4
#![allow(unused)] fn main() { V4(Ipv4Addr) }
Адрес IPv4.
V6
#![allow(unused)] fn main() { V6(Ipv6Addr) }
Адрес IPv6.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); assert_eq!("127.0.0.1".parse(), Ok(localhost_v4)); assert_eq!("::1".parse(), Ok(localhost_v6)); assert_eq!(localhost_v4.is_ipv4(), true); assert_eq!(localhost_v6.is_ipv6(), true); }
Методы
is_unspecified
#![allow(unused)] fn main() { pub const fn is_unspecified(&self) -> bool }
Возвращает true, если это неспецифицированный адрес.
Для IPv4 это 0.0.0.0. Для IPv6 это ::.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; assert_eq!(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)).is_unspecified(), true); assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).is_unspecified(), true); }
is_loopback
#![allow(unused)] fn main() { pub const fn is_loopback(&self) -> bool }
Возвращает true, если это адрес обратной петли.
Для IPv4 это 127.0.0.0/8. Для IPv6 это ::1.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_loopback(), true); assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)).is_loopback(), true); }
is_global
#![allow(unused)] fn main() { pub fn is_global(&self) -> bool }
Возвращает true, если это глобальный адрес.
Глобальные адреса - это все адреса, которые не зарезервированы для специальных целей. Это включает в себя адреса из глобального пула unicast, а также другие адреса, которые могут быть маршрутизированы глобально.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; // Частные адреса не являются глобальными assert_eq!(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)).is_global(), false); assert_eq!(IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)).is_global(), false); // Некоторые публичные адреса являются глобальными assert_eq!(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)).is_global(), true); }
is_multicast
#![allow(unused)] fn main() { pub const fn is_multicast(&self) -> bool }
Возвращает true, если это многоадресный адрес.
Для IPv4 это 224.0.0.0/4. Для IPv6 это ff00::/8.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; assert_eq!(IpAddr::V4(Ipv4Addr::new(224, 0, 0, 1)).is_multicast(), true); assert_eq!(IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 1)).is_multicast(), true); }
is_ipv4
#![allow(unused)] fn main() { pub const fn is_ipv4(&self) -> bool }
Возвращает true, если это адрес IPv4.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_ipv4(), true); assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)).is_ipv4(), false); }
is_ipv6
#![allow(unused)] fn main() { pub const fn is_ipv6(&self) -> bool }
Возвращает true, если это адрес IPv6.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_ipv6(), false); assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)).is_ipv6(), true); }
is_documentation
#![allow(unused)] fn main() { pub fn is_documentation(&self) -> bool }
Возвращает true, если это адрес, зарезервированный для документации.
Для IPv4 это 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24. Для IPv6 это 2001:db8::/32.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; assert_eq!(IpAddr::V4(Ipv4Addr::new(192, 0, 2, 1)).is_documentation(), true); assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)).is_documentation(), true); }
to_ipv6_mapped
#![allow(unused)] fn main() { pub fn to_ipv6_mapped(&self) -> IpAddr }
Преобразует адрес IPv4 в IPv4-отображенный адрес IPv6.
Возвращает адрес IPv6, соответствующий адресу IPv4, используя механизм IPv4-отображения IPv6, определенный в IETF RFC 4291 Section 2.5.5.2.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; let ipv4 = IpAddr::V4(Ipv4Addr::new(192, 0, 2, 255)); let ipv6_mapped = ipv4.to_ipv6_mapped(); assert_eq!( ipv6_mapped, IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff)) ); }
Трайт-реализации
From<Ipv4Addr>
#![allow(unused)] fn main() { impl From<Ipv4Addr> for IpAddr }
Преобразует Ipv4Addr в IpAddr.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr}; let addr = Ipv4Addr::new(127, 0, 0, 1); let ip_addr = IpAddr::from(addr); assert_eq!(ip_addr, IpAddr::V4(addr)); }
From<Ipv6Addr>
#![allow(unused)] fn main() { impl From<Ipv6Addr> for IpAddr }
Преобразует Ipv6Addr в IpAddr.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv6Addr}; let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); let ip_addr = IpAddr::from(addr); assert_eq!(ip_addr, IpAddr::V6(addr)); }
Display, Debug
#![allow(unused)] fn main() { impl Display for IpAddr impl Debug for IpAddr }
Реализует отображение и отладочное отображение для IpAddr.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr}; let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); println!("IP адрес: {}", ip); // "127.0.0.1" println!("Отладочная информация: {:?}", ip); // "V4(127.0.0.1)" }
PartialEq, Eq, PartialOrd, Ord, Hash
#![allow(unused)] fn main() { impl PartialEq for IpAddr impl Eq for IpAddr impl PartialOrd for IpAddr impl Ord for IpAddr impl Hash for IpAddr }
Реализует сравнение и хеширование для IpAddr.
Примеры
#![allow(unused)] fn main() { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::collections::HashMap; let ip1 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); let ip2 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); let ip3 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); assert_eq!(ip1, ip2); assert_ne!(ip1, ip3); let mut map = HashMap::new(); map.insert(ip1, "localhost"); }
FromStr
#![allow(unused)] fn main() { impl FromStr for IpAddr }
Реализует парсинг из строки для IpAddr.
Примеры
#![allow(unused)] fn main() { use std::net::IpAddr; use std::str::FromStr; let ipv4 = IpAddr::from_str("192.168.1.1").unwrap(); assert!(ipv4.is_ipv4()); let ipv6 = IpAddr::from_str("::1").unwrap(); assert!(ipv6.is_ipv6()); }
Примеры использования
Проверка типов адресов
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; fn analyze_ip(ip: IpAddr) { println!("Анализ IP адреса: {}", ip); if ip.is_unspecified() { println!(" Это неспецифицированный адрес"); } if ip.is_loopback() { println!(" Это адрес обратной петли"); } if ip.is_global() { println!(" Это глобальный адрес"); } if ip.is_multicast() { println!(" Это многоадресный адрес"); } if ip.is_documentation() { println!(" Это адрес для документации"); } if ip.is_ipv4() { println!(" Это IPv4 адрес"); } if ip.is_ipv6() { println!(" Это IPv6 адрес"); } } fn main() { let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); let multicast_v4 = IpAddr::V4(Ipv4Addr::new(224, 0, 0, 1)); let documentation_v4 = IpAddr::V4(Ipv4Addr::new(192, 0, 2, 1)); analyze_ip(localhost_v4); analyze_ip(localhost_v6); analyze_ip(multicast_v4); analyze_ip(documentation_v4); }
Использование в сетевых операциях
use std::net::{TcpListener, TcpStream, IpAddr}; use std::io; fn create_server(ip: IpAddr, port: u16) -> io::Result<TcpListener> { let addr = (ip, port); TcpListener::bind(addr) } fn connect_to_server(ip: IpAddr, port: u16) -> io::Result<TcpStream> { let addr = (ip, port); TcpStream::connect(addr) } fn main() -> io::Result<()> { // Использование IPv4 let ipv4 = "127.0.0.1".parse::<IpAddr>().unwrap(); let _server_v4 = create_server(ipv4, 8080)?; // Использование IPv6 let ipv6 = "::1".parse::<IpAddr>().unwrap(); let _client_v6 = connect_to_server(ipv6, 8080)?; Ok(()) }
Фильтрация IP-адресов
use std::net::{IpAddr, Ipv4Addr}; fn filter_private_ips(ips: Vec<IpAddr>) -> Vec<IpAddr> { ips.into_iter() .filter(|ip| { if let IpAddr::V4(ipv4) = ip { // Фильтруем частные адреса IPv4 !(ipv4.octets()[0] == 10 || // 10.0.0.0/8 (ipv4.octets()[0] == 172 && ipv4.octets()[1] >= 16 && ipv4.octets()[1] <= 31) || // 172.16.0.0/12 (ipv4.octets()[0] == 192 && ipv4.octets()[1] == 168)) // 192.168.0.0/16 } else { true // Пропускаем все IPv6 адреса } }) .collect() } fn main() { let ips = vec![ "10.0.0.1".parse().unwrap(), "192.168.1.1".parse().unwrap(), "8.8.8.8".parse().unwrap(), "::1".parse().unwrap(), ]; let public_ips = filter_private_ips(ips); println!("Публичные IP адреса:"); for ip in public_ips { println!(" {}", ip); } }
Преобразование между IPv4 и IPv6
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; fn demonstrate_mapping() { let ipv4 = Ipv4Addr::new(192, 168, 1, 1); let ip_addr_v4 = IpAddr::V4(ipv4); // Преобразование в IPv4-отображенный IPv6 let ipv6_mapped = ip_addr_v4.to_ipv6_mapped(); println!("Оригинальный IPv4: {}", ipv4); println!("IPv4-отображенный IPv6: {}", ipv6_mapped); if let IpAddr::V6(ipv6) = ipv6_mapped { // Проверяем, что это действительно IPv4-отображенный адрес if ipv6.to_ipv4_mapped().is_some() { println!("Это IPv4-отображенный адрес IPv6"); } } } fn main() { demonstrate_mapping(); }