12#ifndef OPENVPN_ADDR_IPV4_H
13#define OPENVPN_ADDR_IPV4_H
76 ret.s_addr = htonl(
u.addr);
83 ret.
u.
addr = ntohl(sa->sin_addr.s_addr);
90 ret.sin_family = AF_INET;
92 ret.sin_addr.s_addr = htonl(
u.addr);
93#if defined(__APPLE__) || defined(__FreeBSD__)
95 ret.sin_len =
sizeof(
struct sockaddr_in);
121 *
reinterpret_cast<base_type *
>(bytestr) = ntohl(
u.addr);
126 return htonl(
u.addr);
164 ret.u.addr = ntohl(
ret.u.addr);
198 const int lb = find_last_set(
u.addr - 1);
202#ifndef OPENVPN_LEGACY_TITLE_ABSTRACTION
204 template <
typename TITLE>
207 openvpn_io::error_code ec;
208 openvpn_io::ip::address_v4 a = openvpn_io::ip::make_address_v4(ipstr, ec);
221 static Addr from_string(
const std::string &ipstr,
const char *title =
nullptr)
223 openvpn_io::error_code ec;
224 openvpn_io::ip::address_v4 a = openvpn_io::ip::make_address_v4(ipstr, ec);
234 const openvpn_io::ip::address_v4 a =
to_asio();
235 std::string
ret = a.to_string();
243 size_t len = s.length();
245 if (len > 0 && s[len - 1] ==
'L')
247 if (len >= 2 && s[0] ==
'0' && s[1] ==
'x')
252 if (len < 1 || len > 8)
253 throw ipv4_exception(
"parse hex error");
254 size_t di = (len - 1) >> 1;
255 for (
int i = (len & 1) ? -1 : 0; i < static_cast<int>(len); i += 2)
257 const size_t idx = base + i;
260 if (bh == -1 || bl == -1)
261 throw ipv4_exception(
"parse hex error");
262 ret.u.bytes[Endian::e4(di--)] =
static_cast<unsigned char>((bh << 4) + bl);
271 bool firstnonzero =
false;
272 for (
size_t i = 0; i < 4; ++i)
274 const unsigned char b =
u.bytes[Endian::e4rev(i)];
275 if (b || firstnonzero || i == 3)
277 const char bh =
static_cast<decltype(bh)
>(b >> 4);
278 if (bh || firstnonzero)
289 std::ostringstream
os;
290 os << static_cast<int>(
u.bytes[Endian::e4(0)]) <<
'.'
291 <<
static_cast<int>(
u.bytes[Endian::e4(1)]) <<
'.'
292 <<
static_cast<int>(
u.bytes[Endian::e4(2)]) <<
'.'
293 <<
static_cast<int>(
u.bytes[Endian::e4(3)]) <<
".in-addr.arpa";
306 return openvpn_io::ip::address_v4(
u.addr);
401 return u.addr == other.
u.
addr;
406 return u.addr != other.
u.
addr;
411 return u.addr < other.
u.
addr;
416 return u.addr > other.
u.
addr;
421 return u.addr <= other.
u.
addr;
426 return u.addr >= other.
u.
addr;
451 return (
u.addr & 0x7F000000) == 0x7F000000;
461 throw ipv4_exception(
"malformed netmask");
490 throw ipv4_exception(
"extent overflow");
496 if (
addr == ~std::uint32_t(0))
500 unsigned int high = 32;
501 unsigned int low = 1;
502 for (
unsigned int i = 0; i < 5; ++i)
504 const unsigned int mid = (high + low) / 2;
517 static constexpr unsigned int size()
522 template <
typename HASH>
528#ifdef USE_OPENVPN_HASH
529 std::uint64_t hashval()
const
537#ifdef OPENVPN_IP_IMMUTABLE
569 u.
addr += (std::uint32_t)delta;
590 throw ipv4_exception(
"bad prefix len");
595 unsigned char bytes[4];
602#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)
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::int32_t signed_base_type
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)
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)