2018-05-18 13:17:58 +00:00
|
|
|
#ifndef LLARP_NET_HPP
|
|
|
|
#define LLARP_NET_HPP
|
2018-08-30 18:48:43 +00:00
|
|
|
#include <llarp/address_info.hpp>
|
2018-05-18 13:17:58 +00:00
|
|
|
#include <llarp/net.h>
|
2018-07-27 00:21:57 +00:00
|
|
|
#include <functional>
|
2018-06-01 17:47:37 +00:00
|
|
|
#include <iostream>
|
2018-08-08 12:43:21 +00:00
|
|
|
#include "logger.hpp"
|
2018-05-23 13:49:00 +00:00
|
|
|
#include "mem.hpp"
|
2018-05-18 13:17:58 +00:00
|
|
|
|
2018-08-08 12:43:21 +00:00
|
|
|
#include <stdlib.h> // for itoa
|
|
|
|
|
2018-09-23 16:45:51 +00:00
|
|
|
// for addrinfo
|
2018-09-25 08:31:29 +00:00
|
|
|
#ifndef _WIN32
|
2018-09-23 16:45:51 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netdb.h>
|
2018-09-25 08:31:29 +00:00
|
|
|
#else
|
|
|
|
#include <winsock2.h>
|
|
|
|
#include <ws2tcpip.h>
|
|
|
|
#include <wspiapi.h>
|
2018-10-01 02:08:03 +00:00
|
|
|
#define inet_aton(x, y) inet_pton(AF_INET, x, y)
|
2018-09-25 08:31:29 +00:00
|
|
|
#endif
|
2018-09-23 16:45:51 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
bool
|
|
|
|
operator==(const sockaddr& a, const sockaddr& b);
|
2018-05-18 13:17:58 +00:00
|
|
|
|
2018-09-04 12:41:25 +00:00
|
|
|
bool
|
|
|
|
operator==(const sockaddr_in& a, const sockaddr_in& b);
|
|
|
|
|
|
|
|
bool
|
|
|
|
operator==(const sockaddr_in6& a, const sockaddr_in6& b);
|
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
bool
|
|
|
|
operator<(const sockaddr_in6& a, const sockaddr_in6& b);
|
2018-05-18 13:54:15 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
bool
|
|
|
|
operator<(const in6_addr& a, const in6_addr& b);
|
2018-05-18 13:54:15 +00:00
|
|
|
|
2018-09-04 12:41:25 +00:00
|
|
|
bool
|
|
|
|
operator==(const in6_addr& a, const in6_addr& b);
|
|
|
|
|
2018-08-08 12:43:21 +00:00
|
|
|
struct privatesInUse
|
|
|
|
{
|
2018-08-09 11:28:55 +00:00
|
|
|
bool ten; // 16m ips
|
|
|
|
bool oneSeven; // 1m ips
|
|
|
|
bool oneNine; // 65k ips
|
2018-08-08 12:43:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct privatesInUse
|
|
|
|
llarp_getPrivateIfs();
|
|
|
|
|
2018-05-18 13:54:15 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
struct Addr
|
|
|
|
{
|
2018-09-23 16:45:51 +00:00
|
|
|
// network order
|
2018-05-23 13:49:00 +00:00
|
|
|
sockaddr_in6 _addr;
|
2018-10-03 10:35:39 +00:00
|
|
|
sockaddr_in _addr4; // why do we even have this?
|
2018-05-22 15:54:19 +00:00
|
|
|
~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
|
|
|
}
|
|
|
|
|
2018-09-04 19:15:06 +00:00
|
|
|
void
|
|
|
|
port(uint16_t port)
|
|
|
|
{
|
|
|
|
if(af() == AF_INET)
|
|
|
|
{
|
|
|
|
_addr4.sin_port = htons(port);
|
|
|
|
}
|
|
|
|
_addr.sin6_port = htons(port);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
2018-09-23 16:47:49 +00:00
|
|
|
|
2018-09-29 10:15:41 +00:00
|
|
|
Addr(const std::string str)
|
|
|
|
{
|
|
|
|
this->from_char_array(str.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
Addr(const std::string str, const uint16_t p_port)
|
|
|
|
{
|
|
|
|
this->from_char_array(str.c_str());
|
|
|
|
this->port(p_port);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
from_char_array(const char* str)
|
2018-09-23 16:45:51 +00:00
|
|
|
{
|
|
|
|
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
|
|
|
struct addrinfo hint, *res = NULL;
|
|
|
|
int ret;
|
2018-09-23 16:47:49 +00:00
|
|
|
|
2018-09-23 16:45:51 +00:00
|
|
|
memset(&hint, '\0', sizeof hint);
|
2018-09-23 16:47:49 +00:00
|
|
|
|
2018-09-23 16:45:51 +00:00
|
|
|
hint.ai_family = PF_UNSPEC;
|
2018-09-23 16:47:49 +00:00
|
|
|
hint.ai_flags = AI_NUMERICHOST;
|
|
|
|
|
2018-09-23 16:45:51 +00:00
|
|
|
ret = getaddrinfo(str, NULL, &hint, &res);
|
2018-09-23 16:47:49 +00:00
|
|
|
if(ret)
|
2018-09-23 16:45:51 +00:00
|
|
|
{
|
|
|
|
llarp::LogError("failed to determine address family: ", str);
|
2018-09-29 10:15:41 +00:00
|
|
|
return false;
|
2018-09-23 16:45:51 +00:00
|
|
|
}
|
2018-09-23 16:47:49 +00:00
|
|
|
|
|
|
|
if(res->ai_family == AF_INET6)
|
2018-09-23 16:45:51 +00:00
|
|
|
{
|
|
|
|
llarp::LogError("IPv6 address not supported yet", str);
|
2018-09-29 10:15:41 +00:00
|
|
|
return false;
|
2018-09-23 16:45:51 +00:00
|
|
|
}
|
2018-09-23 16:47:49 +00:00
|
|
|
else if(res->ai_family != AF_INET)
|
2018-09-23 16:45:51 +00:00
|
|
|
{
|
|
|
|
llarp::LogError("Address family not supported yet", str);
|
2018-09-29 10:15:41 +00:00
|
|
|
return false;
|
2018-09-23 16:45:51 +00:00
|
|
|
}
|
|
|
|
|
2018-10-03 10:35:39 +00:00
|
|
|
// put it in _addr4
|
2018-09-23 16:45:51 +00:00
|
|
|
struct in_addr* addr = &_addr4.sin_addr;
|
2018-09-23 16:47:49 +00:00
|
|
|
if(inet_aton(str, addr) == 0)
|
2018-09-23 16:45:51 +00:00
|
|
|
{
|
|
|
|
llarp::LogError("failed to parse ", str);
|
2018-09-29 10:15:41 +00:00
|
|
|
return false;
|
2018-09-23 16:45:51 +00:00
|
|
|
}
|
2018-09-23 16:47:49 +00:00
|
|
|
|
2018-09-23 16:45:51 +00:00
|
|
|
_addr.sin6_family = res->ai_family;
|
|
|
|
_addr4.sin_family = res->ai_family;
|
|
|
|
_addr4.sin_port = htons(0);
|
|
|
|
#if((__APPLE__ && __MACH__) || __FreeBSD__)
|
|
|
|
_addr4.sin_len = sizeof(in_addr);
|
|
|
|
#endif
|
|
|
|
// set up SIIT
|
2018-09-23 16:47:49 +00:00
|
|
|
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
|
|
|
addrptr[11] = 0xff;
|
|
|
|
addrptr[10] = 0xff;
|
2018-09-23 16:45:51 +00:00
|
|
|
memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr));
|
|
|
|
freeaddrinfo(res);
|
2018-10-03 10:35:39 +00:00
|
|
|
|
2018-09-29 10:15:41 +00:00
|
|
|
return true;
|
2018-09-23 16:45:51 +00:00
|
|
|
}
|
2018-05-18 17:10:48 +00:00
|
|
|
|
2018-09-29 10:15:41 +00:00
|
|
|
Addr(const char* str)
|
|
|
|
{
|
|
|
|
this->from_char_array(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
from_4int(const uint8_t one, const uint8_t two, const uint8_t three,
|
|
|
|
const uint8_t four)
|
2018-08-08 12:43:21 +00:00
|
|
|
{
|
2018-09-23 16:45:51 +00:00
|
|
|
llarp::Zero(&_addr, sizeof(sockaddr_in6));
|
2018-08-08 13:09:38 +00:00
|
|
|
struct in_addr* addr = &_addr4.sin_addr;
|
|
|
|
unsigned char* ip = (unsigned char*)&(addr->s_addr);
|
2018-08-08 12:43:21 +00:00
|
|
|
|
|
|
|
_addr.sin6_family = AF_INET; // set ipv4 mode
|
|
|
|
_addr4.sin_family = AF_INET;
|
|
|
|
_addr4.sin_port = htons(0);
|
|
|
|
|
|
|
|
#if((__APPLE__ && __MACH__) || __FreeBSD__)
|
|
|
|
_addr4.sin_len = sizeof(in_addr);
|
|
|
|
#endif
|
2018-09-29 10:15:41 +00:00
|
|
|
// FIXME: watch endian
|
2018-08-08 13:09:38 +00:00
|
|
|
ip[0] = one;
|
|
|
|
ip[1] = two;
|
|
|
|
ip[2] = three;
|
|
|
|
ip[3] = four;
|
2018-09-23 16:45:51 +00:00
|
|
|
// set up SIIT
|
2018-09-23 16:47:49 +00:00
|
|
|
uint8_t* addrptr = _addr.sin6_addr.s6_addr;
|
|
|
|
addrptr[11] = 0xff;
|
|
|
|
addrptr[10] = 0xff;
|
2018-09-23 16:45:51 +00:00
|
|
|
memcpy(12 + addrptr, &addr->s_addr, sizeof(in_addr));
|
2018-10-03 10:35:39 +00:00
|
|
|
// copy ipv6 SIIT into _addr4
|
|
|
|
memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr));
|
2018-09-29 10:15:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
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(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);
|
2018-08-08 12:43:21 +00:00
|
|
|
}
|
|
|
|
|
2018-08-30 18:48:43 +00:00
|
|
|
Addr(const AddressInfo& other)
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
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
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
|
2018-09-03 12:03:43 +00:00
|
|
|
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(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;
|
|
|
|
}
|
|
|
|
|
2018-05-22 15:54:19 +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)
|
|
|
|
{
|
2018-05-22 15:54:19 +00:00
|
|
|
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));
|
2018-05-22 15:54:19 +00:00
|
|
|
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;
|
2018-05-22 15:54:19 +00:00
|
|
|
break;
|
2018-07-16 03:32:13 +00:00
|
|
|
// TODO : sockaddr_ll
|
2018-05-22 15:54:19 +00:00
|
|
|
default:
|
|
|
|
break;
|
2018-05-18 13:54:15 +00:00
|
|
|
}
|
2018-05-18 17:10:48 +00:00
|
|
|
}
|
|
|
|
|
2018-06-01 17:47:37 +00:00
|
|
|
friend std::ostream&
|
|
|
|
operator<<(std::ostream& out, const Addr& a)
|
2018-05-21 14:28:15 +00:00
|
|
|
{
|
2018-08-24 16:07:17 +00:00
|
|
|
char tmp[128] = {0};
|
2018-05-22 15:54:19 +00:00
|
|
|
const void* ptr = nullptr;
|
2018-06-01 17:47:37 +00:00
|
|
|
if(a.af() == AF_INET6)
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
2018-06-01 17:47:37 +00:00
|
|
|
out << "[";
|
|
|
|
ptr = a.addr6();
|
2018-05-23 13:49:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-01 17:47:37 +00:00
|
|
|
ptr = a.addr4();
|
2018-05-22 15:54:19 +00:00
|
|
|
}
|
2018-07-30 04:38:14 +00:00
|
|
|
#ifndef _MSC_VER
|
2018-08-24 16:07:17 +00:00
|
|
|
if(inet_ntop(a.af(), ptr, tmp, sizeof(tmp)))
|
2018-07-30 04:38:14 +00:00
|
|
|
#else
|
2018-08-24 16:07:17 +00:00
|
|
|
if(inet_ntop(a.af(), (void*)ptr, tmp, sizeof(tmp)))
|
2018-07-30 04:38:14 +00:00
|
|
|
#endif
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
2018-06-01 17:47:37 +00:00
|
|
|
out << tmp;
|
|
|
|
if(a.af() == AF_INET6)
|
|
|
|
out << "]";
|
2018-05-22 15:54:19 +00:00
|
|
|
}
|
|
|
|
|
2018-06-01 17:47:37 +00:00
|
|
|
return out << ":" << a.port();
|
2018-05-21 14:28:15 +00:00
|
|
|
}
|
2018-05-22 15:54:19 +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
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
|
|
|
|
void
|
2018-05-23 13:49:00 +00:00
|
|
|
CopyInto(sockaddr* other) const
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
|
|
|
void *dst, *src;
|
|
|
|
in_port_t* ptr;
|
|
|
|
size_t slen;
|
2018-05-23 13:49:00 +00:00
|
|
|
switch(af())
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
|
|
|
case AF_INET:
|
2018-08-08 13:09:38 +00:00
|
|
|
{
|
|
|
|
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);
|
2018-05-22 15:54:19 +00:00
|
|
|
break;
|
2018-08-08 13:09:38 +00:00
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
case AF_INET6:
|
2018-08-08 13:09:38 +00:00
|
|
|
{
|
2018-08-04 02:59:32 +00:00
|
|
|
dst = (void*)((sockaddr_in6*)other)->sin6_addr.s6_addr;
|
|
|
|
src = (void*)_addr.sin6_addr.s6_addr;
|
|
|
|
ptr = &((sockaddr_in6*)other)->sin6_port;
|
2018-05-22 15:54:19 +00:00
|
|
|
slen = sizeof(in6_addr);
|
|
|
|
break;
|
2018-08-08 13:09:38 +00:00
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
default:
|
2018-08-08 13:09:38 +00:00
|
|
|
{
|
2018-05-22 15:54:19 +00:00
|
|
|
return;
|
2018-08-08 13:09:38 +00:00
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
}
|
2018-05-24 13:03:11 +00:00
|
|
|
memcpy(dst, src, slen);
|
2018-08-04 02:59:32 +00:00
|
|
|
*ptr = htons(port());
|
2018-05-23 13:49:00 +00:00
|
|
|
other->sa_family = af();
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
af() const
|
|
|
|
{
|
|
|
|
return _addr.sin6_family;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t
|
|
|
|
port() const
|
|
|
|
{
|
|
|
|
return ntohs(_addr.sin6_port);
|
2018-05-22 15:54:19 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-05-22 15:54:19 +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-09-03 12:03:43 +00:00
|
|
|
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;
|
|
|
|
}
|
2018-09-23 16:47:49 +00:00
|
|
|
|
2018-09-23 16:45:51 +00:00
|
|
|
uint32_t
|
|
|
|
tohl()
|
|
|
|
{
|
|
|
|
return ntohl(addr4()->s_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
ton()
|
|
|
|
{
|
|
|
|
return addr4()->s_addr;
|
|
|
|
}
|
2018-09-03 12:03:43 +00:00
|
|
|
|
2018-10-03 10:35:39 +00:00
|
|
|
sockaddr*
|
|
|
|
getSockAddr()
|
|
|
|
{
|
|
|
|
return (struct sockaddr*)&_addr4;
|
|
|
|
}
|
|
|
|
|
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-08-08 12:43:21 +00:00
|
|
|
inline uint32_t
|
|
|
|
getHostLong()
|
|
|
|
{
|
|
|
|
in_addr_t addr = this->addr4()->s_addr;
|
|
|
|
uint32_t byte = ntohl(addr);
|
|
|
|
return byte;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool
|
|
|
|
isTenPrivate(uint32_t byte)
|
|
|
|
{
|
|
|
|
uint8_t byte1 = byte >> 24 & 0xff;
|
|
|
|
return byte1 == 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
isOneSevenPrivate(uint32_t byte)
|
|
|
|
{
|
|
|
|
uint8_t byte1 = byte >> 24 & 0xff;
|
2018-09-29 08:16:54 +00:00
|
|
|
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
|
2018-08-08 12:43:21 +00:00
|
|
|
return byte1 == 172 && (byte2 >= 16 || byte2 <= 31);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
isOneNinePrivate(uint32_t byte)
|
|
|
|
{
|
|
|
|
uint8_t byte1 = byte >> 24 & 0xff;
|
2018-09-29 08:16:54 +00:00
|
|
|
uint8_t byte2 = (0x00ff0000 & byte) >> 16;
|
2018-08-08 12:43:21 +00:00
|
|
|
return byte1 == 192 && byte2 == 168;
|
|
|
|
}
|
|
|
|
|
2018-09-04 12:41:25 +00:00
|
|
|
socklen_t
|
|
|
|
SockLen() const
|
|
|
|
{
|
|
|
|
if(af() == AF_INET)
|
|
|
|
return sizeof(sockaddr_in);
|
|
|
|
else
|
|
|
|
return sizeof(sockaddr_in6);
|
|
|
|
}
|
|
|
|
|
2018-09-20 10:04:40 +00:00
|
|
|
// Neuro: can't const this, not sure why...
|
2018-06-29 12:15:15 +00:00
|
|
|
bool
|
2018-09-20 10:04:40 +00:00
|
|
|
isPrivate()
|
2018-06-28 11:24:50 +00:00
|
|
|
{
|
2018-09-20 10:04:40 +00:00
|
|
|
uint32_t byte = this->getHostLong();
|
2018-08-08 12:43:21 +00:00
|
|
|
return this->isTenPrivate(byte) || this->isOneSevenPrivate(byte)
|
|
|
|
|| this->isOneNinePrivate(byte);
|
2018-06-28 11:24:50 +00:00
|
|
|
}
|
2018-05-29 16:11:32 +00:00
|
|
|
|
2018-07-27 00:21:57 +00:00
|
|
|
bool
|
2018-09-19 13:02:55 +00:00
|
|
|
isLoopback() const
|
2018-05-29 16:11:32 +00:00
|
|
|
{
|
2018-07-27 00:21:57 +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
|
|
|
{
|
2018-07-27 00:21:57 +00:00
|
|
|
if(a.af() == AF_INET)
|
|
|
|
{
|
2018-08-04 02:59:32 +00:00
|
|
|
return a.port() ^ a.addr4()->s_addr;
|
2018-07-27 00:21:57 +00:00
|
|
|
}
|
2018-08-27 13:44:16 +00:00
|
|
|
static const uint8_t empty[16] = {0};
|
2018-07-27 00:21:57 +00:00
|
|
|
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
|
2018-06-20 17:45:44 +00:00
|
|
|
}
|
2018-07-27 00:21:57 +00:00
|
|
|
};
|
2018-05-18 13:54:15 +00:00
|
|
|
};
|
2018-07-27 00:21:57 +00:00
|
|
|
|
2018-09-03 12:03:43 +00:00
|
|
|
bool
|
|
|
|
AllInterfaces(int af, Addr& addr);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-07-27 00:21:57 +00:00
|
|
|
/// get first network interface with public address
|
|
|
|
bool
|
|
|
|
GetBestNetIF(std::string& ifname, int af = AF_INET);
|
|
|
|
|
2018-10-03 10:35:39 +00:00
|
|
|
/// look at adapter ranges and find a free one
|
|
|
|
std::string
|
|
|
|
findFreePrivateRange();
|
|
|
|
|
|
|
|
/// look at adapter names and find a free one
|
|
|
|
std::string
|
|
|
|
findFreeLokiTunIfName();
|
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
/// get network interface address for network interface with ifname
|
|
|
|
bool
|
|
|
|
GetIFAddr(const std::string& ifname, Addr& addr, 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
|