mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-19 09:25:28 +00:00
231 lines
5.0 KiB
C++
231 lines
5.0 KiB
C++
#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
|