Go to the documentation of this file.00001
00002
00003
00004
00005
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
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
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
00159 sockaddr *addr = iter->ifa_addr;
00160
00161
00162 if ((f != vaddress::VADDRESS_UNSPEC) && (addr->sa_family != f)) continue;
00163
00164
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 }