BIND 10 trac1237, updated. 73601f240d4b3aa72b3498b71235b949f645a326 [1237] Minor fixes after review.
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Dec 16 17:52:36 UTC 2011
The branch, trac1237 has been updated
via 73601f240d4b3aa72b3498b71235b949f645a326 (commit)
via 5ec569cd8c5e56ec6e4f4f8df05a44485489c38a (commit)
from aaea8925c243f6ead71f368de54ad27cfd19ef6b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 73601f240d4b3aa72b3498b71235b949f645a326
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Fri Dec 16 18:52:18 2011 +0100
[1237] Minor fixes after review.
commit 5ec569cd8c5e56ec6e4f4f8df05a44485489c38a
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Fri Dec 16 18:45:13 2011 +0100
[1237] OS-detection cleanup, Linux-specific IfaceMgr cleanup.
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 9 +-
src/bin/dhcp6/dhcp6_srv.cc | 2 +-
src/lib/dhcp/Makefile.am | 6 -
src/lib/dhcp/iface_mgr.cc | 3 +-
src/lib/dhcp/iface_mgr.h | 6 +
src/lib/dhcp/iface_mgr_bsd.cc | 17 +-
src/lib/dhcp/iface_mgr_linux.cc | 429 ++++++++++++++++++++-------------------
7 files changed, 240 insertions(+), 232 deletions(-)
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 7462bc8..9e0174a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -373,7 +373,7 @@ AC_MSG_CHECKING(OS family)
system=`uname -s`
case $system in
Linux)
- OS_TYPE="LINUX"
+ OS_TYPE="Linux"
CPPFLAGS="$CPPFLAGS -DOS_LINUX"
;;
Darwin | FreeBSD | NetBSD | OpenBSD)
@@ -390,10 +390,13 @@ case $system in
;;
esac
AC_MSG_RESULT($OS_TYPE)
-AM_CONDITIONAL(OS_LINUX, test $OS_TYPE = LINUX)
+
+AM_CONDITIONAL(OS_LINUX, test $OS_TYPE = Linux)
+AM_COND_IF([OS_LINUX], [AC_DEFINE([OS_LINUX], [1], [Running on Linux?])])
AM_CONDITIONAL(OS_BSD, test $OS_TYPE = BSD)
+AM_COND_IF([OS_BSD], [AC_DEFINE([OS_BSD], [1], [Running on BSD?])])
AM_CONDITIONAL(OS_SOLARIS, test $OS_TYPE = Solaris)
-
+AM_COND_IF([OS_SOLARIS], [AC_DEFINE([OS_SOLARIS], [1], [Running on Solaris?])])
AC_MSG_CHECKING(for sa_len in struct sockaddr)
AC_TRY_COMPILE([
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index b126456..c0f050f 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -33,7 +33,7 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
try {
IfaceMgr::instance();
} catch (const std::exception &e) {
- cout << "Failed to instantiate InterfaceManager. Aborting." << endl;
+ cout << "Failed to instantiate InterfaceManager:" << e.what() << ". Aborting." << endl;
shutdown = true;
}
diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am
index bf6aa1f..e399d58 100644
--- a/src/lib/dhcp/Makefile.am
+++ b/src/lib/dhcp/Makefile.am
@@ -18,14 +18,8 @@ libdhcp_la_SOURCES += option6_addrlst.cc option6_addrlst.h
libdhcp_la_SOURCES += dhcp6.h dhcp4.h
libdhcp_la_SOURCES += pkt6.cc pkt6.h
libdhcp_la_SOURCES += pkt4.cc pkt4.h
-
-if OS_LINUX
libdhcp_la_SOURCES += iface_mgr_linux.cc
-endif
-
-if OS_BSD
libdhcp_la_SOURCES += iface_mgr_bsd.cc
-endif
EXTRA_DIST = README
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index 651c07b..d9310db 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -12,6 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
#include <sstream>
#include <fstream>
#include <string.h>
@@ -73,7 +74,7 @@ IfaceMgr::Iface::getPlainMac() const {
tmp << hex;
for (int i = 0; i < mac_len_; i++) {
tmp.width(2);
- tmp << int(mac_[i]);
+ tmp << static_cast<int>(mac_[i]);
if (i < mac_len_-1) {
tmp << ":";
}
diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h
index 2155ae8..47accc8 100644
--- a/src/lib/dhcp/iface_mgr.h
+++ b/src/lib/dhcp/iface_mgr.h
@@ -54,6 +54,12 @@ public:
/// returns link-layer address a plain text
std::string getPlainMac() const;
+ /// @brief Sets flag_*_ fields based on bitmask value returned by OS
+ ///
+ /// Note: Implementation of this method is OS-dependent as bits have
+ /// different meaning on each OS.
+ ///
+ /// @param flags bitmask value returned by OS in interface detection
void setFlags(uint32_t flags);
/// network interface name
diff --git a/src/lib/dhcp/iface_mgr_bsd.cc b/src/lib/dhcp/iface_mgr_bsd.cc
index 6b7f49d..7786b92 100644
--- a/src/lib/dhcp/iface_mgr_bsd.cc
+++ b/src/lib/dhcp/iface_mgr_bsd.cc
@@ -12,6 +12,10 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <config.h>
+
+#if defined(OS_BSD)
+
#include <dhcp/iface_mgr.h>
#include <exceptions/exceptions.h>
@@ -20,17 +24,6 @@ using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
-#if !defined(OS_BSD)
-/// There are several detectIfaces() implementations for specific
-/// Operating Systems. This one is specific to BSD. It works on
-/// BSD only, so it does not make sense to try to compile it somewhere
-/// else. In particular, Makefile.am includes only one iface_mgr_{OS_TYPE}.cc
-/// file.
-
-#error "Attempt to compile iface_mgr_bsd.cc on non-BSD system!"
-
-#endif
-
namespace isc {
void
@@ -41,3 +34,5 @@ IfaceMgr::detectIfaces() {
}
}
+
+#endif
diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc
index f53b26a..27680e2 100644
--- a/src/lib/dhcp/iface_mgr_linux.cc
+++ b/src/lib/dhcp/iface_mgr_linux.cc
@@ -12,6 +12,11 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#if defined(OS_LINUX)
+
#include <dhcp/iface_mgr.h>
#include <exceptions/exceptions.h>
@@ -24,29 +29,20 @@ using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
-#if !defined(OS_LINUX)
-/// There are several detectIfaces() implementations for specific
-/// Operating Systems. This one is specific to Linux. It works on
-/// Linux only, so it does not make sense to try to compile it somewhere
-/// else. In particular, Makefile.am includes only one iface_mgr_{OS_TYPE}.cc
-/// file.
-
-#error "Attempt to compile iface_mgr_linux.cc on non-Linux system!"
-#endif
-
+/// This is a structure that defines context for netlink connection.
struct rtnl_handle
{
- int fd;
- struct sockaddr_nl local;
- struct sockaddr_nl peer;
- __u32 seq;
- __u32 dump;
+ int fd;
+ struct sockaddr_nl local;
+ struct sockaddr_nl peer;
+ __u32 seq;
+ __u32 dump;
};
struct nlmsg_list
{
- struct nlmsg_list *next;
- struct nlmsghdr h;
+ struct nlmsg_list *next;
+ struct nlmsghdr h;
};
const int sndbuf = 32768;
@@ -55,53 +51,61 @@ const int rcvbuf = 32768;
namespace isc {
+/// @brief Opens netlink socket and initializes handle structure.
+///
+/// @exception Unexpected Thrown if socket configuration fails.
+///
+/// @param handle Context will be stored in this structure.
void rtnl_open_socket(struct rtnl_handle& handle) {
// equivalent of rtnl_open
handle.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (handle.fd < 0) {
- isc_throw(Unexpected, "Failed to create NETLINK socket.");
+ isc_throw(Unexpected, "Failed to create NETLINK socket.");
}
-
+
if (setsockopt(handle.fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
- isc_throw(Unexpected, "Failed to set send buffer in NETLINK socket.");
+ isc_throw(Unexpected, "Failed to set send buffer in NETLINK socket.");
}
-
+
if (setsockopt(handle.fd, SOL_SOCKET, SO_RCVBUF, &sndbuf, sizeof(rcvbuf)) < 0) {
- isc_throw(Unexpected, "Failed to set receive buffer in NETLINK socket.");
+ isc_throw(Unexpected, "Failed to set receive buffer in NETLINK socket.");
}
-
+
memset(&handle.local, 0, sizeof(handle.local));
handle.local.nl_family = AF_NETLINK;
handle.local.nl_groups = 0;
if (bind(handle.fd, (struct sockaddr*)&handle.local, sizeof(handle.local)) < 0) {
- isc_throw(Unexpected, "Failed to bind netlink socket.");
+ isc_throw(Unexpected, "Failed to bind netlink socket.");
}
socklen_t addr_len = sizeof(handle.local);
if (getsockname(handle.fd, (struct sockaddr*)&handle.local, &addr_len) < 0) {
- isc_throw(Unexpected, "Getsockname for netlink socket failed.");
+ isc_throw(Unexpected, "Getsockname for netlink socket failed.");
}
// just 2 sanity checks and we are done
if ( (addr_len != sizeof(handle.local)) ||
- (handle.local.nl_family != AF_NETLINK) ) {
- isc_throw(Unexpected, "getsockname() returned unexpected data for netlink socket.");
+ (handle.local.nl_family != AF_NETLINK) ) {
+ isc_throw(Unexpected, "getsockname() returned unexpected data for netlink socket.");
}
}
-// sends request over NETLINK socket
-void rtnl_send_request(struct rtnl_handle& handle,
- int family, int type) {
+/// @brief Sends request over NETLINK socket.
+///
+/// @param handle context structure
+/// @param family requested information family
+/// @param type request type (RTM_GETLINK or RTM_GETADDR)
+void rtnl_send_request(struct rtnl_handle& handle, int family, int type) {
struct {
- struct nlmsghdr nlh;
- struct rtgenmsg g;
+ struct nlmsghdr nlh;
+ struct rtgenmsg g;
} req;
struct sockaddr_nl nladdr;
-
+
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
-
+
memset(&req, 0, sizeof(req));
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_type = type;
@@ -109,98 +113,95 @@ void rtnl_send_request(struct rtnl_handle& handle,
req.nlh.nlmsg_pid = 0;
req.nlh.nlmsg_seq = handle.dump = ++handle.seq;
req.g.rtgen_family = family;
-
+
int status = sendto(handle.fd, (void*)&req, sizeof(req), 0,
- (struct sockaddr*)&nladdr, sizeof(nladdr));
+ (struct sockaddr*)&nladdr, sizeof(nladdr));
if (status<0) {
- isc_throw(Unexpected, "Failed to send " << sizeof(nladdr) << " bytes over netlink socket.");
+ isc_throw(Unexpected, "Failed to send " << sizeof(nladdr) << " bytes over netlink socket.");
}
}
-void rtnl_store_reply(/*const struct sockaddr_nl *who,*/ struct nlmsghdr *n, struct nlmsg_list** linfo)
+/// @brief Appends nlmsg to a list
+///
+/// @param n a message to be added
+/// @param link_info a list
+void rtnl_store_reply(struct nlmsghdr *n, struct nlmsg_list** link_info)
{
struct nlmsg_list *h;
struct nlmsg_list **lp;
-
+
h = (nlmsg_list*)malloc(n->nlmsg_len+sizeof(void*));
if (h == NULL) {
- isc_throw(Unexpected, "Failed to allocate " << n->nlmsg_len+sizeof(void*)
- << " bytes.");
+ isc_throw(Unexpected, "Failed to allocate " << n->nlmsg_len+sizeof(void*)
+ << " bytes.");
}
-
+
memcpy(&h->h, n, n->nlmsg_len);
h->next = NULL;
-
- for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */;
+
+ for (lp = link_info; *lp; lp = &(*lp)->next) /* NOTHING */;
*lp = h;
-
- // ll_remember_index(who, n, NULL);
- // return 0;
}
void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
while (RTA_OK(rta, len)) {
- if (rta->rta_type <= max)
- tb[rta->rta_type] = rta;
- rta = RTA_NEXT(rta,len);
+ if (rta->rta_type <= max)
+ tb[rta->rta_type] = rta;
+ rta = RTA_NEXT(rta,len);
}
if (len) {
- isc_throw(Unexpected, "Failed to parse RTATTR in netlink message.");
+ isc_throw(Unexpected, "Failed to parse RTATTR in netlink message.");
}
}
-
- void ipaddrs_get(IfaceMgr::Iface& iface, struct nlmsg_list *ainfo) {
+void ipaddrs_get(IfaceMgr::Iface& iface, struct nlmsg_list *addr_info) {
uint8_t addr[16];
struct rtattr * rta_tb[IFA_MAX+1];
- for ( ;ainfo ; ainfo = ainfo->next) {
- struct nlmsghdr *n = &ainfo->h;
- struct ifaddrmsg *ifa = (ifaddrmsg*)NLMSG_DATA(n);
-
- // these are not the addresses you are looking for
- if ( ifa->ifa_index != iface.ifindex_) {
- continue;
- }
-
- if ( ifa->ifa_family == AF_INET6 ) {
- memset(rta_tb, 0, sizeof(rta_tb));
- parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
- if (!rta_tb[IFA_LOCAL])
- rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
- if (!rta_tb[IFA_ADDRESS])
- rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
-
- memcpy(addr,(char*)RTA_DATA(rta_tb[IFLA_ADDRESS]),16);
- IOAddress a = IOAddress::from_bytes(AF_INET6, addr);
- iface.addrs_.push_back(a);
-
- /// TODO: Read lifetimes of configured addresses
- }
-
- if ( ifa->ifa_family == AF_INET ) {
- memset(rta_tb, 0, sizeof(rta_tb));
- parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
- if (!rta_tb[IFA_LOCAL])
- rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
- if (!rta_tb[IFA_ADDRESS])
- rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
-
- memcpy(addr,(char*)RTA_DATA(rta_tb[IFLA_ADDRESS]),4);
- IOAddress a = IOAddress::from_bytes(AF_INET, addr);
- iface.addrs_.push_back(a);
- }
-
-
+ for ( ;addr_info ; addr_info = addr_info->next) {
+ struct nlmsghdr *n = &addr_info->h;
+ struct ifaddrmsg *ifa = (ifaddrmsg*)NLMSG_DATA(n);
+
+ // these are not the addresses you are looking for
+ if ( ifa->ifa_index != iface.ifindex_) {
+ continue;
+ }
+
+ if ( ifa->ifa_family == AF_INET6 ) {
+ memset(rta_tb, 0, sizeof(rta_tb));
+ parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
+ if (!rta_tb[IFA_LOCAL])
+ rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
+ if (!rta_tb[IFA_ADDRESS])
+ rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
+
+ memcpy(addr,(char*)RTA_DATA(rta_tb[IFLA_ADDRESS]),16);
+ IOAddress a = IOAddress::from_bytes(AF_INET6, addr);
+ iface.addrs_.push_back(a);
+
+ /// TODO: Read lifetimes of configured addresses
+ }
+
+ if ( ifa->ifa_family == AF_INET ) {
+ memset(rta_tb, 0, sizeof(rta_tb));
+ parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
+ if (!rta_tb[IFA_LOCAL])
+ rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
+ if (!rta_tb[IFA_ADDRESS])
+ rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
+
+ memcpy(addr,(char*)RTA_DATA(rta_tb[IFLA_ADDRESS]),4);
+ IOAddress a = IOAddress::from_bytes(AF_INET, addr);
+ iface.addrs_.push_back(a);
+ }
}
}
-void rtnl_process_reply(struct rtnl_handle &rth,
- struct nlmsg_list *&info) {
+void rtnl_process_reply(struct rtnl_handle &rth, struct nlmsg_list *&info) {
struct sockaddr_nl nladdr;
struct iovec iov;
@@ -212,91 +213,91 @@ void rtnl_process_reply(struct rtnl_handle &rth,
msg.msg_iovlen = 1;
char buf[rcvbuf];
-
+
iov.iov_base = buf;
while (1) {
- int status;
- struct nlmsghdr *h;
-
- iov.iov_len = sizeof(buf);
- status = recvmsg(rth.fd, &msg, 0);
-
- if (status < 0) {
- if (errno == EINTR)
- continue;
- isc_throw(Unexpected, "Overrun while processing reply from netlink socket.");
- }
-
- if (status == 0) {
- isc_throw(Unexpected, "EOF while reading netlink socket.");
- }
-
- h = (struct nlmsghdr*)buf;
- while (NLMSG_OK(h, status)) {
-
- // why we received this anyway?
- if (nladdr.nl_pid != 0 ||
- h->nlmsg_pid != rth.local.nl_pid ||
- h->nlmsg_seq != rth.dump) {
- h = NLMSG_NEXT(h, status);
- continue;
- }
-
- if (h->nlmsg_type == NLMSG_DONE) {
- // end of message
- return;
- }
-
- if (h->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
- if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- // we are really out of luck here. We can't even say what is
- // wrong as error message is truncated. D'oh.
- isc_throw(Unexpected, "Netlink reply read failed.");
- } else {
- isc_throw(Unexpected, "Netlink reply read error " << -err->error);
- }
- // never happens we throw before we reach here
- return;
- }
-
- // store the data
- rtnl_store_reply(/*&nladdr,*/ h, &info);
-
- h = NLMSG_NEXT(h, status);
- }
- if (msg.msg_flags & MSG_TRUNC) {
- isc_throw(Unexpected, "Message received over netlink truncated.");
- }
- if (status) {
- isc_throw(Unexpected, "Trailing garbage of " << status << " bytes received over netlink.");
- }
+ int status;
+ struct nlmsghdr *h;
+
+ iov.iov_len = sizeof(buf);
+ status = recvmsg(rth.fd, &msg, 0);
+
+ if (status < 0) {
+ if (errno == EINTR)
+ continue;
+ isc_throw(Unexpected, "Overrun while processing reply from netlink socket.");
+ }
+
+ if (status == 0) {
+ isc_throw(Unexpected, "EOF while reading netlink socket.");
+ }
+
+ h = (struct nlmsghdr*)buf;
+ while (NLMSG_OK(h, status)) {
+
+ // why we received this anyway?
+ if (nladdr.nl_pid != 0 ||
+ h->nlmsg_pid != rth.local.nl_pid ||
+ h->nlmsg_seq != rth.dump) {
+ h = NLMSG_NEXT(h, status);
+ continue;
+ }
+
+ if (h->nlmsg_type == NLMSG_DONE) {
+ // end of message
+ return;
+ }
+
+ if (h->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
+ if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
+ // we are really out of luck here. We can't even say what is
+ // wrong as error message is truncated. D'oh.
+ isc_throw(Unexpected, "Netlink reply read failed.");
+ } else {
+ isc_throw(Unexpected, "Netlink reply read error " << -err->error);
+ }
+ // never happens we throw before we reach here
+ return;
+ }
+
+ // store the data
+ rtnl_store_reply(h, &info);
+
+ h = NLMSG_NEXT(h, status);
+ }
+ if (msg.msg_flags & MSG_TRUNC) {
+ isc_throw(Unexpected, "Message received over netlink truncated.");
+ }
+ if (status) {
+ isc_throw(Unexpected, "Trailing garbage of " << status << " bytes received over netlink.");
+ }
}
}
-void release_list(struct nlmsg_list *n) {
+/// @brief releases nlmsg list
+///
+/// @param head first element of the list to be released
+void release_list(struct nlmsg_list *head) {
struct nlmsg_list *tmp;
- while (n) {
- tmp = n->next;
- free(n);
- n = tmp;
+ while (head) {
+ tmp = head->next;
+ free(head);
+ head = tmp;
}
}
-
-void
-IfaceMgr::detectIfaces() {
-
+void IfaceMgr::detectIfaces() {
cout << "Linux: detecting interfaces." << endl;
- struct nlmsg_list *linfo = NULL;
- struct nlmsg_list *ainfo = NULL;
- struct nlmsg_list *l = NULL;
+ struct nlmsg_list* link_info = NULL; // link info list
+ struct nlmsg_list* addr_info = NULL; // address info list
+ struct nlmsg_list* l = NULL;
struct rtnl_handle rth;
- /* required to display information about interface */
- struct ifinfomsg *ifi = NULL;
- struct rtattr * tb[IFLA_MAX+1];
+ // required to display information about interface
+ struct ifinfomsg* ifi = NULL;
+ struct rtattr* tb[IFLA_MAX+1];
int len = 0;
memset(tb, 0, sizeof(tb));
memset(&rth,0, sizeof(rth));
@@ -305,60 +306,66 @@ IfaceMgr::detectIfaces() {
rtnl_open_socket(rth);
// now we have open functional socket, let's use it!
+ // ask for list of interface...
rtnl_send_request(rth, AF_PACKET, RTM_GETLINK);
- // process reply
- rtnl_process_reply(rth, linfo);
- //rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL);
-
- /* 2nd attribute: AF_UNSPEC, AF_INET, AF_INET6 */
+ // Get reply and store it in link_info list.
+ rtnl_process_reply(rth, link_info);
+
+ // Now ask for list of addresses (AF_UNSPEC = of any family)
rtnl_send_request(rth, AF_UNSPEC, RTM_GETADDR);
- rtnl_process_reply(rth, ainfo);
-
- /* build list with interface names */
- for (l=linfo; l; l = l->next) {
- ifi = (ifinfomsg*)NLMSG_DATA(&l->h);
- len = (&l->h)->nlmsg_len;
- len -= NLMSG_LENGTH(sizeof(*ifi));
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-
- Iface* iface = new Iface(string( (char*)RTA_DATA(tb[IFLA_IFNAME])), ifi->ifi_index);
-
- iface->hardware_type_ = ifi->ifi_type;
- iface->setFlags(ifi->ifi_flags);
-
- iface->mac_len_ = 0;
- memset(iface->mac_, 0, IfaceMgr::MAX_MAC_LEN);
- /* Does inetface has LL_ADDR? */
- if (tb[IFLA_ADDRESS]) {
- iface->mac_len_ = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
- if (iface->mac_len_ > IfaceMgr::MAX_MAC_LEN) {
- iface->mac_len_ = 0;
- isc_throw(Unexpected, "Interface " << iface->getFullName()
- << " was detected to have link address of length " << RTA_PAYLOAD(tb[IFLA_ADDRESS])
- << ", but maximum supported length is " << IfaceMgr::MAX_MAC_LEN);
- }
- memcpy(iface->mac_, RTA_DATA(tb[IFLA_ADDRESS]), iface->mac_len_);
- }
- else {
- /* Tunnels can have no LL_ADDR. RTA_PAYLOAD doesn't check it and try to
- * dereference it in this manner
- * #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
- */
- iface->mac_len_ = 0;
- }
-
- ipaddrs_get(*iface, ainfo);
- ifaces_.push_back(*iface);
- }
+ // Get reply and store it in addr_info list.
+ rtnl_process_reply(rth, addr_info);
+
+ // Now build list with interface names
+ for (l=link_info; l; l = l->next) {
+ ifi = (ifinfomsg*)NLMSG_DATA(&l->h);
+ len = (&l->h)->nlmsg_len;
+ len -= NLMSG_LENGTH(sizeof(*ifi));
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+ Iface* iface = new Iface(string( (char*)RTA_DATA(tb[IFLA_IFNAME])), ifi->ifi_index);
+
+ iface->hardware_type_ = ifi->ifi_type;
+ iface->setFlags(ifi->ifi_flags);
+
+ iface->mac_len_ = 0;
+ memset(iface->mac_, 0, IfaceMgr::MAX_MAC_LEN);
+ // Does inetface has LL_ADDR?
+ if (tb[IFLA_ADDRESS]) {
+ iface->mac_len_ = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
+ if (iface->mac_len_ > IfaceMgr::MAX_MAC_LEN) {
+ iface->mac_len_ = 0;
+ isc_throw(Unexpected, "Interface " << iface->getFullName()
+ << " was detected to have link address of length " << RTA_PAYLOAD(tb[IFLA_ADDRESS])
+ << ", but maximum supported length is " << IfaceMgr::MAX_MAC_LEN);
+ }
+ memcpy(iface->mac_, RTA_DATA(tb[IFLA_ADDRESS]), iface->mac_len_);
+ }
+ else {
+ // Tunnels can have no LL_ADDR. RTA_PAYLOAD doesn't check it and try to
+ // dereference it in this manner
+ // #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
+ iface->mac_len_ = 0;
+ }
+
+ ipaddrs_get(*iface, addr_info);
+ ifaces_.push_back(*iface);
+ }
- release_list(linfo);
- release_list(ainfo);
+ release_list(link_info);
+ release_list(addr_info);
printIfaces();
}
+/// @brief sets flag_*_ fields.
+///
+/// This implementation is OS-specific as bits have different meaning
+/// on different OSes.
+///
+/// @param flags flags bitfield read from OS
void IfaceMgr::Iface::setFlags(uint32_t flags) {
flags_ = flags;
@@ -370,3 +377,5 @@ void IfaceMgr::Iface::setFlags(uint32_t flags) {
}
}
+
+#endif // if defined(LINUX)
More information about the bind10-changes
mailing list