From 08f6b21ce7cc4aa4069b4461785fc7173bed2998 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Mar 2010 11:45:56 -0700 Subject: added interface address discovery --- host/lib/transport/if_addrs.cpp | 343 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 host/lib/transport/if_addrs.cpp (limited to 'host/lib/transport/if_addrs.cpp') diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp new file mode 100644 index 000000000..d3ea448fd --- /dev/null +++ b/host/lib/transport/if_addrs.cpp @@ -0,0 +1,343 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include + +uhd::transport::if_addrs_t::if_addrs_t(void){ + /* NOP */ +} + +/*********************************************************************** + * Interface address discovery through ifaddrs api + **********************************************************************/ +#ifdef HAVE_IFADDRS_H +#include +#include + +static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ + if (addr->sa_family == AF_INET) return boost::asio::ip::address_v4(ntohl( + reinterpret_cast(addr)->sin_addr.s_addr + )); + return boost::asio::ip::address_v4::any(); +} + +static bool ifaddrs_valid(const struct ifaddrs *ifaddrs){ + return ( + ifaddrs->ifa_addr->sa_family == AF_INET and + sockaddr_to_ip_addr(ifaddrs->ifa_addr) != boost::asio::ip::address_v4::loopback() + ); +} + +std::vector uhd::transport::get_if_addrs(void){ + std::vector if_addrs; + struct ifaddrs *ifap; + if (getifaddrs(&ifap) == 0){ + for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next){ + if (not ifaddrs_valid(iter)) continue; + if_addrs_t if_addr; + if_addr.inet = sockaddr_to_ip_addr(iter->ifa_addr).to_string(); + if_addr.mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_string(); + if_addr.bcast = sockaddr_to_ip_addr(iter->ifa_broadaddr).to_string(); + if_addrs.push_back(if_addr); + } + freeifaddrs(ifap); + } + return if_addrs; +} + +/*********************************************************************** + * Interface address discovery through windows api (TODO) + **********************************************************************/ +//#elif HAVE_XXX_H + +/*********************************************************************** + * Interface address discovery not included + **********************************************************************/ +#else /* HAVE_IFADDRS_H */ + +std::vector uhd::transport::get_if_addrs(void){ + return std::vector(); +} + +#endif /* HAVE_IFADDRS_H */ + +//////////////////////////////////////////////////////////////////////// +// How to extract the ip address: unix/windows +// http://www.developerweb.net/forum/showthread.php?t=5085 +//////////////////////////////////////////////////////////////////////// + +/* +#include + +#ifdef WIN32 +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include + +typedef unsigned long uint32; + +#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__) +# define USE_GETIFADDRS 1 +# include +static uint32 SockAddrToUint32(struct sockaddr * a) +{ + return ((a)&&(a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in *)a)->sin_addr.s_addr) : 0; +} +#endif + +// convert a numeric IP address into its string representation +static void Inet_NtoA(uint32 addr, char * ipbuf) +{ + sprintf(ipbuf, "%li.%li.%li.%li", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF); +} + +// convert a string represenation of an IP address into its numeric equivalent +static uint32 Inet_AtoN(const char * buf) +{ + // net_server inexplicably doesn't have this function; so I'll just fake it + uint32 ret = 0; + int shift = 24; // fill out the MSB first + bool startQuad = true; + while((shift >= 0)&&(*buf)) + { + if (startQuad) + { + unsigned char quad = (unsigned char) atoi(buf); + ret |= (((uint32)quad) << shift); + shift -= 8; + } + startQuad = (*buf == '.'); + buf++; + } + return ret; +} + +static void PrintNetworkInterfaceInfos() +{ +#if defined(USE_GETIFADDRS) + // BSD-style implementation + struct ifaddrs * ifap; + if (getifaddrs(&ifap) == 0) + { + struct ifaddrs * p = ifap; + while(p) + { + uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); + uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); + uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); + if (ifaAddr > 0) + { + char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr); + char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr); + char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr); + printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); + } + p = p->ifa_next; + } + freeifaddrs(ifap); + } +#elif defined(WIN32) + // Windows XP style implementation + + // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx + // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() + // multiple times in order to deal with potential race conditions properly. + MIB_IPADDRTABLE * ipTable = NULL; + { + ULONG bufLen = 0; + for (int i=0; i<5; i++) + { + DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); + if (ipRet == ERROR_INSUFFICIENT_BUFFER) + { + free(ipTable); // in case we had previously allocated it + ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); + } + else if (ipRet == NO_ERROR) break; + else + { + free(ipTable); + ipTable = NULL; + break; + } + } + } + + if (ipTable) + { + // Try to get the Adapters-info table, so we can given useful names to the IP + // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle + // the potential race condition between the size-query call and the get-data call. + // I love a well-designed API :^P + IP_ADAPTER_INFO * pAdapterInfo = NULL; + { + ULONG bufLen = 0; + for (int i=0; i<5; i++) + { + DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); + if (apRet == ERROR_BUFFER_OVERFLOW) + { + free(pAdapterInfo); // in case we had previously allocated it + pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); + } + else if (apRet == ERROR_SUCCESS) break; + else + { + free(pAdapterInfo); + pAdapterInfo = NULL; + break; + } + } + } + + for (DWORD i=0; idwNumEntries; i++) + { + const MIB_IPADDRROW & row = ipTable->table[i]; + + // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it + const char * name = NULL; + const char * desc = NULL; + if (pAdapterInfo) + { + IP_ADAPTER_INFO * next = pAdapterInfo; + while((next)&&(name==NULL)) + { + IP_ADDR_STRING * ipAddr = &next->IpAddressList; + while(ipAddr) + { + if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) + { + name = next->AdapterName; + desc = next->Description; + break; + } + ipAddr = ipAddr->Next; + } + next = next->Next; + } + } + char buf[128]; + if (name == NULL) + { + sprintf(buf, "unnamed-%i", i); + name = buf; + } + + uint32 ipAddr = ntohl(row.dwAddr); + uint32 netmask = ntohl(row.dwMask); + uint32 baddr = ipAddr & netmask; + if (row.dwBCastAddr) baddr |= ~netmask; + + char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr); + char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr); + char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr); + printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); + } + + free(pAdapterInfo); + free(ipTable); + } +#else + // Dunno what we're running on here! +# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!" +#endif +} + +int main(int, char **) +{ + PrintNetworkInterfaceInfos(); + return 0; +} +*/ + +//////////////////////////////////////////////////////////////////////// +// How to extract the mac address: linux/windows +// http://old.nabble.com/MAC-Address-td19111197.html +//////////////////////////////////////////////////////////////////////// + +/* +Linux: + +#include +#include +#include +#include +#include +#include +#include + +ifaddrs * ifap = 0; +if(getifaddrs(&ifap) == 0) +{ + ifaddrs * iter = ifap; + while(iter) + { + sockaddr_ll * sal = + reinterpret_cast(iter->ifa_addr); + if(sal->sll_family == AF_PACKET) + { + // get the mac bytes + // copy(sal->sll_addr, + // sal->sll_addr+sal->sll_hallen, + // buffer); + } + iter = iter->ifa_next; + } + freeifaddrs(ifap); +} + +Windows: +#include +#include + +std::vector buf; +DWORD bufLen = 0; +GetAdaptersAddresses(0, 0, 0, 0, &bufLen); +if(bufLen) +{ + buf.resize(bufLen, 0); + IP_ADAPTER_ADDRESSES * ptr = + reinterpret_cast(&buf[0]); + DWORD err = GetAdaptersAddresses(0, 0, 0, ptr, &bufLen); + if(err == NO_ERROR) + { + while(ptr) + { + if(ptr->PhysicalAddressLength) + { + // get the mac bytes + // copy(ptr->PhysicalAddress, + // ptr->PhysicalAddress+ptr->PhysicalAddressLength, + // buffer); + } + ptr = ptr->Next; + } + } +} +*/ -- cgit v1.2.3 From ae02148f12615ab4f8e326dac5cf388ab976ec7f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Mar 2010 17:52:57 -0800 Subject: get interface addresses on windows --- host/lib/CMakeLists.txt | 6 +- host/lib/load_modules.cpp | 2 +- host/lib/transport/if_addrs.cpp | 311 +++++-------------------------------- host/lib/usrp/usrp2/usrp2_impl.cpp | 3 + 4 files changed, 48 insertions(+), 274 deletions(-) (limited to 'host/lib/transport/if_addrs.cpp') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a0bfd6d0a..170d1d3bf 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -64,7 +64,7 @@ MESSAGE(STATUS "Configuring module loading...") INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) -CHECK_INCLUDE_FILE_CXX(Windows.h HAVE_WINDOWS_H) +CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H) IF(HAVE_DLFCN_H) MESSAGE(STATUS " Module loading supported through dlopen.") @@ -83,10 +83,14 @@ MESSAGE(STATUS "Configuring interface address discovery...") INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) +CHECK_INCLUDE_FILE_CXX(winsock2.h HAVE_WINSOCK2_H) IF(HAVE_IFADDRS_H) MESSAGE(STATUS " Interface address discovery supported through getifaddrs.") ADD_DEFINITIONS(-DHAVE_IFADDRS_H) +ELSEIF(HAVE_WINSOCK2_H) + MESSAGE(STATUS " Interface address discovery supported through SIO_GET_INTERFACE_LIST.") + ADD_DEFINITIONS(-DHAVE_WINSOCK2_H) ELSE(HAVE_IFADDRS_H) MESSAGE(STATUS " Interface address discovery not supported.") ENDIF(HAVE_IFADDRS_H) diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp index bcdff98a6..77426b898 100644 --- a/host/lib/load_modules.cpp +++ b/host/lib/load_modules.cpp @@ -41,7 +41,7 @@ static void load_module(const std::string &file_name){ } #elif HAVE_WINDOWS_H -#include +#include static void load_module(const std::string &file_name){ if (LoadLibrary(file_name.c_str()) == NULL){ diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp index d3ea448fd..eb0e56b3a 100644 --- a/host/lib/transport/if_addrs.cpp +++ b/host/lib/transport/if_addrs.cpp @@ -36,10 +36,7 @@ static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ } static bool ifaddrs_valid(const struct ifaddrs *ifaddrs){ - return ( - ifaddrs->ifa_addr->sa_family == AF_INET and - sockaddr_to_ip_addr(ifaddrs->ifa_addr) != boost::asio::ip::address_v4::loopback() - ); + return ifaddrs->ifa_addr->sa_family == AF_INET; } std::vector uhd::transport::get_if_addrs(void){ @@ -62,7 +59,44 @@ std::vector uhd::transport::get_if_addrs(void){ /*********************************************************************** * Interface address discovery through windows api (TODO) **********************************************************************/ -//#elif HAVE_XXX_H +#elif HAVE_WINSOCK2_H +#include +#include +#include +#include + +std::vector uhd::transport::get_if_addrs(void){ + std::vector if_addrs; + SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0); + if (sd == SOCKET_ERROR) { + std::cerr << "Failed to get a socket. Error " << WSAGetLastError() << + std::endl; return if_addrs; + } + + INTERFACE_INFO InterfaceList[20]; + unsigned long nBytesReturned; + if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, + sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) { + std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() << + std::endl; + return if_addrs; + } + + int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO); + for (int i = 0; i < nNumInterfaces; ++i) { + boost::uint32_t iiAddress = ntohl(reinterpret_cast(InterfaceList[i].iiAddress).sin_addr.s_addr); + boost::uint32_t iiNetmask = ntohl(reinterpret_cast(InterfaceList[i].iiNetmask).sin_addr.s_addr); + boost::uint32_t iiBroadcastAddress = (iiAddress & iiNetmask) | ~iiNetmask; + + if_addrs_t if_addr; + if_addr.inet = boost::asio::ip::address_v4(iiAddress).to_string(); + if_addr.mask = boost::asio::ip::address_v4(iiNetmask).to_string(); + if_addr.bcast = boost::asio::ip::address_v4(iiBroadcastAddress).to_string(); + if_addrs.push_back(if_addr); + } + + return if_addrs; +} /*********************************************************************** * Interface address discovery not included @@ -74,270 +108,3 @@ std::vector uhd::transport::get_if_addrs(void){ } #endif /* HAVE_IFADDRS_H */ - -//////////////////////////////////////////////////////////////////////// -// How to extract the ip address: unix/windows -// http://www.developerweb.net/forum/showthread.php?t=5085 -//////////////////////////////////////////////////////////////////////// - -/* -#include - -#ifdef WIN32 -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include - -typedef unsigned long uint32; - -#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__) -# define USE_GETIFADDRS 1 -# include -static uint32 SockAddrToUint32(struct sockaddr * a) -{ - return ((a)&&(a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in *)a)->sin_addr.s_addr) : 0; -} -#endif - -// convert a numeric IP address into its string representation -static void Inet_NtoA(uint32 addr, char * ipbuf) -{ - sprintf(ipbuf, "%li.%li.%li.%li", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF); -} - -// convert a string represenation of an IP address into its numeric equivalent -static uint32 Inet_AtoN(const char * buf) -{ - // net_server inexplicably doesn't have this function; so I'll just fake it - uint32 ret = 0; - int shift = 24; // fill out the MSB first - bool startQuad = true; - while((shift >= 0)&&(*buf)) - { - if (startQuad) - { - unsigned char quad = (unsigned char) atoi(buf); - ret |= (((uint32)quad) << shift); - shift -= 8; - } - startQuad = (*buf == '.'); - buf++; - } - return ret; -} - -static void PrintNetworkInterfaceInfos() -{ -#if defined(USE_GETIFADDRS) - // BSD-style implementation - struct ifaddrs * ifap; - if (getifaddrs(&ifap) == 0) - { - struct ifaddrs * p = ifap; - while(p) - { - uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); - uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); - uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); - if (ifaAddr > 0) - { - char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr); - char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr); - char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr); - printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - } - p = p->ifa_next; - } - freeifaddrs(ifap); - } -#elif defined(WIN32) - // Windows XP style implementation - - // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx - // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() - // multiple times in order to deal with potential race conditions properly. - MIB_IPADDRTABLE * ipTable = NULL; - { - ULONG bufLen = 0; - for (int i=0; i<5; i++) - { - DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); - if (ipRet == ERROR_INSUFFICIENT_BUFFER) - { - free(ipTable); // in case we had previously allocated it - ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); - } - else if (ipRet == NO_ERROR) break; - else - { - free(ipTable); - ipTable = NULL; - break; - } - } - } - - if (ipTable) - { - // Try to get the Adapters-info table, so we can given useful names to the IP - // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle - // the potential race condition between the size-query call and the get-data call. - // I love a well-designed API :^P - IP_ADAPTER_INFO * pAdapterInfo = NULL; - { - ULONG bufLen = 0; - for (int i=0; i<5; i++) - { - DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); - if (apRet == ERROR_BUFFER_OVERFLOW) - { - free(pAdapterInfo); // in case we had previously allocated it - pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); - } - else if (apRet == ERROR_SUCCESS) break; - else - { - free(pAdapterInfo); - pAdapterInfo = NULL; - break; - } - } - } - - for (DWORD i=0; idwNumEntries; i++) - { - const MIB_IPADDRROW & row = ipTable->table[i]; - - // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it - const char * name = NULL; - const char * desc = NULL; - if (pAdapterInfo) - { - IP_ADAPTER_INFO * next = pAdapterInfo; - while((next)&&(name==NULL)) - { - IP_ADDR_STRING * ipAddr = &next->IpAddressList; - while(ipAddr) - { - if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) - { - name = next->AdapterName; - desc = next->Description; - break; - } - ipAddr = ipAddr->Next; - } - next = next->Next; - } - } - char buf[128]; - if (name == NULL) - { - sprintf(buf, "unnamed-%i", i); - name = buf; - } - - uint32 ipAddr = ntohl(row.dwAddr); - uint32 netmask = ntohl(row.dwMask); - uint32 baddr = ipAddr & netmask; - if (row.dwBCastAddr) baddr |= ~netmask; - - char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr); - char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr); - char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr); - printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - } - - free(pAdapterInfo); - free(ipTable); - } -#else - // Dunno what we're running on here! -# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!" -#endif -} - -int main(int, char **) -{ - PrintNetworkInterfaceInfos(); - return 0; -} -*/ - -//////////////////////////////////////////////////////////////////////// -// How to extract the mac address: linux/windows -// http://old.nabble.com/MAC-Address-td19111197.html -//////////////////////////////////////////////////////////////////////// - -/* -Linux: - -#include -#include -#include -#include -#include -#include -#include - -ifaddrs * ifap = 0; -if(getifaddrs(&ifap) == 0) -{ - ifaddrs * iter = ifap; - while(iter) - { - sockaddr_ll * sal = - reinterpret_cast(iter->ifa_addr); - if(sal->sll_family == AF_PACKET) - { - // get the mac bytes - // copy(sal->sll_addr, - // sal->sll_addr+sal->sll_hallen, - // buffer); - } - iter = iter->ifa_next; - } - freeifaddrs(ifap); -} - -Windows: -#include -#include - -std::vector buf; -DWORD bufLen = 0; -GetAdaptersAddresses(0, 0, 0, 0, &bufLen); -if(bufLen) -{ - buf.resize(bufLen, 0); - IP_ADAPTER_ADDRESSES * ptr = - reinterpret_cast(&buf[0]); - DWORD err = GetAdaptersAddresses(0, 0, 0, ptr, &bufLen); - if(err == NO_ERROR) - { - while(ptr) - { - if(ptr->PhysicalAddressLength) - { - // get the mac bytes - // copy(ptr->PhysicalAddress, - // ptr->PhysicalAddress+ptr->PhysicalAddressLength, - // buffer); - } - ptr = ptr->Next; - } - } -} -*/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index f04ae8d2c..35a4aeb20 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -41,6 +41,9 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ //if no address was specified, send a broadcast on each interface if (not hint.has_key("addr")){ BOOST_FOREACH(const if_addrs_t &if_addrs, get_if_addrs()){ + //avoid the loopback device + if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue; + //create a new hint with this broadcast address device_addr_t new_hint = hint; new_hint["addr"] = if_addrs.bcast; -- cgit v1.2.3 From dd41206f2a5127871fc4c9911a748f7f4e3b6c51 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Mar 2010 19:02:32 -0700 Subject: tweak the ifaddrs address discovery --- host/lib/transport/if_addrs.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'host/lib/transport/if_addrs.cpp') diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp index eb0e56b3a..5c8c8a176 100644 --- a/host/lib/transport/if_addrs.cpp +++ b/host/lib/transport/if_addrs.cpp @@ -16,6 +16,9 @@ // #include +#include +#include +#include uhd::transport::if_addrs_t::if_addrs_t(void){ /* NOP */ @@ -26,17 +29,11 @@ uhd::transport::if_addrs_t::if_addrs_t(void){ **********************************************************************/ #ifdef HAVE_IFADDRS_H #include -#include static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ - if (addr->sa_family == AF_INET) return boost::asio::ip::address_v4(ntohl( + return boost::asio::ip::address_v4(ntohl( reinterpret_cast(addr)->sin_addr.s_addr )); - return boost::asio::ip::address_v4::any(); -} - -static bool ifaddrs_valid(const struct ifaddrs *ifaddrs){ - return ifaddrs->ifa_addr->sa_family == AF_INET; } std::vector uhd::transport::get_if_addrs(void){ @@ -44,7 +41,12 @@ std::vector uhd::transport::get_if_addrs(void){ struct ifaddrs *ifap; if (getifaddrs(&ifap) == 0){ for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next){ - if (not ifaddrs_valid(iter)) continue; + //ensure that the entries are valid + if (iter->ifa_addr->sa_family != AF_INET) continue; + if (iter->ifa_netmask->sa_family != AF_INET) continue; + if (iter->ifa_broadaddr->sa_family != AF_INET) continue; + + //append a new set of interface addresses if_addrs_t if_addr; if_addr.inet = sockaddr_to_ip_addr(iter->ifa_addr).to_string(); if_addr.mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_string(); @@ -60,10 +62,7 @@ std::vector uhd::transport::get_if_addrs(void){ * Interface address discovery through windows api (TODO) **********************************************************************/ #elif HAVE_WINSOCK2_H -#include -#include #include -#include std::vector uhd::transport::get_if_addrs(void){ std::vector if_addrs; -- cgit v1.2.3