12#ifndef OPENVPN_ADDR_IP_H
13#define OPENVPN_ADDR_IP_H
29#define OPENVPN_IP_THROW(ERR) throw openvpn::IP::ip_exception(ERR)
61#ifndef OPENVPN_LEGACY_TITLE_ABSTRACTION
63 template <
typename TITLE>
81 template <
typename TITLE>
87 template <
typename TITLE>
88 Addr(
const std::string &ipstr,
const TITLE &title,
const Version required_version)
93 template <
typename TITLE>
94 Addr(
const std::string &ipstr,
const TITLE &title)
99 Addr(
const std::string &ipstr)
104 template <
typename TITLE>
107 const Version required_version)
109 openvpn_io::error_code ec;
110 openvpn_io::ip::address a = openvpn_io::ip::make_address(ipstr, ec);
114 if (required_version !=
UNSPEC && required_version !=
ret.ver)
119 template <
typename TITLE>
130 template <
typename TITLE>
131 static std::string
validate(
const std::string &ipstr,
133 const Version required_version)
139 template <
typename TITLE>
140 static std::string
validate(
const std::string &ipstr,
const TITLE &title)
145 static std::string
validate(
const std::string &ipstr)
150 template <
typename TITLE>
153 if (required_version !=
UNSPEC && required_version !=
ver)
176 Addr(
const std::string &ipstr,
const char *title =
nullptr,
Version required_version =
UNSPEC)
186 Addr(
const std::string &ipstr,
const std::string &title,
Version required_version =
UNSPEC)
194 if (required_version !=
UNSPEC && required_version !=
ver)
205 static std::string
validate(
const std::string &ipstr,
const char *title =
nullptr,
Version required_version =
UNSPEC)
208 return a.to_string();
212 static std::string
validate(
const std::string &ipstr,
const std::string &title,
Version required_version =
UNSPEC)
214 return validate(ipstr, title.c_str(), required_version);
220 openvpn_io::error_code ec;
221 openvpn_io::ip::address a = openvpn_io::ip::make_address(ipstr, ec);
225 if (required_version !=
UNSPEC && required_version !=
ret.ver)
235 if (std::any_of(ipstr.begin(), ipstr.end(), [](
auto c)
236 { return !(std::isxdigit(c) || c ==
'.' || c ==
':' || c ==
'%'); }))
241 openvpn_io::error_code ec;
242 openvpn_io::ip::make_address(ipstr, ec);
264 a.
u.
v4 = std::move(addr);
272 a.
u.
v6 = std::move(addr);
328 if (sa->sa_family == AF_INET)
330 if (sa->sa_family == AF_INET6)
337 return sa && (sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
359 return u.v4.to_ulong();
361 return u.v6.to_ulong();
386 return u.v4.to_long();
388 return u.v6.to_long();
420 u.v6.to_byte_string(bytestr);
423 std::memset(bytestr, 0, 16);
434 u.v4.to_byte_string(bytestr);
437 u.v6.to_byte_string(bytestr);
446 return (
ver ==
V4) ?
u.v4.to_uint32_net() : 0;
520 return from_ipv4(
u.v4.netmask_from_this_as_extent());
522 return from_ipv6(
u.v6.netmask_from_this_as_extent());
532 const openvpn_io::ip::address a =
to_asio();
533 std::string
ret = a.to_string();
555 return u.v4.to_hex();
557 return u.v6.to_hex();
584 else if (addr.is_v6())
599 return openvpn_io::ip::address_v4(
u.v4.to_asio());
601 return openvpn_io::ip::address_v6(
u.v6.to_asio());
615 ret.u.v4 =
u.v4 + delta;
622 ret.u.v6 =
u.v6 + delta;
643 ret.u.v4 =
u.v4 << shift;
650 ret.u.v6 =
u.v6 << shift;
666 ret.u.v4 =
u.v4 >> shift;
673 ret.u.v6 =
u.v6 >> shift;
735 return u.v4 == other.
u.
v4;
739 return u.v6 == other.
u.
v6;
752 return compare(other, std::less<>{});
757 return compare(other, std::greater<>{});
762 return compare(other, std::less_equal<>{});
767 return compare(other, std::greater_equal<>{});
783 return binary_op(other, std::multiplies<>{});
788 return binary_op(other, std::divides<>{});
793 return binary_op(other, std::modulus<>{});
798 return binary_op(other, std::bit_and<>{});
803 return binary_op(other, std::bit_or<>{});
821 return u.v4.all_zeros();
823 return u.v6.all_zeros();
834 return u.v4.all_ones();
836 return u.v6.all_ones();
847 return u.v4.is_loopback();
849 return u.v6.is_loopback();
863 return u.v6.is_mapped_address();
973 return u.v4.prefix_len();
975 return u.v6.prefix_len();
984 return ver ==
V6 ?
u.v6.scope_id() : -1;
993 return u.v4.host_len();
995 return u.v6.host_len();
1007 return from_ipv4(
u.v4.extent_from_netmask());
1009 return from_ipv6(
u.v6.extent_from_netmask());
1041 template <
typename HASH>
1057#ifdef USE_OPENVPN_HASH
1058 std::uint64_t hashval()
const
1066#ifdef OPENVPN_IP_IMMUTABLE
1149 template <
typename Comparator>
1157 return comp(
u.v4, other.
u.
v4);
1159 return comp(
u.v6, other.
u.
v6);
1164 return comp(
ver, other.
ver);
1167 template <
typename BinaryOp>
1181 ret.u.v4 = op(
u.v4, other.
u.
v4);
1184 ret.u.v6 = op(
u.v6, other.
u.
v6);
1197#ifdef USE_OPENVPN_HASH
static Addr from_asio(const openvpn_io::ip::address &addr)
static bool validate_prefix_len(Version v, const unsigned int prefix_len)
bool operator==(const Addr &other) const
static Addr from_string(const std::string &ipstr, const TITLE &title, const Version required_version)
int version_index() const
Addr operator/(const Addr &other) const
std::uint32_t to_uint32_net() const
void verify_version_consistency(const Addr &other) const
Addr operator-(const long delta) const
union openvpn::IP::Addr::@4 u
IPv4::Addr to_ipv4_zero() const
Addr(const Addr &other, const TITLE &title)
static Addr from_sockaddr(const struct sockaddr *sa)
std::string to_string() const
unsigned int size() const
static std::string validate(const std::string &ipstr, const TITLE &title, const Version required_version)
unsigned int size_bytes() const
void validate_version(const TITLE &title, const Version required_version) const
Addr netmask_from_this_as_extent() const
const IPv4::Addr & to_ipv4() const
std::string to_string_bracket_ipv6() const
Addr & operator=(const Addr &other)
Addr operator>>(const unsigned int shift) const
Addr(const std::string &ipstr, const TITLE &title)
const IPv6::Addr & to_ipv6_nocheck() const
Addr operator%(const Addr &other) const
static std::string validate(const std::string &ipstr, const TITLE &title)
static Addr from_long(Version v, const long ul)
static bool is_valid(const std::string &ipstr)
Addr & operator-=(const long delta)
static Addr from_one(const Version v)
bool compare(const Addr &other, Comparator comp) const
Addr binary_op(const Addr &other, BinaryOp op) const
const IPv4::Addr & to_ipv4_nocheck() const
static Addr netmask_from_prefix_len(Version v, const unsigned int prefix_len)
bool is_compatible(const Addr &other) const
std::string to_hex() const
bool operator<=(const Addr &other) const
Addr operator+(const long delta) const
IP::Addr to_v4_addr() const
void reset_ipv4_from_uint32(const IPv4::Addr::base_type addr)
Addr extent_from_netmask() const
static Addr from_hex(Version v, const std::string &s)
bool operator>=(const Addr &other) const
static std::string validate(const std::string &ipstr)
static bool sockaddr_defined(const struct sockaddr *sa)
Addr operator|(const Addr &other) const
const IPv6::Addr & to_ipv6() const
Addr(const std::string &ipstr, const TITLE &title, const Version required_version)
static Addr from_ipv6(IPv6::Addr addr)
static Addr from_ipv4(IPv4::Addr addr)
static const char * version_string_static(Version ver)
IPv6::Addr to_ipv6_zero() const
bool operator<(const Addr &other) const
void to_byte_string_variable(unsigned char *bytestr) const
static Addr from_byte_string(const unsigned char *bytestr)
Addr & operator+=(const long delta)
bool operator>(const Addr &other) const
void validate_netmask() const
unsigned int prefix_len() const
static Addr from_ulong(Version v, unsigned long ul)
unsigned long to_ulong() const
openvpn_io::ip::address to_asio() const
bool operator!=(const Addr &other) const
void to_byte_string(unsigned char *bytestr) const
static unsigned int version_size(Version v)
Addr operator-(const Addr &other) const
static VersionMask version_mask(const Version ver)
Addr(const std::string &ipstr)
Addr operator<<(const unsigned int shift) const
const char * version_string() const
Addr(const Addr &other, const TITLE &title, const Version required_version)
static Addr from_string(const std::string &ipstr)
Addr network_addr(const unsigned int prefix_len) const
VersionMask version_mask() const
bool is_mapped_address() const
Addr operator&(const Addr &other) const
unsigned int host_len() const
Addr operator+(const Addr &other) const
Addr operator*(const Addr &other) const
static Addr from_zero(const Version v)
static Addr from_string(const std::string &ipstr, const TITLE &title)
static Addr from_zero_complement(const Version v)
static Addr from_hex(const std::string &s)
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
static Addr from_asio(const openvpn_io::ip::address_v4 &asio_addr)
static Addr from_ulong(unsigned long ul)
static Addr from_sockaddr(const sockaddr_in *sa)
static Addr from_long(long ul)
static Addr from_uint32_net(const base_type addr)
static Addr from_zero_complement()
static Addr from_uint32(const base_type addr)
static Addr from_sockaddr(const sockaddr_in6 *sa)
static Addr from_byte_string(const unsigned char *bytestr)
static Addr from_long(long ul)
static bool byte_string_is_v4(const unsigned char *bytestr)
static Addr from_hex(const std::string &s)
static Addr from_zero_complement()
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
static void v4_to_byte_string(unsigned char *bytestr, const std::uint32_t v4addr)
static std::uint32_t v4_from_byte_string(const unsigned char *bytestr)
static Addr from_asio(const openvpn_io::ip::address_v6 &asio_addr)
std::uint32_t get_mapped_ipv4_address() const
static Addr from_ulong(unsigned long ul)
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_HASH_METHOD(T, meth)
#define OPENVPN_IP_THROW(ERR)
std::string format_error(const std::string &ipstr, const TITLE &title, const char *ipver, const std::string &message)
#define OPENVPN_OSTREAM(TYPE, METH)