mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-28 00:49:28 -05:00
Merge pull request #162 from G10h4ck/getLocalAddresses
Get local addresses
This commit is contained in:
commit
2d438b7407
@ -1016,7 +1016,17 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
}
|
||||
else
|
||||
{
|
||||
validAddr = getPreferredInterface(mLocalAddr, prefAddr);
|
||||
// TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local address is a flawed assumption, this should be redesigned soon.
|
||||
std::list<sockaddr_storage> addrs;
|
||||
std::list<sockaddr_storage>::iterator it;
|
||||
if (getLocalAddresses(addrs))
|
||||
for(it = addrs.begin(); (it != addrs.end() && !validAddr); ++it)
|
||||
if(sockaddr_storage_isValidNet(*it) && !sockaddr_storage_isLoopbackNet(*it))
|
||||
{
|
||||
prefAddr = *it;
|
||||
validAddr = true;
|
||||
std::cout << "p3NetMgrIMPL::checkNetAddress() prefAddr: " << sockaddr_storage_iptostring(prefAddr) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -326,6 +326,7 @@ private:
|
||||
|
||||
void netStatusReset_locked();
|
||||
|
||||
// TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just two possible address is a flawed assumption, this should be redesigned soon.
|
||||
struct sockaddr_storage mLocalAddr;
|
||||
struct sockaddr_storage mExtAddr;
|
||||
|
||||
|
@ -38,7 +38,8 @@
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsstring.h"
|
||||
#include <iomanip>
|
||||
#include "util/rsnet.h"
|
||||
|
||||
static const int pqinetzone = 96184;
|
||||
|
||||
/*****
|
||||
@ -149,78 +150,6 @@ std::string socket_errorType(int err)
|
||||
return std::string("UNKNOWN ERROR CODE - ASK RS-DEVS TO ADD IT!");
|
||||
}
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
bool getLocalInterfaces_ipv4(struct in_addr &/*routeAddr*/, std::list<struct in_addr> &addrs)
|
||||
{
|
||||
int sock = 0;
|
||||
struct ifreq ifreq;
|
||||
|
||||
struct if_nameindex *iflist = if_nameindex();
|
||||
struct if_nameindex *ifptr = iflist;
|
||||
|
||||
//need a socket for ioctl()
|
||||
if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
pqioutput(PQL_ALERT, pqinetzone,
|
||||
"Cannot Determine Local Addresses!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ifptr)
|
||||
{
|
||||
pqioutput(PQL_ALERT, pqinetzone,
|
||||
"getLocalInterfaces(): ERROR if_nameindex == NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
// loop through the interfaces.
|
||||
for(; ifptr->if_index != 0; ++ifptr)
|
||||
{
|
||||
//copy in the interface name to look up address of
|
||||
strncpy(ifreq.ifr_name, ifptr->if_name, IF_NAMESIZE-1);// the -1 is here to ensure that there's enough room left to place a \0 termination byte
|
||||
|
||||
if(ioctl(sock, SIOCGIFADDR, &ifreq) != 0)
|
||||
{
|
||||
std::string out;
|
||||
rs_sprintf(out, "Cannot Determine Address for Iface: %s", ifptr -> if_name);
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sockaddr_in *aptr =
|
||||
(struct sockaddr_in *) &ifreq.ifr_addr;
|
||||
std::string astr =rs_inet_ntoa(aptr -> sin_addr);
|
||||
|
||||
std::string out;
|
||||
rs_sprintf(out, "Iface: %s\n Address: %s", ifptr -> if_name, astr.c_str());
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
|
||||
|
||||
// Now check wether the interface is up and running. If not, we don't use it!!
|
||||
//
|
||||
if(ioctl(sock,SIOCGIFFLAGS,&ifreq) != 0)
|
||||
{
|
||||
std::cerr << "Could not get flags from interface " << ifptr -> if_name << std::endl ;
|
||||
continue ;
|
||||
}
|
||||
#ifdef NET_DEBUG
|
||||
std::cout << out.str() ;
|
||||
std::cout << "flags = " << ifreq.ifr_flags << std::endl ;
|
||||
#endif
|
||||
if((ifreq.ifr_flags & IFF_UP) == 0) continue ;
|
||||
if((ifreq.ifr_flags & IFF_RUNNING) == 0) continue ;
|
||||
|
||||
addrs.push_back(aptr->sin_addr);
|
||||
}
|
||||
}
|
||||
// free socket -> or else run out of fds.
|
||||
close(sock);
|
||||
|
||||
if_freenameindex(iflist);
|
||||
return (addrs.size() > 0);
|
||||
}
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#else
|
||||
|
||||
@ -327,80 +256,6 @@ std::string socket_errorType(int err)
|
||||
return std::string("----WINDOWS OPERATING SYSTEM FAILURE----");
|
||||
}
|
||||
|
||||
#include <iphlpapi.h>
|
||||
//#include <iprtrmib.h>
|
||||
|
||||
// A function to determine the interfaces on your computer....
|
||||
// No idea of how to do this in windows....
|
||||
// see if it compiles.
|
||||
bool getLocalInterfaces_ipv4(struct in_addr &routeAddr, std::list<struct in_addr> &addrs)
|
||||
{
|
||||
// Get the best interface for transport to routeAddr
|
||||
// This interface should be first in list!
|
||||
DWORD bestInterface;
|
||||
if (GetBestInterface((IPAddr) routeAddr.s_addr, &bestInterface) != NO_ERROR)
|
||||
{
|
||||
bestInterface = 0;
|
||||
}
|
||||
|
||||
/* USE MIB IPADDR Interface */
|
||||
PMIB_IPADDRTABLE iptable = NULL;
|
||||
DWORD dwSize = 0;
|
||||
|
||||
if (GetIpAddrTable(iptable, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
pqioutput(PQL_ALERT, pqinetzone, "Cannot Find Windoze Interfaces!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
iptable = (MIB_IPADDRTABLE *) malloc(dwSize);
|
||||
GetIpAddrTable(iptable, &dwSize, 0);
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
for (unsigned int i = 0; i < iptable -> dwNumEntries; i++)
|
||||
{
|
||||
MIB_IPADDRROW &ipaddr = iptable->table[i];
|
||||
|
||||
std::string out;
|
||||
|
||||
addr.s_addr = ipaddr.dwAddr;
|
||||
rs_sprintf(out, "Iface(%ld) => %s\n", ipaddr.dwIndex, rs_inet_ntoa(addr).c_str());
|
||||
|
||||
#if __MINGW_MAJOR_VERSION <= 3 && !defined(__MINGW64_VERSION_MAJOR)
|
||||
unsigned short wType = ipaddr.unused2; // should be wType
|
||||
#else
|
||||
unsigned short wType = ipaddr.wType;
|
||||
#endif
|
||||
if (wType & MIB_IPADDR_DISCONNECTED)
|
||||
{
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface disconnected, " + out);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wType & MIB_IPADDR_DELETED)
|
||||
{
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface deleted, " + out);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ipaddr.dwIndex == bestInterface)
|
||||
{
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Best address, " + out);
|
||||
addrs.push_front(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
|
||||
addrs.push_back(addr);
|
||||
}
|
||||
}
|
||||
|
||||
free (iptable);
|
||||
|
||||
return (addrs.size() > 0);
|
||||
}
|
||||
|
||||
// implement the improved unix inet address fn.
|
||||
// using old one.
|
||||
int inet_aton(const char *name, struct in_addr *addr)
|
||||
@ -408,432 +263,84 @@ int inet_aton(const char *name, struct in_addr *addr)
|
||||
return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE);
|
||||
}
|
||||
|
||||
|
||||
// This returns in Net Byte Order.
|
||||
// NB: Linux man page claims it is in Host Byte order, but
|
||||
// this is blatantly wrong!..... (for Debian anyway)
|
||||
// Making this consistent with the Actual behavior (rather than documented).
|
||||
in_addr_t inet_netof(struct in_addr addr)
|
||||
{
|
||||
return pqi_inet_netof(addr);
|
||||
}
|
||||
|
||||
// This returns in Host Byte Order. (as the man page says)
|
||||
// Again, to be consistent with Linux.
|
||||
in_addr_t inet_network(const char *inet_name)
|
||||
{
|
||||
struct in_addr addr;
|
||||
if (inet_aton(inet_name, &addr))
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
// std::cerr << "inet_network(" << inet_name << ") : ";
|
||||
// std::cerr << rs_inet_ntoa(addr) << std::endl;
|
||||
#endif
|
||||
return ntohl(inet_netof(addr));
|
||||
}
|
||||
return 0xffffffff;
|
||||
//return -1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef WINDOWS_SYS
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
#else // WINDOWS_SYS
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
// This returns in Net Byte Order.
|
||||
// NB: Linux man page claims it is in Host Byte order, but
|
||||
// this is blatantly wrong!..... (for Debian anyway)
|
||||
// Making this consistent with the Actual behavior (rather than documented).
|
||||
in_addr_t pqi_inet_netof(struct in_addr addr)
|
||||
void getLocalAddressesFailed()
|
||||
{
|
||||
// decide if A class address.
|
||||
unsigned long haddr = ntohl(addr.s_addr);
|
||||
unsigned long abit = haddr & 0xff000000UL;
|
||||
unsigned long bbit = haddr & 0xffff0000UL;
|
||||
unsigned long cbit = haddr & 0xffffff00UL;
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "inet_netof(" << rs_inet_ntoa(addr) << ") ";
|
||||
#endif
|
||||
|
||||
if (!((haddr >> 31) | 0x0UL)) // MSB = 0
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << " Type A " << std::endl;
|
||||
std::cerr << "\tShifted(31): " << (haddr >> 31);
|
||||
std::cerr << " Xord(0x0UL): " <<
|
||||
!((haddr >> 31) | 0x0UL) << std::endl;
|
||||
#endif
|
||||
|
||||
return htonl(abit);
|
||||
}
|
||||
else if (!((haddr >> 30) ^ 0x2UL)) // 2MSBs = 10
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << " Type B " << std::endl;
|
||||
std::cerr << "\tShifted(30): " << (haddr >> 30);
|
||||
std::cerr << " Xord(0x2UL): " <<
|
||||
!((haddr >> 30) | 0x2UL) << std::endl;
|
||||
#endif
|
||||
|
||||
return htonl(bbit);
|
||||
}
|
||||
else if (!((haddr >> 29) ^ 0x6UL)) // 3MSBs = 110
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << " Type C " << std::endl;
|
||||
std::cerr << "\tShifted(29): " << (haddr >> 29);
|
||||
std::cerr << " Xord(0x6UL): " <<
|
||||
!((haddr >> 29) | 0x6UL) << std::endl;
|
||||
#endif
|
||||
|
||||
return htonl(cbit);
|
||||
}
|
||||
else if (!((haddr >> 28) ^ 0xeUL)) // 4MSBs = 1110
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << " Type Multicast " << std::endl;
|
||||
std::cerr << "\tShifted(28): " << (haddr >> 28);
|
||||
std::cerr << " Xord(0xeUL): " <<
|
||||
!((haddr >> 29) | 0xeUL) << std::endl;
|
||||
#endif
|
||||
|
||||
return addr.s_addr; // return full address.
|
||||
}
|
||||
else if (!((haddr >> 27) ^ 0x1eUL)) // 5MSBs = 11110
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << " Type Reserved " << std::endl;
|
||||
std::cerr << "\tShifted(27): " << (haddr >> 27);
|
||||
std::cerr << " Xord(0x1eUL): " <<
|
||||
!((haddr >> 27) | 0x1eUL) << std::endl;
|
||||
#endif
|
||||
|
||||
return addr.s_addr; // return full address.
|
||||
}
|
||||
return htonl(abit);
|
||||
std::cerr << "FATAL ERROR: getLocalAddresses failed!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 )
|
||||
bool getLocalAddresses(std::list<sockaddr_storage> & addrs)
|
||||
{
|
||||
if (addr1.sin_family != addr2.sin_family)
|
||||
return addr1.sin_family - addr2.sin_family;
|
||||
if (addr1.sin_addr.s_addr != addr2.sin_addr.s_addr)
|
||||
return (addr1.sin_addr.s_addr - addr2.sin_addr.s_addr);
|
||||
if (addr1.sin_port != addr2.sin_port)
|
||||
return (addr1.sin_port - addr2.sin_port);
|
||||
return 0;
|
||||
}
|
||||
addrs.clear();
|
||||
|
||||
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 )
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::string out;
|
||||
rs_sprintf(out, "inaddr_cmp(%s-%lu,%s-%lu)", rs_inet_ntoa(addr1.sin_addr).c_str(), addr1.sin_addr.s_addr, rs_inet_ntoa(addr2.sin_addr).c_str(), addr2.sin_addr.s_addr);
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
|
||||
#endif
|
||||
#ifdef WINDOWS_SYS
|
||||
// Seems strange to me but M$ documentation suggests to allocate this way...
|
||||
DWORD bf_size = 16000;
|
||||
IP_ADAPTER_ADDRESSES* adapter_addresses = (IP_ADAPTER_ADDRESSES*) malloc(bf_size);
|
||||
DWORD error = GetAdaptersAddresses(AF_UNSPEC,
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME,
|
||||
NULL,
|
||||
adapter_addresses,
|
||||
&bf_size);
|
||||
if (error != ERROR_SUCCESS) getLocalAddressesFailed();
|
||||
|
||||
|
||||
if (addr1.sin_addr.s_addr == addr2.sin_addr.s_addr)
|
||||
IP_ADAPTER_ADDRESSES* adapter(NULL);
|
||||
for(adapter = adapter_addresses; NULL != adapter; adapter = adapter->Next)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (addr1.sin_addr.s_addr < addr2.sin_addr.s_addr)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2)
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
struct in_addr inaddr_tmp;
|
||||
inaddr_tmp.s_addr = addr2;
|
||||
|
||||
std::string out;
|
||||
rs_sprintf(out, "inaddr_cmp2(%s vs %s /or/ %10x vs %10x)", rs_inet_ntoa(addr1.sin_addr).c_str(), rs_inet_ntoa(inaddr_tmp).c_str(), addr1.sin_addr.s_addr, addr2);
|
||||
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
|
||||
#endif
|
||||
|
||||
if (addr1.sin_addr.s_addr == addr2)
|
||||
IP_ADAPTER_UNICAST_ADDRESS* address;
|
||||
for ( address = adapter->FirstUnicastAddress; address; address = address->Next)
|
||||
{
|
||||
return 0;
|
||||
sockaddr_storage * tmp = new sockaddr_storage;
|
||||
sockaddr_storage_clear(*tmp);
|
||||
if (sockaddr_storage_copyip(* tmp, * reinterpret_cast<sockaddr_storage*>(address->Address.lpSockaddr)))
|
||||
addrs.push_back(*tmp);
|
||||
else delete tmp;
|
||||
}
|
||||
if (addr1.sin_addr.s_addr < addr2)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool getPreferredInterface_ipv4(in_addr &routeAddr, struct in_addr &prefAddr) // returns best addr.
|
||||
{
|
||||
std::list<struct in_addr> addrs;
|
||||
std::list<struct in_addr>::iterator it;
|
||||
struct in_addr addr_zero, addr_loop, addr_priv, addr_ext;
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
struct in_addr addr;
|
||||
#endif
|
||||
|
||||
bool found_zero = false;
|
||||
bool found_loopback = false;
|
||||
bool found_priv = false;
|
||||
bool found_ext = false;
|
||||
|
||||
if (!getLocalInterfaces_ipv4(routeAddr, addrs))
|
||||
}
|
||||
free(adapter_addresses);
|
||||
#else // WINDOWS_SYS
|
||||
struct ifaddrs *ifsaddrs, *ifa;
|
||||
if(getifaddrs(&ifsaddrs) != 0) getLocalAddressesFailed();
|
||||
for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next )
|
||||
if ( ifa->ifa_addr && (ifa->ifa_flags & IFF_UP) )
|
||||
{
|
||||
return false;
|
||||
sockaddr_storage * tmp = new sockaddr_storage;
|
||||
sockaddr_storage_clear(*tmp);
|
||||
if (sockaddr_storage_copyip(* tmp, * reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr)))
|
||||
addrs.push_back(*tmp);
|
||||
else delete tmp;
|
||||
}
|
||||
|
||||
memset(&addr_zero, 0, sizeof(addr_zero));
|
||||
memset(&addr_loop, 0, sizeof(addr_loop));
|
||||
memset(&addr_priv, 0, sizeof(addr_priv));
|
||||
memset(&addr_ext, 0, sizeof(addr_ext));
|
||||
freeifaddrs(ifsaddrs);
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
#endif
|
||||
|
||||
// find the first of each of these.
|
||||
// if ext - take first.
|
||||
// if no ext -> first priv
|
||||
// if no priv -> first loopback.
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "getPreferredInterface() " << addrs.size() << " interfaces." << std::endl;
|
||||
#endif
|
||||
|
||||
std::list<sockaddr_storage>::iterator it;
|
||||
std::cout << "getLocalAddresses(...) returning: <" ;
|
||||
for(it = addrs.begin(); it != addrs.end(); ++it)
|
||||
{
|
||||
struct in_addr addr = *it;
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "Examining addr: " << rs_inet_ntoa(addr);
|
||||
std::cerr << " => " << (uint32_t) addr.s_addr << std::endl ;
|
||||
std::cout << sockaddr_storage_iptostring(*it) << ", ";
|
||||
std::cout << ">" << std::endl;
|
||||
#endif
|
||||
|
||||
// for windows silliness (returning 0.0.0.0 as valid addr!).
|
||||
if (addr.s_addr == 0)
|
||||
{
|
||||
if (!found_zero)
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "\tFound Zero Address" << std::endl ;
|
||||
#endif
|
||||
|
||||
found_zero = true;
|
||||
addr_zero = addr;
|
||||
}
|
||||
}
|
||||
else if (isLoopbackNet(&addr))
|
||||
{
|
||||
if (!found_loopback)
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "\tFound Loopback Address" << std::endl ;
|
||||
#endif
|
||||
|
||||
found_loopback = true;
|
||||
addr_loop = addr;
|
||||
}
|
||||
}
|
||||
else if (isPrivateNet(&addr))
|
||||
{
|
||||
if (!found_priv)
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "\tFound Private Address" << std::endl ;
|
||||
#endif
|
||||
|
||||
found_priv = true;
|
||||
addr_priv = addr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!found_ext)
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "\tFound Other Address (Ext?) " << std::endl ;
|
||||
#endif
|
||||
found_ext = true;
|
||||
addr_ext = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(found_ext) // external address is best.
|
||||
{
|
||||
prefAddr = addr_ext;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (found_priv)
|
||||
{
|
||||
prefAddr = addr_priv;
|
||||
return true;
|
||||
}
|
||||
|
||||
// next bit can happen under windows,
|
||||
// a general address is still
|
||||
// preferable to a loopback device.
|
||||
if (found_zero)
|
||||
{
|
||||
prefAddr = addr_zero;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (found_loopback)
|
||||
{
|
||||
prefAddr = addr_loop;
|
||||
return true;
|
||||
}
|
||||
|
||||
// shound be 255.255.255.255 (error).
|
||||
prefAddr.s_addr = 0xffffffff;
|
||||
return false;
|
||||
return !addrs.empty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr)
|
||||
{
|
||||
struct in_addr existing_addr;
|
||||
struct in_addr pref_addr;
|
||||
|
||||
{
|
||||
struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr;
|
||||
if (eaddr->sin_family != AF_INET)
|
||||
{
|
||||
std::cerr << "getPreferredInterface() ERROR only valid for IPv4 for now";
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
existing_addr = eaddr->sin_addr;
|
||||
}
|
||||
|
||||
if (getPreferredInterface_ipv4(existing_addr, pref_addr))
|
||||
{
|
||||
/* store into prefAddr */
|
||||
sockaddr_storage_clear(prefAddr);
|
||||
struct sockaddr_in *addr = (sockaddr_in *) &prefAddr;
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr = pref_addr;
|
||||
addr->sin_port = htons(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list<struct sockaddr_storage> &addrs)
|
||||
{
|
||||
struct in_addr existing_addr;
|
||||
std::list<struct in_addr> local_addrs;
|
||||
|
||||
{
|
||||
struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr;
|
||||
if (eaddr->sin_family != AF_INET)
|
||||
{
|
||||
std::cerr << "getLocalInterfaces() ERROR only valid for IPv4 for now";
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
existing_addr = eaddr->sin_addr;
|
||||
}
|
||||
|
||||
if (getLocalInterfaces_ipv4(existing_addr, local_addrs))
|
||||
{
|
||||
std::list<struct in_addr>::iterator it;
|
||||
for(it = local_addrs.begin(); it != local_addrs.end(); ++it)
|
||||
{
|
||||
/* store into prefAddr */
|
||||
|
||||
sockaddr_storage localAddr;
|
||||
sockaddr_storage_clear(localAddr);
|
||||
struct sockaddr_in *addr = (sockaddr_in *) &localAddr;
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr = *it;
|
||||
addr->sin_port = htons(0);
|
||||
addrs.push_back(localAddr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This just might be portable!!! will see!!!
|
||||
* Unfortunately this is usable on winXP+, determined by: (_WIN32_WINNT >= 0x0501)
|
||||
* but not older platforms.... which must use gethostbyname.
|
||||
*
|
||||
* include it for now.....
|
||||
*/
|
||||
|
||||
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr)
|
||||
{
|
||||
|
||||
#if 1
|
||||
char service[100];
|
||||
struct addrinfo hints_st;
|
||||
struct addrinfo *hints = &hints_st;
|
||||
struct addrinfo *res;
|
||||
|
||||
hints -> ai_flags = 0; // (cygwin don;t like these) AI_ADDRCONFIG | AI_NUMERICSERV;
|
||||
hints -> ai_family = AF_INET;
|
||||
hints -> ai_socktype = 0;
|
||||
hints -> ai_protocol = 0;
|
||||
hints -> ai_addrlen = 0;
|
||||
hints -> ai_addr = NULL;
|
||||
hints -> ai_canonname = NULL;
|
||||
hints -> ai_next = NULL;
|
||||
|
||||
/* get the port number */
|
||||
sprintf(service, "%d", ntohs(addr.sin_port));
|
||||
|
||||
/* set it to IPV4 */
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "LookupDNSAddr() name: " << name << " service: " << service << std::endl;
|
||||
#endif
|
||||
|
||||
int err = 0;
|
||||
if (0 != (err = getaddrinfo(name.c_str(), service, hints, &res)))
|
||||
{
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "LookupDNSAddr() getaddrinfo failed!" << std::endl;
|
||||
std::cerr << "Error: " << gai_strerror(err) << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res)
|
||||
{
|
||||
if (res->ai_family == AF_INET)
|
||||
{
|
||||
addr = *((struct sockaddr_in *) res->ai_addr);
|
||||
freeaddrinfo(res);
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "LookupDNSAddr() getaddrinfo found address" << std::endl;
|
||||
std::cerr << "addr: " << rs_inet_ntoa(addr.sin_addr) << std::endl;
|
||||
std::cerr << "port: " << ntohs(addr.sin_port) << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
#ifdef NET_DEBUG
|
||||
std::cerr << "getaddrinfo failed - no address" << std::endl;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef NET_DEBUG
|
||||
//std::cerr << "getaddrinfo disabled" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Socket Library Wrapper Functions
|
||||
* to get over the crapness of the windows.
|
||||
|
@ -49,9 +49,6 @@
|
||||
#include "util/rsnet.h" /* more generic networking header */
|
||||
|
||||
// Some Network functions that are missing from windows.
|
||||
|
||||
in_addr_t inet_netof(struct in_addr addr);
|
||||
in_addr_t inet_network(const char *inet_name);
|
||||
int inet_aton(const char *name, struct in_addr *addr);
|
||||
|
||||
extern int errno; /* Define extern errno, to duplicate unix behaviour */
|
||||
@ -94,20 +91,11 @@ extern int errno; /* Define extern errno, to duplicate unix behaviour */
|
||||
#include <list>
|
||||
|
||||
// Same def - different functions...
|
||||
|
||||
void showSocketError(std::string &out);
|
||||
|
||||
std::string socket_errorType(int err);
|
||||
int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 );
|
||||
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 );
|
||||
int inaddr_cmp(struct sockaddr_in addr1, unsigned long);
|
||||
|
||||
bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr); // returns best addr.
|
||||
bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list<struct sockaddr_storage> &addrs); // returns all possible addrs.
|
||||
|
||||
in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation.
|
||||
|
||||
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr);
|
||||
bool getLocalAddresses(std::list<struct sockaddr_storage> & addrs);
|
||||
|
||||
/* universal socket interface */
|
||||
|
||||
|
@ -59,7 +59,6 @@ net_test
|
||||
Tested Code: pqinetwork.cc, rsnet.cc
|
||||
Description:
|
||||
(1) Tests ntohll / htonll
|
||||
(2) Demonstrates inet_netof / inet_network strange behaviour.
|
||||
(3) Tests socket binding.
|
||||
|
||||
------------------------------------------------------------
|
||||
@ -71,17 +70,6 @@ Description:
|
||||
(2) isPrivateNet()
|
||||
(3) isLoopbackNet()
|
||||
(5) isValidNet()
|
||||
(7) pqi_inet_netof()
|
||||
|
||||
------------------------------------------------------------
|
||||
netiface_test
|
||||
------------------------------------------------------------
|
||||
Tested Code: pqinetwork.cc
|
||||
Description :
|
||||
(1) getPreferredInterface()
|
||||
(2) getLocalInterfaces()
|
||||
|
||||
This is currently a manual test - needs to be converted.
|
||||
|
||||
------------------------------------------------------------
|
||||
pqiarchive_test
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
bool test_byte_manipulation();
|
||||
bool test_local_address_manipulation();
|
||||
bool test_address_listen();
|
||||
|
||||
|
||||
INITTEST();
|
||||
@ -49,8 +48,6 @@ int main(int argc, char **argv)
|
||||
std::cerr << "libretroshare:pqi " << argv[0] << std::endl;
|
||||
|
||||
test_byte_manipulation();
|
||||
test_local_address_manipulation();
|
||||
test_address_listen();
|
||||
|
||||
FINALREPORT("libretroshare Net Basics Tests");
|
||||
return TESTRESULT();
|
||||
@ -89,160 +86,8 @@ const char * localnet2_addrstr = "10.0.0.1";
|
||||
const char * localnet3_addrstr = "10.5.63.78";
|
||||
const char * localnet4_addrstr = "192.168.74.91";
|
||||
|
||||
/* test 2: address manipulation */
|
||||
bool test_local_address_manipulation()
|
||||
{
|
||||
struct sockaddr_in loopback_addr;
|
||||
struct sockaddr_in localnet1_addr;
|
||||
struct sockaddr_in localnet2_addr;
|
||||
struct sockaddr_in localnet3_addr;
|
||||
struct sockaddr_in localnet4_addr;
|
||||
|
||||
std::cerr << "test_local_address_manipulation() NB: This function demonstrates ";
|
||||
std::cerr << "the strange behaviour of inet_netof() and inet_network()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "FAILures are not counted in the test!";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* setup some addresses */
|
||||
inet_aton(loopback_addrstr, &(loopback_addr.sin_addr));
|
||||
inet_aton(localnet1_addrstr, &(localnet1_addr.sin_addr));
|
||||
inet_aton(localnet2_addrstr, &(localnet2_addr.sin_addr));
|
||||
inet_aton(localnet3_addrstr, &(localnet3_addr.sin_addr));
|
||||
inet_aton(localnet4_addrstr, &(localnet4_addr.sin_addr));
|
||||
|
||||
|
||||
std::cerr << "Loopback Addr " << rs_inet_ntoa(loopback_addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "Localnet1 Addr " << rs_inet_ntoa(localnet1_addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Localnet2 Addr " << rs_inet_ntoa(localnet2_addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Localnet3 Addr " << rs_inet_ntoa(localnet3_addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Localnet4 Addr " << rs_inet_ntoa(localnet4_addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "Test 1a - networks";
|
||||
std::cerr << std::endl;
|
||||
|
||||
struct sockaddr_in addr_ans, addr1, addr2;
|
||||
std::string addr_ans_str;
|
||||
|
||||
addr_ans_str = "127.0.0.0";
|
||||
inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr));
|
||||
addr1.sin_addr.s_addr = htonl(inet_netof(loopback_addr.sin_addr));
|
||||
addr2.sin_addr.s_addr = htonl(inet_network(loopback_addrstr));
|
||||
|
||||
std::cerr << "Loopback Net(expected): " << addr_ans_str;
|
||||
std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr);
|
||||
std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr);
|
||||
std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr)));
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr)));
|
||||
|
||||
|
||||
addr_ans_str = "192.168.0.0";
|
||||
inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr));
|
||||
addr1.sin_addr.s_addr = htonl(inet_netof(localnet1_addr.sin_addr));
|
||||
addr2.sin_addr.s_addr = htonl(inet_network(localnet1_addrstr));
|
||||
|
||||
std::cerr << "Localnet1 Net(expected): " << addr_ans_str;
|
||||
std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr);
|
||||
std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr);
|
||||
std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr)));
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr)));
|
||||
|
||||
addr_ans_str = "10.0.0.0";
|
||||
inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr));
|
||||
addr1.sin_addr.s_addr = htonl(inet_netof(localnet2_addr.sin_addr));
|
||||
addr2.sin_addr.s_addr = htonl(inet_network(localnet2_addrstr));
|
||||
|
||||
std::cerr << "Localnet2 Net(expected): " << addr_ans_str;
|
||||
std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr);
|
||||
std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr);
|
||||
std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
|
||||
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr)));
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr)));
|
||||
|
||||
|
||||
addr_ans_str = "10.0.0.0";
|
||||
inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr));
|
||||
addr1.sin_addr.s_addr = htonl(inet_netof(localnet3_addr.sin_addr));
|
||||
addr2.sin_addr.s_addr = htonl(inet_network(localnet3_addrstr));
|
||||
|
||||
std::cerr << "Localnet3 Net(expected): " << addr_ans_str;
|
||||
std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr);
|
||||
std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr);
|
||||
std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
|
||||
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr)));
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr)));
|
||||
|
||||
|
||||
addr_ans_str = "192.168.0.0";
|
||||
inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr));
|
||||
addr1.sin_addr.s_addr = htonl(inet_netof(localnet4_addr.sin_addr));
|
||||
addr2.sin_addr.s_addr = htonl(inet_network(localnet4_addrstr));
|
||||
|
||||
std::cerr << "Localnet4 Net(expected): " << addr_ans_str;
|
||||
std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr);
|
||||
std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr);
|
||||
std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
|
||||
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr)));
|
||||
//CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr)));
|
||||
|
||||
REPORT("Test Local Address Manipulation");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_bind_addr(struct sockaddr_in addr);
|
||||
|
||||
bool test_address_listen()
|
||||
{
|
||||
struct sockaddr_in addr1, addr2, addr3;
|
||||
|
||||
sockaddr_clear(&addr1);
|
||||
addr1.sin_family = AF_INET;
|
||||
inet_aton(loopback_addrstr, &(addr1.sin_addr));
|
||||
addr1.sin_port = htons(12345);
|
||||
|
||||
sockaddr_clear(&addr2);
|
||||
addr2.sin_family = AF_INET;
|
||||
getPreferredInterface(addr2.sin_addr); // returns best addr.
|
||||
addr2.sin_port = htons(13245);
|
||||
|
||||
sockaddr_clear(&addr3);
|
||||
addr3.sin_family = AF_INET;
|
||||
getPreferredInterface(addr3.sin_addr); // returns best addr.
|
||||
addr3.sin_port = htons(23451);
|
||||
|
||||
/* test bind to loopback, and preferred interfaces */
|
||||
test_bind_addr(addr1);
|
||||
test_bind_addr(addr2);
|
||||
test_bind_addr(addr3);
|
||||
|
||||
|
||||
|
||||
REPORT("Test Address Listen");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_bind_addr(struct sockaddr_in addr)
|
||||
{
|
||||
|
||||
|
@ -54,7 +54,6 @@ int test_isExternalNet();
|
||||
int test_isPrivateNet();
|
||||
int test_isLoopbackNet();
|
||||
int test_isValidNet();
|
||||
int test_pqi_inet_netof();
|
||||
|
||||
INITTEST();
|
||||
|
||||
@ -66,7 +65,6 @@ int main(int argc, char **argv)
|
||||
test_isPrivateNet();
|
||||
test_isLoopbackNet();
|
||||
test_isValidNet();
|
||||
test_pqi_inet_netof();
|
||||
|
||||
FINALREPORT("net_test1");
|
||||
|
||||
@ -170,40 +168,3 @@ int test_isValidNet()
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_pqi_inet_netof()
|
||||
{
|
||||
struct in_addr localnet1_addr;
|
||||
struct in_addr localnet2_addr;
|
||||
struct in_addr localnet3_addr;
|
||||
struct in_addr localnet4_addr;
|
||||
struct in_addr localnet5_addr;
|
||||
struct in_addr localnet6_addr;
|
||||
struct in_addr localnet7_addr;
|
||||
struct in_addr localnet8_addr;
|
||||
struct in_addr external_addr;
|
||||
|
||||
inet_aton(localnet1_addrstr, &localnet1_addr);
|
||||
inet_aton(localnet2_addrstr, &localnet2_addr);
|
||||
inet_aton(localnet3_addrstr, &localnet3_addr);
|
||||
inet_aton(localnet4_addrstr, &localnet4_addr);
|
||||
inet_aton(localnet5_addrstr, &localnet5_addr);
|
||||
inet_aton(localnet6_addrstr, &localnet6_addr);
|
||||
inet_aton(localnet7_addrstr, &localnet7_addr);
|
||||
inet_aton(localnet8_addrstr, &localnet8_addr);
|
||||
inet_aton(external_addrstr, &external_addr);
|
||||
|
||||
CHECK(pqi_inet_netof(localnet1_addr)==htonl(10<<24));
|
||||
CHECK(pqi_inet_netof(localnet2_addr)==htonl(169<<24 | 254<<16));
|
||||
CHECK(pqi_inet_netof(localnet3_addr)==htonl(172<<24 | 16<<16));
|
||||
CHECK(pqi_inet_netof(localnet4_addr)==htonl(192<<24 | 168<<16 | 1<<8));
|
||||
CHECK(pqi_inet_netof(localnet5_addr)==htonl(10<<24));
|
||||
CHECK(pqi_inet_netof(localnet6_addr)==htonl(169<<24 | 254<<16));
|
||||
CHECK(pqi_inet_netof(localnet7_addr)==htonl(172<<24 | 20<<16));
|
||||
CHECK(pqi_inet_netof(localnet8_addr)==htonl(192<<24 | 168<<16 | 1<<8));
|
||||
CHECK(pqi_inet_netof(external_addr)==htonl(74<<24));
|
||||
|
||||
REPORT("pqi_inet_netof()");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* libretroshare/src/pqi net_test.cc
|
||||
*
|
||||
* 3P/PQI network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
/******
|
||||
* NETWORKING Test to check Big/Little Endian behaviour
|
||||
* as well as socket behaviour
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pqi/pqinetwork.h"
|
||||
#include "util/rsnet.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
bool test_iface();
|
||||
bool test_iface_loop();
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool repeat = false;
|
||||
if (argc > 1)
|
||||
{
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
test_iface();
|
||||
|
||||
if (repeat)
|
||||
{
|
||||
test_iface_loop();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* test 1: single check if interfaces */
|
||||
bool test_iface()
|
||||
{
|
||||
struct in_addr pref_iface;
|
||||
std::list<struct in_addr> ifaces;
|
||||
std::list<struct in_addr>::iterator it;
|
||||
|
||||
getPreferredInterface(pref_iface);
|
||||
getLocalInterfaces(ifaces);
|
||||
|
||||
std::cerr << "test_iface()" << std::endl;
|
||||
for(it = ifaces.begin(); it != ifaces.end(); it++)
|
||||
{
|
||||
std::cerr << "available iface: " << rs_inet_ntoa(*it) << std::endl;
|
||||
}
|
||||
std::cerr << "preferred " << rs_inet_ntoa(pref_iface) << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* test 2: catch changing interfaces */
|
||||
bool test_iface_loop()
|
||||
{
|
||||
std::cerr << "test_iface_loop()" << std::endl;
|
||||
struct in_addr curr_pref_iface;
|
||||
getPreferredInterface(curr_pref_iface);
|
||||
time_t start = time(NULL);
|
||||
while(1)
|
||||
{
|
||||
struct in_addr pref_iface;
|
||||
std::list<struct in_addr> ifaces;
|
||||
std::list<struct in_addr>::iterator it;
|
||||
|
||||
getPreferredInterface(pref_iface);
|
||||
getLocalInterfaces(ifaces);
|
||||
|
||||
|
||||
std::cerr << "T(" << time(NULL) - start << ") ";
|
||||
|
||||
for(it = ifaces.begin(); it != ifaces.end(); it++)
|
||||
{
|
||||
std::cerr << " I: " << rs_inet_ntoa(*it);
|
||||
}
|
||||
std::cerr << " P: " << rs_inet_ntoa(pref_iface) << std::endl;
|
||||
|
||||
if (curr_pref_iface.s_addr !=
|
||||
pref_iface.s_addr)
|
||||
{
|
||||
std::cerr << "+++++++++++++ Address CHANGED ++++++++++";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "+++++++++++++ Address CHANGED ++++++++++";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "+++++++++++++ Address CHANGED ++++++++++";
|
||||
std::cerr << std::endl;
|
||||
|
||||
curr_pref_iface = pref_iface;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,7 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr);
|
||||
std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr);
|
||||
std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr);
|
||||
std::string sockaddr_storage_porttostring(const struct sockaddr_storage &addr);
|
||||
void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString = NULL);
|
||||
|
||||
// output
|
||||
//void sockaddr_storage_output(const struct sockaddr_storage &addr, std::ostream &out);
|
||||
@ -129,6 +130,6 @@ bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr);
|
||||
|
||||
|
||||
bool rs_inet_ntop(const sockaddr_storage &addr, std::string &dst);
|
||||
|
||||
#endif /* RS_UNIVERSAL_NETWORK_HEADER */
|
||||
|
@ -23,6 +23,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "util/rsnet.h"
|
||||
#include "util/rsstring.h"
|
||||
#include "pqi/pqinetwork.h"
|
||||
@ -107,11 +110,8 @@ int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen)
|
||||
|
||||
if (len > socklen)
|
||||
{
|
||||
std::cerr << "universal_bind() ERROR len > socklen";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "universal_bind() ERROR len > socklen" << std::endl;
|
||||
len = socklen;
|
||||
//return EINVAL;
|
||||
}
|
||||
|
||||
return bind(fd, addr, len);
|
||||
@ -155,8 +155,7 @@ bool sockaddr_storage_zeroip(struct sockaddr_storage &addr)
|
||||
bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_copyip()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_copyip()" << std::endl;
|
||||
#endif
|
||||
|
||||
switch(src.ss_family)
|
||||
@ -169,8 +168,7 @@ bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr
|
||||
break;
|
||||
default:
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_copyip() invalid addr.ss_family";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_copyip() Unknown ss_family: " << src.ss_family << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -193,10 +191,8 @@ uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr)
|
||||
return sockaddr_storage_ipv6_port(addr);
|
||||
break;
|
||||
default:
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_port() invalid addr.ss_family: " << addr.ss_family;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
std::cerr << "sockaddr_storage_port() invalid addr.ss_family" << std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -205,8 +201,7 @@ uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr)
|
||||
bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_setport()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_setport()" << std::endl;
|
||||
#endif
|
||||
|
||||
switch(addr.ss_family)
|
||||
@ -218,10 +213,7 @@ bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port)
|
||||
return sockaddr_storage_ipv6_setport(addr, port);
|
||||
break;
|
||||
default:
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_setport() invalid addr.ss_family";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
std::cerr << "sockaddr_storage_setport() invalid addr.ss_family" << std::endl;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@ -247,8 +239,7 @@ bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *
|
||||
|
||||
bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6)
|
||||
{
|
||||
std::cerr << "sockaddr_storage_setipv6()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_setipv6()" << std::endl;
|
||||
|
||||
sockaddr_storage_clear(addr);
|
||||
struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr);
|
||||
@ -391,8 +382,56 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr)
|
||||
return output;
|
||||
}
|
||||
|
||||
void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString)
|
||||
{
|
||||
// This function must not rely on others sockaddr_storage_*
|
||||
|
||||
std::stringstream output;
|
||||
output << "sockaddr_storage_dump(addr) ";
|
||||
|
||||
switch (addr.ss_family){
|
||||
case AF_INET:
|
||||
{
|
||||
const sockaddr_in * in = (const sockaddr_in *) & addr;
|
||||
output << "addr.ss_family = AF_INET";
|
||||
output << " in->sin_addr = ";
|
||||
output << inet_ntoa(in->sin_addr);
|
||||
output << " in->sin_port = ";
|
||||
output << in->sin_port;
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr;
|
||||
std::string addrStr = "INVALID_IPV6";
|
||||
rs_inet_ntop(addr, addrStr);
|
||||
output << "addr.ss_family = AF_INET6";
|
||||
output << " in6->sin6_addr = ";
|
||||
output << addrStr;
|
||||
output << " in6->sin6_scope_id = ";
|
||||
output << in6->sin6_scope_id;
|
||||
output << " in6->sin6_port = ";
|
||||
output << in6->sin6_port;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
output << "unknown addr.ss_family ";
|
||||
const uint8_t * buf = reinterpret_cast<const uint8_t *>(&addr);
|
||||
for( uint32_t i = 0; i < sizeof(addr); ++i )
|
||||
output << std::setw(2) << std::setfill('0') << std::hex << +buf[i];
|
||||
}}
|
||||
|
||||
if(outputString)
|
||||
{
|
||||
outputString->append(output.str() + "\n");
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << output.str() << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
std::cerr << output.str() << std::endl;
|
||||
}
|
||||
|
||||
std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr)
|
||||
{
|
||||
@ -670,8 +709,7 @@ bool sockaddr_storage_ipv6_zeroip(struct sockaddr_storage &addr)
|
||||
bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_copyip()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_ipv6_copyip()" << std::endl;
|
||||
#endif
|
||||
|
||||
struct sockaddr_in6 *dst_ptr = to_ipv6_ptr(dst);
|
||||
@ -823,17 +861,14 @@ std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & /* addr */)
|
||||
std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & addr)
|
||||
{
|
||||
std::string output;
|
||||
output += "IPv6-ADDRESS-TODO";
|
||||
return output;
|
||||
std::string addrStr;
|
||||
rs_inet_ntop(addr, addrStr);
|
||||
return addrStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************* Net Checks ***********************************/
|
||||
bool sockaddr_storage_ipv4_isnull(const struct sockaddr_storage &addr)
|
||||
{
|
||||
@ -968,5 +1003,43 @@ bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#include <cstdlib>
|
||||
#include <Winsock2.h>
|
||||
#endif
|
||||
|
||||
bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
||||
{
|
||||
bool success = false;
|
||||
char ipStr[255];
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
// Use WSAAddressToString instead of InetNtop because the latter is missing
|
||||
// on XP and is present only on Vista and newers
|
||||
wchar_t wIpStr[255];
|
||||
long unsigned int len = 255;
|
||||
sockaddr_storage tmp;
|
||||
sockaddr_storage_clear(tmp);
|
||||
sockaddr_storage_copyip(tmp, addr);
|
||||
sockaddr * sptr = (sockaddr *) &tmp;
|
||||
success = (0 == WSAAddressToString( sptr, sizeof(sockaddr_storage), NULL, wIpStr, &len ));
|
||||
wcstombs(ipStr, wIpStr, len);
|
||||
#else // WINDOWS_SYS
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
const struct sockaddr_in * addrv4p = (const struct sockaddr_in *) &addr;
|
||||
success = inet_ntop( addr.ss_family, (const void *) &(addrv4p->sin_addr), ipStr, INET_ADDRSTRLEN );
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
const struct sockaddr_in6 * addrv6p = (const struct sockaddr_in6 *) &addr;
|
||||
success = inet_ntop( addr.ss_family, (const void *) &(addrv6p->sin6_addr), ipStr, INET6_ADDRSTRLEN );
|
||||
}
|
||||
}
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
dst = ipStr;
|
||||
return success;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user