module Data.IP.Mask where import Data.Bits import Data.IP.Addr import Data.Word maskIPv4 :: Int -> IPv4 maskIPv4 len = IP4 $ complement $ 0xffffffff `shift` (-len) maskIPv6 :: Int -> IPv6 maskIPv6 len = IP6 $ toIP6Addr $ bimapTup complement $ (0xffffffffffffffff, 0xffffffffffffffff) `shift128` (-len) where bimapTup f (x,y) = (f x, f y) shift128 :: (Word64, Word64) -> Int -> (Word64, Word64) shift128 x i | i < 0 = x `shiftR128` (-i) | i > 0 = x `shiftL128` i | otherwise = x shiftL128 :: (Word64, Word64) -> Int -> (Word64, Word64) shiftL128 (h, l) i = ( (h `shiftL` i) .|. (l `shift` (i - 64) ), (l `shiftL` i)) shiftR128 :: (Word64, Word64) -> Int -> (Word64, Word64) shiftR128 (h, l) i = (h `shiftR` i, (l `shiftR` i) .|. h `shift` (64 - i) ) fromIP6Addr :: IPv6Addr -> (Word64, Word64) fromIP6Addr (w3, w2, w1, w0) = ( (fromIntegral w3 `shiftL` 32) .|. fromIntegral w2 , (fromIntegral w1 `shiftL` 32) .|. fromIntegral w0 ) toIP6Addr :: (Word64, Word64) -> IPv6Addr toIP6Addr (h, l) = ( fromIntegral $ (h `shiftR` 32) .&. m , fromIntegral $ h .&. m , fromIntegral $ (l `shiftR` 32) .&. m , fromIntegral $ l .&. m ) where m = 0xffffffff