Beispiel #1
0
 def test_parses_valid_stream(self):
     stream = io.BytesIO(TESTDATA)
     pcap = PCAP(stream)
     header = pcap.global_header
     self.assertThat(header, Equals((2712847316, 2, 4, 0, 0, 64, 1)))
     pkt1 = pcap.read()
     self.assertThat(pkt1[0], Equals((1467058714, 931534, 60, 60)))
     self.assertThat(
         pkt1[1],
         Equals(
             b"\xff\xff\xff\xff\xff\xff\x00$\xa5\xaf$\x85\x08\x06\x00\x01\x08"
             b"\x00\x06\x04\x00\x01\x00$\xa5\xaf$\x85\xac\x10*\x01\x00\x00\x00"
             b"\x00\x00\x00\xac\x10*\xa7\x00\x00\x00\x00\x00\x00\x00\x00\x00"
             b"\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
     )
     pkt2 = pcap.read()
     self.assertThat(pkt2[0], Equals((1467058715, 380619, 60, 60)))
     self.assertThat(
         pkt2[1],
         Equals(
             b"\x80\xfa[\x0cFN\x00$\xa5\xaf$\x85\x08\x06\x00\x01\x08\x00\x06"
             b"\x04\x00\x01\x00$\xa5\xaf$\x85\xac\x10*\x01\x00\x00\x00\x00\x00"
             b"\x00\xac\x10*m\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
             b"\x00\x00\x00\x00\x00\x00"),
     )
Beispiel #2
0
 def test_raises_PCAPError_for_invalid_packet(self):
     stream = io.BytesIO(TESTDATA_INVALID_PACKET)
     pcap = PCAP(stream)
     header = pcap.global_header
     self.assertThat(header, Equals((2712847316, 2, 4, 0, 0, 64, 1)))
     with ExpectedException(
             PCAPError, "Unexpected end of PCAP stream: invalid packet."):
         pcap.read()
Beispiel #3
0
 def test_gets_time_from_pcap_header(self):
     pcap_file = BytesIO(GOOD_ETHERNET_IPV4_UDP_PCAP)
     pcap = PCAP(pcap_file)
     for header, packet_bytes in pcap:
         packet = decode_ethernet_udp_packet(packet_bytes, header)
         self.expectThat(packet.timestamp, Equals(EXPECTED_PCAP_TIME))
         self.expectThat(packet.payload, Equals(EXPECTED_PAYLOAD))
Beispiel #4
0
 def test_iterator(self):
     stream = io.BytesIO(TESTDATA)
     pcap = PCAP(stream)
     count = 0
     for _ in pcap:
         count += 1
     # Expect no exception to have been thrown, and there are two packets.
     self.assertThat(count, Equals(2))
Beispiel #5
0
def observe_arp_packets(verbose=False,
                        bindings=False,
                        input=sys.stdin.buffer,
                        output=sys.stdout):
    """Read stdin and look for tcpdump binary ARP output.
    :param verbose: Output text-based ARP packet details.
    :type verbose: bool
    :param bindings: Track (MAC, IP) bindings, and print new/update bindings.
    :type bindings: bool
    :param input: Stream to read PCAP data from.
    :type input: a file or stream supporting `read(int)`
    :param output: Stream to write JSON data to.
    :type input: a file or stream supporting `write(str)` and `flush()`.
    """
    if bindings:
        bindings = dict()
    else:
        bindings = None
    try:
        pcap = PCAP(input)
        if pcap.global_header.data_link_type != 1:
            # Not an Ethernet interface. Need to exit here, because our
            # assumptions about the link layer header won't be correct.
            return 4
        for header, packet in pcap:
            ethernet = Ethernet(packet, time=header.timestamp_seconds)
            if not ethernet.is_valid():
                # Ignore packets with a truncated Ethernet header.
                continue
            if len(ethernet.payload) < SIZEOF_ARP_PACKET:
                # Ignore truncated ARP packets.
                continue
            if ethernet.ethertype != ETHERTYPE.ARP:
                # Ignore non-ARP packets.
                continue
            arp = ARP(
                ethernet.payload,
                src_mac=ethernet.src_mac,
                dst_mac=ethernet.dst_mac,
                vid=ethernet.vid,
                time=ethernet.time,
            )
            if bindings is not None:
                update_and_print_bindings(bindings, arp, output)
            if verbose:
                arp.write()
    except EOFError:
        # Capture aborted before it could even begin. Note that this does not
        # occur if the end-of-stream occurs normally. (In that case, the
        # program will just exit.)
        return 3
    except PCAPError:
        # Capture aborted due to an I/O error.
        return 2
    return None
Beispiel #6
0
 def test_raises_EOFError_for_end_of_stream(self):
     stream = io.BytesIO(TESTDATA)
     pcap = PCAP(stream)
     pcap.read()
     pcap.read()
     with ExpectedException(EOFError, "End of PCAP stream."):
         pcap.read()
Beispiel #7
0
def observe_beaconing_packets(input=sys.stdin.buffer, out=sys.stdout):
    """Read stdin and look for tcpdump binary beaconing output.

    :param input: Stream to read PCAP data from.
    :type input: a file or stream supporting `read(int)`
    :param out: Stream to write to.
    :type input: a file or stream supporting `write(str)` and `flush()`.
    """
    err = sys.stderr
    try:
        pcap = PCAP(input)
        if pcap.global_header.data_link_type != 1:
            # Not an Ethernet interface. Need to exit here, because our
            # assumptions about the link layer header won't be correct.
            return 4
        for pcap_header, packet_bytes in pcap:
            try:
                packet = decode_ethernet_udp_packet(packet_bytes, pcap_header)
                beacon = BeaconingPacket(packet.payload)
                if not beacon.valid:
                    continue
                output_json = {
                    "source_mac": format_eui(packet.l2.src_eui),
                    "destination_mac": format_eui(packet.l2.dst_eui),
                    "source_ip": str(packet.l3.src_ip),
                    "destination_ip": str(packet.l3.dst_ip),
                    "source_port": packet.l4.packet.src_port,
                    "destination_port": packet.l4.packet.dst_port,
                    "time": pcap_header.timestamp_seconds
                }
                if packet.l2.vid is not None:
                    output_json["vid"] = packet.l2.vid
                if beacon.data is not None:
                    output_json.update(beacon_to_json(beacon.data))
                out.write(json.dumps(output_json))
                out.write('\n')
                out.flush()
            except PacketProcessingError as e:
                err.write(e.error)
                err.write("\n")
                err.flush()
    except EOFError:
        # Capture aborted before it could even begin. Note that this does not
        # occur if the end-of-stream occurs normally. (In that case, the
        # program will just exit.)
        return 3
    except PCAPError:
        # Capture aborted due to an I/O error.
        return 2
    return None
Beispiel #8
0
def observe_dhcp_packets(input=sys.stdin.buffer, out=sys.stdout):
    """Read stdin and look for tcpdump binary DHCP output.

    :param input: Stream to read PCAP data from.
    :type input: a file or stream supporting `read(int)`
    :param out: Stream to write to.
    :type input: a file or stream supporting `write(str)` and `flush()`.
    """
    try:
        pcap = PCAP(input)
        if pcap.global_header.data_link_type != 1:
            # Not an Ethernet interface. Need to exit here, because our
            # assumptions about the link layer header won't be correct.
            return 4
        for pcap_header, packet_bytes in pcap:
            out.write(str(datetime.now()))
            out.write("\n")
            try:
                packet = decode_ethernet_udp_packet(packet_bytes, pcap_header)
                dhcp = DHCP(packet.payload)
                if not dhcp.is_valid():
                    out.write(dhcp.invalid_reason)
                out.write(
                    "     Source MAC address: %s\n"
                    % format_eui(packet.l2.src_eui)
                )
                out.write(
                    "Destination MAC address: %s\n"
                    % format_eui(packet.l2.dst_eui)
                )
                if packet.l2.vid is not None:
                    out.write("     Seen on 802.1Q VID: %s\n" % packet.l2.vid)
                out.write("      Source IP address: %s\n" % packet.l3.src_ip)
                out.write(" Destination IP address: %s\n" % packet.l3.dst_ip)
                dhcp.write(out=out)
                out.flush()
            except PacketProcessingError as e:
                out.write(e.error)
                out.write("\n\n")
                out.flush()
    except EOFError:
        # Capture aborted before it could even begin. Note that this does not
        # occur if the end-of-stream occurs normally. (In that case, the
        # program will just exit.)
        return 3
    except PCAPError:
        # Capture aborted due to an I/O error.
        return 2
    return None
Beispiel #9
0
 def test_raises_PCAPError_for_invalid_PCAP_header(self):
     stream = io.BytesIO(b"\0" * 5)
     with ExpectedException(
             PCAPError, "Unexpected end of PCAP stream: invalid header."):
         PCAP(stream)
Beispiel #10
0
 def test_raises_PCAPError_for_invalid_PCAP_stream(self):
     stream = io.BytesIO(b"\0" * 24)
     with ExpectedException(PCAPError,
                            "Stream is not in native PCAP format."):
         PCAP(stream)
Beispiel #11
0
 def test_raises_EOFError_for_empty_PCAP_stream(self):
     stream = io.BytesIO(b"")
     with ExpectedException(EOFError, "No PCAP output found."):
         PCAP(stream)