/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /** * Copyright (C) 2014 Named Data Networking Project * See COPYING for copyright and distribution information. */ #include "network-interface.hpp" #include "core/logger.hpp" #include #include // for inet_ntop() #include // for struct sockaddr_in{,6} #include // for getifaddrs() #if defined(__linux__) #include // for ARPHRD_* constants #include // for struct sockaddr_ll #elif defined(__APPLE__) #include // for struct sockaddr_dl #else #error Platform not supported #endif namespace nfd { NFD_LOG_INIT("NetworkInterfaceInfo") std::list< shared_ptr > listNetworkInterfaces() { typedef std::map< std::string, shared_ptr > InterfacesMap; InterfacesMap ifmap; ifaddrs* ifa_list; if (::getifaddrs(&ifa_list) < 0) throw std::runtime_error("getifaddrs() failed"); for (ifaddrs* ifa = ifa_list; ifa != 0; ifa = ifa->ifa_next) { shared_ptr netif; std::string ifname(ifa->ifa_name); InterfacesMap::iterator i = ifmap.find(ifname); if (i == ifmap.end()) { netif = make_shared(); netif->name = ifname; netif->flags = ifa->ifa_flags; ifmap[ifname] = netif; } else { netif = i->second; } if (!ifa->ifa_addr) continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: { const sockaddr_in* sin = reinterpret_cast(ifa->ifa_addr); char address[INET_ADDRSTRLEN]; if (::inet_ntop(AF_INET, &sin->sin_addr, address, sizeof(address))) netif->ipv4Addresses.push_back(boost::asio::ip::address_v4::from_string(address)); else NFD_LOG_WARN("inet_ntop() failed on " << ifname); } break; case AF_INET6: { const sockaddr_in6* sin6 = reinterpret_cast(ifa->ifa_addr); char address[INET6_ADDRSTRLEN]; if (::inet_ntop(AF_INET6, &sin6->sin6_addr, address, sizeof(address))) netif->ipv6Addresses.push_back(boost::asio::ip::address_v6::from_string(address)); else NFD_LOG_WARN("inet_ntop() failed on " << ifname); } break; #if defined(__linux__) case AF_PACKET: { const sockaddr_ll* sll = reinterpret_cast(ifa->ifa_addr); netif->index = sll->sll_ifindex; if (sll->sll_hatype == ARPHRD_ETHER && sll->sll_halen == ethernet::ADDR_LEN) netif->etherAddress = ethernet::Address(sll->sll_addr); else if (sll->sll_hatype != ARPHRD_LOOPBACK) NFD_LOG_WARN("Unrecognized hardware address on " << ifname); } break; #elif defined(__APPLE__) case AF_LINK: { const sockaddr_dl* sdl = reinterpret_cast(ifa->ifa_addr); netif->index = sdl->sdl_index; netif->etherAddress = ethernet::Address(reinterpret_cast(LLADDR(sdl))); } break; #endif } } ::freeifaddrs(ifa_list); std::list< shared_ptr > list; BOOST_FOREACH(InterfacesMap::value_type elem, ifmap) { list.push_back(elem.second); } return list; } } // namespace nfd