Hi,

I'd like to contribute some work that I've done to the wireshark community and 
need some advice on the best way to do this, assuming there is interest. If 
not, that would be good to know as well. I suspect that it might be best to 
fork this off as a separate project vs. incorporating it directly into ongoing 
SVN builds.

My initial goal was to modify the tshark (command line wireshark) and wrap it 
as a Python module. I wanted to expose tshark dissections as Python objects 
during packet capture or capture file processing. In addition this, I found 
that it was quite easy to extend this idea a bit more, so that other scripting 
languages (in additional to Python) could leverage the same code base. See 
below for details.

My motivation was that I wanted to do some work with Scapy and needed to access 
application layer protocol dissections within Python without re-writing all the 
dissection code already available in tshark/wireshark. 

This is what I have done to date (all Linux for now, but am porting to Windows):

a. Modified tshark code base and compiled it as a library, libtshark.a. This is 
the original tshark executable, more or less, with some notable additions. In 
particular, after packet dissection, the epan dissection tree data is copied 
off into another tree structure that I've defined. This t_dissect_node tree is 
then serialized and written out over a named-pipe. The name of the named-pipe 
is defined by the user at run-time. The code to unserialize the t_dissect_node 
tree is also part of libtshark.a. Also, I have incorporated some additional 
helper code that makes tree navigation easier. A function named 'run' is called 
to start tshark and accepts as parameters tshark command line args. 

b. A compiled Python shared library, _tsharkPY.so. I used SWIG to generate the 
Python bindings. Hence one could take the SWIG interface file that I wrote for 
Python (tsharkPY.i) and modify for use with other SWIG supported languages: 
Ruby, Java, etc.

c. tsharkPY.py is the Python module file created by SWIG, leverages my 
tsharkPY.i SWIG interface file.

All the above is based off of the most recent SVN builds and generation of the 
two lib files above has been incorporated into the existing Wireshark build 
process. Hence, all you have to do is run 'make' and you get libtshark.a and 
_tsharkPY.so. 'make install' puts these files into your Python lib path as 
defined by libtool. I do need some help tweaking this, however. Right now, 
libtool wants to put these in /usr/local/lib/python2.6/site-packages/. However, 
they need to be placed in /usr/lib/python2.6/site-packages/. Any thoughts 
(other than hard coding the correct path)?

Some basic Python code to use the Python module is as follows.

import tsharkPY

#fork tshark. tshark will publish its dissections to 'tshark_pipe' FIFO. Will 
read and dissect 3 packets from mycapfile.
tsharkPY.run(["python","-W", "tshark_pipe","-c","3","-r","mycapfile"])

#subscribe to 'tshark_pipe'FIFO
tsharkPY.subscribe("tshark_pipe")

packets = []

#grab packets one at a time from tshark and save them in 'packets' array
while(1):
    
    #get packet from "tshark_pipe" FIFO
    p = tsharkPY.get_next_packet("tshark_pipe")
    
    #check for closed pipe/EOF. break out of loop when detected.
    if(p is None):
        #unsubscribe from tshark_pipe FIFO. cleans up FIFO file and does some 
other house keeping.
        tsharkPY.unsubscribe("tshark_pipe")
        break
    
    #create protocol set, array, and dictionary objects and make them part of 
t_dissect_node object
    p.create_protocol_containers()
    
    #create dictionary containing field names of all the nodes in the packet 
tree that has 'p' as its root.
    p.create_node_dict()
    
    #append t_dissect_node object to 'packets' array
    packets.append(p)


print "Protocol sets: unordered list of protocols found in packet."
for packet in packets:                          #iterate over array of 
t_dissect_node trees. Each tree is one packet's worth of data.
    for proto in packet.protocol_set:           #iterate over each protocol 
name (string) in t_dissect_tree's protocol set object.
        print proto,                            #print protocol name
    print                                       #print extra line    

print "\nProtocol array: ordered array of protocol-level t_dissect_node 
references."    
for packet in packets:                          #iterate over array of 
t_dissect_node trees. Each tree is one packet's worth of data.
    for node in packet.protocol_array:          #iterate over t_dissect_node 
object references in packet's protocol array.
        if node.field_name is not None:         #if node.field_name exists (is 
not NULL), print value                   
            print node.field_name,
    print
    
print "\nProtocol dictionary: hash table indexed by protocol name. provides 
access to t_dissect_node references for protocol level nodes in dissection 
tree."
for packet in packets:                                          #iterate over 
array of t_dissect_node trees. Each tree is one packet's worth of data.
    d_keys = packet.protocol_dict.keys()                        #dump key list 
for packet's protocol_dict object
    for k in d_keys:                                            #iterate over 
key valus
        node = packet.protocol_dict[k]                          #get reference 
to each protocol level node in series
        if node is not None and node.field_name is not None:    #if successful 
in retrieving node using current key, print node's field_name
            print node.field_name,
    print

print "\nPacket debug print"
for packet in packets:                          #iterate over array of 
t_dissect_node trees. Each tree is one packet's worth of data.
    packet.print_tree()                         #print t_dissect_node tree info 
for current packet

print "\nPacket data as Python char list."
for packet in packets:                                          #iterate over 
array of t_dissect_node trees. Each tree is one packet's worth of data.
    try:
        p = packet.first_child.next.last_child                  #find a node in 
tree that probably has data                 
        data_list = p.binary_blob                               #get node data 
as a list of chars 
        print data_list                                         #print list

    except:
        pass                                                    #ignore any 
exceptions thrown from above code
    
print "\nNode dictionary: dictionary that hashes all nodes in node tree by 
their field names (if defined). If duplicate field_names exist, only the first 
one encountered is added."
for packet in packets:                          #iterate over array of 
t_dissect_node trees. Each tree is one packet's worth of data.
    d_keys = packet.node_dict.keys()            #dump key list
    for k in d_keys:                            #iterate over key list
        print k,                                #print each key 
    print "\n"
    
print "\nFind node by its field name. Looking for 'ip.dst_host' in second 
packet"
node = packets[1].node_dict['ip.dst_host']                              #find 
node in second packet that has its field_name param set to 'ip.dst_host'.
if (node is not None):
    print node.field_name+" found! Showname is '"+node.showname+"'"     #if 
found, print some stuff from t_dissect_node structure
print

___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev@wireshark.org>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe

Reply via email to