rpki/src/data_model/resources/ip_resources.rs

157 lines
3.5 KiB
Rust

use std::net::{Ipv4Addr, Ipv6Addr};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IPAddrBlocks {
pub ips: Vec<IPAddressFamily>,
}
// IP Address Family
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IPAddressFamily {
pub address_family: Afi,
pub ip_address_choice: IPAddressChoice,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)]
pub enum Afi {
Ipv4,
Ipv6,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum IPAddressChoice {
Inherit,
AddressOrRange(Vec<IPAddressOrRange>),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum IPAddressOrRange {
AddressPrefix(IPAddressPrefix),
AddressRange(IPAddressRange),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct IPAddressPrefix {
pub address: IPAddress,
pub prefix_length: u8,
}
impl IPAddressPrefix {
pub fn new(address: IPAddress, prefix_length: u8) -> Self {
Self {
address,
prefix_length,
}
}
pub fn is_ipv4(&self) -> bool {
self.address.is_ipv4()
}
pub fn is_ipv6(&self) -> bool {
self.address.is_ipv6()
}
pub fn afi(&self) -> Afi {
self.address.afi()
}
pub fn address(&self) -> IPAddress {
self.address
}
pub fn prefix_length(&self) -> u8 {
self.prefix_length
}
}
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct IPAddressRange {
pub min: IPAddress,
pub max: IPAddress,
}
impl IPAddressRange {
pub fn new(min: IPAddress, max: IPAddress) -> Self {
Self { min, max }
}
pub fn min(&self) -> IPAddress {
self.min
}
pub fn max(&self) -> IPAddress {
self.max
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum IPAddress {
V4(Ipv4Addr),
V6(Ipv6Addr),
}
impl IPAddress {
pub fn from_ipv4(addr: Ipv4Addr) -> Self {
Self::V4(addr)
}
pub fn from_ipv6(addr: Ipv6Addr) -> Self {
Self::V6(addr)
}
pub fn to_ipv4(self) -> Option<Ipv4Addr> {
match self {
Self::V4(addr) => Some(addr),
Self::V6(_) => None,
}
}
pub fn to_ipv6(self) -> Option<Ipv6Addr> {
match self {
Self::V4(_) => None,
Self::V6(addr) => Some(addr),
}
}
pub fn is_ipv4(self) -> bool {
matches!(self, Self::V4(_))
}
pub fn is_ipv6(self) -> bool {
matches!(self, Self::V6(_))
}
pub fn afi(self) -> Afi {
match self {
Self::V4(_) => Afi::Ipv4,
Self::V6(_) => Afi::Ipv6,
}
}
/// Returns the numeric address value.
///
/// For IPv4, this is the 32-bit address widened to u128.
/// For IPv6, this is the full 128-bit address.
pub fn as_u128(self) -> u128 {
match self {
Self::V4(addr) => u32::from(addr) as u128,
Self::V6(addr) => u128::from(addr),
}
}
pub fn as_v4_u32(self) -> Option<u32> {
match self {
Self::V4(addr) => Some(u32::from(addr)),
Self::V6(_) => None,
}
}
pub fn as_v6_u128(self) -> Option<u128> {
match self {
Self::V4(_) => None,
Self::V6(addr) => Some(u128::from(addr)),
}
}
}