lokinet/include/llarp/net.hpp

254 lines
5.9 KiB
C++
Raw Normal View History

2018-05-18 13:17:58 +00:00
#ifndef LLARP_NET_HPP
#define LLARP_NET_HPP
#include <llarp/address_info.h>
2018-05-18 13:17:58 +00:00
#include <llarp/net.h>
#include <functional>
#include <iostream>
2018-05-23 13:49:00 +00:00
#include "mem.hpp"
2018-05-18 13:17:58 +00:00
bool
operator==(const sockaddr& a, const sockaddr& b);
2018-05-18 13:17:58 +00:00
bool
operator<(const sockaddr_in6& a, const sockaddr_in6& b);
2018-05-18 13:54:15 +00:00
bool
operator<(const in6_addr& a, const in6_addr& b);
2018-05-18 13:54:15 +00:00
namespace llarp
{
struct Addr
{
2018-05-23 13:49:00 +00:00
sockaddr_in6 _addr;
2018-05-29 12:15:48 +00:00
sockaddr_in _addr4;
~Addr(){};
Addr(){};
Addr(const Addr& other)
{
2018-05-23 13:49:00 +00:00
memcpy(&_addr, &other._addr, sizeof(sockaddr_in6));
2018-05-29 13:40:26 +00:00
memcpy(&_addr4, &other._addr4, sizeof(sockaddr_in));
2018-05-23 13:49:00 +00:00
}
in6_addr*
addr6()
{
2018-05-23 20:37:43 +00:00
return (in6_addr*)&_addr.sin6_addr.s6_addr[0];
2018-05-23 13:49:00 +00:00
}
in_addr*
addr4()
{
return (in_addr*)&_addr.sin6_addr.s6_addr[12];
}
const in6_addr*
addr6() const
{
2018-05-23 20:37:43 +00:00
return (const in6_addr*)&_addr.sin6_addr.s6_addr[0];
2018-05-23 13:49:00 +00:00
}
const in_addr*
addr4() const
{
return (const in_addr*)&_addr.sin6_addr.s6_addr[12];
2018-05-18 17:10:48 +00:00
}
Addr(const llarp_ai& other)
{
2018-05-23 13:49:00 +00:00
memcpy(addr6(), other.ip.s6_addr, 16);
_addr.sin6_port = htons(other.port);
2018-05-29 12:15:48 +00:00
auto ptr = &_addr.sin6_addr.s6_addr[0];
// TODO: detect SIIT better
2018-05-29 13:40:26 +00:00
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)
2018-05-29 12:15:48 +00:00
{
_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;
2018-05-18 17:10:48 +00:00
}
Addr(const sockaddr& other)
{
2018-05-23 13:49:00 +00:00
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;
2018-05-18 13:54:15 +00:00
switch(other.sa_family)
{
case AF_INET:
// SIIT
memcpy(12 + addrptr, &((const sockaddr_in*)(&other))->sin_addr,
sizeof(in_addr));
2018-05-29 12:15:48 +00:00
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:
2018-05-23 13:49:00 +00:00
memcpy(addrptr, &((const sockaddr_in6*)(&other))->sin6_addr.s6_addr,
16);
*port = ((sockaddr_in6*)(&other))->sin6_port;
break;
2018-07-16 03:32:13 +00:00
// TODO : sockaddr_ll
default:
break;
2018-05-18 13:54:15 +00:00
}
2018-05-18 17:10:48 +00:00
}
friend std::ostream&
operator<<(std::ostream& out, const Addr& a)
2018-05-21 14:28:15 +00:00
{
char tmp[128] = {0};
socklen_t sz;
const void* ptr = nullptr;
if(a.af() == AF_INET6)
{
out << "[";
sz = sizeof(sockaddr_in6);
ptr = a.addr6();
2018-05-23 13:49:00 +00:00
}
else
{
sz = sizeof(sockaddr_in);
ptr = a.addr4();
}
if(inet_ntop(a.af(), ptr, tmp, sz))
{
out << tmp;
if(a.af() == AF_INET6)
out << "]";
}
return out << ":" << a.port();
2018-05-21 14:28:15 +00:00
}
operator const sockaddr*() const
2018-05-18 17:10:48 +00:00
{
2018-05-29 12:15:48 +00:00
if(af() == AF_INET)
return (const sockaddr*)&_addr4;
else
return (const sockaddr*)&_addr;
2018-05-18 13:54:15 +00:00
}
void
2018-05-23 13:49:00 +00:00
CopyInto(sockaddr* other) const
{
void *dst, *src;
in_port_t* ptr;
size_t slen;
2018-05-23 13:49:00 +00:00
switch(af())
{
case AF_INET:
2018-05-23 13:49:00 +00:00
dst = (void*)&((sockaddr_in*)other)->sin_addr.s_addr;
src = (void*)&_addr.sin6_addr.s6_addr[12];
ptr = &((sockaddr_in*)other)->sin_port;
slen = sizeof(in_addr);
break;
case AF_INET6:
2018-05-23 13:49:00 +00:00
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);
2018-05-23 13:49:00 +00:00
*ptr = htons(port());
other->sa_family = af();
}
int
af() const
{
return _addr.sin6_family;
}
uint16_t
port() const
{
return ntohs(_addr.sin6_port);
}
2018-06-06 12:46:26 +00:00
bool
operator<(const Addr& other) const
{
2018-07-02 19:24:22 +00:00
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();
2018-06-06 12:46:26 +00:00
}
bool
2018-05-29 16:11:32 +00:00
operator==(const Addr& other) const
2018-05-18 13:54:15 +00:00
{
2018-07-02 19:24:22 +00:00
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();
2018-05-29 16:11:32 +00:00
}
2018-06-06 21:23:57 +00:00
2018-06-28 11:24:50 +00:00
bool
sameAddr(const Addr& other) const
{
return memcmp(addr6(), other.addr6(), 16) == 0;
}
2018-06-06 21:23:57 +00:00
bool
operator!=(const Addr& other) const
{
return !(*this == other);
}
2018-06-28 11:24:50 +00:00
2018-06-29 12:15:15 +00:00
bool
isPrivate()
2018-06-28 11:24:50 +00:00
{
in_addr_t addr = this->addr4()->s_addr;
2018-06-29 12:15:15 +00:00
unsigned byte = ntohl(addr);
2018-06-28 11:24:50 +00:00
unsigned byte1 = byte >> 24 & 0xff;
2018-07-30 05:52:52 +00:00
unsigned byte2 = (0x00ff0000 & byte >> 16);
2018-06-29 12:15:15 +00:00
return (byte1 == 10 || (byte1 == 192 && byte2 == 168)
2018-07-30 05:49:47 +00:00
|| (byte1 == 172 && (byte2 >= 16 || byte2 <= 31)));
2018-06-28 11:24:50 +00:00
}
2018-05-29 16:11:32 +00:00
bool
isLoopback()
2018-05-29 16:11:32 +00:00
{
return (ntohl(addr4()->s_addr)) >> 24 == 127;
}
struct Hash
{
std::size_t
operator()(Addr const& a) const noexcept
2018-06-20 17:45:44 +00:00
{
if(a.af() == AF_INET)
{
return a.port() + a.addr4()->s_addr;
}
uint8_t empty[16] = {0};
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
2018-06-20 17:45:44 +00:00
}
};
2018-05-18 13:54:15 +00:00
};
/// get first network interface with public address
bool
GetBestNetIF(std::string& ifname, int af = AF_INET);
2018-06-20 17:45:44 +00:00
} // namespace llarp
2018-05-18 13:54:15 +00:00
2018-05-18 13:17:58 +00:00
#endif