ip 0.8.4 → 0.8.5
raw patch · 5 files changed
+79/−6 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Net.Types: instance GHC.Generics.Constructor Net.Types.C1_0IPv4
- Net.Types: instance GHC.Generics.Constructor Net.Types.C1_0IPv4Range
- Net.Types: instance GHC.Generics.Constructor Net.Types.C1_0Mac
- Net.Types: instance GHC.Generics.Constructor Net.Types.C1_0MacEncoding
- Net.Types: instance GHC.Generics.Datatype Net.Types.D1IPv4
- Net.Types: instance GHC.Generics.Datatype Net.Types.D1IPv4Range
- Net.Types: instance GHC.Generics.Datatype Net.Types.D1Mac
- Net.Types: instance GHC.Generics.Datatype Net.Types.D1MacEncoding
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_0IPv4
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_0IPv4Range
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_0Mac
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_0MacEncoding
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_1IPv4Range
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_1Mac
- Net.Types: instance GHC.Generics.Selector Net.Types.S1_0_1MacEncoding
+ Net.IPv4.Range: toGenerator :: MonadPlus m => IPv4Range -> m IPv4
+ Net.IPv4.Range: toList :: IPv4Range -> [IPv4]
+ Net.Internal: countAddrs :: Word8 -> Word64
+ Net.Internal: wordSuccessors :: Word64 -> Word32 -> [Word32]
+ Net.Internal: wordSuccessorsM :: MonadPlus m => (Word32 -> a) -> Word64 -> Word32 -> m a
+ Net.Types: instance Data.Bits.Bits Net.Types.IPv4
Files
- ip.cabal +25/−2
- src/Net/IPv4.hs +1/−1
- src/Net/IPv4/Range.hs +24/−0
- src/Net/Internal.hs +27/−1
- src/Net/Types.hs +2/−2
ip.cabal view
@@ -1,7 +1,6 @@ name: ip-version: 0.8.4+version: 0.8.5 synopsis: Library for IP and MAC addresses-description: Please see README.md homepage: https://github.com/andrewthad/haskell-ip#readme license: BSD3 license-file: LICENSE@@ -11,6 +10,30 @@ category: web build-type: Simple cabal-version: >=1.10+description:+ The `ip` package provides types and functions for dealing with+ IPv4 addresses, CIDR blocks, and MAC addresses. We provide instances+ for typeclasses found in commonly used packages like `aeson`, `vector`,+ and `hashable`. We also provide `Parser`s for working with attoparsec.+ .+ Notably, this package does not overload functions by introducing any+ typeclasses of its own. Neither does it prefix functions with the name+ of the type that they work on. Instead, functions of the same name are+ exported by several different modules, and it is expected that end users+ disambiguate by imported these modules qualified. For example,+ `Data.IPv4.Text` and `Data.IPv4.ByteString.Char8` have nearly identical+ export lists.+ .+ The only module intended to be imported unqualified is `Net.Types`. The+ types in this package should not conflict with the types in+ any other commonly used packages.+ .+ The following packages are intended to be used with this package:+ .+ * `yesod-ip`: Provides orphan instances needed to work with yesod and+ persistent. Also, provides a `yesod-form` helper.+ * `impure-containers`: Provides a trie that can be used for looking+ up which subnet an IP address belongs in. library hs-source-dirs: src
src/Net/IPv4.hs view
@@ -90,7 +90,7 @@ loopback :: IPv4 loopback = fromOctets 127 0 0 1 --- | The broadcast IP address: @127.0.0.1@+-- | The broadcast IP address: @255.255.255.255@ broadcast :: IPv4 broadcast = fromOctets 255 255 255 255
src/Net/IPv4/Range.hs view
@@ -5,6 +5,9 @@ , member , lowerInclusive , upperInclusive+ -- * Conversion to IPv4+ , toList+ , toGenerator -- * Private Ranges , private24 , private20@@ -16,6 +19,8 @@ import Net.Types (IPv4(..),IPv4Range(..)) import Data.Bits ((.&.),(.|.),shiftR,shiftL,complement)+import Data.Coerce (coerce)+import Control.Monad import qualified Net.Internal as Internal import qualified Net.IPv4 as IPv4 import qualified Data.Text.IO as Text@@ -87,6 +92,25 @@ let theInvertedMask = shiftR 0xffffffff (fromIntegral len) theMask = complement theInvertedMask in IPv4 ((w .&. theMask) .|. theInvertedMask)++-- | Convert an 'IPv4Range' into a list of the 'IPv4' addresses that+-- are in it.+-- >>> let r = IPv4Range (fromOctets 192 168 1 8) 30+-- >>> mapM_ I.print (toList r)+-- 192.168.1.8+-- 192.168.1.9+-- 192.168.1.10+-- 192.168.1.11++toList :: IPv4Range -> [IPv4]+toList (IPv4Range (IPv4 ip) len) = + let totalAddrs = Internal.countAddrs len+ in coerce (Internal.wordSuccessors totalAddrs ip)++toGenerator :: MonadPlus m => IPv4Range -> m IPv4+toGenerator (IPv4Range (IPv4 ip) len) = + let totalAddrs = Internal.countAddrs len+ in Internal.wordSuccessorsM IPv4 totalAddrs ip -- | The RFC1918 24-bit block. Subnet mask: @10.0.0.0/8@ private24 :: IPv4Range
src/Net/Internal.hs view
@@ -1,8 +1,10 @@+{-# LANGUAGE BangPatterns #-}+ module Net.Internal where import Data.Monoid ((<>)) import Data.Word-import Data.Bits ((.&.),(.|.),shiftR,shiftL,complement)+import Data.Bits ((.&.),(.|.),shiftR,shiftL,shift,complement) import Control.Monad.ST import Data.Text.Internal (Text(..)) import Data.ByteString (ByteString)@@ -231,6 +233,30 @@ .|. shiftL c 8 .|. d )++-- | Given the size of the mask, return the+-- total number of ips in the subnet. This+-- only works for IPv4 addresses because +-- an IPv6 subnet can have up to 2^128 +-- addresses.+countAddrs :: Word8 -> Word64+countAddrs w = + let amountToShift = if w > 32+ then 0+ else 32 - fromIntegral w+ in shift 1 amountToShift++wordSuccessors :: Word64 -> Word32 -> [Word32]+wordSuccessors !w !a = if w > 0+ then a : wordSuccessors (w - 1) (a + 1)+ else []++wordSuccessorsM :: MonadPlus m => (Word32 -> a) -> Word64 -> Word32 -> m a+wordSuccessorsM f = go where+ go !w !a = if w > 0+ then mplus (return (f a)) (go (w - 1) (a + 1))+ else mzero+{-# INLINE wordSuccessorsM #-} mask :: Word8 -> Word32 mask = complement . shiftR 0xffffffff . fromIntegral
src/Net/Types.hs view
@@ -27,7 +27,7 @@ import qualified Data.Vector.Unboxed.Mutable as MUVector import qualified Data.Vector.Primitive.Mutable as MPVector import Data.Primitive.Types (Prim)-import Data.Bits ((.|.),shiftL)+import Data.Bits (Bits,(.|.),shiftL) import Data.Coerce (coerce) import Control.Monad import Data.Word@@ -38,7 +38,7 @@ -- | A 32-bit Internet Protocol address. newtype IPv4 = IPv4 { getIPv4 :: Word32 }- deriving (Eq,Ord,Show,Read,Enum,Bounded,Hashable,Generic,Prim)+ deriving (Eq,Ord,Show,Read,Enum,Bounded,Hashable,Generic,Prim,Bits) -- | The length should be between 0 and 32. These bounds are inclusive. -- This expectation is not in any way enforced by this library because