12#ifndef OPENVPN_ADDR_IPV4_H
13#define OPENVPN_ADDR_IPV4_H
43 static constexpr unsigned int SIZE = 32;
73 ret.s_addr = htonl(
u.addr);
80 ret.
u.
addr = ntohl(sa->sin_addr.s_addr);
87 ret.sin_family = AF_INET;
89 ret.sin_addr.s_addr = htonl(
u.addr);
90#if defined(__APPLE__) || defined(__FreeBSD__)
92 ret.sin_len =
sizeof(
struct sockaddr_in);
118 *
reinterpret_cast<base_type *
>(bytestr) = ntohl(
u.addr);
123 return htonl(
u.addr);
161 ret.u.addr = ntohl(
ret.u.addr);
195 const int lb = find_last_set(
u.addr - 1);
199#ifndef OPENVPN_LEGACY_TITLE_ABSTRACTION
201 template <
typename TITLE>
204 openvpn_io::error_code ec;
205 const openvpn_io::ip::address_v4 a = openvpn_io::ip::make_address_v4(ipstr, ec);
218 static Addr from_string(
const std::string &ipstr,
const char *title =
nullptr)
220 openvpn_io::error_code ec;
221 openvpn_io::ip::address_v4 a = openvpn_io::ip::make_address_v4(ipstr, ec);
231 const openvpn_io::ip::address_v4 a =
to_asio();
232 std::string
ret = a.to_string();
240 size_t len = s.length();
242 if (len > 0 && s[len - 1] ==
'L')
244 if (len >= 2 && s[0] ==
'0' && s[1] ==
'x')
249 if (len < 1 || len > 8)
250 throw ipv4_exception(
"parse hex error");
251 size_t di = (len - 1) >> 1;
252 for (
int i = (len & 1) ? -1 : 0; i < static_cast<int>(len); i += 2)
254 const size_t idx = base + i;
257 if (bh == -1 || bl == -1)
258 throw ipv4_exception(
"parse hex error");
259 ret.u.bytes[Endian::e4(di--)] =
static_cast<unsigned char>((bh << 4) + bl);
268 bool firstnonzero =
false;
269 for (
size_t i = 0; i < 4; ++i)
271 const unsigned char b =
u.bytes[Endian::e4rev(i)];
272 if (b || firstnonzero || i == 3)
274 const char bh =
static_cast<decltype(bh)
>(b >> 4);
275 if (bh || firstnonzero)
286 std::ostringstream
os;
287 os << static_cast<int>(
u.bytes[Endian::e4(0)]) <<
'.'
288 <<
static_cast<int>(
u.bytes[Endian::e4(1)]) <<
'.'
289 <<
static_cast<int>(
u.bytes[Endian::e4(2)]) <<
'.'
290 <<
static_cast<int>(
u.bytes[Endian::e4(3)]) <<
".in-addr.arpa";
303 return openvpn_io::ip::address_v4(
u.addr);
398 return u.addr == other.
u.
addr;
403 return u.addr != other.
u.
addr;
408 return u.addr < other.
u.
addr;
413 return u.addr > other.
u.
addr;
418 return u.addr <= other.
u.
addr;
423 return u.addr >= other.
u.
addr;
448 return (
u.addr & 0x7F000000) == 0x7F000000;
458 throw ipv4_exception(
"malformed netmask");
487 throw ipv4_exception(
"extent overflow");
493 if (
addr == ~std::uint32_t(0))
497 unsigned int high = 32;
498 unsigned int low = 1;
499 for (
unsigned int i = 0; i < 5; ++i)
501 const unsigned int mid = (high + low) / 2;
514 static constexpr unsigned int size()
519 template <
typename HASH>
525#ifdef USE_OPENVPN_HASH
526 std::uint64_t hashval()
const
534#ifdef OPENVPN_IP_IMMUTABLE
566 u.
addr += (std::uint32_t)delta;
587 throw ipv4_exception(
"bad prefix len");
592 unsigned char bytes[4];
599#ifdef USE_OPENVPN_HASH
Addr operator+(const long delta) const
void to_byte_string(unsigned char *bytestr) const
static Addr from_hex(const std::string &s)
bool operator!=(const Addr &other) const
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
unsigned int prefix_len() const
unsigned long to_ulong() const
openvpn_io::ip::address_v4 to_asio() const
static Addr from_bytes_net(const unsigned char *bytes)
static Addr from_asio(const openvpn_io::ip::address_v4 &asio_addr)
static Addr from_string(const std::string &ipstr)
std::int32_t signed_base_type
Addr operator%(const Addr &other) const
unsigned int host_len() const
Addr operator<<(const unsigned int shift) const
static base_type prefix_len_to_netmask(const unsigned int prefix_len)
static int prefix_len_32(const std::uint32_t addr)
static Addr from_ulong(unsigned long ul)
static Addr from_sockaddr(const sockaddr_in *sa)
std::string to_hex() const
static Addr from_long(long ul)
static Addr from_uint32_net(const base_type addr)
Addr operator&(const Addr &other) const
bool operator<(const Addr &other) const
static Addr from_in_addr(const in_addr *in4)
static constexpr bool defined()
Addr operator-(const Addr &other) const
in_addr to_in_addr() const
bool operator==(const Addr &other) const
Addr operator|(const Addr &other) const
std::uint32_t extent_from_netmask_uint32() const
Addr operator+(const Addr &other) const
Addr operator/(const Addr &other) const
int prefix_len_nothrow() const
Addr & operator+=(const long delta)
static base_type prefix_len_to_netmask_unchecked(const unsigned int prefix_len) noexcept
static Addr from_bytes(const unsigned char *bytes)
std::uint32_t to_uint32_net() const
static Addr from_zero_complement()
Addr netmask_from_this_as_extent() const
static Addr from_addr(const Addr &addr)
static constexpr int ip_version()
Addr operator-(const long delta) const
Addr operator*(const Addr &other) const
static constexpr unsigned int size()
bool operator<=(const Addr &other) const
static Addr from_uint32(const base_type addr)
Addr & operator-=(const long delta)
std::string to_string() const
Addr network_addr(const unsigned int prefix_len) const
bool operator>(const Addr &other) const
std::uint32_t to_uint32() const
Addr extent_from_netmask() const
sockaddr_in to_sockaddr(const unsigned short port=0) const
static Addr from_string(const std::string &ipstr, const TITLE &title)
static constexpr unsigned int SIZE
bool operator>=(const Addr &other) const
union openvpn::IPv4::Addr::@2 u
Addr operator>>(const unsigned int shift) const
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_HASH_METHOD(T, meth)
std::string format_error(const std::string &ipstr, const TITLE &title, const char *ipver, const std::string &message)
int parse_hex_char(const int c)
char render_hex_char(const int c, const bool caps=false)
#define OPENVPN_OSTREAM(TYPE, METH)