diff --git a/edosl0util/stream.py b/edosl0util/stream.py
index 2efd489ac7b573b482e92b74e3e1d6cf14ce32ff..746d82143c9afc6f3bfd5e0a115f9d6e7c6b5704 100644
--- a/edosl0util/stream.py
+++ b/edosl0util/stream.py
@@ -1,4 +1,5 @@
 import os
+import errno
 import logging
 import ctypes as c
 from collections import deque, defaultdict, namedtuple
@@ -40,12 +41,22 @@ class NonConsecutiveSeqId(Error):
 
 
 class BasicStream(object):
+    """
+    Basic packet stream iterator that reads the primary and secondary headers and
+    maintains offsets and read sizes.
+    """
     Tracker = namedtuple('Tracker', ['h1', 'h2', 'size', 'offset', 'data'])
 
     def __init__(self, fobj, header_lookup=None, with_data=True):
         self.file = fobj
         self.header_lookup = header_lookup
         self.with_data = with_data
+        try:
+            self._offset = self.file.tell()
+        except IOError as err:  # handle illegal seek for pipes
+            if err.errno != errno.ESPIPE:
+                raise
+            self._offset = 0
 
     def __iter__(self):
         return self
@@ -61,6 +72,7 @@ class BasicStream(object):
             raise PacketTooShort(
                 'expected to read {:d} bytes, got {:d}'
                 .format(size, len(buf)))
+        self._offset += size
         return buf
 
     def read_primary_header(self):
@@ -77,7 +89,7 @@ class BasicStream(object):
         return H2Impl.from_buffer_copy(buf), h2size
 
     def next(self):
-        offset = self.file.tell()
+        offset = self._offset
         h1, h1size = self.read_primary_header()
         h2, h2size = self.read_secondary_header(h1)
         # data length includes h2size