iproute 1.3.2 → 1.4.0
raw patch · 6 files changed
+156/−13 lines, 6 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Data.IP: addrRangePair :: Addr a => AddrRange a -> (a, Int)
+ Data.IP: ipv4RangeToIPv6 :: AddrRange IPv4 -> AddrRange IPv6
+ Data.IP: ipv4ToIPv6 :: IPv4 -> IPv6
Files
- Data/IP.hs +2/−1
- Data/IP/Addr.hs +116/−7
- Data/IP/Op.hs +23/−2
- Data/IP/Range.hs +2/−0
- Data/IP/RouteTable/Internal.hs +12/−2
- iproute.cabal +1/−1
Data/IP.hs view
@@ -12,7 +12,8 @@ , AddrRange (addr, mask, mlen) -- ** Address class , Addr (..)- , makeAddrRange, (>:>), isMatchedTo+ , makeAddrRange, (>:>), isMatchedTo, addrRangePair+ , ipv4RangeToIPv6, ipv4ToIPv6 ) where import Data.IP.Addr
Data/IP/Addr.hs view
@@ -11,6 +11,7 @@ import Numeric (showHex, showInt) import System.ByteOrder import Text.Appar.String+import GHC.Enum (succError,predError) #ifdef GENERICS import GHC.Generics #endif@@ -30,11 +31,42 @@ data IP = IPv4 { ipv4 :: IPv4 } | IPv6 { ipv6 :: IPv6 } #ifdef GENERICS- deriving (Eq, Ord, Generic)-#else- deriving (Eq, Ord)+ deriving (Generic) #endif +{-|+ Equality over IP addresses. Correctly compare IPv4 and IPv4-embedded-in-IPv6 addresses.++>>> (read "2001:db8:00:00:00:00:00:01" :: IP) == (read "2001:db8:00:00:00:00:00:01" :: IP)+True+>>> (read "2001:db8:00:00:00:00:00:01" :: IP) == (read "2001:db8:00:00:00:00:00:05" :: IP)+False+>>> (read "127.0.0.1" :: IP) == (read "127.0.0.1" :: IP)+True+>>> (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)+True+-}+instance Eq IP where+ (IPv4 ip1) == (IPv4 ip2) = ip1 == ip2+ (IPv6 ip1) == (IPv6 ip2) = ip1 == ip2+ (IPv4 ip1) == (IPv6 ip2) = ipv4ToIPv6 ip1 == ip2+ (IPv6 ip1) == (IPv4 ip2) = ip1 == ipv4ToIPv6 ip2+++instance Ord IP where+ (IPv4 ip1) `compare` (IPv4 ip2) = ip1 `compare` ip2+ (IPv6 ip1) `compare` (IPv6 ip2) = ip1 `compare` ip2+ (IPv4 ip1) `compare` (IPv6 ip2) = ipv4ToIPv6 ip1 `compare` ip2+ (IPv6 ip1) `compare` (IPv4 ip2) = ip1 `compare` ipv4ToIPv6 ip2+ instance Show IP where show (IPv4 ip) = show ip show (IPv6 ip) = show ip@@ -54,9 +86,9 @@ -} newtype IPv4 = IP4 IPv4Addr #ifdef GENERICS- deriving (Eq, Ord,Generic)+ deriving (Eq, Ord, Bounded, Generic) #else- deriving (Eq, Ord)+ deriving (Eq, Ord, Bounded) #endif {-|@@ -80,13 +112,84 @@ -} newtype IPv6 = IP6 IPv6Addr #ifdef GENERICS- deriving (Eq, Ord,Generic)+ deriving (Eq, Ord, Bounded, Generic) #else- deriving (Eq, Ord)+ deriving (Eq, Ord, Bounded) #endif + ---------------------------------------------------------------- --+-- Enum+--++instance Enum IPv4 where+ fromEnum (IP4 a) = fromEnum a+ toEnum = IP4 . toEnum++instance Enum IPv6 where+ -- fromEnum and toEnum are not really useful, but I defined them anyway+ fromEnum (IP6 (a,b,c,d)) = let a' = fromEnum a `shift` 96+ b' = fromEnum b `shift` 64+ c' = fromEnum c `shift` 32+ d' = fromEnum d+ in a' .|. b' .|. c' .|. d'+ toEnum i = let a = toEnum (i `shiftR` 96 .&. 0xffffffff)+ b = toEnum (i `shiftR` 64 .&. 0xffffffff)+ c = toEnum (i `shiftR` 32 .&. 0xffffffff)+ d = toEnum (i .&. 0xffffffff)+ in IP6 (a,b,c,d)++ succ (IP6 (0xffffffff,0xffffffff,0xffffffff,0xffffffff)) = succError "IPv6"+ succ (IP6 (a, 0xffffffff,0xffffffff,0xffffffff)) = IP6 (succ a,0,0,0)+ succ (IP6 (a, b,0xffffffff,0xffffffff)) = IP6 (a,succ b,0,0)+ succ (IP6 (a, b, c,0xffffffff)) = IP6 (a,b,succ c,0)+ succ (IP6 (a, b, c, d)) = IP6 (a,b,c,succ d)++ pred (IP6 (0,0,0,0)) = predError "IPv6"+ pred (IP6 (a,0,0,0)) = IP6 (pred a, 0xffffffff, 0xffffffff, 0xffffffff)+ pred (IP6 (a,b,0,0)) = IP6 ( a, pred b, 0xffffffff, 0xffffffff)+ pred (IP6 (a,b,c,0)) = IP6 ( a, b, pred c, 0xffffffff)+ pred (IP6 (a,b,c,d)) = IP6 ( a, b, c, pred d)++ enumFrom ip = ip:gen ip+ where gen i = let i' = succ i in i':gen i'++ enumFromTo ip ip' = ip:gen ip+ where gen i+ | i == ip' = []+ | otherwise = let i' = succ i in i':gen i'++ -- These two are implemented via the integer enum instance.+ -- A more correct implementation would essentially require+ -- implementing instance Num IPv6, which isn't something+ -- I wanna do. Another approach is to use Word128 to store+ -- an IPv6 address.+ enumFromThen ip ip' = fmap integerToIP6 [ip6ToInteger ip, ip6ToInteger ip' ..]+ enumFromThenTo ip inc fin = fmap integerToIP6 [ip6ToInteger ip, ip6ToInteger inc .. ip6ToInteger fin]++ip6ToInteger :: IPv6 -> Integer+ip6ToInteger (IP6 (a,b,c,d)) = let a' = word32ToInteger a `shift` 96+ b' = word32ToInteger b `shift` 64+ c' = word32ToInteger c `shift` 32+ d' = word32ToInteger d+ in a' .|. b' .|. c' .|. d'+ where+ word32ToInteger :: Word32 -> Integer+ word32ToInteger = toEnum . fromEnum++integerToIP6 :: Integer -> IPv6+integerToIP6 i = let a = integerToWord32 (i `shiftR` 96 .&. 0xffffffff)+ b = integerToWord32 (i `shiftR` 64 .&. 0xffffffff)+ c = integerToWord32 (i `shiftR` 32 .&. 0xffffffff)+ d = integerToWord32 (i .&. 0xffffffff)+ in IP6 (a,b,c,d)+ where+ integerToWord32 :: Integer -> Word32+ integerToWord32 = toEnum . fromEnum++----------------------------------------------------------------+-- -- Show -- @@ -391,3 +494,9 @@ d2 = shiftL s 8 .&. 0x00ff0000 d3 = shiftR s 8 .&. 0x0000ff00 d4 = shiftR s 24 .&. 0x000000ff++-- | Convert IPv4 address to IPv4-embedded-in-IPv6+ipv4ToIPv6 :: IPv4 -> IPv6+ipv4ToIPv6 ip = toIPv6b [0,0,0,0,0,0,0,0,0,0,0xff,0xff,i1,i2,i3,i4]+ where+ [i1,i2,i3,i4] = fromIPv4 ip
Data/IP/Op.hs view
@@ -29,8 +29,7 @@ intToMask = maskIPv4 instance Addr IPv6 where- IP6 (a1,a2,a3,a4) `masked` IP6 (m1,m2,m3,m4) =- IP6 (a1.&.m1,a2.&.m2,a3.&.m3,a4.&.m4)+ masked = maskedIPv6 intToMask = maskIPv6 ----------------------------------------------------------------@@ -84,3 +83,25 @@ where msk = intToMask len adr = ad `masked` msk+++-- | Convert IPv4 range to IPV4-embedded-in-IPV6 range+ipv4RangeToIPv6 :: AddrRange IPv4 -> AddrRange IPv6+ipv4RangeToIPv6 range =+ makeAddrRange (toIPv6 [0,0,0,0,0,0xffff, (i1 `shift` 8) .|. i2, (i3 `shift` 8) .|. i4]) (masklen + 96)+ where+ (ip, masklen) = addrRangePair range+ [i1,i2,i3,i4] = fromIPv4 ip+++{-|+ 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)+addrRangePair (AddrRange adr _ len) = (adr, len)
Data/IP/Range.hs view
@@ -137,6 +137,8 @@ maskedIPv6 :: IPv6 -> IPv6 -> IPv6 IP6 (a1,a2,a3,a4) `maskedIPv6` IP6 (m1,m2,m3,m4) = IP6 (a1.&.m1,a2.&.m2,a3.&.m3,a4.&.m4) ++ ---------------------------------------------------------------- -- -- IsString
Data/IP/RouteTable/Internal.hs view
@@ -7,15 +7,17 @@ -} module Data.IP.RouteTable.Internal where -import Control.Applicative ((<$>))+import Control.Applicative ((<$>),(<*>),pure) import Control.Monad import Data.Bits+import Data.Foldable (Foldable(..)) import Data.IP.Addr import Data.IP.Op import Data.IP.Range import Data.IntMap (IntMap, (!)) import qualified Data.IntMap as IM (fromList)-import Data.List (foldl')+import Data.Monoid+import Data.Traversable import Data.Word import Prelude hiding (lookup) @@ -100,6 +102,14 @@ instance Functor (IPRTable k) where fmap _ Nil = Nil fmap f (Node r a mv b1 b2) = Node r a (f <$> mv) (fmap f b1) (fmap f b2)++instance Foldable (IPRTable k) where+ foldMap _ Nil = mempty+ foldMap f (Node _ _ mv b1 b2) = foldMap f mv <> foldMap f b1 <> foldMap f b2++instance Traversable (IPRTable k) where+ traverse _ Nil = pure Nil+ traverse f (Node r a mv b1 b2) = Node r a <$> traverse f mv <*> traverse f b1 <*> traverse f b2 ----------------------------------------------------------------
iproute.cabal view
@@ -1,5 +1,5 @@ Name: iproute-Version: 1.3.2+Version: 1.4.0 Author: Kazu Yamamoto <kazu@iij.ad.jp> Maintainer: Kazu Yamamoto <kazu@iij.ad.jp> License: BSD3