Kea  1.9.9-git
iface_mgr_sun.cc
Go to the documentation of this file.
1 // Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #if defined(OS_SUN)
10 
11 #include <dhcp/iface_mgr.h>
13 #include <dhcp/pkt_filter_inet.h>
14 #include <exceptions/exceptions.h>
15 
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <net/if_dl.h>
19 #include <net/if.h>
20 #include <ifaddrs.h>
21 
22 using namespace std;
23 using namespace isc;
24 using namespace isc::asiolink;
25 using namespace isc::dhcp;
26 
27 namespace isc {
28 namespace dhcp {
29 
32 void
33 IfaceMgr::detectIfaces() {
34  struct ifaddrs* iflist = 0;// The whole interface list
35  struct ifaddrs* ifptr = 0; // The interface we're processing now
36 
37  // Gets list of ifaddrs struct
38  if(getifaddrs(&iflist) != 0) {
39  isc_throw(Unexpected, "Network interfaces detection failed.");
40  }
41 
42  typedef map<string, IfacePtr> IfaceLst;
43  IfaceLst::iterator iface_iter;
44  IfaceLst ifaces;
45 
46  // First lookup for getting interfaces ...
47  for (ifptr = iflist; ifptr != 0; ifptr = ifptr->ifa_next) {
48  const char * ifname = ifptr->ifa_name;
49  uint ifindex = 0;
50 
51  if (!(ifindex = if_nametoindex(ifname))) {
52  // Interface name does not have corresponding index ...
53  freeifaddrs(iflist);
54  isc_throw(Unexpected, "Interface " << ifname << " has no index");
55  }
56 
57  iface_iter = ifaces.find(ifname);
58  if (iface_iter != ifaces.end()) {
59  continue;
60  }
61 
62  IfacePtr iface(new Iface(ifname, ifindex));
63  iface->setFlags(ifptr->ifa_flags);
64  ifaces.insert(pair<string, IfacePtr>(ifname, iface));
65  }
66 
67  // Second lookup to get MAC and IP addresses
68  for (ifptr = iflist; ifptr != 0; ifptr = ifptr->ifa_next) {
69  iface_iter = ifaces.find(ifptr->ifa_name);
70  if (iface_iter == ifaces.end()) {
71  continue;
72  }
73  // Common byte pointer for following data
74  const uint8_t * ptr = 0;
75  if(ifptr->ifa_addr->sa_family == AF_LINK) {
76  // HWAddr
77  struct sockaddr_dl * ldata =
78  reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_addr);
79  ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));
80 
81  iface_iter->second->setHWType(ldata->sdl_type);
82  iface_iter->second->setMac(ptr, ldata->sdl_alen);
83  } else if(ifptr->ifa_addr->sa_family == AF_INET6) {
84  // IPv6 Addr
85  struct sockaddr_in6 * adata =
86  reinterpret_cast<struct sockaddr_in6 *>(ifptr->ifa_addr);
87  ptr = reinterpret_cast<uint8_t *>(&adata->sin6_addr);
88 
89  IOAddress a = IOAddress::fromBytes(AF_INET6, ptr);
90  iface_iter->second->addAddress(a);
91  } else {
92  // IPv4 Addr
93  struct sockaddr_in * adata =
94  reinterpret_cast<struct sockaddr_in *>(ifptr->ifa_addr);
95  ptr = reinterpret_cast<uint8_t *>(&adata->sin_addr);
96 
97  IOAddress a = IOAddress::fromBytes(AF_INET, ptr);
98  iface_iter->second->addAddress(a);
99  }
100  }
101 
102  freeifaddrs(iflist);
103 
104  // Interfaces registering
105  for(IfaceLst::const_iterator iface_iter = ifaces.begin();
106  iface_iter != ifaces.end(); ++iface_iter) {
107  addInterface(iface_iter->second);
108  }
109 }
110 
116 void Iface::setFlags(uint64_t flags) {
117  flags_ = flags;
118 
119  flag_loopback_ = flags & IFF_LOOPBACK;
120  flag_up_ = flags & IFF_UP;
121  flag_running_ = flags & IFF_RUNNING;
122  flag_multicast_ = flags & IFF_MULTICAST;
123  flag_broadcast_ = flags & IFF_BROADCAST;
124 }
125 
126 void
127 IfaceMgr::setMatchingPacketFilter(const bool /* direct_response_desired */) {
128  // @todo Currently we ignore the preference to use direct traffic
129  // because it hasn't been implemented for Solaris.
130  setPacketFilter(PktFilterPtr(new PktFilterInet()));
131 }
132 
133 bool
134 IfaceMgr::openMulticastSocket(Iface& iface,
135  const isc::asiolink::IOAddress& addr,
136  const uint16_t port,
137  IfaceMgrErrorMsgCallback error_handler) {
138  try {
139  // This should open a socket, bound it to link-local address
140  // and join multicast group.
141  openSocket(iface.getName(), addr, port,
142  iface.flag_multicast_);
143 
144  } catch (const Exception& ex) {
145  IFACEMGR_ERROR(SocketConfigError, error_handler,
146  "Failed to open link-local socket on "
147  " interface " << iface.getName() << ": "
148  << ex.what());
149  return (false);
150 
151  }
152  return (true);
153 }
154 
155 int
156 IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port,
157  const bool join_multicast) {
158  IOAddress actual_address = join_multicast ? IOAddress("::") : addr;
159  SocketInfo info = packet_filter6_->openSocket(iface, actual_address, port,
160  join_multicast);
161  iface.addSocket(info);
162  return (info.sockfd_);
163 }
164 
165 } // end of isc::dhcp namespace
166 } // end of dhcp namespace
167 
168 #endif
IfaceMgr exception thrown thrown when socket opening or configuration failed.
Definition: iface_mgr.h:63
void addSocket(const SocketInfo &sock)
Adds socket descriptor to an interface.
Definition: iface_mgr.h:318
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
Definition: iface_mgr.h:463
STL namespace.
std::function< void(const std::string &errmsg)> IfaceMgrErrorMsgCallback
This type describes the callback function invoked when error occurs in the IfaceMgr.
Definition: iface_mgr.h:624
Packet handling class using AF_INET socket family.
Represents a single network interface.
Definition: iface_mgr.h:118
boost::shared_ptr< PktFilter > PktFilterPtr
Pointer to a PktFilter object.
Definition: pkt_filter.h:134
int sockfd_
IPv4 or IPv6.
Definition: socket_info.h:26
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
bool flag_multicast_
Flag specifies if selected interface is multicast capable.
Definition: iface_mgr.h:435
A generic exception that is thrown when an unexpected error condition occurs.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
std::string getName() const
Returns interface name.
Definition: iface_mgr.h:221
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
#define IFACEMGR_ERROR(ex_type, handler, stream)
A macro which handles an error in IfaceMgr.
Holds information about socket.
Definition: socket_info.h:19