1

Using Python I want to continuously read the packets one-by-one in the same order they are written into, from a pcap file that is being continuously written by tshark (or a piece of code written in libpcap or pfring) live capture.

To test this I used tshark and scapy in Python in the following way.

@terminal1: ping -i 5 192.168.1.10

@terminal2: tshark -f "icmp" -a filesize:1000 -w ping_live.pcap

Packet reader in Python intended to read each unread packet at every 5 seconds (not the whole set of packets every time). But it will not wait for the next set of packets that are about to written after 5 second, and it exits.

from scapy.all import *

def process_packet(packet):
    print(packet.summary())

sniff(offline="ping_live.pcap", prn=process_packet, store=0)
print("sniff complete, exiting")

Then I tried to put while True: loop around the sniff method, but it is not reading only the next unread packet, instead reading whole file again and again.

What is the solution for my requirement (not limited to scapy)?

Thank you

reddi hari
  • 173
  • 1
  • 12
  • You are reading the same pcap eveytime, thus you are parsing all packets of this pcap. A solution could be with a filter and only parse the last two packets of this pcap. – sinkmanu Jan 24 '21 at 12:51
  • I'm auditing my old answers. Did my answer on this question help you? – Life is complex Jan 11 '22 at 13:47

1 Answers1

1

I'm unsure if this answers your question, because I cannot understand the exact requirement. Based on my interpretation of the information within your question, you want to 'continuously read the packets in the same order as they are written into a PCAP file."

Your example used ICMP, so my answer will use that protocol.

import pyshark

# filter live capture by type, which is ICMP
capture = pyshark.LiveCapture('en0', display_filter='icmp')

for packet in capture:

    # obtain all the field names within the ICMP packets
    field_names = packet.icmp._all_fields

    # obtain all the field values 
    field_values = packet.icmp._all_fields.values()

    # enumerate the field names and field values
    for field_name, field_value in zip(field_names, field_values):

        # filter the time stamp
        if field_name == 'icmp.data_time':
            print(field_value)
            # output
            Mar 21, 2021 09:03:21.681450000 EDT
            Mar 21, 2021 09:03:21.681450000 EDT
            Mar 21, 2021 09:03:22.686135000 EDT
            Mar 21, 2021 09:03:22.686135000 EDT
            Mar 21, 2021 09:03:23.689576000 EDT
            Mar 21, 2021 09:03:23.689576000 EDT
            Mar 21, 2021 09:03:24.691429000 EDT
            Mar 21, 2021 09:03:24.691429000 EDT
            Mar 21, 2021 09:03:25.692395000 EDT
            Mar 21, 2021 09:03:25.692395000 EDT
            truncated...

Here are the field names that can be filtered:

icmp.type
icmp.code
icmp.checksum
icmp.checksum.status
icmp.ident
icmp.seq
icmp.seq_le
icmp.data_time
icmp.data_time_relative
data
data.data
data.len

Hopefully, this answer helps you.

P.S. Here is a GitHub document that I wrote on using pyshark.

Life is complex
  • 15,374
  • 5
  • 29
  • 58
  • I guess it will miss some of the packets if we have 10GB ethernet speed and packets are being sent continuously. At least in my case from 95k packets where I send 1GB file from A to B, it only captured the first 200 packets with scapy and 88k with dpkt(I decreased speed from 10GB to 1GB). How to resolve this issue in such a case? – Nagmat Aug 24 '22 at 19:19