Kea 2.2.0
iface_mgr_sun.cc
Go to the documentation of this file.
1// Copyright (C) 2011-2022 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>
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
22using namespace std;
23using namespace isc;
24using namespace isc::asiolink;
25using namespace isc::dhcp;
26
27namespace isc {
28namespace dhcp {
29
32void
33IfaceMgr::detectIfaces(bool update_only) {
34 if (isTestMode() && update_only) {
35 return;
36 }
37
38 struct ifaddrs* iflist = 0;// The whole interface list
39 struct ifaddrs* ifptr = 0; // The interface we're processing now
40
41 // Gets list of ifaddrs struct
42 if (getifaddrs(&iflist) != 0) {
43 isc_throw(Unexpected, "Network interfaces detection failed.");
44 }
45
46 typedef map<string, IfacePtr> IfaceLst;
47 IfaceLst::iterator iface_iter;
48 IfaceLst ifaces;
49
50 // First lookup for getting interfaces ...
51 for (ifptr = iflist; ifptr != 0; ifptr = ifptr->ifa_next) {
52 const char * ifname = ifptr->ifa_name;
53 uint ifindex = 0;
54
55 if (!(ifindex = if_nametoindex(ifname))) {
56 // Interface name does not have corresponding index ...
57 freeifaddrs(iflist);
58 isc_throw(Unexpected, "Interface " << ifname << " has no index");
59 }
60
61 iface_iter = ifaces.find(ifname);
62 if (iface_iter != ifaces.end()) {
63 continue;
64 }
65
66 IfacePtr iface;
67 if (update_only) {
68 iface = getIface(ifname);
69 }
70 if (!iface) {
71 iface.reset(new Iface(ifname, ifindex));
72 }
73 iface->setFlags(ifptr->ifa_flags);
74 ifaces.insert(pair<string, IfacePtr>(ifname, iface));
75 }
76
77 // Second lookup to get MAC and IP addresses
78 for (ifptr = iflist; ifptr != 0; ifptr = ifptr->ifa_next) {
79 iface_iter = ifaces.find(ifptr->ifa_name);
80 if (iface_iter == ifaces.end()) {
81 continue;
82 }
83 // Common byte pointer for following data
84 const uint8_t * ptr = 0;
85 if (ifptr->ifa_addr->sa_family == AF_LINK) {
86 // HWAddr
87 struct sockaddr_dl * ldata =
88 reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_addr);
89 ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));
90
91 iface_iter->second->setHWType(ldata->sdl_type);
92 iface_iter->second->setMac(ptr, ldata->sdl_alen);
93 } else if (ifptr->ifa_addr->sa_family == AF_INET6) {
94 // IPv6 Addr
95 struct sockaddr_in6 * adata =
96 reinterpret_cast<struct sockaddr_in6 *>(ifptr->ifa_addr);
97 ptr = reinterpret_cast<uint8_t *>(&adata->sin6_addr);
98
99 IOAddress a = IOAddress::fromBytes(AF_INET6, ptr);
100 iface_iter->second->addAddress(a);
101 } else {
102 // IPv4 Addr
103 struct sockaddr_in * adata =
104 reinterpret_cast<struct sockaddr_in *>(ifptr->ifa_addr);
105 ptr = reinterpret_cast<uint8_t *>(&adata->sin_addr);
106
107 IOAddress a = IOAddress::fromBytes(AF_INET, ptr);
108 iface_iter->second->addAddress(a);
109 }
110 }
111
112 freeifaddrs(iflist);
113
114 // Interfaces registering
115 for (IfaceLst::const_iterator iface_iter = ifaces.begin();
116 iface_iter != ifaces.end(); ++iface_iter) {
117 IfacePtr iface;
118 if (update_only) {
119 iface = getIface(iface_iter->first);
120 }
121 if (!iface) {
122 addInterface(iface_iter->second);
123 }
124 }
125}
126
132void Iface::setFlags(uint64_t flags) {
133 flags_ = flags;
134
135 flag_loopback_ = flags & IFF_LOOPBACK;
136 flag_up_ = flags & IFF_UP;
137 flag_running_ = flags & IFF_RUNNING;
138 flag_multicast_ = flags & IFF_MULTICAST;
139 flag_broadcast_ = flags & IFF_BROADCAST;
140}
141
142void
143IfaceMgr::setMatchingPacketFilter(const bool /* direct_response_desired */) {
144 // @todo Currently we ignore the preference to use direct traffic
145 // because it hasn't been implemented for Solaris.
147}
148
149bool
150IfaceMgr::openMulticastSocket(Iface& iface,
151 const isc::asiolink::IOAddress& addr,
152 const uint16_t port,
153 IfaceMgrErrorMsgCallback error_handler) {
154 try {
155 // This should open a socket, bind it to link-local address
156 // and join multicast group.
157 openSocket(iface.getName(), addr, port, iface.flag_multicast_);
158
159 } catch (const Exception& ex) {
160 IFACEMGR_ERROR(SocketConfigError, error_handler, IfacePtr(),
161 "Failed to open link-local socket on "
162 "interface " << iface.getName() << ": "
163 << ex.what());
164 return (false);
165
166 }
167 return (true);
168}
169
170int
171IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port,
172 const bool join_multicast) {
173 // On Solaris, we bind the socket to in6addr_any and join multicast group
174 // to receive multicast traffic. So, if the multicast is requested,
175 // replace the address specified by the caller with the "unspecified"
176 // address.
177 IOAddress actual_address = join_multicast ? IOAddress("::") : addr;
178 SocketInfo info = packet_filter6_->openSocket(iface, actual_address, port,
179 join_multicast);
180 iface.addSocket(info);
181 return (info.sockfd_);
182}
183
184} // end of isc::dhcp namespace
185} // end of dhcp namespace
186
187#endif
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
int openSocket(const std::string &ifname, const isc::asiolink::IOAddress &addr, const uint16_t port, const bool receive_bcast=false, const bool send_bcast=false)
Opens UDP/IP socket and binds it to address, interface and port.
Definition: iface_mgr.cc:958
void setPacketFilter(const PktFilterPtr &packet_filter)
Set packet filter object to handle sending and receiving DHCPv4 messages.
Definition: iface_mgr.cc:389
void detectIfaces(bool update_only=false)
Detects network interfaces.
int openSocket6(Iface &iface, const isc::asiolink::IOAddress &addr, uint16_t port, const bool join_multicast)
Opens IPv6 socket.
bool isTestMode() const
Checks if the IfaceMgr is in the test mode.
Definition: iface_mgr.h:722
void addInterface(const IfacePtr &iface)
Adds an interface to list of known interfaces.
Definition: iface_mgr.cc:798
IfacePtr getIface(int ifindex)
Returns interface specified interface index.
Definition: iface_mgr.cc:902
void setMatchingPacketFilter(const bool direct_response_desired=false)
Set Packet Filter object to handle send/receive packets.
Represents a single network interface.
Definition: iface_mgr.h:118
uint64_t flags_
Interface flags (this value is as is returned by OS, it may mean different things on different OSes).
Definition: iface_mgr.h:460
bool flag_multicast_
Flag specifies if selected interface is multicast capable.
Definition: iface_mgr.h:451
std::string getName() const
Returns interface name.
Definition: iface_mgr.h:224
void setFlags(uint64_t flags)
Sets flag_*_ fields based on bitmask value returned by OS.
bool flag_running_
Flag specifies if selected interface is running (e.g.
Definition: iface_mgr.h:448
bool flag_loopback_
Specifies if selected interface is loopback.
Definition: iface_mgr.h:441
void addSocket(const SocketInfo &sock)
Adds socket descriptor to an interface.
Definition: iface_mgr.h:321
bool flag_up_
Specifies if selected interface is up.
Definition: iface_mgr.h:444
bool flag_broadcast_
Flag specifies if selected interface is broadcast capable.
Definition: iface_mgr.h:454
Packet handling class using AF_INET socket family.
IfaceMgr exception thrown thrown when socket opening or configuration failed.
Definition: iface_mgr.h:63
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define IFACEMGR_ERROR(ex_type, handler, iface, stream)
A macro which handles an error in IfaceMgr.
@ info
Definition: db_log.h:117
boost::shared_ptr< PktFilter > PktFilterPtr
Pointer to a PktFilter object.
Definition: pkt_filter.h:134
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
Definition: iface_mgr.h:487
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:648
Defines the logger used by the top-level component of kea-lfc.
Holds information about socket.
Definition: socket_info.h:19