Example #1
0
def test_spb_snap_lengths():
    """
    Simple Packet Blocks present a unique challenge in parsing. The packet does not
    contain an explicit "captured length" indicator, only the original observed
    packet length; one must consult the capturing network interface's snap length
    in order to determine whether the packet may have been truncated.

    The block interface was designed to take care of most of this for the developer,
    both for reading and writing. For reading, the :py:method:`captured_len` is
    a property that works out its value from the capturing interface and the original
    packet length. For writing, packet data will be truncated to the capturing
    interface's snap length if it would be too big.
    """

    # Binary data to write/test
    data = bytes(range(0, 256))

    # First session: no snap length
    o_shb = blocks.SectionHeader()
    o_idb = o_shb.new_member(blocks.InterfaceDescription)  # noqa: F841
    o_blk1 = o_shb.new_member(blocks.SimplePacket, packet_data=data)

    fake_file = io.BytesIO()
    writer = FileWriter(fake_file, o_shb)
    writer.write_block(o_blk1)

    fake_file.seek(0)
    (i_shb, i_idb, i_blk1) = list(FileScanner(fake_file))
    assert i_blk1.captured_len == len(data)
    assert i_blk1.packet_len == len(data)
    assert i_blk1.packet_data == data

    # Second session: with snap length
    o_shb = blocks.SectionHeader()
    o_idb = o_shb.new_member(blocks.InterfaceDescription,
                             snaplen=32)  # noqa: F841
    o_blk1 = o_shb.new_member(blocks.SimplePacket, packet_data=data[:16])
    o_blk2 = o_shb.new_member(blocks.SimplePacket, packet_data=data[:32])
    o_blk3 = o_shb.new_member(blocks.SimplePacket, packet_data=data[:33])

    fake_file = io.BytesIO()
    writer = FileWriter(fake_file, o_shb)
    writer.write_block(o_blk1)
    writer.write_block(o_blk2)
    writer.write_block(o_blk3)

    fake_file.seek(0)
    (i_shb, i_idb, i_blk1, i_blk2, i_blk3) = list(FileScanner(fake_file))

    assert i_blk1.captured_len == 16
    assert i_blk1.packet_len == 16
    assert i_blk1.packet_data == data[:16]

    assert i_blk2.captured_len == 32
    assert i_blk2.packet_len == 32
    assert i_blk2.packet_data == data[:32]

    assert i_blk3.captured_len == 32
    assert i_blk3.packet_len == 33
    assert i_blk3.packet_data == data[:32]
Example #2
0
    def _read_section_header(self):
        """
        Section information headers are special blocks in that they
        modify the state of the FileScanner instance (to change current
        section / endianness)
        """

        section_info = read_section_header(self.stream)
        self.endianness = section_info["endianness"]  # todo: use property?

        # todo: make this use the standard schema facilities as well!
        return blocks.SectionHeader(raw=section_info["data"],
                                    endianness=section_info["endianness"])
Example #3
0
def test_write_read_all_blocks(endianness):
    # Track the blocks we're writing
    out_blocks = []

    # Build our original/output session
    o_shb = blocks.SectionHeader(
        endianness=endianness,
        options={
            "shb_hardware": "pytest",
            "shb_os": "python",
            "shb_userappl": "python-pcapng",
        },
    )
    out_blocks.append(o_shb)

    o_idb = o_shb.new_member(
        blocks.InterfaceDescription,
        link_type=1,
        snaplen=65535,
        options={
            "if_name": "Interface Zero",
            "if_description": "Test interface",
            "if_os": "python",
            "if_hardware": "whatever",
            "if_filter": [(0, b"tcp port 23 and host 192.0.2.5")],
        },
    )
    out_blocks.append(o_idb)

    # The SHB and IDBs will be written right away here.
    fake_file = io.BytesIO()
    writer = FileWriter(fake_file, o_shb)

    # Add blocks to the output

    # epb
    blk = o_shb.new_member(blocks.EnhancedPacket)
    blk.packet_data = b"Test data 123 XYZ"
    writer.write_block(blk)
    out_blocks.append(blk)

    # spb
    blk = o_shb.new_member(blocks.SimplePacket)
    blk.packet_data = b"Test data 123 XYZ"
    writer.write_block(blk)
    out_blocks.append(blk)

    # pb (which is obsolete)
    set_strictness(Strictness.FORBID)
    blk = o_shb.new_member(blocks.ObsoletePacket)
    blk.packet_data = b"Test data 123 XYZ"
    with pytest.raises(PcapngStrictnessError, match="obsolete"):
        # Should prevent writing by default
        writer.write_block(blk)

    # Set to warning mode and try again
    set_strictness(Strictness.WARN)
    with pytest.warns(PcapngStrictnessWarning, match="obsolete"):
        # Should write the obsolete block now
        writer.write_block(blk)
    out_blocks.append(blk)

    # Set to fix mode and try again
    set_strictness(Strictness.FIX)
    with pytest.warns(PcapngStrictnessWarning, match="obsolete"):
        # Should write an enhanced block now
        writer.write_block(blk)
    out_blocks.append(blk.enhanced())

    set_strictness(Strictness.FORBID)

    # nrb
    blk = o_shb.new_member(
        blocks.NameResolution,
        records=[
            {
                "type": 1,
                "address": "127.0.0.1",
                "names": ["localhost", "localhost.localdomain"],
            },
            {
                "type": 2,
                "address": "::1",
                "names": ["localhost", "localhost.localdomain"],
            },
        ],
    )
    writer.write_block(blk)
    out_blocks.append(blk)

    # isb
    blk = o_shb.new_member(
        blocks.InterfaceStatistics,
        interface_id=0,
        timestamp_high=0x01234567,
        timestamp_low=0x89ABCDEF,
        options={
            "isb_starttime": 0x0123456789ABCD00,
            "isb_endtime": 0x0123456789ABCDEF,
            "isb_usrdeliv": 50,
        },
    )
    writer.write_block(blk)
    out_blocks.append(blk)

    # Done writing blocks.
    # Now get back what we wrote and see if things line up.
    fake_file.seek(0)
    in_blocks = list(FileScanner(fake_file))

    compare_blocklists(in_blocks, out_blocks)
Example #4
0
#!/usr/bin/env python

import argparse

import pcapng.blocks as blocks
from pcapng import FileWriter

parser = argparse.ArgumentParser()
parser.add_argument("outfile", type=argparse.FileType("wb"))
args = parser.parse_args()

shb = blocks.SectionHeader(
    options={
        "shb_hardware": "artificial",
        "shb_os": "python",
        "shb_userappl": "python-pcapng",
    })
idb = shb.new_member(
    blocks.InterfaceDescription,
    link_type=1,
    options={
        "if_description": "Hand-rolled",
        "if_os": "Python",
        "if_filter": [(0, b"tcp port 23 and host 192.0.2.5")],
    },
)

# FileWriter() immediately writes the SHB and any IDBs you've added to it
writer = FileWriter(args.outfile, shb)

# fmt: off
Example #5
0
#!/usr/bin/env python

import pcapng
import pcapng.blocks as blocks
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('outfile', type=argparse.FileType('wb'))
args = parser.parse_args()

shb = blocks.SectionHeader(
    options={
        'shb_hardware': 'artificial',
        'shb_os': 'python',
        'shb_userappl': 'python-pcapng'
    })
shb.write(args.outfile)
idb = shb.new_member(blocks.InterfaceDescription,
                     link_type=1,
                     options={
                         "if_description": "Hand-rolled",
                         "if_os": "Python"
                     })
idb.write(args.outfile)

test_pl = (
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,