IBR-DTNSuite 0.6

ibrcommon/ibrcommon/net/LinkManager.cpp

Go to the documentation of this file.
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 }