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) {
94 if ((family != AF_INET) && (family != AF_INET6)) {
96 <<
" specified when requested to close all sockets" 97 <<
" which belong to this family");
101 SocketCollection::iterator sock =
sockets_.begin();
103 if (sock->family_ == family) {
106 close(sock->sockfd_);
108 if (sock->fallbackfd_ >= 0) {
109 close(sock->fallbackfd_);
134 for (
int i = 0; i <
mac_len_; i++) {
136 tmp << static_cast<int>(
mac_[i]);
137 if (i < mac_len_-1) {
147 <<
" was detected to have link address of length " 148 << len <<
", but maximum supported length is " 153 memcpy(
mac_, mac, len);
158 for (AddressCollection::iterator a =
addrs_.begin();
160 if (a->get() == addr) {
169 list<SocketInfo>::iterator sock =
sockets_.begin();
171 if (sock->sockfd_ == sockfd) {
174 if (sock->fallbackfd_ >= 0) {
175 close(sock->fallbackfd_);
189 allow_loopback_(false) {
196 }
catch (
const std::exception& ex) {
207 }
catch (
const std::exception& ex) {
214 if (a.get() == addr) {
216 <<
" already defined on the " <<
name_ <<
" interface.");
226 for (
Address addr : getAddresses()) {
229 if (addr.get().isV4()) {
230 address = addr.get();
240 for (
Address addr : getAddresses()) {
241 if (address == addr.get()) {
250 if (!hasAddress(addr)) {
251 addrs_.push_back(
Address(addr));
257 for (AddressCollection::iterator addr_it = addrs_.begin();
258 addr_it != addrs_.end(); ++addr_it) {
259 if (address == addr_it->get()) {
260 addr_it->unspecified(!active);
265 " found on the interface " << getName());
270 for (AddressCollection::iterator addr_it = addrs_.begin();
271 addr_it != addrs_.end(); ++addr_it) {
272 addr_it->unspecified(!active);
280 if (!addr.unspecified() && addr.get().isV4()) {
295 iface->closeSockets();
301 dhcp_receiver_->stop();
304 dhcp_receiver_.reset();
321 return (packet_filter_->isDirectResponseSupported());
330 std::lock_guard<std::mutex> lock(callbacks_mutex_);
334 if (s.socket_ == socketfd) {
335 s.callback_ = callback;
344 callbacks_.push_back(x);
349 std::lock_guard<std::mutex> lock(callbacks_mutex_);
350 deleteExternalSocketInternal(socketfd);
354 IfaceMgr::deleteExternalSocketInternal(
int socketfd) {
355 for (SocketCallbackInfoContainer::iterator s = callbacks_.begin();
356 s != callbacks_.end(); ++s) {
357 if (s->socket_ == socketfd) {
366 std::lock_guard<std::mutex> lock(callbacks_mutex_);
367 std::vector<int> bad_fds;
370 if (fcntl(s.socket_, F_GETFD) < 0 && (errno == EBADF)) {
371 bad_fds.push_back(s.socket_);
375 for (
auto bad_fd : bad_fds) {
376 deleteExternalSocketInternal(bad_fd);
379 return (bad_fds.size());
384 std::lock_guard<std::mutex> lock(callbacks_mutex_);
391 if (!packet_filter) {
404 "it is not allowed to set new packet" 405 <<
" filter when there are open IPv4 sockets - need" 406 <<
" to close them first");
409 packet_filter_ = packet_filter;
414 if (!packet_filter) {
422 "it is not allowed to set new packet" 423 <<
" filter when there are open IPv6 sockets - need" 424 <<
" to close them first");
427 packet_filter6_ = packet_filter;
436 if (sock.family_ == family) {
457 if (sock.addr_ == addr) {
459 }
else if (sock.addr_.isV6Zero()) {
466 if (addr == a.get()) {
482 const string v4addr(
"127.0.0.1"), v6addr(
"::1");
488 if (if_nametoindex(
"lo") > 0) {
491 }
else if (if_nametoindex(
"lo0") > 0) {
497 "Interface detection on this OS is not supported.");
500 IfacePtr iface(
new Iface(ifaceName, if_nametoindex(ifaceName.c_str())));
501 iface->flag_up_ =
true;
502 iface->flag_running_ =
true;
508 iface->flag_loopback_ =
false;
509 iface->flag_multicast_ =
true;
510 iface->flag_broadcast_ =
true;
511 iface->setHWType(HWTYPE_ETHERNET);
521 const bool skip_opened) {
527 iface->clearErrors();
531 if (iface->inactive4_) {
542 if (iface->flag_loopback_ && !allow_loopback_) {
544 "must not open socket on the loopback" 545 " interface " << iface->getName());
549 if (!iface->flag_up_) {
551 "the interface " << iface->getName()
556 if (!iface->flag_running_) {
558 "the interface " << iface->getName()
559 <<
" is not running");
564 if (!iface->getAddress4(out_address)) {
566 "the interface " << iface->getName()
567 <<
" has no usable IPv4 addresses configured");
573 if (addr.unspecified() || !addr.get().isV4()) {
580 bool is_open_as_broadcast = iface->flag_broadcast_ && use_bcast;
597 "Binding socket to an interface is not" 598 " supported on this OS; therefore only" 599 " one socket listening to broadcast traffic" 600 " can be opened. Sockets will not be opened" 601 " on remaining interfaces");
613 is_open_as_broadcast,
614 is_open_as_broadcast);
617 "Failed to open socket on interface " 625 if (is_open_as_broadcast) {
651 const bool skip_opened) {
656 iface->clearErrors();
660 if (iface->inactive6_) {
671 if (iface->flag_loopback_ && !allow_loopback_) {
673 "must not open socket on the loopback" 674 " interface " << iface->getName());
676 }
else if (!iface->flag_up_) {
678 "the interface " << iface->getName()
681 }
else if (!iface->flag_running_) {
683 "the interface " << iface->getName()
684 <<
" is not running");
697 !iface->getSockets().size()) {
702 "Failed to open unicast socket on interface " 704 <<
", reason: " << ex.
what());
715 if (!addr.get().isV6()) {
724 if (!addr.get().isV6LinkLocal()){
739 !iface->getSockets().size()) {
743 IfaceMgr::openMulticastSocket(*iface, addr, port);
746 "Failed to open multicast socket on interface " 747 << iface->getName() <<
", reason: " << ex.
what());
779 dhcp_receiver_->start(std::bind(&IfaceMgr::receiveDHCP4Packets,
this));
789 dhcp_receiver_->start(std::bind(&IfaceMgr::receiveDHCP6Packets,
this));
800 if ((existing->getName() == iface->getName()) ||
801 (existing->getIndex() == iface->getIndex())) {
803 " when " << existing->getFullName() <<
807 ifaces_.push_back(iface);
815 out <<
"Detected interface " << iface->getFullName()
816 <<
", hwtype=" << iface->getHWType()
817 <<
", mac=" << iface->getPlainMac();
818 out <<
", flags=" << hex << iface->flags_ << dec <<
"(" 819 << (iface->flag_loopback_?
"LOOPBACK ":
"")
820 << (iface->flag_up_?
"UP ":
"")
821 << (iface->flag_running_?
"RUNNING ":
"")
822 << (iface->flag_multicast_?
"MULTICAST ":
"")
823 << (iface->flag_broadcast_?
"BROADCAST ":
"")
825 out <<
" " << addrs.size() <<
" addr(s):";
828 out <<
" " << addr.get().toText();
836 return (getIfaceInternal(ifindex, MultiThreadingMgr::instance().getMode()));
842 return (getIfaceInternal(ifname, MultiThreadingMgr::instance().getMode()));
846 IfaceCollection::getIfaceInternal(uint32_t ifindex,
bool need_lock) {
848 lock_guard<mutex> lock(mutex_);
849 if (cache_ && (cache_->getIndex() == ifindex)) {
853 if (cache_ && (cache_->getIndex() == ifindex)) {
857 const auto& idx = ifaces_container_.get<1>();
858 auto it = idx.find(ifindex);
859 if (it == idx.end()) {
863 lock_guard<mutex> lock(mutex_);
867 lock_guard<mutex> lock(mutex_);
874 IfaceCollection::getIfaceInternal(
const std::string& ifname,
bool need_lock) {
876 lock_guard<mutex> lock(mutex_);
877 if (cache_ && (cache_->getName() == ifname)) {
881 if (cache_ && (cache_->getName() == ifname)) {
885 const auto& idx = ifaces_container_.get<2>();
886 auto it = idx.find(ifname);
887 if (it == idx.end()) {
891 lock_guard<mutex> lock(mutex_);
895 lock_guard<mutex> lock(mutex_);
903 if ((ifindex < 0) || (ifindex > std::numeric_limits<int32_t>::max())) {
911 if (ifname.empty()) {
919 if (pkt->indexSet()) {
954 iface->clearUnicasts();
959 const uint16_t port,
const bool receive_bcast,
960 const bool send_bcast) {
966 return openSocket4(*iface, addr, port, receive_bcast, send_bcast);
968 }
else if (addr.
isV6()) {
969 return openSocket6(*iface, addr, port, receive_bcast);
979 const uint8_t family) {
982 if ((iface->getFullName() != ifname) &&
983 (iface->getName() != ifname)) {
990 Iface::AddressCollection::iterator addr_it = addrs.begin();
991 while (addr_it != addrs.end()) {
992 if (addr_it->get().getFamily() == family) {
995 return (
openSocket(iface->getName(), *addr_it, port,
false));
1001 if (addr_it == addrs.end()) {
1003 std::string family_name(
"AF_INET");
1004 if (family == AF_INET6) {
1005 family_name =
"AF_INET6";
1009 << ifname <<
", port: " << port <<
", address " 1010 " family: " << family_name);
1019 const uint16_t port) {
1029 if (a.get() == addr) {
1032 return (
openSocket(iface->getName(), a, port,
false));
1042 const uint16_t port) {
1045 IOAddress local_address(getLocalAddress(remote_addr, port));
1053 IfaceMgr::getLocalAddress(
const IOAddress& remote_addr,
const uint16_t port) {
1055 boost::scoped_ptr<const UDPEndpoint>
1056 remote_endpoint(static_cast<const UDPEndpoint*>
1058 if (!remote_endpoint) {
1063 boost::asio::io_service io_service;
1064 boost::asio::ip::udp::socket sock(io_service);
1066 boost::system::error_code err_code;
1069 if (remote_addr.
isV4() &&
1082 sock.open(boost::asio::ip::udp::v4(), err_code);
1084 const char* errstr = strerror(errno);
1088 sock.set_option(boost::asio::socket_base::broadcast(
true), err_code);
1096 sock.connect(remote_endpoint->getASIOEndpoint(), err_code);
1103 boost::asio::ip::udp::socket::endpoint_type local_endpoint =
1104 sock.local_endpoint();
1105 boost::asio::ip::address local_address(local_endpoint.address());
1116 const bool receive_bcast,
const bool send_bcast) {
1119 receive_bcast, send_bcast);
1130 << pkt->getIface() <<
") specified.");
1135 return (packet_filter6_->send(*iface,
getSocket(pkt), pkt) == 0);
1143 << pkt->getIface() <<
") specified.");
1148 return (packet_filter_->send(*iface,
getSocket(pkt).sockfd_, pkt) == 0);
1161 if (timeout_usec >= 1000000) {
1163 " one million microseconds");
1173 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1174 if (!callbacks_.empty()) {
1183 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::READY), maxfd, &sockets);
1194 struct timeval select_timeout;
1196 select_timeout.tv_sec = timeout_sec;
1197 select_timeout.tv_usec = timeout_usec;
1199 select_timeout.tv_sec = 0;
1200 select_timeout.tv_usec = 0;
1206 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1211 }
else if (result < 0) {
1219 if (errno == EINTR) {
1221 }
else if (errno == EBADF) {
1224 "SELECT interrupted by one invalid sockets, purged " 1225 << cnt <<
" socket descriptors");
1235 string msg = dhcp_receiver_->getLastError();
1244 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1246 if (!FD_ISSET(s.socket_, &sockets)) {
1275 dhcp_receiver_->clearReady(WatchedThread::READY);
1283 if (timeout_usec >= 1000000) {
1285 " one million microseconds");
1287 boost::scoped_ptr<SocketInfo> candidate;
1299 if (s.addr_.isV4()) {
1308 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1309 if (!callbacks_.empty()) {
1317 struct timeval select_timeout;
1318 select_timeout.tv_sec = timeout_sec;
1319 select_timeout.tv_usec = timeout_usec;
1324 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1330 }
else if (result < 0) {
1338 if (errno == EINTR) {
1340 }
else if (errno == EBADF) {
1343 "SELECT interrupted by one invalid sockets, purged " 1344 << cnt <<
" socket descriptors");
1354 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1356 if (!FD_ISSET(s.socket_, &sockets)) {
1385 if (FD_ISSET(s.sockfd_, &sockets)) {
1396 if (!candidate || !recv_if) {
1402 return (packet_filter_->receive(*recv_if, *candidate));
1420 FD_SET(fd, sockets);
1429 if (timeout_usec >= 1000000) {
1431 " one million microseconds");
1434 boost::scoped_ptr<SocketInfo> candidate;
1446 if (s.addr_.isV6()) {
1455 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1456 if (!callbacks_.empty()) {
1464 struct timeval select_timeout;
1465 select_timeout.tv_sec = timeout_sec;
1466 select_timeout.tv_usec = timeout_usec;
1471 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1477 }
else if (result < 0) {
1485 if (errno == EINTR) {
1487 }
else if (errno == EBADF) {
1490 "SELECT interrupted by one invalid sockets, purged " 1491 << cnt <<
" socket descriptors");
1501 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1503 if (!FD_ISSET(s.socket_, &sockets)) {
1531 if (FD_ISSET(s.sockfd_, &sockets)) {
1545 return (packet_filter6_->receive(*candidate));
1551 if (timeout_usec >= 1000000) {
1553 " one million microseconds");
1563 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1564 if (!callbacks_.empty()) {
1573 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::READY), maxfd, &sockets);
1584 struct timeval select_timeout;
1586 select_timeout.tv_sec = timeout_sec;
1587 select_timeout.tv_usec = timeout_usec;
1589 select_timeout.tv_sec = 0;
1590 select_timeout.tv_usec = 0;
1596 int result = select(maxfd + 1, &sockets, 0, 0, &select_timeout);
1601 }
else if (result < 0) {
1609 if (errno == EINTR) {
1611 }
else if (errno == EBADF) {
1614 "SELECT interrupted by one invalid sockets, purged " 1615 << cnt <<
" socket descriptors");
1625 string msg = dhcp_receiver_->getLastError();
1634 std::lock_guard<std::mutex> lock(callbacks_mutex_);
1636 if (!FD_ISSET(s.socket_, &sockets)) {
1665 dhcp_receiver_->clearReady(WatchedThread::READY);
1672 IfaceMgr::receiveDHCP4Packets() {
1679 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::TERMINATE), maxfd, &sockets);
1685 if (s.addr_.isV4()) {
1694 if (dhcp_receiver_->shouldTerminate()) {
1705 int result = select(maxfd + 1, &rd_set, 0, 0, 0);
1708 if (dhcp_receiver_->shouldTerminate()) {
1716 }
else if (result < 0) {
1718 if (errno != EINTR) {
1720 dhcp_receiver_->setError(strerror(errno));
1732 if (FD_ISSET(s.sockfd_, &sockets)) {
1733 receiveDHCP4Packet(*iface, s);
1735 if (dhcp_receiver_->shouldTerminate()) {
1746 IfaceMgr::receiveDHCP6Packets() {
1753 addFDtoSet(dhcp_receiver_->getWatchFd(WatchedThread::TERMINATE), maxfd, &sockets);
1759 if (s.addr_.isV6()) {
1768 if (dhcp_receiver_->shouldTerminate()) {
1779 int result = select(maxfd + 1, &rd_set, 0, 0, 0);
1782 if (dhcp_receiver_->shouldTerminate()) {
1789 }
else if (result < 0) {
1791 if (errno != EINTR) {
1793 dhcp_receiver_->setError(strerror(errno));
1805 if (FD_ISSET(s.sockfd_, &sockets)) {
1806 receiveDHCP6Packet(s);
1808 if (dhcp_receiver_->shouldTerminate()) {
1818 IfaceMgr::receiveDHCP4Packet(
Iface& iface,
const SocketInfo& socket_info) {
1821 int result = ioctl(socket_info.
sockfd_, FIONREAD, &len);
1824 dhcp_receiver_->setError(strerror(errno));
1835 pkt = packet_filter_->receive(iface, socket_info);
1836 }
catch (
const std::exception& ex) {
1837 dhcp_receiver_->setError(strerror(errno));
1839 dhcp_receiver_->setError(
"packet filter receive() failed");
1844 dhcp_receiver_->markReady(WatchedThread::READY);
1849 IfaceMgr::receiveDHCP6Packet(
const SocketInfo& socket_info) {
1852 int result = ioctl(socket_info.
sockfd_, FIONREAD, &len);
1855 dhcp_receiver_->setError(strerror(errno));
1866 pkt = packet_filter6_->receive(socket_info);
1867 }
catch (
const std::exception& ex) {
1868 dhcp_receiver_->setError(ex.what());
1870 dhcp_receiver_->setError(
"packet filter receive() failed");
1875 dhcp_receiver_->markReady(WatchedThread::READY);
1889 Iface::SocketCollection::const_iterator candidate = socket_collection.end();
1891 Iface::SocketCollection::const_iterator s;
1892 for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
1897 if (s->family_ != AF_INET6) {
1902 if (s->addr_.isV6Multicast()) {
1906 if (s->addr_ == pkt->getLocalAddr()) {
1909 return (s->sockfd_);
1913 if (candidate == socket_collection.end()) {
1919 if ( (pkt->getRemoteAddr().isV6LinkLocal() &&
1920 s->addr_.isV6LinkLocal()) ||
1921 (!pkt->getRemoteAddr().isV6LinkLocal() &&
1922 !s->addr_.isV6LinkLocal()) ) {
1928 if (candidate != socket_collection.end()) {
1929 return (candidate->sockfd_);
1933 <<
" does not have any suitable IPv6 sockets open.");
1947 Iface::SocketCollection::const_iterator candidate = socket_collection.end();
1948 Iface::SocketCollection::const_iterator s;
1949 for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
1950 if (s->family_ == AF_INET) {
1951 if (s->addr_ == pkt->getLocalAddr()) {
1955 if (candidate == socket_collection.end()) {
1961 if (candidate == socket_collection.end()) {
1963 <<
" does not have any suitable IPv4 sockets open.");
1966 return (*candidate);
1973 " while DHCP receiver thread is running");
1976 bool enable_queue =
false;
1977 if (queue_control) {
1988 if (family == AF_INET) {
1989 packet_queue_mgr4_->createPacketQueue(queue_control);
1991 packet_queue_mgr6_->createPacketQueue(queue_control);
1995 if (family == AF_INET) {
1996 packet_queue_mgr4_->destroyPacketQueue();
1998 packet_queue_mgr6_->destroyPacketQueue();
2002 return (enable_queue);
2007 errors_.push_back(message);
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.
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.
bool hasAddress(const isc::asiolink::IOAddress &address) const
Check if the interface has the specified address assigned.
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.
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).
ErrorBuffer const & getErrors() const
Get the consistent list of error messages.
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 clearErrors()
Clears all errors.
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.
#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.
bool openSockets6(const uint16_t port=DHCP6_SERVER_PORT, IfaceMgrErrorMsgCallback error_handler=0, const bool skip_opened=false)
Opens IPv6 sockets on detected interfaces.
int purgeBadSockets()
Scans registered socket set and removes any that are invalid.
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.
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.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
boost::shared_ptr< PktFilter > PktFilterPtr
Pointer to a PktFilter object.
std::vector< std::string > ErrorBuffer
Type definition for a list of error messages.
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.
std::string getPlainMac() const
Returns link-layer address a plain text.
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.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
void deleteExternalSocket(int socketfd)
Deletes external socket.
BoundAddresses bound_address_
Unordered set of IPv4 bound addresses.
unsigned int countActive4() const
Returns a number of activated IPv4 addresses on the interface.
#define IFACEMGR_ERROR(ex_type, handler, iface, stream)
A macro which handles an error in IfaceMgr.
bool hasOpenSocket(const uint16_t family) const
Checks if there is at least one socket of the specified family open.
A generic exception that is thrown when an unexpected error condition occurs.
void detectIfaces(bool update_only=false)
Detects network interfaces.
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.
bool isV6() const
Convenience function to check for an IPv6 address.
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.
bool isV4() const
Convenience function to check for an IPv4 address.
void deleteAllExternalSockets()
Deletes all external sockets.
void addInterface(const IfacePtr &iface)
Adds an interface to list of known interfaces.
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.
bool openSockets4(const uint16_t port=DHCP4_SERVER_PORT, const bool use_bcast=true, IfaceMgrErrorMsgCallback error_handler=0, const bool skip_opened=false)
Opens IPv4 sockets on detected interfaces.
Defines the logger used by the top-level component of kea-lfc.
AddressCollection addrs_
List of assigned addresses.
std::list< Address > AddressCollection
Type that defines list of addresses.
boost::shared_ptr< PktFilter6 > PktFilter6Ptr
Pointer to a PktFilter object.
bool getAddress4(isc::asiolink::IOAddress &address) const
Returns IPv4 address assigned to the interface.
Exception thrown when a call to select is interrupted by a signal.
std::string getFullName() const
Returns full interface name as "ifname/ifindex" string.
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.
bool isDHCPReceiverRunning() const
Returns true if there is a receiver exists and its thread is currently running.
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 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.
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.
bool isDirectResponseSupported() const
Check if packet be sent directly to the client having no address.
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)
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.
void addError(std::string const &message)
Add an error to the list of messages.
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.
void stubDetectIfaces()
Stub implementation of network interface detection.
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.