diff --git a/hw-ip.cabal b/hw-ip.cabal
--- a/hw-ip.cabal
+++ b/hw-ip.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           hw-ip
-version:        0.2.1.1
+version:        0.3.0
 synopsis:       Library for manipulating IP addresses and CIDR blocks
 description:    Please see README.md
 category:       Network
diff --git a/src/HaskellWorks/Data/Network/Ip.hs b/src/HaskellWorks/Data/Network/Ip.hs
--- a/src/HaskellWorks/Data/Network/Ip.hs
+++ b/src/HaskellWorks/Data/Network/Ip.hs
@@ -12,6 +12,8 @@
   , textToMaybeIpv4Address
   , ipv4AddressToString
   , ipv4AddressToText
+  , firstIpv4Address
+  , lastIpv4Address
   ) where
 
 import Control.Monad
@@ -45,6 +47,12 @@
 
 blockSize :: Z.Ipv4Block -> Int
 blockSize (Z.Ipv4Block _ m) = 2 ^ bitPower m
+
+firstIpv4Address :: Z.Ipv4Block -> Z.Ipv4Address
+firstIpv4Address (Z.Ipv4Block base _) = base
+
+lastIpv4Address :: Z.Ipv4Block -> Z.Ipv4Address
+lastIpv4Address b@(Z.Ipv4Block (Z.Ipv4Address base) _) = Z.Ipv4Address (base + fromIntegral (blockSize b) - 1)
 
 textToMaybeIpv4Address :: T.Text -> Maybe Z.Ipv4Address
 textToMaybeIpv4Address t = join $ AP.maybeResult <$> AP.parseWith (return mempty) APT.ipv4Address t
diff --git a/test/HaskellWorks/Data/Network/IpSpec.hs b/test/HaskellWorks/Data/Network/IpSpec.hs
--- a/test/HaskellWorks/Data/Network/IpSpec.hs
+++ b/test/HaskellWorks/Data/Network/IpSpec.hs
@@ -32,6 +32,16 @@
       show (Ipv4Block (Ipv4Address 0x0000ff00) (Ipv4NetMask 16)) === "0.0.255.0/16"
       show (Ipv4Block (Ipv4Address 0x00ff0000) (Ipv4NetMask 16)) === "0.255.0.0/16"
       show (Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 16)) === "255.0.0.0/16"
+      show (firstIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 8))  === "255.0.0.0"
+      show (lastIpv4Address  $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 8))  === "255.255.255.255"
+      show (firstIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 16)) === "255.0.0.0"
+      show (lastIpv4Address  $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 16)) === "255.0.255.255"
+      show (firstIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 24)) === "255.0.0.0"
+      show (lastIpv4Address  $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 24)) === "255.0.0.255"
+      show (firstIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 32)) === "255.0.0.0"
+      show (lastIpv4Address  $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 32)) === "255.0.0.0"
+      show (firstIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 21)) === "255.0.0.0"
+      show (lastIpv4Address  $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 21)) === "255.0.7.255"
     it "should implement splitBlock" $ require $ property $ do
       splitBlock (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 32)) === Nothing
       splitBlock (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 31)) === Just (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 32), Ipv4Block (Ipv4Address 0x00000001) (Ipv4NetMask 32))
