mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-10-31 09:20:21 +00:00
refactor out net.hpp => net_addr.*, new inAddr struct API
This commit is contained in:
parent
c3c2eda283
commit
4646779b0a
167
include/llarp/net_addr.hpp
Normal file
167
include/llarp/net_addr.hpp
Normal file
@ -0,0 +1,167 @@
|
||||
#ifndef LLARP_NET_ADDR_HPP
|
||||
#define LLARP_NET_ADDR_HPP
|
||||
#include <string>
|
||||
#include <llarp/net.h>
|
||||
#include <llarp/address_info.hpp>
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
// fwd declr
|
||||
struct huint32_t;
|
||||
struct nuint32_t;
|
||||
|
||||
// real work
|
||||
struct Addr
|
||||
{
|
||||
// network order
|
||||
sockaddr_in6 _addr;
|
||||
sockaddr_in _addr4; // why do we even have this? favor cpu over memory
|
||||
~Addr();
|
||||
|
||||
Addr();
|
||||
|
||||
Addr(const Addr& other);
|
||||
|
||||
void
|
||||
port(uint16_t port);
|
||||
|
||||
in6_addr*
|
||||
addr6();
|
||||
|
||||
in_addr*
|
||||
addr4();
|
||||
|
||||
const in6_addr*
|
||||
addr6() const;
|
||||
|
||||
const in_addr*
|
||||
addr4() const;
|
||||
|
||||
Addr(const std::string str);
|
||||
|
||||
Addr(const std::string str, const uint16_t p_port);
|
||||
|
||||
bool
|
||||
from_char_array(const char* str);
|
||||
|
||||
Addr(const char* str);
|
||||
|
||||
bool
|
||||
from_4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four);
|
||||
|
||||
Addr(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four);
|
||||
|
||||
Addr(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four, const uint16_t p_port);
|
||||
|
||||
Addr(const AddressInfo& other);
|
||||
Addr(const sockaddr_in& other);
|
||||
Addr(const sockaddr_in6& other);
|
||||
Addr(const sockaddr& other);
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const Addr& a);
|
||||
|
||||
operator const sockaddr*() const;
|
||||
|
||||
operator sockaddr*() const;
|
||||
|
||||
void
|
||||
CopyInto(sockaddr* other) const;
|
||||
|
||||
int
|
||||
af() const;
|
||||
|
||||
uint16_t
|
||||
port() const;
|
||||
|
||||
bool
|
||||
operator<(const Addr& other) const;
|
||||
|
||||
bool
|
||||
operator==(const Addr& other) const;
|
||||
|
||||
Addr&
|
||||
operator=(const sockaddr& other);
|
||||
|
||||
inline uint32_t
|
||||
tohl() const
|
||||
{
|
||||
return ntohl(addr4()->s_addr);
|
||||
}
|
||||
|
||||
inline huint32_t
|
||||
xtohl() const
|
||||
{
|
||||
return huint32_t{ntohl(addr4()->s_addr)};
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
ton() const
|
||||
{
|
||||
return addr4()->s_addr;
|
||||
}
|
||||
|
||||
inline nuint32_t
|
||||
xtonl() const
|
||||
{
|
||||
return nuint32_t{addr4()->s_addr};
|
||||
}
|
||||
|
||||
bool
|
||||
sameAddr(const Addr& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const Addr& other) const;
|
||||
|
||||
inline uint32_t
|
||||
getHostLong()
|
||||
{
|
||||
in_addr_t addr = this->addr4()->s_addr;
|
||||
uint32_t byte = ntohl(addr);
|
||||
return byte;
|
||||
};
|
||||
|
||||
bool
|
||||
isTenPrivate(uint32_t byte);
|
||||
|
||||
bool
|
||||
isOneSevenPrivate(uint32_t byte);
|
||||
|
||||
bool
|
||||
isOneNinePrivate(uint32_t byte);
|
||||
|
||||
/// return true if our ipv4 address is a bogon
|
||||
/// TODO: ipv6
|
||||
bool
|
||||
IsBogon() const;
|
||||
|
||||
socklen_t
|
||||
SockLen() const;
|
||||
|
||||
bool
|
||||
isPrivate() const;
|
||||
|
||||
bool
|
||||
isLoopback() const;
|
||||
|
||||
struct Hash
|
||||
{
|
||||
std::size_t
|
||||
operator()(Addr const& a) const noexcept
|
||||
{
|
||||
if(a.af() == AF_INET)
|
||||
{
|
||||
return a.port() ^ a.addr4()->s_addr;
|
||||
}
|
||||
static const uint8_t empty[16] = {0};
|
||||
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
|
||||
}
|
||||
};
|
||||
}; // end struct
|
||||
} // namespace llarp
|
||||
#endif
|
64
include/llarp/net_inaddr.hpp
Normal file
64
include/llarp/net_inaddr.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef LLARP_NET_INADDR_HPP
|
||||
#define LLARP_NET_INADDR_HPP
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// IPv4 or IPv6 holder
|
||||
struct inAddr
|
||||
{
|
||||
// unsigned char s6_addr[16];
|
||||
struct in6_addr _addr; // store in network order
|
||||
|
||||
void
|
||||
reset();
|
||||
|
||||
bool
|
||||
from_char_array(const char* str);
|
||||
|
||||
void
|
||||
fromSIIT();
|
||||
|
||||
void
|
||||
toSIIT();
|
||||
|
||||
inline bool
|
||||
isIPv6Mode() const;
|
||||
|
||||
bool
|
||||
isIPv4Mode() const;
|
||||
|
||||
void
|
||||
setIPv4Mode();
|
||||
void
|
||||
hexDebug();
|
||||
|
||||
//
|
||||
// IPv4 specific functions
|
||||
//
|
||||
|
||||
in_addr
|
||||
toIAddr();
|
||||
|
||||
void
|
||||
from4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four);
|
||||
|
||||
void
|
||||
fromN32(nuint32_t in);
|
||||
void
|
||||
fromH32(huint32_t in);
|
||||
nuint32_t
|
||||
toN32();
|
||||
huint32_t
|
||||
toH32();
|
||||
|
||||
//
|
||||
// IPv6 specific functions
|
||||
//
|
||||
};
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
475
llarp/net_addr.cpp
Normal file
475
llarp/net_addr.cpp
Normal file
@ -0,0 +1,475 @@
|
||||
#include <llarp/net_addr.hpp>
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
// for addrinfo
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
||||
#endif
|
||||
|
||||
llarp::Addr::operator const sockaddr*() const
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
return (const sockaddr*)&_addr4;
|
||||
else
|
||||
return (const sockaddr*)&_addr;
|
||||
}
|
||||
|
||||
llarp::Addr::operator sockaddr*() const
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
return (sockaddr*)&_addr4;
|
||||
else
|
||||
return (sockaddr*)&_addr;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp::Addr::operator<(const Addr& other) const
|
||||
{
|
||||
if(af() == AF_INET && other.af() == AF_INET)
|
||||
return port() < other.port() || addr4()->s_addr < other.addr4()->s_addr;
|
||||
else
|
||||
return port() < other.port() || *addr6() < *other.addr6()
|
||||
|| af() < other.af();
|
||||
}
|
||||
|
||||
bool
|
||||
llarp::Addr::operator==(const Addr& other) const
|
||||
{
|
||||
if(af() == AF_INET && other.af() == AF_INET)
|
||||
return port() == other.port() && addr4()->s_addr == other.addr4()->s_addr;
|
||||
else
|
||||
return af() == other.af() && memcmp(addr6(), other.addr6(), 16) == 0
|
||||
&& port() == other.port();
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
Addr::Addr(){};
|
||||
Addr::~Addr(){};
|
||||
|
||||
Addr::Addr(const Addr& other)
|
||||
{
|
||||
memcpy(&_addr, &other._addr, sizeof(sockaddr_in6));
|
||||
memcpy(&_addr4, &other._addr4, sizeof(sockaddr_in));
|
||||
}
|
||||
|
||||
void
|
||||
Addr::port(uint16_t port)
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
{
|
||||
_addr4.sin_port = htons(port);
|
||||
}
|
||||
_addr.sin6_port = htons(port);
|
||||
}
|
||||
|
||||
in6_addr*
|
||||
Addr::addr6()
|
||||
{
|
||||
return (in6_addr*)&_addr.sin6_addr.s6_addr[0];
|
||||
}
|
||||
|
||||
in_addr*
|
||||
Addr::addr4()
|
||||
{
|
||||
return (in_addr*)&_addr.sin6_addr.s6_addr[12];
|
||||
}
|
||||
|
||||
const in6_addr*
|
||||
Addr::addr6() const
|
||||
{
|
||||
return (const in6_addr*)&_addr.sin6_addr.s6_addr[0];
|
||||
}
|
||||
|
||||
const in_addr*
|
||||
Addr::addr4() const
|
||||
{
|
||||
return (const in_addr*)&_addr.sin6_addr.s6_addr[12];
|
||||
}
|
||||
|
||||
Addr::Addr(const std::string str)
|
||||
{
|
||||
this->from_char_array(str.c_str());
|
||||
}
|
||||
|
||||
Addr::Addr(const std::string str, const uint16_t p_port)
|
||||
{
|
||||
this->from_char_array(str.c_str());
|
||||
this->port(p_port);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::from_char_array(const char* str)
|
||||
{
|
||||
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
||||
struct addrinfo hint, *res = NULL;
|
||||
int ret;
|
||||
|
||||
memset(&hint, '\0', sizeof hint);
|
||||
|
||||
hint.ai_family = PF_UNSPEC;
|
||||
hint.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
ret = getaddrinfo(str, NULL, &hint, &res);
|
||||
if(ret)
|
||||
{
|
||||
llarp::LogError("failed to determine address family: ", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(res->ai_family == AF_INET6)
|
||||
{
|
||||
llarp::LogError("IPv6 address not supported yet", str);
|
||||
return false;
|
||||
}
|
||||
else if(res->ai_family != AF_INET)
|
||||
{
|
||||
llarp::LogError("Address family not supported yet", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
// put it in _addr4
|
||||
struct in_addr* addr = &_addr4.sin_addr;
|
||||
if(inet_aton(str, addr) == 0)
|
||||
{
|
||||
llarp::LogError("failed to parse ", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
_addr.sin6_family = res->ai_family;
|
||||
_addr4.sin_family = res->ai_family;
|
||||
_addr4.sin_port = 0; // save a call, 0 is 0 no matter how u arrange it
|
||||
#if((__APPLE__ && __MACH__) || __FreeBSD__)
|
||||
_addr4.sin_len = sizeof(in_addr);
|
||||
#endif
|
||||
// set up SIIT
|
||||
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
||||
addrptr[11] = 0xff;
|
||||
addrptr[10] = 0xff;
|
||||
memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr));
|
||||
freeaddrinfo(res);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Addr::Addr(const char* str)
|
||||
{
|
||||
this->from_char_array(str);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::from_4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four)
|
||||
{
|
||||
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
||||
struct in_addr* addr = &_addr4.sin_addr;
|
||||
unsigned char* ip = (unsigned char*)&(addr->s_addr);
|
||||
|
||||
_addr.sin6_family = AF_INET; // set ipv4 mode
|
||||
_addr4.sin_family = AF_INET;
|
||||
_addr4.sin_port = 0;
|
||||
|
||||
#if((__APPLE__ && __MACH__) || __FreeBSD__)
|
||||
_addr4.sin_len = sizeof(in_addr);
|
||||
#endif
|
||||
// FIXME: watch endian
|
||||
ip[0] = one;
|
||||
ip[1] = two;
|
||||
ip[2] = three;
|
||||
ip[3] = four;
|
||||
// set up SIIT
|
||||
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
||||
addrptr[11] = 0xff;
|
||||
addrptr[10] = 0xff;
|
||||
memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr));
|
||||
// copy ipv6 SIIT into _addr4
|
||||
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
Addr::Addr(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four)
|
||||
{
|
||||
this->from_4int(one, two, three, four);
|
||||
}
|
||||
|
||||
Addr::Addr(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four, const uint16_t p_port)
|
||||
{
|
||||
this->from_4int(one, two, three, four);
|
||||
this->port(p_port);
|
||||
}
|
||||
|
||||
Addr::Addr(const AddressInfo& other)
|
||||
{
|
||||
memcpy(addr6(), other.ip.s6_addr, 16);
|
||||
_addr.sin6_port = htons(other.port);
|
||||
if(ipv6_is_siit(other.ip))
|
||||
{
|
||||
_addr4.sin_family = AF_INET;
|
||||
_addr4.sin_port = htons(other.port);
|
||||
_addr.sin6_family = AF_INET;
|
||||
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
||||
}
|
||||
else
|
||||
_addr.sin6_family = AF_INET6;
|
||||
}
|
||||
|
||||
Addr::Addr(const sockaddr_in& other)
|
||||
{
|
||||
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
||||
_addr.sin6_family = AF_INET;
|
||||
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
||||
uint16_t* port = &_addr.sin6_port;
|
||||
// SIIT
|
||||
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
|
||||
sizeof(in_addr));
|
||||
addrptr[11] = 0xff;
|
||||
addrptr[10] = 0xff;
|
||||
*port = ((sockaddr_in*)(&other))->sin_port;
|
||||
_addr4.sin_family = AF_INET;
|
||||
_addr4.sin_port = *port;
|
||||
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
||||
}
|
||||
|
||||
Addr::Addr(const sockaddr_in6& other)
|
||||
{
|
||||
memcpy(addr6(), other.sin6_addr.s6_addr, 16);
|
||||
_addr.sin6_port = htons(other.sin6_port);
|
||||
auto ptr = &_addr.sin6_addr.s6_addr[0];
|
||||
// TODO: detect SIIT better
|
||||
if(ptr[11] == 0xff && ptr[10] == 0xff && ptr[9] == 0 && ptr[8] == 0
|
||||
&& ptr[7] == 0 && ptr[6] == 0 && ptr[5] == 0 && ptr[4] == 0
|
||||
&& ptr[3] == 0 && ptr[2] == 0 && ptr[1] == 0 && ptr[0] == 0)
|
||||
{
|
||||
_addr4.sin_family = AF_INET;
|
||||
_addr4.sin_port = htons(other.sin6_port);
|
||||
_addr.sin6_family = AF_INET;
|
||||
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
||||
}
|
||||
else
|
||||
_addr.sin6_family = AF_INET6;
|
||||
}
|
||||
|
||||
Addr::Addr(const sockaddr& other)
|
||||
{
|
||||
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
||||
_addr.sin6_family = other.sa_family;
|
||||
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
||||
uint16_t* port = &_addr.sin6_port;
|
||||
switch(other.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
// SIIT
|
||||
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
|
||||
sizeof(in_addr));
|
||||
addrptr[11] = 0xff;
|
||||
addrptr[10] = 0xff;
|
||||
*port = ((sockaddr_in*)(&other))->sin_port;
|
||||
_addr4.sin_family = AF_INET;
|
||||
_addr4.sin_port = *port;
|
||||
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr,
|
||||
16);
|
||||
*port = ((sockaddr_in6*)(&other))->sin6_port;
|
||||
break;
|
||||
// TODO : sockaddr_ll
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, const Addr& a)
|
||||
{
|
||||
char tmp[128] = {0};
|
||||
const void* ptr = nullptr;
|
||||
if(a.af() == AF_INET6)
|
||||
{
|
||||
out << "[";
|
||||
ptr = a.addr6();
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = a.addr4();
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
if(inet_ntop(a.af(), ptr, tmp, sizeof(tmp)))
|
||||
#else
|
||||
if(inet_ntop(a.af(), (void*)ptr, tmp, sizeof(tmp)))
|
||||
#endif
|
||||
{
|
||||
out << tmp;
|
||||
if(a.af() == AF_INET6)
|
||||
out << "]";
|
||||
}
|
||||
return out << ":" << a.port();
|
||||
}
|
||||
|
||||
void
|
||||
Addr::CopyInto(sockaddr* other) const
|
||||
{
|
||||
void *dst, *src;
|
||||
in_port_t* ptr;
|
||||
size_t slen;
|
||||
switch(af())
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
sockaddr_in* ipv4_dst = (sockaddr_in*)other;
|
||||
dst = (void*)&ipv4_dst->sin_addr.s_addr;
|
||||
src = (void*)&_addr4.sin_addr.s_addr;
|
||||
ptr = &((sockaddr_in*)other)->sin_port;
|
||||
slen = sizeof(in_addr);
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
dst = (void*)((sockaddr_in6*)other)->sin6_addr.s6_addr;
|
||||
src = (void*)_addr.sin6_addr.s6_addr;
|
||||
ptr = &((sockaddr_in6*)other)->sin6_port;
|
||||
slen = sizeof(in6_addr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(dst, src, slen);
|
||||
*ptr = htons(port());
|
||||
other->sa_family = af();
|
||||
}
|
||||
|
||||
int
|
||||
Addr::af() const
|
||||
{
|
||||
return _addr.sin6_family;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Addr::port() const
|
||||
{
|
||||
return ntohs(_addr.sin6_port);
|
||||
}
|
||||
|
||||
Addr&
|
||||
Addr::operator=(const sockaddr& other)
|
||||
{
|
||||
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
||||
_addr.sin6_family = other.sa_family;
|
||||
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
||||
uint16_t* port = &_addr.sin6_port;
|
||||
switch(other.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
// SIIT
|
||||
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
|
||||
sizeof(in_addr));
|
||||
addrptr[11] = 0xff;
|
||||
addrptr[10] = 0xff;
|
||||
*port = ((sockaddr_in*)(&other))->sin_port;
|
||||
_addr4.sin_family = AF_INET;
|
||||
_addr4.sin_port = *port;
|
||||
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr,
|
||||
16);
|
||||
*port = ((sockaddr_in6*)(&other))->sin6_port;
|
||||
break;
|
||||
// TODO : sockaddr_ll
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::sameAddr(const Addr& other) const
|
||||
{
|
||||
return memcmp(addr6(), other.addr6(), 16) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::operator!=(const Addr& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isTenPrivate(uint32_t byte)
|
||||
{
|
||||
uint8_t byte1 = byte >> 24 & 0xff;
|
||||
return byte1 == 10;
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isOneSevenPrivate(uint32_t byte)
|
||||
{
|
||||
uint8_t byte1 = byte >> 24 & 0xff;
|
||||
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
|
||||
return byte1 == 172 && (byte2 >= 16 || byte2 <= 31);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isOneNinePrivate(uint32_t byte)
|
||||
{
|
||||
uint8_t byte1 = byte >> 24 & 0xff;
|
||||
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
|
||||
return byte1 == 192 && byte2 == 168;
|
||||
}
|
||||
|
||||
/// return true if our ipv4 address is a bogon
|
||||
/// TODO: ipv6
|
||||
bool
|
||||
Addr::IsBogon() const
|
||||
{
|
||||
return IsIPv4Bogon(xtohl());
|
||||
}
|
||||
|
||||
socklen_t
|
||||
Addr::SockLen() const
|
||||
{
|
||||
if(af() == AF_INET)
|
||||
return sizeof(sockaddr_in);
|
||||
else
|
||||
return sizeof(sockaddr_in6);
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isPrivate() const
|
||||
{
|
||||
return IsBogon();
|
||||
}
|
||||
|
||||
bool
|
||||
Addr::isLoopback() const
|
||||
{
|
||||
return (ntohl(addr4()->s_addr)) >> 24 == 127;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
std::size_t
|
||||
operator()(Addr const& a) const noexcept
|
||||
{
|
||||
if(a.af() == AF_INET)
|
||||
{
|
||||
return a.port() ^ a.addr4()->s_addr;
|
||||
}
|
||||
static const uint8_t empty[16] = {0};
|
||||
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
|
||||
}
|
||||
}; // end struct Hash
|
||||
} // namespace llarp
|
230
llarp/net_inaddr.cpp
Normal file
230
llarp/net_inaddr.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include <llarp/net_inaddr.hpp>
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, const llarp::inAddr& a)
|
||||
{
|
||||
char tmp[128] = {0};
|
||||
if(a.isIPv6Mode())
|
||||
{
|
||||
out << "[";
|
||||
}
|
||||
if(inet_ntop(a.isIPv4Mode() ? AF_INET : AF_INET6, (void*)&a._addr, tmp,
|
||||
sizeof(tmp)))
|
||||
{
|
||||
out << tmp;
|
||||
if(a.isIPv6Mode())
|
||||
out << "]";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
void
|
||||
inAddr::reset()
|
||||
{
|
||||
llarp::Zero(&this->_addr, sizeof(in6_addr));
|
||||
}
|
||||
|
||||
bool
|
||||
inAddr::from_char_array(const char* str)
|
||||
{
|
||||
this->reset();
|
||||
|
||||
// maybe refactor the family detection out
|
||||
struct addrinfo hint, *res = NULL;
|
||||
int ret;
|
||||
|
||||
memset(&hint, '\0', sizeof hint);
|
||||
|
||||
hint.ai_family = PF_UNSPEC;
|
||||
hint.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
ret = getaddrinfo(str, NULL, &hint, &res);
|
||||
if(ret)
|
||||
{
|
||||
llarp::LogError("failed to determine address family: ", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
|
||||
{
|
||||
llarp::LogError("Address family not supported yet", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert detected-family (ipv4 or ipv6) str to in6_addr
|
||||
|
||||
/*
|
||||
if (res->ai_family == AF_INET)
|
||||
{
|
||||
freeaddrinfo(res);
|
||||
// get IPv4
|
||||
struct in_addr addr; // basically a uint32_t network order
|
||||
if(inet_aton(str, &addr) == 0)
|
||||
{
|
||||
llarp::LogError("failed to parse ", str);
|
||||
return false;
|
||||
}
|
||||
nuint32_t result;
|
||||
result.n = addr.s_addr;
|
||||
this->fromN32(result);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
ret = inet_pton(res->ai_family, str, &this->_addr);
|
||||
// inet_pton won't set SIIT
|
||||
// this->hexDebug();
|
||||
freeaddrinfo(res);
|
||||
if(ret <= 0)
|
||||
{
|
||||
if(ret == 0)
|
||||
{
|
||||
llarp::LogWarn("Not in presentation format");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("inet_pton failure");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::fromSIIT()
|
||||
{
|
||||
if(ipv6_is_siit(this->_addr))
|
||||
{
|
||||
this->_addr.s6_addr[0] = this->_addr.s6_addr[12];
|
||||
this->_addr.s6_addr[1] = this->_addr.s6_addr[13];
|
||||
this->_addr.s6_addr[2] = this->_addr.s6_addr[14];
|
||||
this->_addr.s6_addr[3] = this->_addr.s6_addr[15];
|
||||
this->setIPv4Mode();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::toSIIT()
|
||||
{
|
||||
if(!ipv6_is_siit(this->_addr))
|
||||
{
|
||||
this->_addr.s6_addr[10] = 0xff;
|
||||
this->_addr.s6_addr[11] = 0xff;
|
||||
this->_addr.s6_addr[12] = this->_addr.s6_addr[0];
|
||||
this->_addr.s6_addr[13] = this->_addr.s6_addr[1];
|
||||
this->_addr.s6_addr[14] = this->_addr.s6_addr[2];
|
||||
this->_addr.s6_addr[15] = this->_addr.s6_addr[3];
|
||||
llarp::Zero(&this->_addr, sizeof(in6_addr) - 6);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
inAddr::isIPv6Mode() const
|
||||
{
|
||||
return !this->isIPv4Mode();
|
||||
}
|
||||
|
||||
bool
|
||||
inAddr::isIPv4Mode() const
|
||||
{
|
||||
return ipv6_is_siit(this->_addr)
|
||||
|| (this->_addr.s6_addr[4] == 0 && this->_addr.s6_addr[5] == 0
|
||||
&& this->_addr.s6_addr[6] == 0 && this->_addr.s6_addr[7] == 0
|
||||
&& this->_addr.s6_addr[8] == 0 && this->_addr.s6_addr[9] == 0
|
||||
&& this->_addr.s6_addr[10] == 0 && this->_addr.s6_addr[11] == 0
|
||||
&& this->_addr.s6_addr[12] == 0 && this->_addr.s6_addr[13] == 0
|
||||
&& this->_addr.s6_addr[14] == 0 && this->_addr.s6_addr[15] == 0);
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::setIPv4Mode()
|
||||
{
|
||||
// keep first 4
|
||||
// llarp::Zero(&this->_addr + 4, sizeof(in6_addr) - 4);
|
||||
this->_addr.s6_addr[4] = 0;
|
||||
this->_addr.s6_addr[5] = 0;
|
||||
this->_addr.s6_addr[6] = 0;
|
||||
this->_addr.s6_addr[7] = 0;
|
||||
this->_addr.s6_addr[8] = 0;
|
||||
this->_addr.s6_addr[9] = 0;
|
||||
this->_addr.s6_addr[10] = 0;
|
||||
this->_addr.s6_addr[11] = 0;
|
||||
this->_addr.s6_addr[12] = 0;
|
||||
this->_addr.s6_addr[13] = 0;
|
||||
this->_addr.s6_addr[14] = 0;
|
||||
this->_addr.s6_addr[15] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::hexDebug()
|
||||
{
|
||||
char hex_buffer[16 * 3 + 1];
|
||||
hex_buffer[16 * 3] = 0;
|
||||
for(unsigned int j = 0; j < 16; j++)
|
||||
sprintf(&hex_buffer[3 * j], "%02X ", this->_addr.s6_addr[j]);
|
||||
printf("in6_addr: [%s]\n", hex_buffer);
|
||||
}
|
||||
|
||||
//
|
||||
// IPv4 specific functions
|
||||
//
|
||||
|
||||
in_addr
|
||||
inAddr::toIAddr()
|
||||
{
|
||||
in_addr res;
|
||||
res.s_addr = toN32().n;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::from4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
||||
const uint8_t four)
|
||||
{
|
||||
this->reset();
|
||||
this->setIPv4Mode();
|
||||
// Network byte order
|
||||
this->_addr.s6_addr[0] = one;
|
||||
this->_addr.s6_addr[1] = two;
|
||||
this->_addr.s6_addr[2] = three;
|
||||
this->_addr.s6_addr[3] = four;
|
||||
}
|
||||
|
||||
void
|
||||
inAddr::fromN32(nuint32_t in)
|
||||
{
|
||||
this->reset();
|
||||
this->setIPv4Mode();
|
||||
memcpy(&this->_addr, &in.n, sizeof(uint32_t));
|
||||
}
|
||||
void
|
||||
inAddr::fromH32(huint32_t in)
|
||||
{
|
||||
this->fromN32(xhtonl(in));
|
||||
}
|
||||
|
||||
nuint32_t
|
||||
inAddr::toN32()
|
||||
{
|
||||
nuint32_t result;
|
||||
result.n = 0; // return 0 for IPv6
|
||||
if(this->isIPv4Mode())
|
||||
{
|
||||
memcpy(&result.n, &this->_addr, sizeof(uint32_t));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
huint32_t
|
||||
inAddr::toH32()
|
||||
{
|
||||
return xntohl(this->toN32());
|
||||
}
|
||||
|
||||
//
|
||||
// IPv6 specific functions
|
||||
//
|
||||
|
||||
} // namespace llarp
|
Loading…
Reference in New Issue
Block a user