]> gitweb.michael.orlitzky.com - hath.git/blobdiff - src/Cidr.hs
Added the adjacent function to Cidr.
[hath.git] / src / Cidr.hs
index 12d9689df71a7cbe955f4be1edb74c934263ef65..1b7d1dd0892c2536e09cf9fb5e97a132a02cfdb8 100644 (file)
@@ -1,7 +1,7 @@
 module Cidr
 ( Cidr(..),
   cidr_from_string,
-  contains
+  combine_all
 ) where
 
 import IPv4Address
@@ -13,7 +13,12 @@ import Octet
 
 data Cidr = None | Cidr { ipv4address :: IPv4Address,
                           maskbits :: Maskbits }
-            deriving (Eq, Show)
+            deriving (Eq)
+
+
+instance Show Cidr where
+    show Cidr.None = "None"
+    show cidr = (show (ipv4address cidr)) ++ "/" ++ (show (maskbits cidr))
 
 
 -- Returns the mask portion of a CIDR address. That is, everything
@@ -91,3 +96,39 @@ contains (Cidr addr1 mbits1) (Cidr addr2 mbits2)
     where
       addr1masked = apply_mask addr1 mbits1
       addr2masked = apply_mask addr2 mbits1
+
+
+contains_proper :: Cidr -> Cidr -> Bool
+contains_proper cidr1 cidr2 =
+    (cidr1 `contains` cidr2) && (not (cidr1 == cidr2))
+
+
+-- A CIDR range is redundant (with respect to the given list) if
+-- another CIDR range in that list properly contains it.
+redundant :: [Cidr] -> Cidr -> Bool
+redundant cidrlist cidr = any ((flip contains_proper) cidr) cidrlist
+
+
+-- We want to get rid of all the Cidrs that are properly contained
+-- in some other Cidr.
+combine_all :: [Cidr] -> [Cidr]
+combine_all cidrs =
+    filter (not . (redundant cidrs)) cidrs
+
+
+-- Determine whether or not two CIDR ranges are adjacent. If two
+-- ranges lie consecutively within the IP space, they can be
+-- combined. For example, 10.1.0.0/24 and 10.0.1.0/24 are adjacent,
+-- and can be combined in to 10.1.0.0/23.
+adjacent :: Cidr -> Cidr -> Bool
+adjacent Cidr.None _ = False
+adjacent _ Cidr.None = False
+adjacent cidr1 cidr2
+  | mbits1 /= mbits2 = False
+  | mbits1 == Maskbits.Zero = False -- They're equal.
+  | otherwise = (mbits1 == (most_sig_bit_different addr1 addr2))
+  where
+    addr1 = ipv4address cidr1
+    addr2 = ipv4address cidr2
+    mbits1 = maskbits cidr1
+    mbits2 = maskbits cidr2