aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-03-26 17:52:57 -0800
committerJosh Blum <josh@joshknows.com>2010-03-26 17:52:57 -0800
commitae02148f12615ab4f8e326dac5cf388ab976ec7f (patch)
tree1c89914d05965e02730504eb17c22ac907348e52
parent72927d983f1f84127e83bf2d80db6b8ee882bad7 (diff)
downloaduhd-ae02148f12615ab4f8e326dac5cf388ab976ec7f.tar.gz
uhd-ae02148f12615ab4f8e326dac5cf388ab976ec7f.tar.bz2
uhd-ae02148f12615ab4f8e326dac5cf388ab976ec7f.zip
get interface addresses on windows
-rw-r--r--host/lib/CMakeLists.txt6
-rw-r--r--host/lib/load_modules.cpp2
-rw-r--r--host/lib/transport/if_addrs.cpp311
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp3
4 files changed, 48 insertions, 274 deletions
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 <Windows.h>
+#include <windows.h>
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::if_addrs_t> uhd::transport::get_if_addrs(void){
@@ -62,7 +59,44 @@ std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){
/***********************************************************************
* Interface address discovery through windows api (TODO)
**********************************************************************/
-//#elif HAVE_XXX_H
+#elif HAVE_WINSOCK2_H
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/cstdint.hpp>
+#include <winsock2.h>
+#include <iostream>
+
+std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){
+ std::vector<if_addrs_t> 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<sockaddr_in&>(InterfaceList[i].iiAddress).sin_addr.s_addr);
+ boost::uint32_t iiNetmask = ntohl(reinterpret_cast<sockaddr_in&>(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::if_addrs_t> 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 <stdio.h>
-
-#ifdef WIN32
-# include <windows.h>
-# include <winsock.h>
-# include <iphlpapi.h>
-#else
-# include <unistd.h>
-# include <stdlib.h>
-# include <sys/socket.h>
-# include <netdb.h>
-# include <netinet/in.h>
-# include <net/if.h>
-# include <sys/ioctl.h>
-#endif
-
-#include <string.h>
-#include <sys/stat.h>
-
-typedef unsigned long uint32;
-
-#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
-# define USE_GETIFADDRS 1
-# include <ifaddrs.h>
-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; i<ipTable->dwNumEntries; 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 <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netpacket/packet.h>
-#include <ifaddrs.h>
-
-ifaddrs * ifap = 0;
-if(getifaddrs(&ifap) == 0)
-{
- ifaddrs * iter = ifap;
- while(iter)
- {
- sockaddr_ll * sal =
- reinterpret_cast<sockaddr_ll*>(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 <winsock2.h>
-#include <iphlpapi.h>
-
-std::vector<boost::uint8_t> buf;
-DWORD bufLen = 0;
-GetAdaptersAddresses(0, 0, 0, 0, &bufLen);
-if(bufLen)
-{
- buf.resize(bufLen, 0);
- IP_ADAPTER_ADDRESSES * ptr =
- reinterpret_cast<IP_ADAPTER_ADDRESSES*>(&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;