V.      !"#$%&'()*+,-None0IThe abstract data type to express an IPv6 address. To create this, use  . Or use .  "2001:DB8::1" :: , 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" :: IPv62001:db8:11e:c00::101/read "2001:db8:11e:c00:aa:bb:192.0.2.1" :: IPv62001:db8:11e:c00:aa:bb:c000:201"read "2001:db8::192.0.2.1" :: IPv62001:db8::c000:201 read "0::ffff:192.0.2.1" :: IPv6::ffff:192.0.2.1read "0::0:c000:201" :: IPv6 ::192.0.2.1read "::0.0.0.1" :: IPv6::1IThe abstract data type to express an IPv4 address. To create this, use  . Or use .  "192.0.2.1" :: , for example. Also,  "192.0.2.1"/ can be used as literal with OverloadedStrings.read "192.0.2.1" :: IPv4 192.0.2.1A unified IP data for  and 6. To create this, use the data constructors. Or use .  "192.0.2.1" :: , 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/1Show an IPv4 address in the dot-decimal notation.0hShow an IPv6 address in the most appropriate notation, based on recommended representation proposed by  "http://tools.ietf.org/html/rfc5952RFC 5952.U/The implementation is completely compatible with the current implementation of the  inet_ntop function in glibc./The  function takes a list of 1 and returns .toIPv4 [192,0,2,1] 192.0.2.1The  function takes a list of 1 and returns .!toIPv6 [0x2001,0xDB8,0,0,0,0,0,1] 2001:db8::1 The   function takes a list of 1: where each member repserents a single byte and returns .4toIPv6b [0x20,0x01,0xD,0xB8,0,0,0,0,0,0,0,0,0,0,0,1] 2001:db8::1 The   function converts  to a list of 1.fromIPv4 (toIPv4 [192,0,2,1]) [192,0,2,1] The  function converts  to a list of 1.,fromIPv6 (toIPv6 [0x2001,0xDB8,0,0,0,0,0,1])[8193,3512,0,0,0,0,0,1] The   function converts  to a list of 1. 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] The   function converts 2 to .The  function converts  to 2.The  function converts 3 to .The  function converts  to 3.-Convert IPv4 address to IPv4-embedded-in-IPv64WEquality over IP addresses. Correctly compare IPv4 and IPv4-embedded-in-IPv6 addresses.V(read "2001:db8:00:00:00:00:00:01" :: IP) == (read "2001:db8:00:00:00:00:00:01" :: IP)TrueV(read "2001:db8:00:00:00:00:00:01" :: IP) == (read "2001:db8:00:00:00:00:00:05" :: IP)False4(read "127.0.0.1" :: IP) == (read "127.0.0.1" :: IP)True3(read "127.0.0.1" :: IP) == (read "10.0.0.1" :: IP)False;(read "::ffff:127.0.0.1" :: IP) == (read "127.0.0.1" :: IP)True;(read "::ffff:127.0.0.1" :: IP) == (read "127.0.0.9" :: IP)False;(read "::ffff:127.0.0.1" :: IP) >= (read "127.0.0.1" :: IP)True;(read "::ffff:127.0.0.1" :: IP) <= (read "127.0.0.1" :: IP)True556789:/0 ;<=>?@ABCDEFG HIJKLMNOPQRST4(56789:/0 ;<=>?@ABCDEFG H/56789:/0 ;<=>?@ABCDEFG HIJKLMNOPQRST4None0UVWXYUVWXYUVWXYNone024The 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 . "192.0.2.0/24" ::   . 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/246read "2001:db8:00:00:00:00:00:01/48" :: AddrRange IPv6 2001:db8::/48The " function returns an address from .The  function returns a contiguous  mask from .The % function returns a mask length from .A unified data for   and  . To create this, use . "192.0.2.0/24" ::  . Also, "192.0.2.0/24"/ can be used as literal with OverloadedStrings.U(read "192.0.2.1/24" :: IPRange) == IPv4Range (read "192.0.2.0/24" :: AddrRange IPv4)Truew(read "2001:db8:00:00:00:00:00:01/48" :: IPRange) == IPv6Range (read "2001:db8:00:00:00:00:00:01/48" :: AddrRange IPv6)TrueZ[\]^_`abcdefghiZ[\]^_`aZ[\]^_`abcdefghiNone0'toIPv4 [127,0,2,1] `masked` intToMask 7 126.0.0.0The  function takes an 3 and a contiguous mask and returned a masked .The  function takes 1% and returns a contiguous mask.The >:> operator takes two  . It returns j if the first  contains the second . Otherwise, it returns k.FmakeAddrRange ("127.0.2.1" :: IPv4) 8 >:> makeAddrRange "127.0.2.1" 24TrueFmakeAddrRange ("127.0.2.1" :: IPv4) 24 >:> makeAddrRange "127.0.2.1" 8FalseKmakeAddrRange ("2001:DB8::1" :: IPv6) 16 >:> makeAddrRange "2001:DB8::1" 32TrueKmakeAddrRange ("2001:DB8::1" :: IPv6) 32 >:> makeAddrRange "2001:DB8::1" 16FalseThe  toMatchedTo function take an  address and an , and returns j# if the range contains the address.@("127.0.2.0" :: IPv4) `isMatchedTo` makeAddrRange "127.0.2.1" 24True@("127.0.2.0" :: IPv4) `isMatchedTo` makeAddrRange "127.0.2.1" 32FalseD("2001:DB8::1" :: IPv6) `isMatchedTo` makeAddrRange "2001:DB8::1" 32TrueD("2001:DB8::" :: IPv6) `isMatchedTo` makeAddrRange "2001:DB8::1" 128False The   functions takes an Y address and a mask length. It creates a bit mask from the mask length and masks the  address, then returns  made of them.$makeAddrRange (toIPv4 [127,0,2,1]) 8 127.0.0.0/83makeAddrRange (toIPv6 [0x2001,0xDB8,0,0,0,0,0,1]) 82000::/8!1Convert IPv4 range to IPV4-embedded-in-IPV6 range"The unmakeAddrRange functions take a 5 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)  !"lm !" !"lmNone0 #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 ( or * , instead.$!A class to contain IPv4 and IPv6.%The % function takes 1 and returns an $* address whose only n-th bit is set.&The & function takes an $ address and an test bit $ address and returns j. is the bit is unset, otherwise returns k.'The ', function returns an empty IP routing table.*(empty :: IPRTable IPv4 ()) == fromList []True(The (( function inserts a value with a key of  to # and returns a new #.P(insert ("127.0.0.1" :: AddrRange IPv4) () empty) == fromList [("127.0.0.1",())]True)The )& function deletes a value by a key of  from # and returns a new #.Odelete "127.0.0.1" (insert "127.0.0.1" () empty) == (empty :: IPRTable IPv4 ())True*The * function looks up # with a key of  . If a routing information in #* 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 v4lookup "127.0.0.1" rtNothinglookup "133.3.0.1" rtNothinglookup "133.4.0.0" rtJust 133.4.0.0/16lookup "133.4.0.1" rtJust 133.4.0.0/16lookup "133.5.16.0" rtJust 133.5.16.0/24lookup "133.5.16.1" rtJust 133.5.16.0/24+The + function looks up # with a key of /. If the key matches routing informations in #, 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 ()4findMatch "133.4.0.0/15" rt :: [(AddrRange IPv4,())]K[(133.4.0.0/16,()),(133.5.0.0/16,()),(133.5.16.0/24,()),(133.5.23.0/24,())],The ,D function creates a new IP routing table from a list of a pair of IPrange and value.-The -& function creates a list of a pair of & and value from an IP routing table.#no$%&pqrst'(uvwx)y*z+,-{|}~#no$%&pqrst'(uvwx)y*z+,-{#on$%&pqrst'(uvwx)y*z+,-{|}~None0 #$%&'()*+,- $%&#'()*+,-None0#  !"#   "!       !"#$%&'()*+,-./0123456789:;<=><=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrst9:u9:vwxyz{|}~ iproute-1.4.0Data.IPData.IP.RouteTable Data.IP.Addr Data.IP.Mask Data.IP.Range Data.IP.OpData.IP.RouteTable.InternalIPv6IPv4IPipv6ipv4toIPv4toIPv6toIPv6bfromIPv4fromIPv6 fromIPv6bfromHostAddress toHostAddressfromHostAddress6toHostAddress6 ipv4ToIPv6 AddrRangeaddrmaskmlenIPRange IPv6Range ipv6range IPv4Range ipv4rangeAddrmasked intToMask>:> isMatchedTo makeAddrRangeipv4RangeToIPv6 addrRangePairIPRTableRoutable intToTBitisZeroemptyinsertdeletelookup findMatchfromListtoListbase Text.ReadreadshowIPv4showIPv6ghc-prim GHC.TypesIntnetwork-2.6.0.2Network.Socket.Types HostAddress HostAddress6$fEqIPIP6IP4IPv6AddrIPv4Addr ip6ToInteger integerToIP6parseIP parseIPv4 parseIPv6digip4ip4' skipSpaceshexcolon2formatip6ip6' ip4Embedded fixByteOrder$fIsStringIPv6$fIsStringIPv4 $fIsStringIP $fReadIPv6 $fReadIPv4$fReadIP $fShowIPv6 $fShowIPv4 $fEnumIPv6 $fEnumIPv4$fShowIP$fOrdIPmaskIPv4maskIPv6 masksWord32 masksIPv4 masksIPv6 parseIPRangeparseIPv4RangeparseIPv6Rangeip4range maskedIPv4ip6range maskedIPv6$fIsStringAddrRange$fIsStringAddrRange0$fIsStringIPRange$fReadAddrRange$fReadAddrRange0 $fReadIPRange $fShowIPRange$fShowAddrRangeTrueFalse $fAddrIPv6 $fAddrIPv4NodeNil intToTBitIPv4 intToTBitIPv6intToTBitsWord32intToTBitsIPv4intToTBitsIPv6linkglue keyToTestBitisLeftnodesearchfoldt$fTraversableIPRTable$fFoldableIPRTable$fFunctorIPRTable$fRoutableIPv6$fRoutableIPv4