Структура Ipv6Addr
#![allow(unused)] fn main() { pub struct Ipv6Addr(_); }
Адрес IPv6.
IPv6-адреса определяются как 128-битные целые числа в IETF RFC 4291. Они обычно представляются в виде восьми 16-битных сегментов, разделенных двоеточиями.
См. также IpAddr для типа, представляющий либо IPv4, либо IPv6.
Представление в памяти
Ipv6Addr представляет собой 128-битное целое число без знака, хранящееся в сетевом порядке байт (big-endian). Это то же представление, что и в системных вызовах Unix и Windows.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); assert_eq!("::1".parse(), Ok(localhost)); let unspecified = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0); assert_eq!(unspecified, Ipv6Addr::UNSPECIFIED); }
Константы
UNSPECIFIED
#![allow(unused)] fn main() { pub const UNSPECIFIED: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0); }
Неспецифицированный адрес IPv6: ::.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::UNSPECIFIED; assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); assert!(addr.is_unspecified()); }
LOCALHOST
#![allow(unused)] fn main() { pub const LOCALHOST: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); }
Адрес обратной петли IPv6: ::1.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::LOCALHOST; assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); assert!(addr.is_loopback()); }
BROADCAST
#![allow(unused)] fn main() { // Примечание: IPv6 не имеет широковещательных адресов, используется многоадресная рассылка }
В IPv6 нет широковещательных адресов. Вместо них используется многоадресная рассылка.
Методы
new
#![allow(unused)] fn main() { pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr }
Создает новый IPv6-адрес из восьми 16-битных сегментов.
Результат представляет собой адрес a:b:c:d:e:f:g:h.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert_eq!(addr.to_string(), "2001:db8::1"); }
segments
#![allow(unused)] fn main() { pub const fn segments(&self) -> [u16; 8] }
Возвращает восемь 16-битных сегментов, из которых состоит адрес.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert_eq!(addr.segments(), [0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]); }
is_unspecified
#![allow(unused)] fn main() { pub const fn is_unspecified(&self) -> bool }
Возвращает true, если это неспецифицированный адрес (::).
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let unspecified = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0); let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); assert!(unspecified.is_unspecified()); assert!(!localhost.is_unspecified()); }
is_loopback
#![allow(unused)] fn main() { pub const fn is_loopback(&self) -> bool }
Возвращает true, если это адрес обратной петли (::1).
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); let other = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert!(localhost.is_loopback()); assert!(!other.is_loopback()); }
is_global
#![allow(unused)] fn main() { pub fn is_global(&self) -> bool }
Возвращает true, если это глобальный (публично маршрутизируемый) адрес.
Глобальные адреса - это все адреса, которые не зарезервированы для специальных целей.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let global = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let unique_local = Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 1); assert!(global.is_global()); assert!(!unique_local.is_global()); }
is_unique_local
#![allow(unused)] fn main() { pub fn is_unique_local(&self) -> bool }
Возвращает true, если это unique local адрес (fc00::/7).
Unique local адреса определены в IETF RFC 4193 и являются аналогом IPv4 частных адресов.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let unique_local = Ipv6Addr::new(0xfd00, 0, 0, 0, 0, 0, 0, 1); let global = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert!(unique_local.is_unique_local()); assert!(!global.is_unique_local()); }
is_unicast_link_local
#![allow(unused)] fn main() { pub const fn is_unicast_link_local(&self) -> bool }
Возвращает true, если это unicast link-local адрес (fe80::/10).
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let link_local = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); let global = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert!(link_local.is_unicast_link_local()); assert!(!global.is_unicast_link_local()); }
is_unicast_site_local
#![allow(unused)] fn main() { #[deprecated = "используйте Ipv6Addr::is_unique_local вместо этого"] pub fn is_unicast_site_local(&self) -> bool }
Устарело: используйте is_unique_local вместо этого.
is_documentation
#![allow(unused)] fn main() { pub fn is_documentation(&self) -> bool }
Возвращает true, если это адрес, зарезервированный для документации (2001:db8::/32).
Адреса документации определены в IETF RFC 3849.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let doc = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let other = Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 1); assert!(doc.is_documentation()); assert!(!other.is_documentation()); }
is_multicast
#![allow(unused)] fn main() { pub const fn is_multicast(&self) -> bool }
Возвращает true, если это многоадресный адрес (ff00::/8).
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let multicast = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 1); let unicast = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert!(multicast.is_multicast()); assert!(!unicast.is_multicast()); }
multicast_scope
#![allow(unused)] fn main() { pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> }
Возвращает область многоадресной рассылки, если это многоадресный адрес.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv6Addr, Ipv6MulticastScope}; let multicast = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 1); if let Some(scope) = multicast.multicast_scope() { println!("Область многоадресной рассылки: {:?}", scope); } }
is_unicast_global
#![allow(unused)] fn main() { pub fn is_unicast_global(&self) -> bool }
Возвращает true, если это глобальный unicast адрес.
Глобальные unicast адреса определены в IETF RFC 4291 и включают большинство публично маршрутизируемых адресов.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let global_unicast = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let link_local = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); assert!(global_unicast.is_unicast_global()); assert!(!link_local.is_unicast_global()); }
to_ipv4
#![allow(unused)] fn main() { pub fn to_ipv4(&self) -> Option<Ipv4Addr> }
Преобразует IPv4-отображенный или IPv4-совместимый адрес IPv6 в IPv4.
Возвращает Some(Ipv4Addr), если адрес является IPv4-отображенным (::ffff:0:0/96) или IPv4-совместимым (::/96), иначе None.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, Ipv6Addr}; let ipv4_mapped = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x201); let ipv4 = ipv4_mapped.to_ipv4().unwrap(); assert_eq!(ipv4, Ipv4Addr::new(192, 0, 2, 1)); let regular_ipv6 = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert!(regular_ipv6.to_ipv4().is_none()); }
to_ipv4_mapped
#![allow(unused)] fn main() { pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> }
Преобразует IPv4-отображенный адрес IPv6 в IPv4.
Возвращает Some(Ipv4Addr), если адрес является IPv4-отображенным (::ffff:0:0/96), иначе None.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, Ipv6Addr}; let ipv4_mapped = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x201); let ipv4 = ipv4_mapped.to_ipv4_mapped().unwrap(); assert_eq!(ipv4, Ipv4Addr::new(192, 0, 2, 1)); let ipv4_compatible = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x201); assert!(ipv4_compatible.to_ipv4_mapped().is_none()); }
to_bits
#![allow(unused)] fn main() { pub const fn to_bits(&self) -> u128 }
Возвращает 128-битное представление адреса в порядке байт хоста.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); assert_eq!(addr.to_bits(), 0x20010db8000000000000000000000001); }
from_bits
#![allow(unused)] fn main() { pub const fn from_bits(bits: u128) -> Ipv6Addr }
Создает Ipv6Addr из 128-битного представления в порядке байт хоста.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::from_bits(0x20010db8000000000000000000000001); assert_eq!(addr, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); }
octets
#![allow(unused)] fn main() { pub const fn octets(&self) -> [u8; 16] }
Возвращает шестнадцать восьмибитных октетов, из которых состоит адрес.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let octets = addr.octets(); assert_eq!(octets[0..2], [0x20, 0x01]); // 2001 assert_eq!(octets[2..4], [0x0d, 0xb8]); // db8 }
Трайт-реализации
From<[u16; 8]>
#![allow(unused)] fn main() { impl From<[u16; 8]> for Ipv6Addr }
Преобразует [u16; 8] в Ipv6Addr.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let segments = [0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]; let addr = Ipv6Addr::from(segments); assert_eq!(addr, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); }
From<[u8; 16]>
#![allow(unused)] fn main() { impl From<[u8; 16]> for Ipv6Addr }
Преобразует [u8; 16] в Ipv6Addr.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let octets = [ 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]; let addr = Ipv6Addr::from(octets); assert_eq!(addr, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); }
From<u128>
#![allow(unused)] fn main() { impl From<u128> for Ipv6Addr }
Преобразует u128 в Ipv6Addr.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::from(0x20010db8000000000000000000000001); assert_eq!(addr, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); }
Into<[u16; 8]>
#![allow(unused)] fn main() { impl Into<[u16; 8]> for Ipv6Addr }
Преобразует Ipv6Addr в [u16; 8].
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let segments: [u16; 8] = addr.into(); assert_eq!(segments, [0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]); }
Into<[u8; 16]>
#![allow(unused)] fn main() { impl Into<[u8; 16]> for Ipv6Addr }
Преобразует Ipv6Addr в [u8; 16].
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let octets: [u8; 16] = addr.into(); assert_eq!(octets[0..2], [0x20, 0x01]); }
Into<u128>
#![allow(unused)] fn main() { impl Into<u128> for Ipv6Addr }
Преобразует Ipv6Addr в u128.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let bits: u128 = addr.into(); assert_eq!(bits, 0x20010db8000000000000000000000001); }
Display, Debug
#![allow(unused)] fn main() { impl Display for Ipv6Addr impl Debug for Ipv6Addr }
Реализует отображение и отладочное отображение для Ipv6Addr.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); println!("IP адрес: {}", addr); // "2001:db8::1" println!("Отладочная информация: {:?}", addr); // "2001:db8::1" }
PartialEq, Eq, PartialOrd, Ord, Hash
#![allow(unused)] fn main() { impl PartialEq for Ipv6Addr impl Eq for Ipv6Addr impl PartialOrd for Ipv6Addr impl Ord for Ipv6Addr impl Hash for Ipv6Addr }
Реализует сравнение и хеширование для Ipv6Addr.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; use std::collections::HashMap; let addr1 = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let addr2 = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); let addr3 = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2); assert_eq!(addr1, addr2); assert_ne!(addr1, addr3); let mut map = HashMap::new(); map.insert(addr1, "server"); }
FromStr
#![allow(unused)] fn main() { impl FromStr for Ipv6Addr }
Реализует парсинг из строки для Ipv6Addr.
Примеры
#![allow(unused)] fn main() { use std::net::Ipv6Addr; use std::str::FromStr; let addr = Ipv6Addr::from_str("2001:db8::1").unwrap(); assert_eq!(addr, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); }
Примеры использования
Создание и проверка IPv6 адресов
use std::net::Ipv6Addr; fn analyze_ipv6(addr: Ipv6Addr) { println!("Анализ IPv6 адреса: {}", addr); println!(" Сегменты: {:x?}", addr.segments()); println!(" 128-битное значение: 0x{:032x}", addr.to_bits()); // Проверка свойств let properties = [ ("неспецифицированный", addr.is_unspecified()), ("обратная петля", addr.is_loopback()), ("глобальный", addr.is_global()), ("unique local", addr.is_unique_local()), ("unicast link-local", addr.is_unicast_link_local()), ("для документации", addr.is_documentation()), ("многоадресный", addr.is_multicast()), ("unicast global", addr.is_unicast_global()), ]; for (name, value) in properties { if value { println!(" ✓ {}", name); } } // Проверка многоадресной области if let Some(scope) = addr.multicast_scope() { println!(" Область многоадресной рассылки: {:?}", scope); } // Попытка преобразования в IPv4 if let Some(ipv4) = addr.to_ipv4() { println!(" IPv4-отображенный: {}", ipv4); } } fn main() { let addresses = [ Ipv6Addr::UNSPECIFIED, Ipv6Addr::LOCALHOST, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), // Документация Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), // Link-local Ipv6Addr::new(0xfd00, 0, 0, 0, 0, 0, 0, 1), // Unique local Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 1), // Multicast Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x201), // IPv4-mapped ]; for addr in addresses { analyze_ipv6(addr); println!(); } }
Преобразование между форматами
use std::net::{Ipv4Addr, Ipv6Addr}; fn demonstrate_ipv6_conversions() { let original = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); // Преобразование в сегменты let segments = original.segments(); println!("Оригинальный: {}", original); println!("Сегменты: {:x?}", segments); // Преобразование из сегментов let from_segments = Ipv6Addr::from(segments); println!("Из сегментов: {}", from_segments); // Преобразование в u128 let bits = original.to_bits(); println!("128-битное значение: 0x{:032x}", bits); // Преобразование из u128 let from_bits = Ipv6Addr::from_bits(bits); println!("Из 128-битного: {}", from_bits); // Преобразование в октеты let octets = original.octets(); println!("Октеты: {:02x?}", octets); // Преобразование из октетов let from_octets = Ipv6Addr::from(octets); println!("Из октетов: {}", from_octets); // Работа с IPv4-отображенными адресами let ipv4 = Ipv4Addr::new(192, 168, 1, 1); let ipv6_mapped = ipv4.to_ipv6_mapped(); println!("IPv4: {}", ipv4); println!("IPv4-отображенный IPv6: {}", ipv6_mapped); if let Some(back_to_ipv4) = ipv6_mapped.to_ipv4() { println!("Обратно в IPv4: {}", back_to_ipv4); } } fn main() { demonstrate_ipv6_conversions(); }
Фильтрация и классификация IPv6 адресов
use std::net::Ipv6Addr; #[derive(Debug)] struct IPv6Classifier; impl IPv6Classifier { fn classify(addr: Ipv6Addr) -> &'static str { if addr.is_unspecified() { "неспецифицированный" } else if addr.is_loopback() { "обратная петля" } else if addr.is_multicast() { "многоадресный" } else if addr.is_unicast_link_local() { "unicast link-local" } else if addr.is_unique_local() { "unique local" } else if addr.is_documentation() { "документация" } else if addr.is_unicast_global() { "unicast global" } else if addr.is_global() { "глобальный" } else { "неизвестный тип" } } fn is_private(addr: Ipv6Addr) -> bool { addr.is_loopback() || addr.is_unicast_link_local() || addr.is_unique_local() || addr.is_unspecified() } fn filter_public_addresses(addrs: Vec<Ipv6Addr>) -> Vec<Ipv6Addr> { addrs.into_iter() .filter(|&addr| !Self::is_private(addr) && addr.is_global()) .collect() } } fn main() { let test_addresses = vec![ Ipv6Addr::UNSPECIFIED, Ipv6Addr::LOCALHOST, Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(0xfd00, 0, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(0x2606, 0x4700, 0x4700, 0, 0, 0, 0, 0x1111), // Cloudflare DNS ]; println!("Классификация IPv6 адресов:"); for addr in &test_addresses { let classification = IPv6Classifier::classify(*addr); let is_private = IPv6Classifier::is_private(*addr); println!(" {} -> {} {}", addr, classification, if is_private { "(private)" } else { "(public)" }); } let public_addrs = IPv6Classifier::filter_public_addresses(test_addresses); println!("\nПубличные адреса:"); for addr in public_addrs { println!(" {}", addr); } }
Работа с многоадресными адресами
use std::net::{Ipv6Addr, Ipv6MulticastScope}; fn analyze_multicast() { let multicast_addresses = [ Ipv6Addr::new(0xff01, 0, 0, 0, 0, 0, 0, 1), // Interface-local Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 1), // Link-local Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 1), // Site-local Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 1), // Global ]; println!("Анализ многоадресных IPv6 адресов:"); for addr in multicast_addresses { println!("\nАдрес: {}", addr); println!(" Сегменты: {:x?}", addr.segments()); if let Some(scope) = addr.multicast_scope() { println!(" Область: {:?}", scope); match scope { Ipv6MulticastScope::InterfaceLocal => { println!(" Описание: В пределах одного интерфейса"); } Ipv6MulticastScope::LinkLocal => { println!(" Описание: В пределах одной ссылки"); } Ipv6MulticastScope::RealmLocal => { println!(" Описание: В пределах REALM"); } Ipv6MulticastScope::AdminLocal => { println!(" Описание: Административно ограниченная область"); } Ipv6MulticastScope::SiteLocal => { println!(" Описание: В пределах одного сайта"); } Ipv6MulticastScope::OrganizationLocal => { println!(" Описание: В пределах одной организации"); } Ipv6MulticastScope::Global => { println!(" Описание: Глобальная область"); } Ipv6MulticastScope::Reserved => { println!(" Описание: Зарезервированная область"); } Ipv6MulticastScope::Unassigned => { println!(" Описание: Не назначенная область"); } } } } } fn main() { analyze_multicast(); }