21 #include <boost/scoped_ptr.hpp>
30 #include <arpa/inet.h>
31 #include <netinet/in.h>
33 #include <sys/ioctl.h>
34 #include <sys/select.h>
37 #define FD_COPY(orig, copy) \
39 memmove(copy, orig, sizeof(fd_set)); \
53 IfaceMgr::instance() {
54 return (*instancePtr());
58 IfaceMgr::instancePtr() {
63 Iface::Iface(
const std::string& name,
unsigned int ifindex)
64 :
name_(name), ifindex_(ifindex), mac_len_(0), hardware_type_(0),
65 flag_loopback_(false), flag_up_(false), flag_running_(false),
66 flag_multicast_(false), flag_broadcast_(false), flags_(0),
67 inactive4_(false), inactive6_(false)
95 if ((family != AF_INET) && (family != AF_INET6)) {
97 <<
" specified when requested to close all sockets"
98 <<
" which belong to this family");
102 SocketCollection::iterator sock =
sockets_.begin();
104 if (sock->family_ == family) {
107 close(sock->sockfd_);
109 if (sock->fallbackfd_ >= 0) {
110 close(sock->fallbackfd_);
135 for (
int i = 0; i <
mac_len_; i++) {
137 tmp << static_cast<int>(
mac_[i]);
138 if (i < mac_len_-1) {
148 <<
" was detected to have link address of length "
149 << len <<
", but maximum supported length is "
154 memcpy(
mac_, mac, len);
159 for (AddressCollection::iterator a =
addrs_.begin();
161 if (a->get() == addr) {
170 list<SocketInfo>::iterator sock =
sockets_.begin();
172 if (sock->sockfd_ == sockfd) {
175 if (sock->fallbackfd_ >= 0) {
176 close(sock->fallbackfd_);
190 allow_loopback_(false) {
197 }
catch (
const std::exception& ex) {
208 }
catch (
const std::exception& ex) {
215 if (a.get() == addr) {
217 <<
" already defined on the " <<
name_ <<
" interface.");
230 if (addr.get().isV4()) {
231 address = addr.get();
242 if (address == addr.get()) {
256 for (AddressCollection::iterator addr_it =
addrs_.begin();
257 addr_it !=
addrs_.end(); ++addr_it) {
258 if (address == addr_it->get()) {
259 addr_it->unspecified(!active);
264 " found on the interface " <<
getName());
269 for (AddressCollection::iterator addr_it =
addrs_.begin();
270 addr_it !=
addrs_.end(); ++addr_it) {
271 addr_it->unspecified(!active);
279 if (!addr.unspecified() && addr.get().isV4()) {
294 iface->closeSockets();
300 dhcp_receiver_->stop();
303 dhcp_receiver_.reset();
320 return (packet_filter_->isDirectResponseSupported());
329 std::lock_guard<std::mutex> lock(callbacks_mutex_);
333 if (s.socket_ == socketfd) {
334 s.callback_ = callback;
343 callbacks_.push_back(x);
348 std::lock_guard<std::mutex> lock(callbacks_mutex_);
349 deleteExternalSocketInternal(socketfd);
353 IfaceMgr::deleteExternalSocketInternal(
int socketfd) {
354 for (SocketCallbackInfoContainer::iterator s = callbacks_.begin();
355 s != callbacks_.end(); ++s) {
356 if (s->socket_ == socketfd) {
365 std::lock_guard<std::mutex> lock(callbacks_mutex_);
366 std::vector<int> bad_fds;
369 if (fcntl(s.socket_, F_GETFD) < 0 && (errno == EBADF)) {
370 bad_fds.push_back(s.socket_);
374 for (
auto bad_fd : bad_fds) {
375 deleteExternalSocketInternal(bad_fd);
378 return (bad_fds.size());
383 std::lock_guard<std::mutex> lock(callbacks_mutex_);
390 if (!packet_filter) {
403 "it is not allowed to set new packet"
404 <<
" filter when there are open IPv4 sockets - need"
405 <<
" to close them first");
408 packet_filter_ = packet_filter;
413 if (!packet_filter) {
421 "it is not allowed to set new packet"
422 <<
" filter when there are open IPv6 sockets - need"
423 <<
" to close them first");
426 packet_filter6_ = packet_filter;
435 if (sock.family_ == family) {
456 if (sock.addr_ == addr) {
458 }
else if (sock.addr_.isV6Zero()) {
465 if (addr == a.get()) {
481 const string v4addr(
"127.0.0.1"), v6addr(
"::1");
487 if (if_nametoindex(
"lo") > 0) {
490 }
else if (if_nametoindex(
"lo0") > 0) {
496 "Interface detection on this OS is not supported.");
499 IfacePtr iface(
new Iface(ifaceName, if_nametoindex(ifaceName.c_str())));
500 iface->flag_up_ =
true;
501 iface->flag_running_ =
true;
507 iface->flag_loopback_ =
false;
508 iface->flag_multicast_ =
true;
509 iface->flag_broadcast_ =
true;
510 iface->setHWType(HWTYPE_ETHERNET);
526 if (iface->inactive4_) {
537 if (iface->flag_loopback_ && !allow_loopback_) {
539 "must not open socket on the loopback"
540 " interface " << iface->getName());
545 if (!iface->flag_up_) {
547 "the interface " << iface->getName()
552 if (!iface->flag_running_) {
554 "the interface " << iface->getName()
555 <<
" is not running");
560 if (!iface->getAddress4(out_address)) {
562 "the interface " << iface->getName()
563 <<
" has no usable IPv4 addresses configured");
570 if (addr.unspecified() || !addr.get().isV4()) {
577 if (iface->flag_broadcast_ && use_bcast) {
593 "Binding socket to an interface is not"
594 " supported on this OS; therefore only"
595 " one socket listening to broadcast traffic"
596 " can be opened. Sockets will not be opened"
597 " on remaining interfaces");
604 openSocket(iface->getName(), addr.get(), port,
true,
true);
607 "failed to open socket on interface "
608 << iface->getName() <<
", reason: "
622 openSocket(iface->getName(), addr.get(), port,
false,
false);
625 "failed to open socket on interface "
626 << iface->getName() <<
", reason: "
655 if (iface->inactive6_) {
666 if (iface->flag_loopback_ && !allow_loopback_) {
668 "must not open socket on the loopback"
669 " interface " << iface->getName());
672 }
else if (!iface->flag_up_) {
674 "the interface " << iface->getName()
677 }
else if (!iface->flag_running_) {
679 "the interface " << iface->getName()
680 <<
" is not running");
693 "Failed to open unicast socket on interface "
694 << iface->getName() <<
", reason: "
706 if (!addr.get().isV6()) {
715 if (!addr.get().isV6LinkLocal()){
722 if (openMulticastSocket(*iface, addr, port, error_handler)) {
752 dhcp_receiver_->start(std::bind(&IfaceMgr::receiveDHCP4Packets,
this));
762 dhcp_receiver_->start(std::bind(&IfaceMgr::receiveDHCP6Packets,
this));
773 if ((existing->getName() == iface->getName()) ||
774 (existing->getIndex() == iface->getIndex())) {
776 " when " << existing->getFullName() <<
780 ifaces_.push_back(iface);
788 out <<
"Detected interface " << iface->getFullName()
789 <<
", hwtype=" << iface->getHWType()
790 <<
", mac=" << iface->getPlainMac();
791 out <<
", flags=" << hex << iface->flags_ << dec <<
"("
792 << (iface->flag_loopback_?
"LOOPBACK ":
"")
793 << (iface->flag_up_?
"UP ":
"")
794 << (iface->flag_running_?
"RUNNING ":
"")
795 << (iface->flag_multicast_?
"MULTICAST ":
"")
796 << (iface->flag_broadcast_?
"BROADCAST ":
"")
798 out <<
" " << addrs.size() <<
" addr(s):";
801 out <<
" " << addr.get().toText();
809 return (getIfaceInternal(ifindex, MultiThreadingMgr::instance().getMode()));
815 return (getIfaceInternal(ifname, MultiThreadingMgr::instance().getMode()));
819 IfaceCollection::getIfaceInternal(uint32_t ifindex,
bool need_lock) {
821 lock_guard<mutex> lock(mutex_);
822 if (cache_ && (cache_->getIndex() == ifindex)) {
826 if (cache_ && (cache_->getIndex() == ifindex)) {
830 const auto& idx = ifaces_container_.get<1>();
831 auto it = idx.find(ifindex);
832 if (it == idx.end()) {
836 lock_guard<mutex> lock(mutex_);
840 lock_guard<mutex> lock(mutex_);
847 IfaceCollection::getIfaceInternal(
const std::string& ifname,
bool need_lock) {
849 lock_guard<mutex> lock(mutex_);
850 if (cache_ && (cache_->getName() == ifname)) {
854 if (cache_ && (cache_->getName() == ifname)) {
858 const auto& idx = ifaces_container_.get<2>();
859 auto it = idx.find(ifname);
860 if (it == idx.end()) {
864 lock_guard<mutex> lock(mutex_);
868 lock_guard<mutex> lock(mutex_);
876 if ((ifindex < 0) || (ifindex > std::numeric_limits<int32_t>::max())) {
884 if (ifname.empty()) {
892 if (pkt->indexSet()) {
927 iface->clearUnicasts();
932 const uint16_t port,
const bool receive_bcast,
933 const bool send_bcast) {
939 return openSocket4(*iface, addr, port, receive_bcast, send_bcast);
941 }
else if (addr.
isV6()) {
942 return openSocket6(*iface, addr, port, receive_bcast);
952 const uint8_t family) {
955 if ((iface->getFullName() != ifname) &&
956 (iface->getName() != ifname)) {
963 Iface::AddressCollection::iterator addr_it = addrs.begin();
964 while (addr_it != addrs.end()) {
965 if (addr_it->get().getFamily() == family) {
968 return (
openSocket(iface->getName(), *addr_it, port,
false));
974 if (addr_it == addrs.end()) {
976 std::string family_name(
"AF_INET");
977 if (family == AF_INET6) {
978 family_name =
"AF_INET6";
982 << ifname <<
", port: " << port <<
", address "
983 " family: " << family_name);
992 const uint16_t port) {
1002 if (a.get() == addr) {
1005 return (
openSocket(iface->getName(), a, port,
false));
1015 const uint16_t port) {
1018 IOAddress local_address(getLocalAddress(remote_addr, port));
1026 IfaceMgr::getLocalAddress(
const IOAddress& remote_addr,
const uint16_t port) {
1028 boost::scoped_ptr<const UDPEndpoint>
1029 remote_endpoint(static_cast<const UDPEndpoint*>
1031 if (!remote_endpoint) {
1036 boost::asio::io_service io_service;
1037 boost::asio::ip::udp::socket sock(io_service);
1039 boost::system::error_code err_code;
1042 if (remote_addr.
isV4() &&
1055 sock.open(boost::asio::ip::udp::v4(), err_code);
1057 const char* errstr = strerror(errno);
1061 sock.set_option(boost::asio::socket_base::broadcast(
true), err_code);
1064 isc_throw(Unexpected,
"failed to enable broadcast on the socket");
1069 sock.connect(remote_endpoint->getASIOEndpoint(), err_code);
1072 isc_throw(Unexpected,
"failed to connect to remote endpoint.");
1076 boost::asio::ip::udp::socket::endpoint_type local_endpoint =
1077 sock.local_endpoint();
1078 boost::asio::ip::address local_address(local_endpoint.address());
1089 const uint16_t port,
const bool receive_bcast,
1090 const bool send_bcast) {
1094 receive_bcast, send_bcast);
1105 << pkt->getIface() <<
") specified.");
1110 return (packet_filter6_->send(*iface,
getSocket(pkt), pkt) == 0);
1118 << pkt->getIface() <<
") specified.");
1123 return (packet_filter_->send(*iface,
getSocket(pkt).sockfd_, pkt) == 0);
1136 if (timeout_usec >= 1000000) {
1138 " one million microseconds");
1148 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1149 if (!callbacks_.empty()) {
1158 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::READY), maxfd, &sockets);
1169 struct timeval select_timeout;
1171 select_timeout.tv_sec = timeout_sec;
1172 select_timeout.tv_usec = timeout_usec;
1174 select_timeout.tv_sec = 0;
1175 select_timeout.tv_usec = 0;
1181 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1186 }
else if (result < 0) {
1194 if (errno == EINTR) {
1196 }
else if (errno == EBADF) {
1199 "SELECT interrupted by one invalid sockets, purged "
1200 << cnt <<
" socket descriptors");
1210 string msg = dhcp_receiver_->getLastError();
1219 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1221 if (!FD_ISSET(s.socket_, &sockets)) {
1250 dhcp_receiver_->clearReady(WatchedThread::READY);
1258 if (timeout_usec >= 1000000) {
1260 " one million microseconds");
1262 boost::scoped_ptr<SocketInfo> candidate;
1274 if (s.addr_.isV4()) {
1283 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1284 if (!callbacks_.empty()) {
1292 struct timeval select_timeout;
1293 select_timeout.tv_sec = timeout_sec;
1294 select_timeout.tv_usec = timeout_usec;
1299 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1305 }
else if (result < 0) {
1313 if (errno == EINTR) {
1315 }
else if (errno == EBADF) {
1318 "SELECT interrupted by one invalid sockets, purged "
1319 << cnt <<
" socket descriptors");
1329 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1331 if (!FD_ISSET(s.socket_, &sockets)) {
1360 if (FD_ISSET(s.sockfd_, &sockets)) {
1371 if (!candidate || !recv_if) {
1377 return (packet_filter_->receive(*recv_if, *candidate));
1395 FD_SET(fd, sockets);
1404 if (timeout_usec >= 1000000) {
1406 " one million microseconds");
1409 boost::scoped_ptr<SocketInfo> candidate;
1421 if (s.addr_.isV6()) {
1430 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1431 if (!callbacks_.empty()) {
1439 struct timeval select_timeout;
1440 select_timeout.tv_sec = timeout_sec;
1441 select_timeout.tv_usec = timeout_usec;
1446 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1452 }
else if (result < 0) {
1460 if (errno == EINTR) {
1462 }
else if (errno == EBADF) {
1465 "SELECT interrupted by one invalid sockets, purged "
1466 << cnt <<
" socket descriptors");
1476 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1478 if (!FD_ISSET(s.socket_, &sockets)) {
1506 if (FD_ISSET(s.sockfd_, &sockets)) {
1520 return (packet_filter6_->receive(*candidate));
1526 if (timeout_usec >= 1000000) {
1528 " one million microseconds");
1538 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1539 if (!callbacks_.empty()) {
1548 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::READY), maxfd, &sockets);
1559 struct timeval select_timeout;
1561 select_timeout.tv_sec = timeout_sec;
1562 select_timeout.tv_usec = timeout_usec;
1564 select_timeout.tv_sec = 0;
1565 select_timeout.tv_usec = 0;
1571 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1576 }
else if (result < 0) {
1584 if (errno == EINTR) {
1586 }
else if (errno == EBADF) {
1589 "SELECT interrupted by one invalid sockets, purged "
1590 << cnt <<
" socket descriptors");
1600 string msg = dhcp_receiver_->getLastError();
1609 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1611 if (!FD_ISSET(s.socket_, &sockets)) {
1640 dhcp_receiver_->clearReady(WatchedThread::READY);
1647 IfaceMgr::receiveDHCP4Packets() {
1654 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::TERMINATE), maxfd, &sockets);
1660 if (s.addr_.isV4()) {
1669 if (dhcp_receiver_->shouldTerminate()) {
1680 int result = select(maxfd + 1, &rd_set, 0, 0, 0);
1683 if (dhcp_receiver_->shouldTerminate()) {
1691 }
else if (result < 0) {
1693 if (errno != EINTR) {
1695 dhcp_receiver_->setError(strerror(errno));
1706 for (SocketInfo s : iface->getSockets()) {
1707 if (FD_ISSET(s.sockfd_, &sockets)) {
1708 receiveDHCP4Packet(*iface, s);
1710 if (dhcp_receiver_->shouldTerminate()) {
1721 IfaceMgr::receiveDHCP6Packets() {
1728 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::TERMINATE), maxfd, &sockets);
1732 for (SocketInfo s : iface->getSockets()) {
1734 if (s.addr_.isV6()) {
1743 if (dhcp_receiver_->shouldTerminate()) {
1754 int result = select(maxfd + 1, &rd_set, 0, 0, 0);
1757 if (dhcp_receiver_->shouldTerminate()) {
1764 }
else if (result < 0) {
1766 if (errno != EINTR) {
1768 dhcp_receiver_->setError(strerror(errno));
1779 for (SocketInfo s : iface->getSockets()) {
1780 if (FD_ISSET(s.sockfd_, &sockets)) {
1781 receiveDHCP6Packet(s);
1783 if (dhcp_receiver_->shouldTerminate()) {
1793 IfaceMgr::receiveDHCP4Packet(Iface& iface,
const SocketInfo& socket_info) {
1796 int result = ioctl(socket_info.sockfd_, FIONREAD, &len);
1799 dhcp_receiver_->setError(strerror(errno));
1810 pkt = packet_filter_->receive(iface, socket_info);
1811 }
catch (
const std::exception& ex) {
1812 dhcp_receiver_->setError(strerror(errno));
1814 dhcp_receiver_->setError(
"packet filter receive() failed");
1819 dhcp_receiver_->markReady(WatchedThread::READY);
1824 IfaceMgr::receiveDHCP6Packet(
const SocketInfo& socket_info) {
1827 int result = ioctl(socket_info.sockfd_, FIONREAD, &len);
1830 dhcp_receiver_->setError(strerror(errno));
1841 pkt = packet_filter6_->receive(socket_info);
1842 }
catch (
const std::exception& ex) {
1843 dhcp_receiver_->setError(ex.what());
1845 dhcp_receiver_->setError(
"packet filter receive() failed");
1850 dhcp_receiver_->markReady(WatchedThread::READY);
1864 Iface::SocketCollection::const_iterator candidate = socket_collection.end();
1866 Iface::SocketCollection::const_iterator s;
1867 for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
1872 if (s->family_ != AF_INET6) {
1877 if (s->addr_.isV6Multicast()) {
1881 if (s->addr_ == pkt->getLocalAddr()) {
1884 return (s->sockfd_);
1888 if (candidate == socket_collection.end()) {
1894 if ( (pkt->getRemoteAddr().isV6LinkLocal() &&
1895 s->addr_.isV6LinkLocal()) ||
1896 (!pkt->getRemoteAddr().isV6LinkLocal() &&
1897 !s->addr_.isV6LinkLocal()) ) {
1903 if (candidate != socket_collection.end()) {
1904 return (candidate->sockfd_);
1908 <<
" does not have any suitable IPv6 sockets open.");
1922 Iface::SocketCollection::const_iterator candidate = socket_collection.end();
1923 Iface::SocketCollection::const_iterator s;
1924 for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
1925 if (s->family_ == AF_INET) {
1926 if (s->addr_ == pkt->getLocalAddr()) {
1930 if (candidate == socket_collection.end()) {
1936 if (candidate == socket_collection.end()) {
1938 <<
" does not have any suitable IPv4 sockets open.");
1941 return (*candidate);
1948 " while DHCP receiver thread is running");
1951 bool enable_queue =
false;
1952 if (queue_control) {
1963 if (family == AF_INET) {
1964 packet_queue_mgr4_->createPacketQueue(queue_control);
1966 packet_queue_mgr6_->createPacketQueue(queue_control);
1970 if (family == AF_INET) {
1971 packet_queue_mgr4_->destroyPacketQueue();
1973 packet_queue_mgr6_->destroyPacketQueue();
1977 return(enable_queue);
SocketCallback callback_
A callback that will be called when data arrives over socket_.
void clearIfaces()
Removes detected interfaces.
IfacePtr getIface(int ifindex)
Returns interface specified interface index.
Provides a thread and controls for monitoring its activities.
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
int openSocketFromRemoteAddress(const isc::asiolink::IOAddress &remote_addr, const uint16_t port)
Opens UDP/IP socket to be used to connect to remote address.
Pkt4Ptr receive4Direct(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv4 packets directly or data from external sockets.
void collectBoundAddresses()
Collect the addresses all sockets are bound to.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
IfaceMgr exception thrown thrown when socket opening or configuration failed.
A generic exception that is thrown when a function is not implemented.
Packet Queue Manager for DHPCv6 servers.
void addSocket(const SocketInfo &sock)
Adds socket descriptor to an interface.
IfaceMgr exception thrown when there is no suitable socket found.
void setPacketFilter(const PktFilterPtr &packet_filter)
Set packet filter object to handle sending and receiving DHCPv4 messages.
bool isDHCPReceiverRunning() const
Returns true if there is a receiver exists and its thread is currently running.
static const unsigned int MAX_MAC_LEN
Maximum MAC address length (Infiniband uses 20 bytes)
size_t mac_len_
Length of link-layer address (usually 6).
Pkt6Ptr receive6Indirect(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv6 packets indirectly or data from external sockets.
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
bool delSocket(uint16_t sockfd)
Closes socket.
IfaceMgr exception thrown thrown when interface detection fails.
void addUnicast(const isc::asiolink::IOAddress &addr)
Adds unicast the server should listen on.
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
std::string getPlainMac() const
Returns link-layer address a plain text.
#define FD_COPY(orig, copy)
void startDHCPReceiver(const uint16_t family)
Starts DHCP packet receiver.
#define DHCP_IPV4_BROADCAST_ADDRESS
int ifindex_
Interface index (a value that uniquely identifies an interface).
void setActive(const isc::asiolink::IOAddress &address, const bool active)
Activates or deactivates address for the interface.
std::list< SocketInfo > SocketCollection
Type that holds a list of socket information.
unsigned int countActive4() const
Returns a number of activated IPv4 addresses on the interface.
AddressCollection unicasts_
List of unicast addresses the server should listen on.
int purgeBadSockets()
Scans registered socket set and removes any that are invalid.
bool openSockets6(const uint16_t port=DHCP6_SERVER_PORT, IfaceMgrErrorMsgCallback error_handler=0)
Opens IPv6 sockets on detected interfaces.
std::function< void(const std::string &errmsg)> IfaceMgrErrorMsgCallback
This type describes the callback function invoked when error occurs in the IfaceMgr.
PacketQueue6Ptr getPacketQueue6()
Fetches the DHCPv6 receiver packet queue.
bool hasAddress(const isc::asiolink::IOAddress &address) const
Check if the interface has the specified address assigned.
Handles network interfaces, transmission and reception.
Packet handling class using AF_INET socket family.
Represents a single network interface.
int openSocketFromAddress(const isc::asiolink::IOAddress &addr, const uint16_t port)
Opens UDP/IP socket and binds to address specified.
boost::shared_ptr< PktFilter > PktFilterPtr
Pointer to a PktFilter object.
bool isV4() const
Convenience function to check for an IPv4 address.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
void closeSockets()
Closes all open sockets on interface.
Keeps callback information for external sockets.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv4 packets or data from external sockets.
IfaceMgr exception thrown when there is no suitable interface.
void deleteExternalSocket(int socketfd)
Deletes external socket.
BoundAddresses bound_address_
Unordered set of IPv4 bound addresses.
A generic exception that is thrown when an unexpected error condition occurs.
Exception thrown when invalid packet filter object specified.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< const Element > ConstElementPtr
void clearUnicasts()
Clears unicast addresses on all interfaces.
Packet Queue Manager for DHPCv4 servers.
IfacePtr getIface(uint32_t ifindex)
Lookup by interface index.
void clearBoundAddresses()
Clears the addresses all sockets are bound to.
IfaceMgr exception thrown thrown when error occurred during reading data from socket.
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
void deleteAllExternalSockets()
Deletes all external sockets.
bool getAddress4(isc::asiolink::IOAddress &address) const
Returns IPv4 address assigned to the interface.
void addInterface(const IfacePtr &iface)
Adds an interface to list of known interfaces.
std::string getName() const
Returns interface name.
std::function< void(int fd)> SocketCallback
Defines callback used when data is received over external sockets.
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.
AddressCollection addrs_
List of assigned addresses.
std::list< Address > AddressCollection
Type that defines list of addresses.
bool hasOpenSocket(const uint16_t family) const
Checks if there is at least one socket of the specified family open.
boost::shared_ptr< PktFilter6 > PktFilter6Ptr
Pointer to a PktFilter object.
std::string getFullName() const
Returns full interface name as "ifname/ifindex" string.
util::Optional< asiolink::IOAddress > Address
Address type.
Exception thrown when a call to select is interrupted by a signal.
#define IFACEMGR_ERROR(ex_type, handler, stream)
A macro which handles an error in IfaceMgr.
static const IOEndpoint * create(const int protocol, const IOAddress &address, const unsigned short port)
A polymorphic factory of endpoint from address and port.
void closeSockets()
Closes all open sockets.
A generic exception that is thrown if a function is called in a prohibited way.
SocketCollection sockets_
Socket used to send data.
bool delAddress(const isc::asiolink::IOAddress &addr)
Deletes an address from an interface.
uint8_t mac_[MAX_MAC_LEN]
Link-layer address.
A DHCPv6 packet handling class using datagram sockets.
uint16_t getSocket(const isc::dhcp::Pkt6Ptr &pkt)
Return most suitable socket for transmitting specified IPv6 packet.
void detectIfaces()
Detects network interfaces.
void addAddress(const isc::asiolink::IOAddress &addr)
Adds an address to an interface.
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.
virtual ~IfaceMgr()
Destructor.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
int openSocketFromIface(const std::string &ifname, const uint16_t port, const uint8_t family)
Opens UDP/IP socket and binds it to interface specified.
bool isV6() const
Convenience function to check for an IPv6 address.
static void addFDtoSet(int fd, int &maxfd, fd_set *sockets)
Convenience method for adding an descriptor to a set.
int openSocket4(Iface &iface, const isc::asiolink::IOAddress &addr, const uint16_t port, const bool receive_bcast=false, const bool send_bcast=false)
Opens IPv4 socket.
PacketQueue4Ptr getPacketQueue4()
Fetches the DHCPv4 receiver packet queue.
IfaceMgr()
Protected constructor.
Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv4 packets or data from external sockets.
The IOAddress class represents an IP addresses (version agnostic)
bool isDirectResponseSupported() const
Check if packet be sent directly to the client having no address.
int openSocket6(Iface &iface, const isc::asiolink::IOAddress &addr, uint16_t port, const bool join_multicast)
Opens IPv6 socket.
int socket_
Socket descriptor of the external socket.
void printIfaces(std::ostream &out=std::cout)
Debugging method that prints out all available interfaces.
Pkt6Ptr receive6Direct(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv6 packets directly or data from external sockets.
std::string name_
Network interface name.
A template representing an optional value.
void stopDHCPReceiver()
Stops the DHCP packet receiver.
Pkt4Ptr receive4Indirect(uint32_t timeout_sec, uint32_t timeout_usec=0)
Receive IPv4 packets indirectly or data from external sockets.
boost::shared_ptr< IfaceMgr > IfaceMgrPtr
Type definition for the pointer to the IfaceMgr.
const AddressCollection & getAddresses() const
Returns all addresses available on an interface.
void stubDetectIfaces()
Stub implementation of network interface detection.
bool openSockets4(const uint16_t port=DHCP4_SERVER_PORT, const bool use_bcast=true, IfaceMgrErrorMsgCallback error_handler=0)
Opens IPv4 sockets on detected interfaces.
Holds information about socket.
Exception thrown when it is not allowed to set new Packet Filter.
IfaceCollection ifaces_
List of available interfaces.
bool configureDHCPPacketQueue(const uint16_t family, data::ConstElementPtr queue_control)
Configures DHCP packet queue.
void clear()
Clear the collection.
void setMac(const uint8_t *mac, size_t macLen)
Sets MAC address of the interface.