// // 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; } } } */