IBR-DTNSuite  0.10
PosixLinkManager.cpp
Go to the documentation of this file.
1 /*
2  * PosixLinkManager.cpp
3  *
4  * Created on: 11.10.2012
5  * Author: morgenro
6  */
7 
8 #include "ibrcommon/config.h"
10 
11 #include <string>
12 #include <typeinfo>
13 
14 #include <sys/types.h>
15 #include <netinet/ip.h>
16 #include <netinet/ip6.h>
17 #include <arpa/inet.h>
18 #include <sys/socket.h>
19 
20 #include <stdlib.h>
21 #include <net/if.h>
22 #include <ifaddrs.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <netdb.h>
26 
27 namespace ibrcommon
28 {
30  {
31  }
32 
34  {
35  }
36 
38  {
39  struct ifaddrs *ifap = NULL;
40  int status = getifaddrs(&ifap);
41  int i = 0;
42  std::string ret;
43 
44  if ((status != 0) || (ifap == NULL))
45  {
46  // error, return with default address
47  throw ibrcommon::Exception("can not iterate through interfaces");
48  }
49 
50  for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next, i++)
51  {
52  if (index == i)
53  {
54  ret = iter->ifa_name;
55  break;
56  }
57  }
58 
59  freeifaddrs(ifap);
60 
61  return ret;
62  }
63 
64  const std::list<vaddress> PosixLinkManager::getAddressList(const vinterface &iface, const std::string &scope)
65  {
66  std::list<vaddress> ret;
67 
68  struct ifaddrs *ifap = NULL;
69  int status = getifaddrs(&ifap);
70  int i = 0;
71 
72  if ((status != 0) || (ifap == NULL))
73  {
74  // error, return with default address
75  throw ibrcommon::Exception("can not iterate through interfaces");
76  }
77 
78  for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next, i++)
79  {
80  if (iter->ifa_addr == NULL) continue;
81  if ((iter->ifa_flags & IFF_UP) == 0) continue;
82 
83  // get the interface name
84  vinterface interface(iter->ifa_name);
85 
86  // skip all non-matching interfaces
87  if (interface != iface) continue;
88 
89  // cast to a sockaddr
90  sockaddr *ifaceaddr = iter->ifa_addr;
91 
92  if (scope.length() > 0) {
93  // scope filter only available with IPv6
94  if (ifaceaddr->sa_family == AF_INET6) {
95  // get ipv6 specific address
96  sockaddr_in6 *addr6 = (sockaddr_in6*)ifaceaddr;
97 
98  // if the id is set, then this scope is link-local
99  if (addr6->sin6_scope_id == 0) {
100  if (scope != vaddress::SCOPE_GLOBAL) continue;
101  } else {
102  if (scope != vaddress::SCOPE_LINKLOCAL) continue;
103  }
104  }
105  }
106 
107  char address[256];
108  if (::getnameinfo((struct sockaddr *) ifaceaddr, sizeof (struct sockaddr_storage), address, sizeof address, 0, 0, NI_NUMERICHOST) == 0) {
109  ret.push_back( vaddress(std::string(address), "", ifaceaddr->sa_family) );
110  }
111  }
112  freeifaddrs(ifap);
113 
114  return ret;
115  }
116 
117 } /* namespace ibrcommon */