Botan 3.13.0
Crypto and TLS for C&
Botan::IPv6Subnet Class Referencefinal

#include <ipv6_address.h>

Public Member Functions

const IPv6Addressaddress () const
 The network address (host bits already zeroed).
bool contains (const IPv6Address &ip) const
 True iff ip falls within this subnet.
 IPv6Subnet (IPv6Address address, size_t prefix_length)
bool is_host () const
 True iff prefix_length() == 128.
size_t prefix_length () const
 Prefix length in [0, 128].
std::vector< uint8_t > serialize () const
std::string to_string () const
 CIDR-style "2001:db8::/32".

Static Public Member Functions

static std::optional< IPv6Subnetfrom_address_and_mask (std::span< const uint8_t, 32 > addr_and_mask)
static std::optional< IPv6Subnetfrom_string (std::string_view str)
static IPv6Subnet host (IPv6Address address)

Friends

bool operator== (const IPv6Subnet &, const IPv6Subnet &)=default

Detailed Description

An IPv6 subnet in CIDR form: a network address paired with a prefix length

Definition at line 112 of file ipv6_address.h.

Constructor & Destructor Documentation

◆ IPv6Subnet()

Botan::IPv6Subnet::IPv6Subnet ( IPv6Address address,
size_t prefix_length )

Construct from a network address and a prefix length in [0, 128]. Host bits of address are cleared.

Throws Invalid_Argument if prefix_length > 128.

Definition at line 296 of file ipv6_address.cpp.

296 :
297 m_address(address & IPv6Address::netmask(prefix_length)), m_prefix_length(static_cast<uint8_t>(prefix_length)) {
298 // IPv6Address::netmask validates prefix_length <= 128, so by this point
299 // the static_cast is in range.
300}
static IPv6Address netmask(size_t bits)
size_t prefix_length() const
Prefix length in [0, 128].
const IPv6Address & address() const
The network address (host bits already zeroed).

References address(), IPv6Subnet(), and prefix_length().

Referenced by from_address_and_mask(), from_string(), host(), IPv6Subnet(), and operator==.

Member Function Documentation

◆ address()

const IPv6Address & Botan::IPv6Subnet::address ( ) const
inline

The network address (host bits already zeroed).

Definition at line 150 of file ipv6_address.h.

150{ return m_address; }

Referenced by host(), and IPv6Subnet().

◆ contains()

bool Botan::IPv6Subnet::contains ( const IPv6Address & ip) const

True iff ip falls within this subnet.

Definition at line 347 of file ipv6_address.cpp.

347 {
348 return (ip & IPv6Address::netmask(m_prefix_length)) == m_address;
349}

References Botan::IPv6Address::netmask().

◆ from_address_and_mask()

std::optional< IPv6Subnet > Botan::IPv6Subnet::from_address_and_mask ( std::span< const uint8_t, 32 > addr_and_mask)
static

Construct from a network address and a 16-byte CIDR netmask. Returns nullopt if netmask is not a valid contiguous CIDR prefix.

Definition at line 303 of file ipv6_address.cpp.

303 {
304 const auto addr = IPv6Address(addr_and_mask.first<16>());
305 const auto mask = IPv6Address(addr_and_mask.last<16>());
306
307 if(const auto plen = mask.prefix_length()) {
308 return IPv6Subnet(addr, *plen);
309 } else {
310 return {};
311 }
312}
IPv6Subnet(IPv6Address address, size_t prefix_length)

References IPv6Subnet().

Referenced by Botan::GeneralName::decode_from().

◆ from_string()

std::optional< IPv6Subnet > Botan::IPv6Subnet::from_string ( std::string_view str)
static

Parse the CIDR-style form "2001:db8::/32".

The "/N" suffix is required: bare addresses should be parsed via IPv6Address::from_string and wrapped with IPv6Subnet::host if needed. The input must already be canonical, such that from_string and to_string are exact inverses: the address is RFC 5952 form with host bits clear ("2001:db8::/32") and the prefix length is canonical decimal ("/32", not "/032"). In particular the IPv4-mapped dotted form ("::ffff:1.2.3.4/120") is rejected even though IPv6Address::from_string would accept the address.

Returns nullopt on parse failure or out-of-range prefix length.

Definition at line 315 of file ipv6_address.cpp.

315 {
316 const auto slash = str.find('/');
317 if(slash == std::string_view::npos) {
318 return std::nullopt;
319 }
320
321 auto addr = IPv6Address::from_string(str.substr(0, slash));
322 if(!addr.has_value()) {
323 return std::nullopt;
324 }
325
326 // Parse the prefix length as a canonical decimal integer in [0, 128]
327 const auto plen_str = str.substr(slash + 1);
328
329 const auto plen = parse_sz(plen_str, /*require_canonical=*/true);
330
331 if(!plen.has_value() || plen.value() > 128) {
332 return std::nullopt;
333 }
334
335 const IPv6Subnet subnet(*addr, plen.value());
336
337 // Require the input to already be canonical: from_string and to_string are
338 // exact inverses, so a non-canonical address (including the IPv4-mapped
339 // dotted form) or a set host bit is rejected rather than masked away
340 if(subnet.to_string() != str) {
341 return std::nullopt;
342 }
343
344 return subnet;
345}
static std::optional< IPv6Address > from_string(std::string_view str)
std::optional< size_t > parse_sz(std::string_view input, bool require_canonical)
Definition parsing.cpp:72

References Botan::IPv6Address::from_string(), IPv6Subnet(), Botan::parse_sz(), and to_string().

◆ host()

IPv6Subnet Botan::IPv6Subnet::host ( IPv6Address address)
inlinestatic

A single-host subnet (prefix length 128) covering exactly address.

Definition at line 147 of file ipv6_address.h.

147{ return IPv6Subnet(address, 128); }

References address(), and IPv6Subnet().

Referenced by Botan::GeneralName::ipv6_address().

◆ is_host()

bool Botan::IPv6Subnet::is_host ( ) const
inline

True iff prefix_length() == 128.

Definition at line 156 of file ipv6_address.h.

156{ return m_prefix_length == 128; }

Referenced by serialize().

◆ prefix_length()

size_t Botan::IPv6Subnet::prefix_length ( ) const
inline

Prefix length in [0, 128].

Definition at line 153 of file ipv6_address.h.

153{ return m_prefix_length; }

Referenced by IPv6Subnet().

◆ serialize()

std::vector< uint8_t > Botan::IPv6Subnet::serialize ( ) const

Bytes for use in a DER-encoded GeneralName iPAddress field:

  • 16 bytes (the address) if is_host(); the SAN form per RFC 5280 4.2.1.6.
  • 32 bytes (address || netmask) otherwise; the name constraint form per RFC 5280 4.2.1.10.

Definition at line 355 of file ipv6_address.cpp.

355 {
356 const auto addr = m_address.address();
357 if(is_host()) {
358 return std::vector<uint8_t>(addr.begin(), addr.end());
359 }
360 const auto mask = IPv6Address::netmask(m_prefix_length).address();
361 std::vector<uint8_t> out;
362 out.reserve(32);
363 out.insert(out.end(), addr.begin(), addr.end());
364 out.insert(out.end(), mask.begin(), mask.end());
365 return out;
366}
std::array< uint8_t, 16 > address() const
bool is_host() const
True iff prefix_length() == 128.

References Botan::IPv6Address::address(), is_host(), and Botan::IPv6Address::netmask().

◆ to_string()

std::string Botan::IPv6Subnet::to_string ( ) const

CIDR-style "2001:db8::/32".

Definition at line 351 of file ipv6_address.cpp.

351 {
352 return fmt("{}/{}", m_address.to_string(), static_cast<size_t>(m_prefix_length));
353}
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References Botan::fmt().

Referenced by from_string().

◆ operator==

bool operator== ( const IPv6Subnet & ,
const IPv6Subnet &  )
friend

References IPv6Subnet().


The documentation for this class was generated from the following files: