diff --git a/Changelog b/Changelog
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,7 @@
+2.0.2
+	- Providing a new API: decodeMany.
+2.0.1
+	- Updating document.
 2.0.0
 	- DNSMessage is now monomorphic
 	- RDATA is now monomorphic
diff --git a/Network/DNS/Decode.hs b/Network/DNS/Decode.hs
--- a/Network/DNS/Decode.hs
+++ b/Network/DNS/Decode.hs
@@ -2,9 +2,11 @@
 
 module Network.DNS.Decode (
     decode
+  , decodeMany
   , receive
   ) where
 
+import Control.Applicative (many)
 import Control.Monad (replicateM)
 import Control.Monad.Trans.Resource (ResourceT, runResourceT)
 import qualified Control.Exception as ControlException
@@ -45,6 +47,20 @@
 
 decode :: BL.ByteString -> Either String DNSMessage
 decode bs = fst <$> runSGet decodeResponse bs
+
+-- | Parse many length-encoded DNS records, for example, from TCP traffic.
+
+decodeMany :: BL.ByteString -> Either String ([DNSMessage], BL.ByteString)
+decodeMany bs = do
+    ((bss, _), leftovers) <- runSGetWithLeftovers lengthEncoded bs
+    msgs <- mapM decode bss
+    return (msgs, leftovers)
+  where
+    -- Read a list of length-encoded lazy bytestrings
+    lengthEncoded :: SGet [BL.ByteString]
+    lengthEncoded = many $ do
+      len <- getInt16
+      fmap BL.fromStrict (getNByteString len)
 
 ----------------------------------------------------------------
 receiveDNSFormat :: Source (ResourceT IO) ByteString -> IO DNSMessage
diff --git a/Network/DNS/StateBinary.hs b/Network/DNS/StateBinary.hs
--- a/Network/DNS/StateBinary.hs
+++ b/Network/DNS/StateBinary.hs
@@ -168,5 +168,12 @@
 runSGet :: SGet a -> BL.ByteString -> Either String (a, PState)
 runSGet parser bs = AL.eitherResult $ AL.parse (ST.runStateT parser initialState) bs
 
+runSGetWithLeftovers :: SGet a -> BL.ByteString -> Either String ((a, PState), BL.ByteString)
+runSGetWithLeftovers parser bs = toResult $ AL.parse (ST.runStateT parser initialState) bs
+  where
+    toResult :: AL.Result r -> Either String (r, BL.ByteString)
+    toResult (AL.Done i r) = Right (r, i)
+    toResult (AL.Fail _ _ err) = Left err
+
 runSPut :: SPut -> BL.ByteString
 runSPut = BB.toLazyByteString . BB.fromWrite . flip ST.evalState initialWState
diff --git a/dns.cabal b/dns.cabal
--- a/dns.cabal
+++ b/dns.cabal
@@ -1,5 +1,5 @@
 Name:                   dns
-Version:                2.0.1
+Version:                2.0.2
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
