Reading PCAP file with scapy - python

I have about 10GB pcap data with IPv6 traffic to analyze infos stored in IPv6 header and other extension header. To do this I decided to use Scapy framework. I tried rdpcap function , but for such big files it is not recommended. It tries to load all file into memory and get stuck in my case.
I found in the Net that in such situation sniff is recommended, my code look like:
def main():
sniff(offline='traffic.pcap', prn=my_method,store=0)
def my_method(packet):
packet.show()
In function called my_method I receive each packet separately and I can parse them, but....
When I call show function with is in-build framework method I got sth like this:
When opened in wireshark I got properly looking packet:
Could you tell me how to parse this packets in scapy to get proper results?
EDIT:
According to the discussion in comments I found a way to parse PCAP file with Python. In my opinion the easies way is to use pyshark framework:
import pyshark
pcap = pyshark.FileCapture(pcap_path) ### for reading PCAP file
It is possible to easily iterate read file with for loop
for pkt in pcap:
#do what you want
For parsing IPv6 header following methods may be useful:
pkt['ipv6'].tclass #Traffic class field
pkt['ipv6'].tclass_dscp #Traffic class DSCP field
pkt['ipv6'].tclass_ecn #Traffic class ECN field
pkt['ipv6'].flow #Flow label field
pkt['ipv6'].plen #Payload length field
pkt['ipv6'].nxt #Next header field
pkt['ipv6'].hlim #Hop limit field

Update
The latest scapy versions now support ipv6 parsing.
So to parse an ipv6 ".pcap" file with scapy now it can be done like so:
from scapy.all import *
scapy_cap = rdpcap('file.pcap')
for packet in scapy_cap:
print packet[IPv6].src
Now as I had commented back when this question was originally asked, for older
scapy versions (that don't support ipv6 parsing):
pyshark can be used instead (pyshark is a tshark wrapper) like so:
import pyshark
shark_cap = pyshark.FileCapture('file.pcap')
for packet in shark_cap:
print packet.ipv6.src
or even of course tshark (kind of the terminal version of wireshark):
$ tshark -r file.pcap -q -Tfields -e ipv6.src

If you want to keep using scapy and read the file Iteratively I'd recommend you to give it a shot to PcapReader()
It would do the same you tried to do with pyshark but in Scapy
from scapy.all import *
for packet in PcapReader('file.pcap')
try:
print(packet[IPv6].src)
except:
pass
I'd recommend wrapping this around just as a failsafe if you have any packet that does not have an IPv6 address.

Related

Loop through pyshark's FileCapture object stops working

I am reading a pcap file I have acquired with tcpdump. The pcap file is ~500MB. I read the file with FileCapture() and then I want to loop through each packet to extract the TLS payload. When I create the FileCapture object I also use override_prefs={'tls.keylog_file': os.path.abspath('tlsKey') where tlsKey is the file with the master keys to decrypt the file. The decryption works just fine, I can extract all the information from each single packet. However, if I want to loop through each packet and extract some information, the loop stops working at the packet for which packet.number = 258. My file contains more than 258 packets. What is going on?
My code
import pyshark
import os
cap = pyshark.FileCapture('traffic.pcap')
for packet in cap:
print(packet.number)
if "IP" in packet:
print(packet)
print('Finished')
the last output I get is here. As you can see, the layer TLS does not get printed. Why?
Expected behavior
I would expect my script to print Finished at the end, but it doesn't. The for loop looks stuck. Since the pcap file is large I cannot attach it. Any explanation of what's happening?
Versions (please complete the following information):
OS: MacOS 13.1
pyshark version: 0.5.3
tshark version: TShark (Wireshark) 4.0.2 (v4.0.2-0-g415456d13370)

How to read pcapng (wireshark) files in Python?

I have a capture of some TCP packets in pcapng format and I'd like to open it in python to inspect the TCP payloads with address 192.168.1.198. I've only found this library: https://python-pcapng.readthedocs.io/en/latest/api/blocks.html but it does not support inspecting TCP payloads.
Is there an easy way?
You can use python-pcapng package. First install python-pcapng package by following command.
pip install python-pcapng
Then use following sample code.
from pcapng import FileScanner
with open(r'C:\Users\zahangir\Downloads\MDS19 Wireshark Log 08072021.pcapng', 'rb') as fp:
scanner = FileScanner(fp)
for block in scanner:
print(block)
print(block._raw) #byte type raw data
Above code worked for me.
Reference: https://pypi.org/project/python-pcapng/

Getting a particular package from the pcap file using the Scapy module (python)

Is there a way to load a particular package from the pcap file using Scapy?
I know that I can load a specific number of packages using the' sniff' function and count attribute, e. g.'
sniff(offline='file.pcap', prn=action, count=31)
However, I need to get a 30th packet without loading the previous packets.
In other words, I am not satisfied with such an example:
packages = (pkt for pkt in sniff (offline=path, prn=action, count=31)
print(packages[30])
The attempt to load a millionth of a package is too long.
Each packet header states how long it is. Once the parser has read that header, it can calculate the position of the next one. So as far as I know, you cannot open a pcap file and instantly locate packet 30; you'll need to parse the headers of the first 29.
But you don't have to keep all packets in memory either, as long as you process them while receiving.
i = 0
for pkt in sniff(offline=path, prn=action):
if i == 30:
print pkt
break

Python based network sniffer (scapy not good enough?)

I am looking for the specific task:
Grab the payload/data from a packet -> Append to a file... BUT. I want specifically to follow packets according to flags/ICMP types/etc... So lets say I want specifically to take the payload of "echo" packets and not the rest.
My (ineffective) code is the following:
from scapy.all import *
f= open('filecaptured', 'a+')
def pkt_diam(pkt):
raw = pkt.getlayer(Raw).load
print raw
# pkt.show()
# fo = open("payload", "wb")
f.write(raw);
sniff (filter="icmp" , store=0, prn=pkt_diam, timeout = 120 )
The problem here is that I cannot find a way to sniff specifically for "type = echo request" and the only parameters that I can use is 'protocol' and host or 'and not host 127.0.0.1'.
Is there a way around this?
I think for this one I need to use ctypes and libpcap.so but I am not sure... (I didnt find any [other] libraries for python - sniffing )
I don't have scapy installed right now, but what if you simply check for the type echo-reply in your callback-function pkt_diam:
if not "echo-reply" in pkt.show():
return
Try filter="icmp[0]=8" for filtering during capture or
if pkt[ICMP].type==8:
in callback function.

print scapy sniff output to file

I have created a sniffer in scapy and I want the packets captured by scapy to be written onto a file for further analysis?
def sniffer(ip):
filter_str = "icmp and host " + ip
packets=sniff(filter=filter_str,count=20)
f = open('log.txt',"a")
#f.write(packets)
The last line of code does not work. Is there any way I could do this?
f.write expects a character buffer, but you supply it with a Sniffed object which is the result of calling sniff. You can, very simply, do the following:
f.write(str(packets))
This should work. But it probably won't display the information exactly as you would like it. You are going to have to do more work collecting information from packets as strings before you write to f.

Categories