secdev / scapy

Scapy: the Python-based interactive packet manipulation program & library.
https://scapy.net
GNU General Public License v2.0
10.29k stars 1.99k forks source link

pcapng reader cannot read pipe #4405

Closed wataash closed 3 days ago

wataash commented 1 month ago

Brief description

pcapng reader cannot read pipe

Scapy version

master (a795ad6b57035b401b7e4e507a4e2fd925ade670)

Python version

3.10

Operating system

Linux 5.15.39+

Additional environment information

No response

How to reproduce

python -c "rdpcap('/dev/stdin')" <a.pcapng is OK, but cat a.pcapng | python -c "rdpcap('/dev/stdin')" fails.

python -c "from scapy.all import *; wrpcapng('a.pcapng', [Ether()])"

xxd a.pcapng
#00000000: 0a0d 0d0a 1c00 0000 4d3c 2b1a 0100 0000  ........M<+.....
#00000010: ffff ffff ffff ffff 1c00 0000 0100 0000  ................
#00000020: 1400 0000 0100 0000 0000 0400 1400 0000  ................
#00000030: 0600 0000 3000 0000 0000 0000 9119 0600  ....0...........
#00000040: 36d7 0f87 0e00 0000 0e00 0000 ffff ffff  6...............
#00000050: ffff 34cf f6f3 9364 9000 0000 3000 0000  ..4....d....0...

               python -c "from scapy.all import *; rdpcap('/dev/stdin')" <a.pcapng # ok

cat a.pcapng | python -c "from scapy.all import *; rdpcap('/dev/stdin')"           # error!
#Traceback (most recent call last):
#  File "<string>", line 1, in <module>
#  File "/home/wsh/qpy/scapy/scapy/utils.py", line 1355, in rdpcap
#    with PcapReader(filename) as fdesc:  # type: ignore
#  File "/home/wsh/qpy/scapy/scapy/utils.py", line 1397, in __call__
#    raise Scapy_Exception(
#scapy.error.Scapy_Exception: No data could be read!

This is because the first some bytes (0a 0d 0d 0a 1c ...) are discarded in try: gzip.open().read(4) when the file is a pipe:

https://github.com/secdev/scapy/blob/a795ad6b57035b401b7e4e507a4e2fd925ade670/scapy/utils.py#L1431

            try:
                fdesc = gzip.open(filename, "rb")  # type: _ByteStream
                magic = fdesc.read(4)  # raises IOError
            except IOError:
                fdesc = open(filename, "rb")
                # <a.pcapng      : /dev/stdin is a regular file, magic = b'\n\r\r\n' (0a 0d 0d 0a), ok
                # cat a.pcapng | : /dev/stdin is a pipe,         magic = b'6\x00\x00\x00' (06 00 00 00) -- it's at 00000030: in xxd above. the first 0x30 bytes are discarded in gzip.open().read()!
                magic = fdesc.read(4)

Actual result

No response

Expected result

No response

Related resources

No response

gpotter2 commented 2 weeks ago

This should be fixed in https://github.com/secdev/scapy/pull/4428, feel free to try it out.

wataash commented 2 weeks ago

Thanks!