-module IPv4Address where
-
-import Bit
-import Octet
-
-type Maskbits = Int
-
-data IPv4Address = IPv4Address { octet1 :: Octet,
- octet2 :: Octet,
- octet3 :: Octet,
- octet4 :: Octet }
- deriving (Eq, Show)
-
-
-min_address :: IPv4Address -> Maskbits -> IPv4Address
-min_address addr mask
- | mask == 32 = IPv4Address oct1 oct2 oct3 oct4
- | mask == 31 = IPv4Address oct1 oct2 oct3 (Octet a25 a26 a27 a28 a29 a30 a31 Zero)
- | mask == 30 = IPv4Address oct1 oct2 oct3 (Octet a25 a26 a27 a28 a29 a30 Zero Zero)
- | mask == 29 = IPv4Address oct1 oct2 oct3 (Octet a25 a26 a27 a28 a29 Zero Zero Zero)
- | mask == 28 = IPv4Address oct1 oct2 oct3 (Octet a25 a26 a27 a28 Zero Zero Zero Zero)
- | mask == 27 = IPv4Address oct1 oct2 oct3 (Octet a25 a26 a27 Zero Zero Zero Zero Zero)
- | mask == 26 = IPv4Address oct1 oct2 oct3 (Octet a25 a26 Zero Zero Zero Zero Zero Zero)
- | mask == 25 = IPv4Address oct1 oct2 oct3 (Octet a25 Zero Zero Zero Zero Zero Zero Zero)
- | mask == 24 = IPv4Address oct1 oct2 oct3 (min_octet)
- | mask == 23 = IPv4Address oct1 oct2 (Octet a17 a18 a19 a20 a21 a22 a23 Zero) (min_octet)
- | mask == 22 = IPv4Address oct1 oct2 (Octet a17 a18 a19 a20 a21 a22 Zero Zero) (min_octet)
- | mask == 21 = IPv4Address oct1 oct2 (Octet a17 a18 a19 a20 a21 Zero Zero Zero) (min_octet)
- | mask == 20 = IPv4Address oct1 oct2 (Octet a17 a18 a19 a20 Zero Zero Zero Zero) (min_octet)
- | mask == 19 = IPv4Address oct1 oct2 (Octet a17 a18 a19 Zero Zero Zero Zero Zero) (min_octet)
- | mask == 18 = IPv4Address oct1 oct2 (Octet a17 a18 Zero Zero Zero Zero Zero Zero) (min_octet)
- | mask == 17 = IPv4Address oct1 oct2 (Octet a17 Zero Zero Zero Zero Zero Zero Zero) (min_octet)
- | mask == 16 = IPv4Address oct1 oct2 (min_octet) (min_octet)
- | mask == 15 = IPv4Address oct1 (Octet a9 a10 a11 a12 a13 a14 a15 Zero) (min_octet) (min_octet)
- | mask == 14 = IPv4Address oct1 (Octet a9 a10 a11 a12 a13 a14 Zero Zero) (min_octet) (min_octet)
- | mask == 13 = IPv4Address oct1 (Octet a9 a10 a11 a12 a13 Zero Zero Zero) (min_octet) (min_octet)
- | mask == 12 = IPv4Address oct1 (Octet a9 a10 a11 a12 Zero Zero Zero Zero) (min_octet) (min_octet)
- | mask == 11 = IPv4Address oct1 (Octet a9 a10 a11 Zero Zero Zero Zero Zero) (min_octet) (min_octet)
- | mask == 10 = IPv4Address oct1 (Octet a9 a10 Zero Zero Zero Zero Zero Zero) (min_octet) (min_octet)
- | mask == 9 = IPv4Address oct1 (Octet a9 Zero Zero Zero Zero Zero Zero Zero) (min_octet) (min_octet)
- | mask == 8 = IPv4Address oct1 (min_octet) (min_octet) (min_octet)
- | mask == 7 = IPv4Address (Octet a1 a2 a3 a4 a5 a6 a7 Zero) (min_octet) (min_octet) (min_octet)
- | mask == 6 = IPv4Address (Octet a1 a2 a3 a4 a5 a6 Zero Zero) (min_octet) (min_octet) (min_octet)
- | mask == 5 = IPv4Address (Octet a1 a2 a3 a4 a5 Zero Zero Zero) (min_octet) (min_octet) (min_octet)
- | mask == 4 = IPv4Address (Octet a1 a2 a3 a4 Zero Zero Zero Zero) (min_octet) (min_octet) (min_octet)
- | mask == 3 = IPv4Address (Octet a1 a2 a3 Zero Zero Zero Zero Zero) (min_octet) (min_octet) (min_octet)
- | mask == 2 = IPv4Address (Octet a1 a2 Zero Zero Zero Zero Zero Zero) (min_octet) (min_octet) (min_octet)
- | mask == 1 = IPv4Address (Octet a1 Zero Zero Zero Zero Zero Zero Zero) (min_octet) (min_octet) (min_octet)
- | mask == 0 = IPv4Address (min_octet) (min_octet) (min_octet) (min_octet)
- | otherwise = addr
+module IPv4Address(
+ IPv4Address(..),
+ ipv4address_properties,
+ ipv4address_tests,
+ most_sig_bit_different )
+where
+
+import Test.HUnit (assertEqual)
+import Test.Framework (Test, testGroup)
+import Test.Framework.Providers.HUnit (testCase)
+import Test.Framework.Providers.QuickCheck2 (testProperty)
+import Test.QuickCheck (Arbitrary(..), Gen, Property, (==>))
+
+import Maskable (Maskable(..))
+import Maskbits (Maskbits(..))
+import Octet (Octet(..))
+
+data IPv4Address =
+ IPv4Address { octet1 :: Octet,
+ octet2 :: Octet,
+ octet3 :: Octet,
+ octet4 :: Octet }
+ deriving (Eq)
+
+
+instance Show IPv4Address where
+ show addr = concat [(show oct1) ++ ".",
+ (show oct2) ++ ".",
+ (show oct3) ++ ".",
+ (show oct4)]
+ where
+ oct1 = (octet1 addr)
+ oct2 = (octet2 addr)
+ oct3 = (octet3 addr)
+ oct4 = (octet4 addr)
+
+
+instance Arbitrary IPv4Address where
+ arbitrary = do
+ oct1 <- arbitrary :: Gen Octet
+ oct2 <- arbitrary :: Gen Octet
+ oct3 <- arbitrary :: Gen Octet
+ oct4 <- arbitrary :: Gen Octet
+ return (IPv4Address oct1 oct2 oct3 oct4)
+
+
+
+instance Maskable IPv4Address where
+
+ apply_mask addr mask bit =
+ apply_mask' mask
+ where
+ oct1 = octet1 addr
+ oct2 = octet2 addr
+ oct3 = octet3 addr
+ oct4 = octet4 addr
+
+ -- A copy of 'addr' with the fourth octet zeroed (or oned).
+ new_addr1 = addr { octet4 = (apply_mask oct4 Zero bit) }
+
+ -- Likewise for new_addr1's third octet.
+ new_addr2 = new_addr1 { octet3 = (apply_mask oct3 Zero bit) }
+
+ -- And new_addr2's second octet.
+ new_addr3 = new_addr2 { octet2 = (apply_mask oct2 Zero bit) }
+
+ -- This helper function allows us to pattern-match cleanly.
+ apply_mask' :: Maskbits -> IPv4Address
+
+ apply_mask' ThirtyTwo = addr
+
+ apply_mask' ThirtyOne = addr { octet4 = (apply_mask oct4 Seven bit) }
+
+ apply_mask' Thirty =
+ addr { octet4 = (apply_mask oct4 Six bit) }
+
+ apply_mask' TwentyNine =
+ addr { octet4 = (apply_mask oct4 Five bit) }
+
+ apply_mask' TwentyEight =
+ addr { octet4 = (apply_mask oct4 Four bit) }
+
+ apply_mask' TwentySeven =
+ addr { octet4 = (apply_mask oct4 Three bit) }
+
+ apply_mask' TwentySix =
+ addr { octet4 = (apply_mask oct4 Two bit) }
+
+ apply_mask' TwentyFive =
+ addr { octet4 = (apply_mask oct4 One bit) }
+
+ apply_mask' TwentyFour = new_addr1
+
+ apply_mask' TwentyThree =
+ new_addr1 { octet3 = (apply_mask oct3 Seven bit) }
+
+ apply_mask' TwentyTwo =
+ new_addr1 { octet3 = (apply_mask oct3 Six bit) }
+
+ apply_mask' TwentyOne =
+ new_addr1 { octet3 = (apply_mask oct3 Five bit) }
+
+ apply_mask' Twenty =
+ new_addr1 { octet3 = (apply_mask oct3 Four bit) }
+
+ apply_mask' Nineteen =
+ new_addr1 { octet3 = (apply_mask oct3 Three bit) }
+
+ apply_mask' Eighteen =
+ new_addr1 { octet3 = (apply_mask oct3 Two bit) }
+
+ apply_mask' Seventeen =
+ new_addr1 { octet3 = (apply_mask oct3 One bit) }
+
+ apply_mask' Sixteen =
+ new_addr2
+
+ apply_mask' Fifteen =
+ new_addr2 { octet2 = (apply_mask oct2 Seven bit) }
+
+ apply_mask' Fourteen =
+ new_addr2 { octet2 = (apply_mask oct2 Six bit) }
+
+ apply_mask' Thirteen =
+ new_addr2 { octet2 = (apply_mask oct2 Five bit) }
+
+ apply_mask' Twelve =
+ new_addr2 { octet2 = (apply_mask oct2 Four bit) }
+
+ apply_mask' Eleven =
+ new_addr2 { octet2 = (apply_mask oct2 Three bit) }
+
+ apply_mask' Ten =
+ new_addr2 { octet2 = (apply_mask oct2 Two bit) }
+
+ apply_mask' Nine =
+ new_addr2 { octet2 = (apply_mask oct2 One bit) }
+
+ apply_mask' Eight =
+ new_addr3 { octet2 = (apply_mask oct2 Zero bit) }
+
+ apply_mask' Seven =
+ new_addr3 { octet1 = (apply_mask oct1 Seven bit) }
+
+ apply_mask' Six =
+ new_addr3 { octet1 = (apply_mask oct1 Six bit) }
+
+ apply_mask' Five =
+ new_addr3 { octet1 = (apply_mask oct1 Five bit) }
+
+ apply_mask' Four =
+ new_addr3 { octet1 = (apply_mask oct1 Four bit) }
+
+ apply_mask' Three =
+ new_addr3 { octet1 = (apply_mask oct1 Three bit) }
+
+ apply_mask' Two =
+ new_addr3 { octet1 = (apply_mask oct1 Two bit) }
+
+ apply_mask' One =
+ new_addr3 { octet1 = (apply_mask oct1 One bit) }
+
+ apply_mask' Zero =
+ new_addr3 { octet1 = (apply_mask oct1 Zero bit) }
+
+
+instance Bounded IPv4Address where
+ -- | The minimum possible IPv4 address, 0.0.0.0.
+ minBound = IPv4Address minBound minBound minBound minBound
+
+ -- | The maximum possible IPv4 address, 255.255.255.255.
+ maxBound = IPv4Address maxBound maxBound maxBound maxBound
+
+
+
+
+instance Enum IPv4Address where
+ -- | Convert an 'Int' @x@ to an 'IPv4Address'. Each octet of @x@ is
+ -- right-shifted by the appropriate number of bits, and the fractional
+ -- part is dropped.
+ toEnum x =
+ IPv4Address oct1 oct2 oct3 oct4