add IP_RANGE::netmap including unit tests
authorGerd von Egidy <gerd.von.egidy@intra2net.com>
Fri, 3 Sep 2010 09:34:23 +0000 (11:34 +0200)
committerGerd von Egidy <gerd.von.egidy@intra2net.com>
Fri, 3 Sep 2010 09:34:23 +0000 (11:34 +0200)
src/ipfunc.cpp
src/ipfunc.hxx
test/ip_range.cpp

index 7924ef6..c7bda20 100644 (file)
@@ -182,6 +182,41 @@ bool IP_RANGE::overlapping(const IP_RANGE& a) const
     return false;
 }
 
+/** @brief map this IP_RANGE to another network (resembles iptables NETMAP-target)
+    @param original_net the original net that is netmapped. *this needs to be within it.
+    @param target_net the net that original_net is netmapped to.
+    @retval true if the netmap was successful, false in case of an error
+    @note no support for overlapping nets or ranges
+*/
+bool IP_RANGE::netmap(const IP_RANGE& original_net, const IP_RANGE& target_net)
+{
+    // input validation
+    if (original_net.t != ip_type::NETWORK ||
+        target_net.t != ip_type::NETWORK)
+        return false;
+
+    if (original_net.mask != target_net.mask)
+        return false;
+
+    // only map if we are within the original net
+    if (!is_within(original_net))
+        return false;
+
+    // everything ok, ready to go
+
+    // difference to start of original net
+    int ipno=turn_ip(ip)-turn_ip(original_net.ip);
+
+    // add that difference to the target net
+    ip=turn_ip(turn_ip(target_net.ip)+ipno);
+
+    // turn the end too
+    ipno=turn_ip(end)-turn_ip(original_net.ip);
+    end=turn_ip(turn_ip(target_net.ip)+ipno);
+
+    return true;
+}
+
 IP_RANGE operator+(const IP_RANGE &base, const int &ips)
 {
     IP_RANGE ret=base;
index 505e9a6..a708179 100644 (file)
@@ -51,6 +51,8 @@ class IP_RANGE
 
         bool is_within(const IP_RANGE& a) const;
         bool overlapping(const IP_RANGE& a) const;
+
+        bool netmap(const IP_RANGE& original_net, const IP_RANGE& target_net);
         
         int operator-(const IP_RANGE &other);
         
index e18cf41..dce227e 100644 (file)
@@ -33,6 +33,15 @@ inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, t
 
     return os;
 }
+
+template <class charT, class traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os,
+                                                     const IP_RANGE& x)
+{
+    os << x.to_string();
+    return os;
+}
+
 } // eo namespace std
 
 
@@ -769,4 +778,61 @@ BOOST_AUTO_TEST_CASE(IpNumString3)
     BOOST_CHECK_EQUAL(expected,IP_RANGE::ip_num_string(myip.get_base()));
 }
 
+BOOST_AUTO_TEST_CASE(NetmapValidation1)
+{
+    IP_RANGE myip("192.168.1.11");
+    IP_RANGE original("192.168.1.0/255.255.255.0");
+    IP_RANGE target("192.168.2.0/255.255.0.0");
+
+    BOOST_CHECK_EQUAL(false,myip.netmap(original,target));
+}
+
+BOOST_AUTO_TEST_CASE(NetmapValidation2)
+{
+    IP_RANGE myip("192.168.3.11");
+    IP_RANGE original("192.168.1.0/255.255.255.0");
+    IP_RANGE target("192.168.2.0/255.255.255.0");
+
+    BOOST_CHECK_EQUAL(false,myip.netmap(original,target));
+}
+
+BOOST_AUTO_TEST_CASE(NetmapValidation3)
+{
+    IP_RANGE myip("192.168.1.70-192.168.2.20");
+    IP_RANGE original("192.168.1.0/255.255.255.0");
+    IP_RANGE target("192.168.2.0/255.255.255.0");
+
+    BOOST_CHECK_EQUAL(false,myip.netmap(original,target));
+}
+
+BOOST_AUTO_TEST_CASE(Netmap1)
+{
+    IP_RANGE myip("192.168.1.11");
+    IP_RANGE original("192.168.1.0/255.255.255.0");
+    IP_RANGE target("192.168.2.0/255.255.255.0");
+
+    BOOST_CHECK_EQUAL(true,myip.netmap(original,target));
+    BOOST_CHECK_EQUAL(IP_RANGE("192.168.2.11"),myip);
+}
+
+BOOST_AUTO_TEST_CASE(Netmap2)
+{
+    IP_RANGE myip("192.168.1.11-192.168.1.22");
+    IP_RANGE original("192.168.1.0/255.255.255.0");
+    IP_RANGE target("192.168.2.0/255.255.255.0");
+
+    BOOST_CHECK_EQUAL(true,myip.netmap(original,target));
+    BOOST_CHECK_EQUAL(IP_RANGE("192.168.2.11-192.168.2.22"),myip);
+}
+
+BOOST_AUTO_TEST_CASE(Netmap3)
+{
+    IP_RANGE myip("192.168.1.0/255.255.255.0");
+    IP_RANGE original("192.168.1.0/255.255.255.0");
+    IP_RANGE target("192.168.2.0/255.255.255.0");
+
+    BOOST_CHECK_EQUAL(true,myip.netmap(original,target));
+    BOOST_CHECK_EQUAL(IP_RANGE("192.168.2.0/255.255.255.0"),myip);
+}
+
 BOOST_AUTO_TEST_SUITE_END()