|
IBR-DTNSuite 0.6
|
00001 /* 00002 * LinkManager.cpp 00003 * 00004 * Created on: 21.12.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include "ibrcommon/config.h" 00009 #include "ibrcommon/net/LinkManager.h" 00010 #include <list> 00011 #include <string> 00012 #include <typeinfo> 00013 00014 #ifdef HAVE_LIBNL 00015 #include "ibrcommon/net/NetLinkManager.h" 00016 #else 00017 #include <sys/types.h> 00018 #include <netinet/ip.h> 00019 #include <netinet/ip6.h> 00020 #include <arpa/inet.h> 00021 #include <sys/socket.h> 00022 00023 #include <stdlib.h> 00024 #include <net/if.h> 00025 #include <ifaddrs.h> 00026 #include <errno.h> 00027 #include <string.h> 00028 #endif 00029 00030 namespace ibrcommon 00031 { 00032 LinkManager& LinkManager::getInstance() 00033 { 00034 #ifdef HAVE_LIBNL 00035 static NetLinkManager lm; 00036 #else 00037 static DefaultLinkManager lm; 00038 #endif 00039 00040 return lm; 00041 } 00042 00043 void LinkManager::initialize() 00044 { 00045 #ifdef HAVE_LIBNL 00046 try { 00047 dynamic_cast<NetLinkManager&>(getInstance()).start(); 00048 } catch (const std::bad_cast&) { 00049 00050 } 00051 #endif 00052 } 00053 00054 DefaultLinkManager::DefaultLinkManager() 00055 { 00056 } 00057 00058 DefaultLinkManager::~DefaultLinkManager() 00059 { 00060 } 00061 00062 const std::string DefaultLinkManager::getInterface(int index) const 00063 { 00064 #ifdef HAVE_LIBNL 00065 throw ibrcommon::Exception("not implemented - use NetlinkManager instead"); 00066 #else 00067 struct ifaddrs *ifap = NULL; 00068 int status = getifaddrs(&ifap); 00069 int i = 0; 00070 std::string ret; 00071 00072 if ((status != 0) || (ifap == NULL)) 00073 { 00074 // error, return with default address 00075 throw ibrcommon::Exception("can not iterate through interfaces"); 00076 } 00077 00078 for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next, i++) 00079 { 00080 if (index == i) 00081 { 00082 ret = iter->ifa_name; 00083 break; 00084 } 00085 } 00086 00087 freeifaddrs(ifap); 00088 00089 return ret; 00090 #endif 00091 } 00092 00093 #ifndef HAVE_LIBNL 00094 char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen) 00095 { 00096 switch(sa->sa_family) { 00097 case AF_INET: 00098 inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), 00099 s, maxlen); 00100 break; 00101 00102 case AF_INET6: 00103 inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), 00104 s, maxlen); 00105 break; 00106 00107 default: 00108 strncpy(s, "Unknown AF", maxlen); 00109 return NULL; 00110 } 00111 00112 return s; 00113 } 00114 00115 int get_scope_id(struct sockaddr *sa) 00116 { 00117 switch(sa->sa_family) 00118 { 00119 case AF_INET6: 00120 { 00121 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 00122 return sin6->sin6_scope_id; 00123 } 00124 00125 case AF_INET: 00126 { 00127 return 0; 00128 } 00129 00130 default: 00131 { 00132 return 0; 00133 } 00134 } 00135 } 00136 #endif 00137 00138 const std::list<vaddress> DefaultLinkManager::getAddressList(const vinterface &iface, const vaddress::Family f) 00139 { 00140 std::list<vaddress> ret; 00141 00142 #ifndef HAVE_LIBNL 00143 struct ifaddrs *ifap = NULL; 00144 int status = getifaddrs(&ifap); 00145 int i = 0; 00146 00147 if ((status != 0) || (ifap == NULL)) 00148 { 00149 // error, return with default address 00150 throw ibrcommon::Exception("can not iterate through interfaces"); 00151 } 00152 00153 for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next, i++) 00154 { 00155 if (iter->ifa_addr == NULL) continue; 00156 if ((iter->ifa_flags & IFF_UP) == 0) continue; 00157 00158 // cast to a sockaddr 00159 sockaddr *addr = iter->ifa_addr; 00160 00161 // compare the address family 00162 if ((f != vaddress::VADDRESS_UNSPEC) && (addr->sa_family != f)) continue; 00163 00164 // check the name of the interface 00165 if (string(iter->ifa_name).compare(iface.toString()) != 0) continue; 00166 00167 char buf[INET6_ADDRSTRLEN+5]; 00168 char *name = get_ip_str(iter->ifa_addr, buf, INET6_ADDRSTRLEN+5); 00169 00170 if (name != NULL) 00171 { 00172 std::string name_str(name); 00173 if (get_scope_id(addr) == 0) 00174 { 00175 ret.push_back( 00176 vaddress(vaddress::Family(iter->ifa_addr->sa_family), name_str) 00177 ); 00178 } 00179 else 00180 { 00181 ret.push_back( 00182 vaddress(vaddress::Family(iter->ifa_addr->sa_family), name_str, i) 00183 ); 00184 } 00185 } 00186 00187 00188 } 00189 freeifaddrs(ifap); 00190 #endif 00191 00192 return ret; 00193 } 00194 }