diff --git a/Network/Pcap/Streaming.hs b/Network/Pcap/Streaming.hs
--- a/Network/Pcap/Streaming.hs
+++ b/Network/Pcap/Streaming.hs
@@ -10,25 +10,24 @@
 
 module Network.Pcap.Streaming
   ( Packet(..)
+  , PktHdr(..)
   , offline
   , online
   ) where
 
-import qualified Data.ByteString as BS
+import qualified Data.Attoparsec.ByteString.Streaming as A
+import qualified Data.ByteString.Streaming as Q
 import           Data.Int (Int64)
 import           Network.Pcap
+import           Network.Pcap.Streaming.Internal
 import           Streaming
 import qualified Streaming.Prelude as P
 
 ---
 
--- | A <https://en.wikipedia.org/wiki/Pcap pcap> packet. Assumes nothing about
--- the contents or structure of the `bytes` value.
-data Packet = Packet { header :: PktHdr, bytes :: BS.ByteString } deriving (Eq, Show)
-
--- | Read `Packet`s from some file dump. See also `Network.Pcap.openOffline`.
-offline :: FilePath -> Stream (Of Packet) IO ()
-offline path = lift (openOffline path) >>= packets
+-- | Read `Packet`s from some file dump.
+offline :: FilePath -> Stream (Of Packet) (ResourceT IO) ()
+offline = void . A.parsed packetP . Q.drop 24 . Q.readFile
 
 -- | Read `Packet`s from some network device. See `Network.Pcap.openLive`
 -- for a description of each argument.
diff --git a/Network/Pcap/Streaming/Internal.hs b/Network/Pcap/Streaming/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Network/Pcap/Streaming/Internal.hs
@@ -0,0 +1,25 @@
+module Network.Pcap.Streaming.Internal where
+
+import qualified Data.Attoparsec.ByteString as A
+import qualified Data.ByteString as BS
+import           Data.Word (Word32)
+import           Network.Pcap
+
+---
+
+-- | A <https://en.wikipedia.org/wiki/Pcap pcap> packet. Assumes nothing about
+-- the contents or structure of the `bytes` value.
+data Packet = Packet { header :: PktHdr, bytes :: BS.ByteString } deriving (Eq, Show)
+
+packetP :: A.Parser Packet
+packetP = do
+  hdr <- pktHeader
+  bts <- A.take . fromIntegral $ hdrCaptureLength hdr
+  pure $ Packet hdr bts
+
+pktHeader :: A.Parser PktHdr
+pktHeader = PktHdr <$> four <*> four <*> four <*> four
+
+four :: A.Parser Word32
+four = BS.foldr' (\w acc -> acc * 256 + fromIntegral w) 0 <$> A.take 4
+{-# INLINE four #-}
diff --git a/streaming-pcap.cabal b/streaming-pcap.cabal
--- a/streaming-pcap.cabal
+++ b/streaming-pcap.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: c37ffea4ae53bdbe6e7f8ec6c8834974fadb48711722864ed540a2e2753fb5c0
+-- hash: 0fd1730d1afb3007c23b227e5d2dad0105c2c0822a6b6a52cbe8649358211a72
 
 name:           streaming-pcap
-version:        1.0.0
+version:        1.1.0
 synopsis:       Stream packets via libpcap.
 description:    Stream packets via libpcap.
 category:       Web
@@ -21,18 +21,23 @@
 extra-source-files:
     README.md
     test/test.pcap
+    test/tsuru.pcap
 
 library
   hs-source-dirs:
       ./.
-  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns -O2
   build-depends:
-      base >=4.7 && <5
+      attoparsec >=0.13 && <0.14
+    , base >=4.7 && <5
     , bytestring
     , pcap >=0.4 && <0.5
-    , streaming >=0.2 && <0.3
+    , streaming >=0.1 && <0.3
+    , streaming-bytestring >=0.1 && <0.2
+    , streaming-utils >=0.1 && <0.2
   exposed-modules:
       Network.Pcap.Streaming
+      Network.Pcap.Streaming.Internal
   default-language: Haskell2010
 
 test-suite streaming-pcap-test
@@ -40,15 +45,16 @@
   main-is: Test.hs
   hs-source-dirs:
       test
-  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns -threaded
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns -O2 -threaded
   build-depends:
-      base >=4.7 && <5
+      attoparsec >=0.13 && <0.14
+    , base >=4.7 && <5
     , bytestring
     , pcap >=0.4 && <0.5
-    , streaming >=0.2 && <0.3
+    , streaming >=0.1 && <0.3
+    , streaming-bytestring >=0.1 && <0.2
     , streaming-pcap
+    , streaming-utils >=0.1 && <0.2
     , tasty >=0.11 && <1.1
     , tasty-hunit >=0.9 && <0.11
-  other-modules:
-      Paths_streaming_pcap
   default-language: Haskell2010
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,6 +1,10 @@
 module Main ( main ) where
 
+import qualified Data.Attoparsec.ByteString as A
+import qualified Data.ByteString as BS
 import           Network.Pcap.Streaming
+import           Network.Pcap.Streaming.Internal
+import           Streaming (runResourceT)
 import qualified Streaming.Prelude as P
 import           Test.Tasty
 import           Test.Tasty.HUnit
@@ -12,5 +16,23 @@
 
 suite :: TestTree
 suite = testGroup "Unit Tests"
-  [ testCase "Packet Quantity" $ P.length_ (offline "test/test.pcap") >>= (@?= 21273)
+  [ testGroup "Byte Parsing"
+    [ testCase "pktHeader" $ A.parseOnly pktHeader heady @?= Right good
+    , testCase "four" $ A.parseOnly four foury @?= Right 1338882754
+    ]
+  , testGroup "Streaming"
+    [ testCase "Packet Quantity (test)" $ runResourceT (P.length_ $ offline "test/test.pcap") >>= (@?= 4)
+    -- , testCase "Packet Quantity (tsuru)" $ runResourceT (P.length_ $ offline "test/tsuru.pcap") >>= (@?= 21273)
+    ]
   ]
+
+foury :: BS.ByteString
+foury = BS.pack [ 0xc2, 0xba, 0xcd, 0x4f ]
+
+heady :: BS.ByteString
+heady = BS.pack
+  [ 0xc2, 0xba, 0xcd, 0x4f, 0xb6, 0x35, 0x0f, 0x00
+  , 0x36, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 ]
+
+good :: PktHdr
+good = PktHdr 1338882754 996790 54 54
diff --git a/test/test.pcap b/test/test.pcap
# file too large to diff: test/test.pcap
diff --git a/test/tsuru.pcap b/test/tsuru.pcap
new file mode 100644
# file too large to diff: test/tsuru.pcap
