hw-ip-0.2.0.0: src/HaskellWorks/Data/Network/Ip.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DuplicateRecordFields #-}
module HaskellWorks.Data.Network.Ip
( Z.Ipv4Address(Ipv4Address)
, Z.Ipv4NetMask(Ipv4NetMask)
, Z.Ipv4Block(Ipv4Block)
, bitPower
, blockSize
, isCanonical
, splitBlock
) where
import Data.Word
import GHC.Generics
import HaskellWorks.Data.Bits.BitWise
import qualified HaskellWorks.Data.Network.Ip.Type as Z
bitPower :: Z.Ipv4NetMask -> Word64
bitPower (Z.Ipv4NetMask m) = fromIntegral (32 - m)
isCanonical :: Z.Ipv4Block -> Bool
isCanonical (Z.Ipv4Block (Z.Ipv4Address b) m) = ((b .>. bitPower m) .<. bitPower m) == b
splitBlock :: Z.Ipv4Block -> Maybe (Z.Ipv4Block, Z.Ipv4Block)
splitBlock (Z.Ipv4Block (Z.Ipv4Address b) (Z.Ipv4NetMask m)) =
if m >= 0 && m < 32
then let !hm = m + 1
!halfMask = Z.Ipv4NetMask hm
!c = fromIntegral ((0x100000000 :: Word64) .>. fromIntegral (m + 1))
in Just
( Z.Ipv4Block (Z.Ipv4Address b ) halfMask
, Z.Ipv4Block (Z.Ipv4Address (b + c)) halfMask
)
else Nothing
blockSize :: Z.Ipv4Block -> Int
blockSize (Z.Ipv4Block _ m) = 2 ^ bitPower m