File: Mask.hs

package info (click to toggle)
haskell-iproute 1.7.15-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 152 kB
  • sloc: haskell: 1,299; makefile: 2
file content (48 lines) | stat: -rw-r--r-- 1,256 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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