libi2ncommon: (tomj) extended IP_RANGE class with operator+ and operator-
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 26 Aug 2004 16:52:30 +0000 (16:52 +0000)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 26 Aug 2004 16:52:30 +0000 (16:52 +0000)
src/ipfunc.cpp
src/ipfunc.hxx
test/ip_range.cpp

index 62c8667..b02a168 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <string>
 #include <sstream>
+#include <iostream>
 #include <stdexcept>
 
 #include <arpa/inet.h>
@@ -163,6 +164,13 @@ void IP_RANGE::load(type t, const std::string& ip, const std::string& mask_or_en
     
         this->ip=ia_ip1.s_addr;
         this->end=ia_ip2.s_addr;
+        
+        // Automatically turn IP if IP & and are swapped
+        if (turn_ip(this->ip) > turn_ip(this->end)) {
+            unsigned int tmp = this->ip;
+            this->ip = this->end;
+            this->end = tmp;
+        }
     }
 }
 
@@ -206,6 +214,31 @@ bool IP_RANGE::overlapping(const IP_RANGE& a) const
     return false;
 }
 
+IP_RANGE operator+(const IP_RANGE &base, const int &ips)
+{
+    IP_RANGE ret=base;
+
+    ret.ip = ret.turn_ip(ret.turn_ip(ret.ip) + ips);
+    ret.end = ret.turn_ip(ret.turn_ip(ret.end) + ips);
+    
+    // Check if this is still a valid network
+    // If not: Convert network to range
+    if (ret.t == NETWORK && (ret.ip&ret.mask) != ret.ip) {
+        ret.t = RANGE;
+        ret.mask = 0;
+    }
+    
+    if (ret.t == RANGE && ret.turn_ip(ret.end) < ret.turn_ip(ret.ip))
+        throw out_of_range("range end lower than begin");
+    
+    return ret;
+}
+
+int IP_RANGE::operator-(const IP_RANGE &other)
+{
+    return turn_ip(ip)-turn_ip(other.ip);
+}
+
 std::string IP_RANGE::to_string(void) const
 {
     struct in_addr ia_ip;
index a4e2a24..1972846 100644 (file)
@@ -17,6 +17,8 @@
 
 class IP_RANGE
 {
+    friend IP_RANGE operator+(const IP_RANGE &base, const int &ips);
+
     private:
         unsigned int ip;
         unsigned int mask;
@@ -37,6 +39,8 @@ class IP_RANGE
         bool is_within(const IP_RANGE& a) const;
         bool overlapping(const IP_RANGE& a) const;
         
+        int operator-(const IP_RANGE &other);
+        
         // returns the complete IP_RANGE
         std::string to_string(void) const;
         
index 0b17edc..6f28dab 100644 (file)
@@ -28,6 +28,7 @@ class ip_range : public TestFixture
     CPPUNIT_TEST(ConstructNet2);
     CPPUNIT_TEST(ConstructRange1);
     CPPUNIT_TEST(ConstructRange2);
+    CPPUNIT_TEST(ConstructRangeSwap);
     CPPUNIT_TEST(OverlapIP);
     CPPUNIT_TEST(OverlapNet1);
     CPPUNIT_TEST(OverlapNet2);
@@ -57,6 +58,10 @@ class ip_range : public TestFixture
     CPPUNIT_TEST(WithinRange8);
     CPPUNIT_TEST(WithinRange9);
     CPPUNIT_TEST(WithinRange10);
+    CPPUNIT_TEST(OperatorPlus1);
+    CPPUNIT_TEST(OperatorPlus2);
+    CPPUNIT_TEST(OperatorPlusOverflow);
+    CPPUNIT_TEST(OperatorMinus);
     
     CPPUNIT_TEST_SUITE_END();
     
@@ -105,6 +110,12 @@ class ip_range : public TestFixture
             CPPUNIT_ASSERT_EQUAL(string("192.168.1.5-192.168.3.1"),i.to_string());
         }
 
+        void ConstructRangeSwap()
+        {
+            IP_RANGE i(ip_type::RANGE,"192.168.3.1","192.168.1.5");
+            CPPUNIT_ASSERT_EQUAL(string("192.168.1.5-192.168.3.1"),i.to_string());
+        }
+        
         void OverlapIP()
         {
             IP_RANGE a("192.168.1.5");
@@ -336,6 +347,38 @@ class ip_range : public TestFixture
             
             CPPUNIT_ASSERT_EQUAL(false,a.is_within(b));
         }
+
+        void OperatorPlus1()
+        {
+            IP_RANGE a("192.168.2.0/255.255.255.0");
+            
+            a=a+256;
+            
+            CPPUNIT_ASSERT_EQUAL(string("192.168.3.0/255.255.255.0"),a.to_string());
+        }
+
+        void OperatorPlus2()
+        {
+            IP_RANGE a("192.168.2.0/255.255.255.0");
+            
+            a=a+13;
+            
+            CPPUNIT_ASSERT_EQUAL(string("192.168.2.13-192.168.3.12"),a.to_string());
+        }
+        
+        void OperatorPlusOverflow()
+        {
+            IP_RANGE a("255.255.255.0/255.255.255.0");
+            CPPUNIT_ASSERT_THROW(a=a+1, std::out_of_range);
+        }
+        
+        void OperatorMinus()
+        {
+            IP_RANGE a("192.168.2.0/255.255.255.0");
+            IP_RANGE b("192.168.1.0/255.255.255.0");
+            
+            CPPUNIT_ASSERT_EQUAL(256,a-b);
+        }
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(ip_range);