View on GitHub

PyShark

Python packet parser using wireshark's tshark

Download this project as a .zip file Download this project as a tar.gz file

pyshark

Python wrapper for tshark, allowing python packet parsing using wireshark dissectors.

There are quite a few python packet parsing modules, this one is different because it doesn't actually parse any packets, it simply uses tshark's (wireshark command-line utility) ability to export XMLs to use its parsing.

This package allows parsing from a capture file or a live capture, using all wireshark dissectors you have installed. Tested on windows/linux.

Usage

Pyshark features a few "Capture" objects (Live, Remote, File, InMem). Each of those files read from their respective source and then can be used as an iterator to get their packets. Each capture object can also receive various filters so that only some of the incoming packets will be saved.

Reading from a capture file:

import pyshark
cap = pyshark.FileCapture('/tmp/mycapture.cap')
cap
>>> <FileCapture /tmp/mycapture.cap>
print cap[0]
Packet (Length: 698)
Layer ETH:
        Destination: aa:bb:cc:dd:ee:ff
        Source: 00:de:ad:be:ef:00
        Type: IP (0x0800)
Layer IP:
        Version: 4
        Header Length: 20 bytes
        Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        Total Length: 684
        Identification: 0x254f (9551)
        Flags: 0x00
        Fragment offset: 0
        Time to live: 1
        Protocol: UDP (17)
        Header checksum: 0xe148 [correct]
        Source: 192.168.0.1
        Destination: 192.168.0.2
  ...

Reading from a live interface:

capture = pyshark.LiveCapture(interface='eth0')
capture.sniff(timeout=50)
capture
>>> <LiveCapture (5 packets)>
capture[3]
<UDP/HTTP Packet>

for packet in capture.sniff_continuously(packet_count=5):
    print 'Just arrived:', packet

Capturing from a live interface can be done in two ways: either using the sniff() method to capture a given amount of packets (or for a given amount of time) and then read the packets from the capture object as a list, or use the sniff_continously() method as a generator and work on each packet as it arrives. Another alternative is defining a callback for each received packet:

def print_callback(pkt):
    print 'Just arrived:', pkt
capture.apply_on_packets(print_callback, timeout=5)

The capture can also run on multiple interfaces if a list is provided, or all interfaces if no interface is provided. It can even be run through a remote interface using RemoteCapture.

Filtering packets:

Filtering packets can be done with any capture object, like so:

filtered_cap = pyshark.FileCapture(path_to_file, display_filter='http')
filtered_cap2 = pyshark.LiveCapture('eth0', bpf_filter='tcp port 80')

There are two types of filters, BPF filters and display filters. Generally, bpf filters are more limited but are faster while display filters can be used on pretty much any attribute of the packet but are much slower. (Note: there is currently an issue with BPF filters on FileCapture and it is not recommended it be used).

See BPF syntax help here and display filters help here.

Accessing packet data:

Data can be accessed in multiple ways. Packets are divided into layers, first you have to reach the appropriate layer and then you can select your field.

All of the following work:

packet['ip'].dst # By protocol string
>>> 192.168.0.1
packet.ip.src # By protocol attribute
>>> 192.168.0.100
packet[2].src # By layer index
>>> 192.168.0.100

To easily view the different attributes of the layer, you can simply run dir(packet.my_layer) or even print it or use the special pretty_print() method both layer and packet have. Note that all attributes return as strings at the moment.