-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | IP Routing Table
--   
--   IP Routing Table is a tree of IP ranges to search one of them on the
--   longest match base. It is a kind of TRIE with one way branching
--   removed. Both IPv4 and IPv6 are supported.
@package iproute
@version 1.7.1

module Data.IP.Internal

-- | The abstract data type to express an IPv4 address. To create this, use
--   toIPv4. Or use read "192.0.2.1" :: IPv4,
--   for example. Also, "192.0.2.1" can be used as literal with
--   OverloadedStrings.
--   
--   
--   >>> read "192.0.2.1" :: IPv4
--   192.0.2.1
--   
newtype IPv4
IP4 :: IPv4Addr -> IPv4

-- | The abstract data type to express an IPv6 address. To create this, use
--   toIPv6. Or use read "2001:DB8::1" ::
--   IPv6, for example. Also, "2001:DB8::1" can be used as
--   literal with OverloadedStrings.
--   
--   
--   >>> read "2001:db8:00:00:00:00:00:01" :: IPv6
--   2001:db8::1
--   
--   >>> read "2001:db8:11e:c00::101" :: IPv6
--   2001:db8:11e:c00::101
--   
--   >>> read "2001:db8:11e:c00:aa:bb:192.0.2.1" :: IPv6
--   2001:db8:11e:c00:aa:bb:c000:201
--   
--   >>> read "2001:db8::192.0.2.1" :: IPv6
--   2001:db8::c000:201
--   
--   >>> read "0::ffff:192.0.2.1" :: IPv6
--   ::ffff:192.0.2.1
--   
--   >>> read "0::0:c000:201" :: IPv6
--   ::192.0.2.1
--   
--   >>> read "::0.0.0.1" :: IPv6
--   ::1
--   
newtype IPv6
IP6 :: IPv6Addr -> IPv6

-- | The Addr range consists of an address, a contiguous mask, and mask
--   length. The contiguous mask and the mask length are essentially same
--   information but contained for pre calculation.
--   
--   To create this, use makeAddrRange or read
--   "192.0.2.0/24" :: AddrRange IPv4. Also,
--   "192.0.2.0/24" can be used as literal with OverloadedStrings.
--   
--   
--   >>> read "192.0.2.1/24" :: AddrRange IPv4
--   192.0.2.0/24
--   
--   >>> read "2001:db8:00:00:00:00:00:01/48" :: AddrRange IPv6
--   2001:db8::/48
--   
data AddrRange a
AddrRange :: !a -> !a -> {-# UNPACK #-} !Int -> AddrRange a

-- | The addr function returns an address from AddrRange.
[addr] :: AddrRange a -> !a

-- | The mask function returns a contiguous IP mask from
--   AddrRange.
[mask] :: AddrRange a -> !a

-- | The mlen function returns a mask length from AddrRange.
[mlen] :: AddrRange a -> {-# UNPACK #-} !Int

-- | IP routing table is a tree of IPRange to search one of them
--   on the longest match base. It is a kind of TRIE with one way branching
--   removed. Both IPv4 and IPv6 are supported.
--   
--   For more information, see:
--   http://www.mew.org/~kazu/proj/iproute/
module Data.IP.RouteTable

-- | A class to contain IPv4 and IPv6.
class Addr a => Routable a

-- | The intToTBit function takes Int and returns an
--   Routable address whose only n-th bit is set.
intToTBit :: Routable a => Int -> a

-- | The isZero function takes an Routable address and an
--   test bit Routable address and returns True is the bit is
--   unset, otherwise returns False.
isZero :: Routable a => a -> a -> Bool

-- | The Tree structure for IP routing table based on TRIE with one way
--   branching removed. This is an abstract data type, so you cannot touch
--   its inside. Please use insert or lookup, instead.
data IPRTable k a

-- | The empty function returns an empty IP routing table.
--   
--   
--   >>> (empty :: IPRTable IPv4 ()) == fromList []
--   True
--   
empty :: Routable k => IPRTable k a

-- | The insert function inserts a value with a key of
--   AddrRange to IPRTable and returns a new IPRTable.
--   
--   
--   >>> (insert ("127.0.0.1" :: AddrRange IPv4) () empty) == fromList [("127.0.0.1",())]
--   True
--   
insert :: (Routable k) => AddrRange k -> a -> IPRTable k a -> IPRTable k a

-- | The delete function deletes a value by a key of
--   AddrRange from IPRTable and returns a new
--   IPRTable.
--   
--   
--   >>> delete "127.0.0.1" (insert "127.0.0.1" () empty) == (empty :: IPRTable IPv4 ())
--   True
--   
delete :: (Routable k) => AddrRange k -> IPRTable k a -> IPRTable k a

-- | The lookup function looks up IPRTable with a key of
--   AddrRange. If a routing information in IPRTable matches
--   the key, its value is returned.
--   
--   
--   >>> let v4 = ["133.4.0.0/16","133.5.0.0/16","133.5.16.0/24","133.5.23.0/24"] :: [AddrRange IPv4]
--   
--   >>> let rt = fromList $ zip v4 v4
--   
--   >>> lookup "127.0.0.1" rt
--   Nothing
--   
--   >>> lookup "133.3.0.1" rt
--   Nothing
--   
--   >>> lookup "133.4.0.0" rt
--   Just 133.4.0.0/16
--   
--   >>> lookup "133.4.0.1" rt
--   Just 133.4.0.0/16
--   
--   >>> lookup "133.5.16.0" rt
--   Just 133.5.16.0/24
--   
--   >>> lookup "133.5.16.1" rt
--   Just 133.5.16.0/24
--   
lookup :: Routable k => AddrRange k -> IPRTable k a -> Maybe a

-- | The findMatch function looks up IPRTable with a key of
--   AddrRange. If the key matches routing informations in
--   IPRTable, they are returned.
--   
--   
--   >>> let v4 = ["133.4.0.0/16","133.5.0.0/16","133.5.16.0/24","133.5.23.0/24"] :: [AddrRange IPv4]
--   
--   >>> let rt = fromList $ zip v4 $ repeat ()
--   
--   >>> findMatch "133.4.0.0/15" rt :: [(AddrRange IPv4,())]
--   [(133.4.0.0/16,()),(133.5.0.0/16,()),(133.5.16.0/24,()),(133.5.23.0/24,())]
--   
findMatch :: MonadPlus m => Routable k => AddrRange k -> IPRTable k a -> m (AddrRange k, a)

-- | The fromList function creates a new IP routing table from a
--   list of a pair of IPrange and value.
fromList :: Routable k => [(AddrRange k, a)] -> IPRTable k a

-- | The toList function creates a list of a pair of
--   AddrRange and value from an IP routing table.
toList :: Routable k => IPRTable k a -> [(AddrRange k, a)]

-- | Data structures to express IPv4, IPv6 and IP range.
module Data.IP

-- | A unified IP data for IPv4 and IPv6. To create this, use
--   the data constructors. Or use read "192.0.2.1" ::
--   IP, for example. Also, "192.0.2.1" can be used as
--   literal with OverloadedStrings.
--   
--   
--   >>> (read "192.0.2.1" :: IP) == IPv4 (read "192.0.2.1" :: IPv4)
--   True
--   
--   >>> (read "2001:db8:00:00:00:00:00:01" :: IP) == IPv6 (read "2001:db8:00:00:00:00:00:01" :: IPv6)
--   True
--   
data IP
IPv4 :: IPv4 -> IP
[ipv4] :: IP -> IPv4
IPv6 :: IPv6 -> IP
[ipv6] :: IP -> IPv6

-- | The abstract data type to express an IPv4 address. To create this, use
--   toIPv4. Or use read "192.0.2.1" :: IPv4,
--   for example. Also, "192.0.2.1" can be used as literal with
--   OverloadedStrings.
--   
--   
--   >>> read "192.0.2.1" :: IPv4
--   192.0.2.1
--   
data IPv4

-- | The toIPv4 function takes a list of Int and returns
--   IPv4.
--   
--   
--   >>> toIPv4 [192,0,2,1]
--   192.0.2.1
--   
toIPv4 :: [Int] -> IPv4

-- | The fromIPv4 function converts IPv4 to a list of
--   Int.
--   
--   
--   >>> fromIPv4 (toIPv4 [192,0,2,1])
--   [192,0,2,1]
--   
fromIPv4 :: IPv4 -> [Int]

-- | The fromHostAddress function converts HostAddress to
--   IPv4.
fromHostAddress :: HostAddress -> IPv4

-- | The toHostAddress function converts IPv4 to
--   HostAddress.
toHostAddress :: IPv4 -> HostAddress

-- | The abstract data type to express an IPv6 address. To create this, use
--   toIPv6. Or use read "2001:DB8::1" ::
--   IPv6, for example. Also, "2001:DB8::1" can be used as
--   literal with OverloadedStrings.
--   
--   
--   >>> read "2001:db8:00:00:00:00:00:01" :: IPv6
--   2001:db8::1
--   
--   >>> read "2001:db8:11e:c00::101" :: IPv6
--   2001:db8:11e:c00::101
--   
--   >>> read "2001:db8:11e:c00:aa:bb:192.0.2.1" :: IPv6
--   2001:db8:11e:c00:aa:bb:c000:201
--   
--   >>> read "2001:db8::192.0.2.1" :: IPv6
--   2001:db8::c000:201
--   
--   >>> read "0::ffff:192.0.2.1" :: IPv6
--   ::ffff:192.0.2.1
--   
--   >>> read "0::0:c000:201" :: IPv6
--   ::192.0.2.1
--   
--   >>> read "::0.0.0.1" :: IPv6
--   ::1
--   
data IPv6

-- | The toIPv6 function takes a list of Int and returns
--   IPv6.
--   
--   
--   >>> toIPv6 [0x2001,0xDB8,0,0,0,0,0,1]
--   2001:db8::1
--   
toIPv6 :: [Int] -> IPv6

-- | The toIPv6b function takes a list of Int where each
--   member repserents a single byte and returns IPv6.
--   
--   
--   >>> toIPv6b [0x20,0x01,0xD,0xB8,0,0,0,0,0,0,0,0,0,0,0,1]
--   2001:db8::1
--   
toIPv6b :: [Int] -> IPv6

-- | The toIPv6 function converts IPv6 to a list of
--   Int.
--   
--   
--   >>> fromIPv6 (toIPv6 [0x2001,0xDB8,0,0,0,0,0,1])
--   [8193,3512,0,0,0,0,0,1]
--   
fromIPv6 :: IPv6 -> [Int]

-- | The fromIPv6b function converts IPv6 to a list of
--   Int where each member represents a single byte.
--   
--   
--   >>> fromIPv6b (toIPv6b [0x20,0x01,0xD,0xB8,0,0,0,0,0,0,0,0,0,0,0,1])
--   [32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,1]
--   
fromIPv6b :: IPv6 -> [Int]

-- | The fromHostAddress6 function converts HostAddress6 to
--   IPv6.
fromHostAddress6 :: HostAddress6 -> IPv6

-- | The toHostAddress6 function converts IPv6 to
--   HostAddress6.
toHostAddress6 :: IPv6 -> HostAddress6

-- | A unified data for AddrRange IPv4 and AddrRange
--   IPv6. To create this, use read "192.0.2.0/24"
--   :: IPRange. Also, "192.0.2.0/24" can be used as
--   literal with OverloadedStrings.
--   
--   
--   >>> (read "192.0.2.1/24" :: IPRange) == IPv4Range (read "192.0.2.0/24" :: AddrRange IPv4)
--   True
--   
--   >>> (read "2001:db8:00:00:00:00:00:01/48" :: IPRange) == IPv6Range (read "2001:db8:00:00:00:00:00:01/48" :: AddrRange IPv6)
--   True
--   
data IPRange
IPv4Range :: AddrRange IPv4 -> IPRange
[ipv4range] :: IPRange -> AddrRange IPv4
IPv6Range :: AddrRange IPv6 -> IPRange
[ipv6range] :: IPRange -> AddrRange IPv6

-- | The Addr range consists of an address, a contiguous mask, and mask
--   length. The contiguous mask and the mask length are essentially same
--   information but contained for pre calculation.
--   
--   To create this, use makeAddrRange or read
--   "192.0.2.0/24" :: AddrRange IPv4. Also,
--   "192.0.2.0/24" can be used as literal with OverloadedStrings.
--   
--   
--   >>> read "192.0.2.1/24" :: AddrRange IPv4
--   192.0.2.0/24
--   
--   >>> read "2001:db8:00:00:00:00:00:01/48" :: AddrRange IPv6
--   2001:db8::/48
--   
data AddrRange a

-- | 
--   >>> toIPv4 [127,0,2,1] `masked` intToMask 7
--   126.0.0.0
--   
class Eq a => Addr a

-- | The masked function takes an Addr and a contiguous mask
--   and returned a masked Addr.
masked :: Addr a => a -> a -> a

-- | The intToMask function takes an Int representing the
--   number of bits to be set in the returned contiguous mask. When this
--   integer is positive the bits will be starting from the MSB and from
--   the LSB otherwise.
--   
--   
--   >>> intToMask 16 :: IPv4
--   255.255.0.0
--   
--   
--   
--   >>> intToMask (-16) :: IPv4
--   0.0.255.255
--   
--   
--   
--   >>> intToMask 16 :: IPv6
--   ffff::
--   
--   
--   
--   >>> intToMask (-16) :: IPv6
--   ::ffff
--   
intToMask :: Addr a => Int -> a

-- | The makeAddrRange functions takes an Addr address and a
--   mask length. It creates a bit mask from the mask length and masks the
--   Addr address, then returns AddrRange made of them.
--   
--   
--   >>> makeAddrRange (toIPv4 [127,0,2,1]) 8
--   127.0.0.0/8
--   
--   >>> makeAddrRange (toIPv6 [0x2001,0xDB8,0,0,0,0,0,1]) 8
--   2000::/8
--   
makeAddrRange :: Addr a => a -> Int -> AddrRange a

-- | The >:> operator takes two AddrRange. It returns
--   True if the first AddrRange contains the second
--   AddrRange. Otherwise, it returns False.
--   
--   
--   >>> makeAddrRange ("127.0.2.1" :: IPv4) 8 >:> makeAddrRange "127.0.2.1" 24
--   True
--   
--   >>> makeAddrRange ("127.0.2.1" :: IPv4) 24 >:> makeAddrRange "127.0.2.1" 8
--   False
--   
--   >>> makeAddrRange ("2001:DB8::1" :: IPv6) 16 >:> makeAddrRange "2001:DB8::1" 32
--   True
--   
--   >>> makeAddrRange ("2001:DB8::1" :: IPv6) 32 >:> makeAddrRange "2001:DB8::1" 16
--   False
--   
(>:>) :: Addr a => AddrRange a -> AddrRange a -> Bool

-- | The toMatchedTo function take an Addr address and an
--   AddrRange, and returns True if the range contains the
--   address.
--   
--   
--   >>> ("127.0.2.0" :: IPv4) `isMatchedTo` makeAddrRange "127.0.2.1" 24
--   True
--   
--   >>> ("127.0.2.0" :: IPv4) `isMatchedTo` makeAddrRange "127.0.2.1" 32
--   False
--   
--   >>> ("2001:DB8::1" :: IPv6) `isMatchedTo` makeAddrRange "2001:DB8::1" 32
--   True
--   
--   >>> ("2001:DB8::" :: IPv6) `isMatchedTo` makeAddrRange "2001:DB8::1" 128
--   False
--   
isMatchedTo :: Addr a => a -> AddrRange a -> Bool

-- | The unmakeAddrRange functions take a AddrRange and
--   returns the network address and a mask length.
--   
--   
--   >>> addrRangePair ("127.0.0.0/8" :: AddrRange IPv4)
--   (127.0.0.0,8)
--   
--   >>> addrRangePair ("2000::/8" :: AddrRange IPv6)
--   (2000::,8)
--   
addrRangePair :: Addr a => AddrRange a -> (a, Int)

-- | Convert IPv4 range to IPV4-embedded-in-IPV6 range
ipv4RangeToIPv6 :: AddrRange IPv4 -> AddrRange IPv6

-- | Convert IPv4 address to IPv4-embedded-in-IPv6
ipv4ToIPv6 :: IPv4 -> IPv6
