diff --git a/ip.cabal b/ip.cabal
--- a/ip.cabal
+++ b/ip.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name: ip
-version: 1.7.6
+version: 1.7.7
 synopsis: Library for IP and MAC addresses
 homepage: https://github.com/andrewthad/haskell-ip#readme
 license: BSD-3-Clause
@@ -55,8 +55,8 @@
     , bytestring >= 0.10.8 && < 0.12
     , deepseq >= 1.4 && < 1.5
     , hashable >= 1.2 && < 1.5
-    , natural-arithmetic >= 0.1 && <0.2
-    , primitive >= 0.6.4 && < 0.8
+    , natural-arithmetic >= 0.1 && <0.3
+    , primitive >= 0.6.4 && < 0.10
     , bytebuild >= 0.3.4 && <0.4
     , text >= 1.2 && < 2.1
     , text-short >= 0.1.3 && < 0.2
diff --git a/src/Net/IPv4.hs b/src/Net/IPv4.hs
--- a/src/Net/IPv4.hs
+++ b/src/Net/IPv4.hs
@@ -63,6 +63,7 @@
   , fromBounds
   , normalize
   , contains
+  , isSubsetOf
   , member
   , lowerInclusive
   , upperInclusive
@@ -1052,6 +1053,18 @@
   let theMask = mask len
       wsubnetNormalized = wsubnet .&. theMask
    in \(IPv4 w) -> (w .&. theMask) == wsubnetNormalized
+
+-- | Checks if the first range is a subset of the second range.
+--
+-- >>> IPv4.isSubsetOf (IPv4.IPv4Range (IPv4.fromOctets 192 0 2 128) 25) (IPv4.IPv4Range (IPv4.fromOctets 192 0 2 0) 24)
+-- True
+-- >>> IPv4.isSubsetOf (IPv4.IPv4Range (IPv4.fromOctets 192 0 2 0) 30) (IPv4.IPv4Range (IPv4.fromOctets 192 0 2 4) 30)
+-- False
+isSubsetOf :: IPv4Range -> IPv4Range -> Bool
+isSubsetOf a b =
+  lowerInclusive a >= lowerInclusive b
+  &&
+  upperInclusive a <= upperInclusive b
 
 mask :: Word8 -> Word32
 mask = complement . shiftR 0xffffffff . fromIntegral
diff --git a/src/Net/IPv6.hs b/src/Net/IPv6.hs
--- a/src/Net/IPv6.hs
+++ b/src/Net/IPv6.hs
@@ -47,6 +47,7 @@
   , fromBounds
   , normalize
   , contains
+  , isSubsetOf
   , member
   , lowerInclusive
   , upperInclusive
@@ -900,6 +901,13 @@
   let theMask = mask len
       subnetNormalized = subnet .&. theMask
    in \ip -> (ip .&. theMask) == subnetNormalized
+
+-- | Checks if the first range is a subset of the second range.
+isSubsetOf :: IPv6Range -> IPv6Range -> Bool
+isSubsetOf a b =
+  lowerInclusive a >= lowerInclusive b
+  &&
+  upperInclusive a <= upperInclusive b
 
 -- | This is provided to mirror the interface provided by @Data.Set@. It
 -- behaves just like 'contains' but with flipped arguments.
