IBR-DTNSuite  0.12
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  down();
36  }
37 
38  void PosixLinkManager::up() throw()
39  {
40  _lm.start();
41  }
42 
43  void PosixLinkManager::down() throw()
44  {
45  _lm.stop();
46  _lm.join();
47  }
48 
50  {
51  struct ifaddrs *ifap = NULL;
52  int status = getifaddrs(&ifap);
53  int i = 0;
54  std::string ret;
55 
56  if ((status != 0) || (ifap == NULL))
57  {
58  // error, return with default address
59  throw ibrcommon::Exception("can not iterate through interfaces");
60  }
61 
62  for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next, i++)
63  {
64  if (index == i)
65  {
66  ret = iter->ifa_name;
67  break;
68  }
69  }
70 
71  freeifaddrs(ifap);
72 
73  return ret;
74  }
75 
76  const std::list<vaddress> PosixLinkManager::getAddressList(const vinterface &iface, const std::string &scope)
77  {
78  std::list<vaddress> ret;
79 
80  struct ifaddrs *ifap = NULL;
81  int status = getifaddrs(&ifap);
82  int i = 0;
83 
84  if ((status != 0) || (ifap == NULL))
85  {
86  // error, return with default address
87  throw ibrcommon::Exception("can not iterate through interfaces");
88  }
89 
90  for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next, i++)
91  {
92  if (iter->ifa_addr == NULL) continue;
93  if ((iter->ifa_flags & IFF_UP) == 0) continue;
94 
95  // get the interface name
96  vinterface interface(iter->ifa_name);
97 
98  // skip all non-matching interfaces
99  if (interface != iface) continue;
100 
101  // cast to a sockaddr
102  sockaddr *ifaceaddr = iter->ifa_addr;
103 
104  if (scope.length() > 0) {
105  // scope filter only available with IPv6
106  if (ifaceaddr->sa_family == AF_INET6) {
107  // get ipv6 specific address
108  sockaddr_in6 *addr6 = (sockaddr_in6*)ifaceaddr;
109 
110  // if the id is set, then this scope is link-local
111  if (addr6->sin6_scope_id == 0) {
112  if (scope != vaddress::SCOPE_GLOBAL) continue;
113  } else {
114  if (scope != vaddress::SCOPE_LINKLOCAL) continue;
115  }
116  }
117  }
118 
119  char address[256];
120  if (::getnameinfo((struct sockaddr *) ifaceaddr, sizeof (struct sockaddr_storage), address, sizeof address, 0, 0, NI_NUMERICHOST) == 0) {
121  ret.push_back( vaddress(std::string(address), "", ifaceaddr->sa_family) );
122  }
123  }
124  freeifaddrs(ifap);
125 
126  return ret;
127  }
128 
130  {
131  // initialize LinkManager with new listened interface
132  _lm.add(iface);
133 
134  // call super-method
136  }
137 
139  {
140  // call super-method
142 
143  // remove no longer monitored interfaces
144  _lm.remove();
145  }
146 
148  {
149  // call super-method
151 
152  // remove no longer monitored interfaces
153  _lm.remove();
154  }
155 } /* namespace ibrcommon */