Filter protocols in python
<p>I'm trying to filter certain packets with protocols using user input from a given pcap file and than move the packets to a new pcap file.</p>

<p>That the code I made so far: </p>

<pre><code># ===================================================
# Imports
# ===================================================


from scapy.all import *
from scapy.utils import PcapWriter
"""
your going to need to install the modules below
"""
from Tkinter import Tk
from tkFileDialog import askopenfilename

# ===================================================
# Constants
# ===================================================


#OS commands:
#~~~~~~~~~~~~~

if "linux2" in sys.platform:
    """
    linux based system clear command
    """
    CLEAR_COMMAND = "clear"
elif "win32" in sys.platform:
    """
    windows based system clear command
    """
    CLEAR_COMMAND = "cls"
elif "cygwin" in sys.platform:
    """
    crygwin based clear command
    """
    CLEAR_COMMAND = "printf \"\\033c\""
elif "darwin" in sys.platform:
    """
    mac OS X based clear command
    """
    CLEAR_COMMAND = "printf \'\\33c\\e[3J\'"

#Usage string:
#~~~~~~~~~~~~~~


FILE_STRING = "please choose a pcap file to use"
BROWSE_STRING = "press any key to browser files\n"
BAD_PATH_STRING = "bad file please try agien\n"
BAD_INPUT_STRING = "bad input please try agien\n"
PROTOCOL_STRING = "please enter the protocol you wish to filter\n"
NAME_STRING = "please enter the new pcap file name\n"



# ===================================================
# Code
# ===================================================


def filter_pcap():
    """
    filtering from the given pcap file a protocol the user chooce (from any layer in the OSI model)
    and than asks for a new pcap file name, than filters the given protocol to a new pcap file
    :param none
    :return nothing:
    """
    path = file_browse()
    i = 0
    filtertype = raw_input(PROTOCOL_STRING)
    name = raw_input(NAME_STRING)
    packs = rdpcap(path)
    for i in range(len(packs)):
        if filtertype in packs[i]:
           wrpcap(name +".pcap", packs[i])





def file_browse():


    """
    Purpose: It will allow the user to browse files on his computer
    than it will check if the path is ok and will return it

    :returns - the path to the chosen pcap file
    """
    path = "test"
    while ".pcap" not in path:
        print FILE_STRING
        raw_input(BROWSE_STRING)
        os.system(CLEAR_COMMAND)
        Tk().withdraw()
        path = askopenfilename()
        if ".pcap" not in path:
            print BAD_PATH_STRING
    return path

filter_pcap()
</code></pre>

<p>Now the problem is that I'm failing to filter the packets correctly.</p>

<p>The code need to filter protocols from any layer and any kind.</p>

<p>I have checked that thread: <a href="http://stackoverflow.com/questions/2247140/how-can-i-filter-a-pcap-file-by-specific-protocol-using-python">How can I filter a pcap file by specific protocol using python?</a></p>

<p>But as you can see it was not answered and the user added the problems I had in the edit, if any one could help me it would be great</p>

<p><strong>Example for how it should work:</strong> 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>

<ol>
<li>lets say i use the file "sniff" as my first pcap file and it has 489 packets when 200 from those packets are http packets.</li>
</ol>

<p>now there is that print:</p>

<pre><code>please enter the protocol you wish to filter
'http'
</code></pre>

<p>and than there is the print: </p>

<pre><code>please enter the new pcap file name
'new'
</code></pre>

<p>the user input was 'http' now the program will search for every packet that run on http protocol and will create a new pcap file called 'new.pcap'.</p>

<p>the file 'new.pcap' will contain 200 http packets.</p>

<p>now that thing should work with any protocol on the OSI model including protocols like IP, TCP, Ethernet and so on (all the protocols in the ascii model).</p>

<p>I have found out that wireshark command line has the option -R and tshark has .protocols, but it dont really work... Can any one check that?</p>

<p>edit: i found pyshark but i dont know how to write with it</p>

<p>I don't believe that scapy has any functions or methods to support application layer protocols in the way that you are after. However, using sport and dport as a filter will do the trick (provided you are going to see/are expecting default ports). </p>

<p>Try something like this:</p>

<pre><code>def filter_pcap(filtertype = None):
    ..... snip .....
    # Static Dict of port to protocol values. Like so:
    protocols = {'http': 80, 'ssh': 22, 'telnet': 21} 

    # Check to see if it is in the list
    while filtertype not in protocols:
        filtertype = raw_input(PROTOCOL_STRING) 

    # Name for output file
    name = raw_input(NAME_STRING)

    # Read Input File
    packs = rdpcap(path)

    # Filters to only TCP packets
    for packet in packs[TCP]:

        # Filter only the proto (aka Port) that we want
        if protocols[filtertype] in packet.sport or protocols[filtertype] in packet.dport :

            # Write to file
            wrpcap(name +".pcap", packet)
</code></pre>

python filter protocols wireshark