core: NetworkInterfacePredicate accepts ndn::net::NetworkInterface

refs #4021

Change-Id: I6612a67db03b6651e8fbccad91f776ae502283d9
diff --git a/core/network-interface-predicate.cpp b/core/network-interface-predicate.cpp
index 81f199b..daf4cf4 100644
--- a/core/network-interface-predicate.cpp
+++ b/core/network-interface-predicate.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -122,6 +122,24 @@
          netif.etherAddress.toString() == rule;
 }
 
+static bool
+doesMatchRule2(const ndn::net::NetworkInterface& netif, const std::string& rule)
+{
+  // if '/' is in rule, this is a subnet, check if IP in subnet
+  if (rule.find('/') != std::string::npos) {
+    Network n = boost::lexical_cast<Network>(rule);
+    for (const auto& addr : netif.getNetworkAddresses()) {
+      if (n.doesContain(addr.getIp())) {
+        return true;
+      }
+    }
+  }
+
+  return rule == "*" ||
+         doesMatchPattern(netif.getName(), rule) ||
+         netif.getEthernetAddress().toString() == rule;
+}
+
 bool
 NetworkInterfacePredicate::operator()(const NetworkInterfaceInfo& netif) const
 {
@@ -130,6 +148,13 @@
 }
 
 bool
+NetworkInterfacePredicate::operator()(const ndn::net::NetworkInterface& netif) const
+{
+  return std::any_of(m_whitelist.begin(), m_whitelist.end(), bind(&doesMatchRule2, cref(netif), _1)) &&
+         std::none_of(m_blacklist.begin(), m_blacklist.end(), bind(&doesMatchRule2, cref(netif), _1));
+}
+
+bool
 NetworkInterfacePredicate::operator==(const NetworkInterfacePredicate& other) const
 {
   return this->m_whitelist == other.m_whitelist &&
diff --git a/core/network-interface-predicate.hpp b/core/network-interface-predicate.hpp
index f48da05..2443735 100644
--- a/core/network-interface-predicate.hpp
+++ b/core/network-interface-predicate.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -27,6 +27,7 @@
 #define NFD_CORE_NETWORK_INTERFACE_PREDICATE_HPP
 
 #include "common.hpp"
+#include <ndn-cxx/net/network-interface.hpp>
 
 namespace nfd {
 
@@ -62,6 +63,9 @@
   operator()(const NetworkInterfaceInfo& netif) const;
 
   bool
+  operator()(const ndn::net::NetworkInterface& netif) const;
+
+  bool
   operator==(const NetworkInterfacePredicate& other) const;
 
   bool
diff --git a/tests/core/network-interface-predicate.t.cpp b/tests/core/network-interface-predicate.t.cpp
index 4b6a375..3ec581b 100644
--- a/tests/core/network-interface-predicate.t.cpp
+++ b/tests/core/network-interface-predicate.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -28,6 +28,7 @@
 
 #include "tests/test-common.hpp"
 
+#include <ndn-cxx/net/network-monitor-stub.hpp>
 #include <boost/property_tree/info_parser.hpp>
 #include <sstream>
 
@@ -69,6 +70,46 @@
         address_v4::from_string("192.168.2.255"),
         IFF_UP});
 
+    using namespace ndn::net;
+
+    netifs.push_back(NetworkMonitorStub::makeNetworkInterface());
+    netifs.back()->setIndex(0);
+    netifs.back()->setName("eth0");
+    netifs.back()->setEthernetAddress(ethernet::Address::fromString("3e:15:c2:8b:65:00"));
+    netifs.back()->addNetworkAddress(NetworkAddress(AddressFamily::V4,
+      address_v4::from_string("129.82.100.1"), address_v4::from_string("129.82.255.255"),
+      16, AddressScope::GLOBAL, 0));
+    netifs.back()->setFlags(IFF_UP);
+
+    netifs.push_back(NetworkMonitorStub::makeNetworkInterface());
+    netifs.back()->setIndex(1);
+    netifs.back()->setName("eth1");
+    netifs.back()->setEthernetAddress(ethernet::Address::fromString("3e:15:c2:8b:65:01"));
+    netifs.back()->addNetworkAddress(NetworkAddress(AddressFamily::V4,
+      address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.255"),
+      24, AddressScope::GLOBAL, 0));
+    netifs.back()->setFlags(IFF_UP);
+
+    netifs.push_back(NetworkMonitorStub::makeNetworkInterface());
+    netifs.back()->setIndex(2);
+    netifs.back()->setName("eth2");
+    netifs.back()->setEthernetAddress(ethernet::Address::fromString("3e:15:c2:8b:65:02"));
+    netifs.back()->addNetworkAddress(NetworkAddress(AddressFamily::V4,
+      address_v4::from_string("198.51.100.1"), address_v4::from_string("198.51.100.255"),
+      24, AddressScope::GLOBAL, 0));
+    netifs.back()->addNetworkAddress(NetworkAddress(AddressFamily::V6,
+      address_v6::from_string("2001:db8::1"), address_v6::from_string("2001:db8::ffff"),
+      112, AddressScope::GLOBAL, 0));
+    netifs.back()->setFlags(IFF_MULTICAST | IFF_BROADCAST | IFF_UP);
+
+    netifs.push_back(NetworkMonitorStub::makeNetworkInterface());
+    netifs.back()->setIndex(3);
+    netifs.back()->setName("enp68s0f1");
+    netifs.back()->setEthernetAddress(ethernet::Address::fromString("3e:15:c2:8b:65:03"));
+    netifs.back()->addNetworkAddress(NetworkAddress(AddressFamily::V4,
+      address_v4::from_string("192.168.2.3"), address_v4::from_string("192.168.2.255"),
+      24, AddressScope::GLOBAL, 0));
+    netifs.back()->setFlags(IFF_UP);
   }
 
   void
@@ -91,6 +132,7 @@
 protected:
   NetworkInterfacePredicate predicate;
   std::vector<NetworkInterfaceInfo> interfaces;
+  std::vector<shared_ptr<ndn::net::NetworkInterface>> netifs;
 };
 
 BOOST_FIXTURE_TEST_SUITE(TestNetworkInterfacePredicate, NetworkInterfacePredicateFixture)
@@ -103,6 +145,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), true);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), true);
 }
 
 BOOST_AUTO_TEST_CASE(EmptyWhitelist)
@@ -115,6 +162,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(WildcardBlacklist)
@@ -128,6 +180,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameWhitelist)
@@ -142,6 +199,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameBlacklist)
@@ -156,6 +218,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), true);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), true);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameWildcardStart)
@@ -169,6 +236,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), true);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), true);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameWildcardMiddle)
@@ -182,6 +254,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameWildcardDouble)
@@ -195,6 +272,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameWildcardOnly)
@@ -208,6 +290,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), true);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), true);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameQuestionMark)
@@ -221,6 +308,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(IfnameMalformed)
@@ -245,6 +337,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(EtherBlacklist)
@@ -259,6 +356,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), true);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), true);
 }
 
 BOOST_AUTO_TEST_CASE(EtherMalformed)
@@ -282,6 +384,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), true);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), true);
 }
 
 BOOST_AUTO_TEST_CASE(SubnetBlacklist)
@@ -295,6 +402,11 @@
   BOOST_CHECK_EQUAL(predicate(interfaces[1]), false);
   BOOST_CHECK_EQUAL(predicate(interfaces[2]), true);
   BOOST_CHECK_EQUAL(predicate(interfaces[3]), false);
+
+  BOOST_CHECK_EQUAL(predicate(*netifs[0]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[1]), false);
+  BOOST_CHECK_EQUAL(predicate(*netifs[2]), true);
+  BOOST_CHECK_EQUAL(predicate(*netifs[3]), false);
 }
 
 BOOST_AUTO_TEST_CASE(SubnetMalformed)