diff --git a/Data/IP.hs b/Data/IP.hs
--- a/Data/IP.hs
+++ b/Data/IP.hs
@@ -2,18 +2,22 @@
   Data structures to express IPv4, IPv6 and IP range.
 -}
 module Data.IP (
-  -- * Documentation
-  -- ** IP data
+  -- * IP data
     IP (..)
+  -- ** IPv4
   , IPv4, toIPv4, fromIPv4, fromHostAddress, toHostAddress
+  -- ** IPv6
   , IPv6, toIPv6, toIPv6b, fromIPv6, fromIPv6b, fromHostAddress6, toHostAddress6
-  -- ** IP range data
+  -- ** Converters
+  , ipv4ToIPv6
+  , fromSockAddr
+  -- * IP range data
   , IPRange (..)
   , AddrRange (addr, mask, mlen)
-  -- ** Address class
+  -- * Address class
   , Addr (..)
   , makeAddrRange, (>:>), isMatchedTo, addrRangePair
-  , ipv4RangeToIPv6, ipv4ToIPv6
+  , ipv4RangeToIPv6
   ) where
 
 import Data.IP.Addr
diff --git a/Data/IP/Addr.hs b/Data/IP/Addr.hs
--- a/Data/IP/Addr.hs
+++ b/Data/IP/Addr.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric      #-}
+
 module Data.IP.Addr where
 
 import Control.Monad
@@ -520,3 +521,11 @@
 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
+
+-- | Convert 'SockAddr' to 'IP'.
+--
+--   Since: 1.7.4.
+fromSockAddr :: SockAddr -> Maybe (IP, PortNumber)
+fromSockAddr (SockAddrInet  pn   ha)    = Just (IPv4 (fromHostAddress  ha),  pn)
+fromSockAddr (SockAddrInet6 pn _ ha6 _) = Just (IPv6 (fromHostAddress6 ha6), pn)
+fromSockAddr _                          = Nothing
diff --git a/Data/IP/RouteTable/Internal.hs b/Data/IP/RouteTable/Internal.hs
--- a/Data/IP/RouteTable/Internal.hs
+++ b/Data/IP/RouteTable/Internal.hs
@@ -10,9 +10,8 @@
 -}
 module Data.IP.RouteTable.Internal where
 
-#if __GLASGOW_HASKELL__ < 709
-import Control.Applicative ((<$>),(<*>),pure)
-#endif
+import Control.Applicative hiding (empty)
+import qualified Control.Applicative as A (empty)
 import Control.Monad
 import Data.Bits
 import Data.Foldable (Foldable(..))
@@ -266,16 +265,16 @@
 [(133.4.0.0/16,()),(133.5.0.0/16,()),(133.5.16.0/24,()),(133.5.23.0/24,())]
 -}
 
-findMatch :: MonadPlus m => Routable k => AddrRange k -> IPRTable k a -> m (AddrRange k, a)
-findMatch _ Nil = mzero
+findMatch :: Alternative m => Routable k => AddrRange k -> IPRTable k a -> m (AddrRange k, a)
+findMatch _ Nil = A.empty
 findMatch k1 (Node k2 _ Nothing l r)
-  | k1 >:> k2 = findMatch k1 l `mplus` findMatch k1 r
-  | k2 >:> k1 = findMatch k1 l `mplus` findMatch k1 r
-  | otherwise = mzero
+  | k1 >:> k2 = findMatch k1 l <|> findMatch k1 r
+  | k2 >:> k1 = findMatch k1 l <|> findMatch k1 r
+  | otherwise = A.empty
 findMatch k1 (Node k2 _ (Just vl) l r)
-  | k1 >:> k2 = return (k2, vl) `mplus` findMatch k1 l `mplus` findMatch k1 r
-  | k2 >:> k1 = findMatch k1 l `mplus` findMatch k1 r
-  | otherwise = mzero
+  | k1 >:> k2 = pure (k2, vl) <|> findMatch k1 l <|> findMatch k1 r
+  | k2 >:> k1 = findMatch k1 l <|> findMatch k1 r
+  | otherwise = A.empty
 
 ----------------------------------------------------------------
 
diff --git a/iproute.cabal b/iproute.cabal
--- a/iproute.cabal
+++ b/iproute.cabal
@@ -1,5 +1,5 @@
 Name:                   iproute
-Version:                1.7.3
+Version:                1.7.4
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
