aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wspython
diff options
context:
space:
mode:
authorSebastien Tandel <sebastien@tandel.be>2009-05-29 21:10:40 +0000
committerSebastien Tandel <sebastien@tandel.be>2009-05-29 21:10:40 +0000
commit52cc5fb1e86ac8007eabe1291bf543d3803f7148 (patch)
tree0ee2757e438e9d9db9dd0ddab19f0e84f3f29f03 /epan/wspython
parentcb4f0a40c23a3247fbb74a74dc117cbef4f83bf4 (diff)
python binding for wireshark (first commit)
* ability to write dissectors with python for wireshark. documentation (http://wiki.wireshark.org/Python) svn path=/trunk/; revision=28529
Diffstat (limited to 'epan/wspython')
-rw-r--r--epan/wspython/Makefile.am56
-rw-r--r--epan/wspython/Makefile.common32
-rw-r--r--epan/wspython/register-dissector.py76
-rw-r--r--epan/wspython/wspy_dissector.py392
-rw-r--r--epan/wspython/wspy_dissectors/homeplug.py.sample90
-rw-r--r--epan/wspython/wspy_libws.py48
-rw-r--r--epan/wspython/wspy_proto.c92
-rw-r--r--epan/wspython/wspy_proto.h46
-rw-r--r--epan/wspython/wspy_register.c270
-rw-r--r--epan/wspython/wspy_register.h42
10 files changed, 1144 insertions, 0 deletions
diff --git a/epan/wspython/Makefile.am b/epan/wspython/Makefile.am
new file mode 100644
index 0000000000..f181dab5f7
--- /dev/null
+++ b/epan/wspython/Makefile.am
@@ -0,0 +1,56 @@
+# Makefile.am
+#
+# $Id: $
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if HAVE_WARNINGS_AS_ERRORS
+AM_CFLAGS = -Werror
+endif
+
+include Makefile.common
+
+noinst_LTLIBRARIES = libwspython.la
+
+CLEANFILES = \
+ libwspython.a \
+ libwspython.la \
+ *~
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+INCLUDES = -I$(srcdir)/../.. -I$(srcdir)/..
+
+libwspython_la_SOURCES = $(LIBWSPYTHON_SRC) $(LIBWSPYTHON_INCLUDES)
+
+libwspython_la_LIBADD = @PY_LIBS@
+libwspython_la_CFLAGS = @PY_CFLAGS@
+
+wspythondir=@pythondir@
+
+wspython_DATA= \
+ register-dissector.py \
+ wspy_dissector.py \
+ wspy_libws.py
+
+
+EXTRA_DIST = \
+ Makefile.common \
+ Makefile.nmake
diff --git a/epan/wspython/Makefile.common b/epan/wspython/Makefile.common
new file mode 100644
index 0000000000..d743d4a937
--- /dev/null
+++ b/epan/wspython/Makefile.common
@@ -0,0 +1,32 @@
+# Makefile.common
+# Contains the stuff from Makefile.am and Makefile.nmake that is
+# a) common to both files and
+# b) portable between both files
+#
+# $Id: $
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+LIBWSPYTHON_SRC = \
+ wspy_register.c \
+ wspy_proto.c
+
+LIBWSPYTHON_INCLUDES = \
+ wspy_register.h \
+ wspy_proto.h
diff --git a/epan/wspython/register-dissector.py b/epan/wspython/register-dissector.py
new file mode 100644
index 0000000000..e05bfbcc37
--- /dev/null
+++ b/epan/wspython/register-dissector.py
@@ -0,0 +1,76 @@
+# register-dissector.py
+#
+# $Id: $
+#
+# Wireshark Protocol Python Binding
+#
+# Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+# Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+import sys
+import re
+import os
+import imp
+
+#
+# Build a list of files belonging to a directory and matching a regexp (f.e.
+# '(?P<plugin>.*)\.py$' )
+#
+def get_plugin_list(dir, regexp):
+ lDir = os.listdir(dir)
+
+ lPlugins=[]
+ for sDir in lDir:
+ MatchedObject = re.match(regexp, sDir)
+ if (MatchedObject != None):
+ lPlugins.append(MatchedObject.group("plugin"))
+ return lPlugins
+
+#Import the module "name"
+def plugin_import(name):
+ #if the module was already loaded
+ try:
+ return sys.modules[name]
+ except KeyError:
+ pass
+
+ return __import__(name)
+
+def register_dissectors(dir):
+ #append dir to be able to import py_lib
+ sys.path.append(dir)
+ from wspy_libws import get_libws_handle
+ libws = get_libws_handle()
+
+ dissectors_dir = os.path.join(dir, "wspy_dissectors")
+ #append dir to be able to import python dissectors
+ sys.path.append(dissectors_dir)
+
+ registered_protocols = []
+ #Read all python dissectors
+ try:
+ dissectors = get_plugin_list(dissectors_dir, "(?P<plugin>.*)\.py$")
+ #For each dissector, register it and put it in the list of registered
+ #protocols
+ for dissector in dissectors:
+ d = plugin_import(dissector)
+ registered_protocol = d.register_protocol()
+ if registered_protocol:
+ registered_protocols.append(registered_protocol)
+ except Exception, e:
+ print e
+
+ return registered_protocols
diff --git a/epan/wspython/wspy_dissector.py b/epan/wspython/wspy_dissector.py
new file mode 100644
index 0000000000..e44f529cfe
--- /dev/null
+++ b/epan/wspython/wspy_dissector.py
@@ -0,0 +1,392 @@
+# wspy_dissector.py
+#
+# $Id: $
+#
+# Wireshark Protocol Python Binding
+#
+# Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+# Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from ctypes import c_int, pointer, POINTER, py_object
+from wspy_libws import get_libws_handle
+
+# From epan/proto.h
+# ? STA ? : is there a better way to include/define these constants?
+# (duplicating definition is not a good thing)
+(BASE_NONE,
+BASE_DEC,
+BASE_HEX,
+BASE_OCT,
+BASE_DEC_HEX,
+BASE_HEX_DEC,
+BASE_CUSTOM) = map(int, xrange(7))
+
+# field types, see epan/ftypes/ftypes.h
+(FT_NONE,
+FT_PROTOCOL,
+FT_BOOLEAN,
+FT_UINT8,
+FT_UINT16,
+FT_UINT24,
+FT_UINT32,
+FT_UINT64,
+FT_INT8,
+FT_INT16,
+FT_INT24,
+FT_INT32,
+FT_INT64,
+FT_FLOAT,
+FT_DOUBLE,
+FT_ABSOLUTE_TIME,
+FT_RELATIVE_TIME,
+FT_STRING,
+FT_STRINGZ,
+FT_EBCDIC,
+FT_UINT_STRING,
+FT_ETHER,
+FT_BYTES,
+FT_UINT_BYTES,
+FT_IPv4,
+FT_IPv6,
+FT_IPXNET,
+FT_FRAMENUM,
+FT_PCRE,
+FT_GUID,
+FT_OID) = map(int, xrange(31))
+
+# hf_register_info from usual dissectors
+class register_info(object):
+ def __init__(self, wsl):
+ self.__protocol = None
+ self.__wsl = wsl
+ self.__hf_register = None
+ self.__registers = []
+
+ def add(self, name, short_desc, \
+ type=FT_UINT32, display=BASE_DEC, \
+ strings=None, bitmask=0x0, desc=None):
+ if not desc:
+ desc = name
+ self.__registers.append( (name, short_desc, \
+ type, display, strings, bitmask, desc) )
+
+ def register(self, protocol):
+ self.__protocol = protocol
+ hf = self.__registers
+ lr = len(hf)
+ if not lr:
+ return None
+
+ self.__hf_register = self.__wsl.hf_register_info_create(lr)
+ chf = self.__hf_register
+ if not self.__hf_register:
+ return None
+
+ for i in xrange(lr):
+ n, sd, t, d, st, bm, ld = hf[i]
+ sdn = sd.replace('.', '_')
+ self.__dict__[sdn] = c_int(-1)
+ p_id = pointer(self.__dict__[sdn])
+ self.__wsl.hf_register_info_add(chf, i, p_id, n , sd, t, d, st, bm, ld)
+
+ self.__wsl.proto_register_field_array(self.__protocol, chf, lr)
+
+ def display(self):
+ self.__wsl.hf_register_info_print(self.__hf_register, \
+ len(self.__registers))
+
+ def get(self):
+ return self.__hf_register, len(self.__registers)
+
+ def __del__(self):
+ self.__wsl.hf_register_info_destroy(self.__hf_register)
+
+#Subtrees definition
+#Every subtree added can be accesses as an attribute after having been
+#registered
+class Subtree(object):
+ def __init__(self, wsl, protocol):
+ self.__wsl = wsl
+ self.__protocol = protocol
+ self.__st = {}
+ self.__user_defined_protocol_tree = False
+
+ def add(self, name):
+ if name == self.__protocol:
+ self.__user_defined_protocol_tree = True
+
+ self.__st[name] = c_int(-1)
+
+ def has_user_defined_protocol_tree(self):
+ return self.__user_defined_protocol_tree
+
+ def register(self):
+ if not self.__user_defined_protocol_tree:
+ self.__st[self.__protocol] = c_int(-1)
+
+ ls = len(self.__st)
+ if not ls:
+ return
+
+ CSubtrees = POINTER(c_int) * ls
+ p_sts = CSubtrees()
+ k = self.__st.keys()
+ for i in xrange(ls):
+ p_sts[i] = pointer(self.__st[k[i]])
+
+ self.__wsl.proto_register_subtree_array(p_sts, ls)
+
+ def __getattr__(self, name):
+ if self.__st.has_key(name):
+ return self.__st[name]
+ #raise KeyError
+
+#Dissector class : base class to write a dissector in python
+class Dissector(object):
+ def __init__(self, protocol_name, short_desc, short):
+ self.__protocol_name = protocol_name
+ self.__short_desc = short_desc
+ self.__short = short
+
+ self.__tvb = None
+ self.__pinfo = None
+ self.__tree = None
+
+ self.__Tree = None
+
+ self.__offset = 0
+
+ self.__wsl = get_libws_handle()
+ self.__hf = None
+ self.__subtree = None
+
+ def fields(self):
+ if not self.__hf:
+ self.__hf = register_info(self.__wsl)
+ return self.__hf
+
+ def subtrees(self):
+ if not self.__subtree:
+ self.__subtree = Subtree(self.__wsl, self.__short)
+ return self.__subtree
+
+ def tree(self):
+ if not self.__Tree:
+ self.__Tree = Tree(self.__tree, self)
+ return self.__Tree
+
+ def display(self):
+ print self.__short
+
+ def __str__(self):
+ # STA TODO : keep with short_desc because used in the hash table of
+ # dissectors in C code. If it is modified, it won't work anymore
+ return self.__short_desc
+
+ def __unicode__(self):
+ return self.__short
+
+ def __hash__(self):
+ return hash(self.__short)
+
+ def protocol(self):
+ return self.__protocol
+
+ def register_protocol(self):
+ self.__protocol = \
+ self.__wsl.proto_register_protocol( \
+ self.__protocol_name, self.__short_desc, \
+ self.__short)
+ self.__hf.register(self.__protocol)
+ #self.__hf.display()
+ self.__subtree.register()
+
+ def dissect(self):
+ pass
+
+ def pre_dissect(self):
+ self.__tvb = self.__wsl.py_tvbuff()
+ self.__pinfo = self.__wsl.py_pinfo()
+ self.__tree = self.__wsl.py_tree()
+
+ #self.__wsl.print_current_proto(py_object(pinfo))
+ subt = self.subtrees()
+ try:
+ if not subt.has_user_defined_protocol_tree():
+ tree = self.tree()
+ p_tree = tree.add_item(self.protocol())
+ self.__Tree = p_tree.add_subtree(subt.homeplug)
+ except:
+ print e
+ self.dissect()
+
+ def protocol_ids(self):
+ return [ (None, 0, None) ]
+
+ def create_dissector_handle(self, protocol=None):
+ gdissector = self.__wsl.py_generic_dissector()
+ if not protocol:
+ protocol = self.__protocol
+ return self.__wsl.create_dissector_handle(gdissector, protocol)
+
+ def find_dissector(self, protocol):
+ return self.__wsl.find_dissector(protocol)
+
+ def register_handoff(self):
+ #TODO STA : think how we would use dissector_add in an easy way *and* with
+ #the possibility to add the same dissector for TCP and UDP (extend
+ #py_generic_dissector)
+ private_handle = None
+ try:
+ ids = self.protocol_ids()
+ for type, protocol_id, handle in self.protocol_ids():
+ if not type:
+ continue
+ if not handle:
+ if not private_handle:
+ handle = \
+ self.create_dissector_handle(self.__protocol)
+ else:
+ handle = private_handle
+ self.__wsl.dissector_add(type, protocol_id, handle)
+ except Exception, e:
+ print "creating dissector failed", e
+ raise
+
+ def advance(self, step):
+ self.__offset += step
+
+ def offset(self):
+ return self.__offset
+
+ def _wsl(self):
+ return self.__wsl
+
+ def _tvb(self):
+ return self.__tvb
+
+#Tree class implementation
+#see proto.h
+class Tree(object):
+ def __init__(self, tree, dissector):
+ self.__dissector = dissector
+ self.__tree = tree
+ self.__wsl = dissector._wsl()
+ self.__tvb = dissector._tvb()
+
+ def add_item(self, field, offset=0, length=-1, little_endian=False, adv=True):
+ '''add an item to the tree'''
+ try:
+ tree = self.__wsl.proto_tree_add_item(self.__tree, \
+ field, self.__tvb, self.__dissector.offset(), length, \
+ little_endian)
+ except Exception, e:
+ print e
+ else:
+ if length > 0 and adv:
+ self.__dissector.advance(length)
+ return Tree(tree, self.__dissector)
+
+ def add_uint(self, field, value, offset=0, length=4, adv=True):
+ '''add unsigned integer to the tree'''
+ try:
+ tree = self.__wsl.proto_tree_add_uint(self.__tree, field, self.__tvb, self.__dissector.offset(), length, value)
+ except Exception, e:
+ print e
+ else:
+ if adv:
+ self.__dissector.advance(length)
+ return Tree(tree, self.__dissector)
+
+ def add_text(self, string, offset=0, length=-1, adv=True):
+ '''add text to the tree'''
+ try:
+ tree = self.__wsl.proto_tree_add_text(self.__tree, self.__tvb, self.__dissector.offset(), length, string)
+ except Exception, e:
+ print e
+ else:
+ if length > 0 and adv:
+ self.__dissector.advance(length)
+ return Tree(tree, self.__dissector)
+
+ def add_subtree(self, subtree):
+ '''add a subtree to the tree'''
+ try:
+ tree = self.__wsl.proto_item_add_subtree(self.__tree, subtree)
+ except Exception, e:
+ print e
+ else:
+ return Tree(tree, self.__dissector)
+
+#tvb class implementation
+#see proto.h
+class TVB(object):
+ def __init__(self, wsl, tvb, dissector):
+ self.__tvb = tvb
+ self.__wsl = wsl
+ self.__dissector = dissector
+
+ def length(self):
+ return self.__wsl.length(self.__wsl)
+
+ def length_remaining(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_length_remaining(self.__tvb, offset)
+
+ def reported_length(self):
+ return self.__wsl.tvb_reported_length(self.__tvb)
+
+ def reported_length_remaining(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_length_remaining(self.__tvb, offset)
+
+ def get_guint8(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_get_guint8(self.__tvb)
+
+ def get_ntohs(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_get_ntohs(self.__tvb, offset)
+
+ def get_ntohl(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_get_ntohl(self.__tvb, offset)
+
+ def get_letohl(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_get_letohl(self.__tvb, offset)
+
+ def get_letohs(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_get_letohs(self.__tvb, offset)
+
+ #STA TODO : check that we can do that
+ def get_ptr(self, offset=-1):
+ if offset < 0:
+ offset = self.__dissector.offset()
+ return self.__wsl.tvb_get_ptr(self.__tvb, offset)
+
+ #how to get this working ??? check how application uses this!
+ #def new_subset(self, offset=0):
+ # return self.__wsl.tvb_get_new_subset(self.tvb, offset)
diff --git a/epan/wspython/wspy_dissectors/homeplug.py.sample b/epan/wspython/wspy_dissectors/homeplug.py.sample
new file mode 100644
index 0000000000..d12a29c139
--- /dev/null
+++ b/epan/wspython/wspy_dissectors/homeplug.py.sample
@@ -0,0 +1,90 @@
+from wspy_dissector import Dissector
+from wspy_dissector import FT_UINT8, FT_NONE
+from wspy_dissector import BASE_NONE, BASE_HEX
+
+class homeplug(Dissector):
+ # return the two first parameters of dissector_add as a tuple
+ def protocol_ids(self):
+ #you could use self.find_dissector() or self.create_dissector_handle() as
+ #defined in proto.h and pass the result in the third element of the tuple
+ #returned
+ return [ ("ethertype", 0x887B, None) ]
+
+ #Main default entry point of dissection
+ def dissect(self):
+ self.dissect_mctrl()
+ self.dissect_mehdr()
+ self.dissect_melen()
+
+ def dissect_mctrl(self):
+ self.hf = self.fields()
+ self.subt = self.subtrees()
+ self.c_tree = self.tree()
+ try:
+ tree = self.c_tree.add_item(self.hf.homeplug_mctrl, length=1, adv=False)
+ mctrl_tree = tree.add_subtree(self.subt.mctrl)
+
+ mctrl_tree.add_item(self.hf.homeplug_mctrl_rsvd, length=1, adv=False)
+ mctrl_tree.add_item(self.hf.homeplug_mctrl_ne, length=1)
+ except Exception, e:
+ print e
+
+ def dissect_mehdr(self):
+ try:
+ tree = self.c_tree.add_item(self.hf.homeplug_mehdr, length=1, adv=False)
+ mehdr_tree = tree.add_subtree(self.subt.mehdr)
+
+ mehdr_tree.add_item(self.hf.homeplug_mehdr_mev, length=1, adv=False)
+ mehdr_tree.add_item(self.hf.homeplug_mehdr_metype, length=1)
+ except Exception, e:
+ print e
+
+ def dissect_melen(self):
+ try:
+ self.c_tree.add_item(self.hf.homeplug_melen, length=1)
+ except Exception, e:
+ print e
+
+ def dissect_mme(self):
+ try:
+ self.c_tree.add_item(self.hf.homeplug_mme, length=1)
+ except Exception, e:
+ print e
+
+
+HOMEPLUG_MCTRL_RSVD = 0x80
+HOMEPLUG_MCTRL_NE = 0x7F
+HOMEPLUG_MEHDR_MEV = 0xE0
+HOMEPLUG_MEHDR_METYPE = 0x1F
+
+def register_protocol():
+ tp = homeplug("HomePlug protocol", "HomePlug", "homeplug")
+
+ #
+ # Register Protocol Fields
+ #
+ hf = tp.fields()
+ # MAC Control Field
+ hf.add("Mac Control Field", "homeplug.mctrl", FT_NONE, BASE_NONE)
+ hf.add("Reserved", "homeplug.mctrl.rsvd", FT_UINT8, bitmask=HOMEPLUG_MCTRL_RSVD)
+ hf.add("Number of MAC Data Entries", "homeplug.mctrl.ne", FT_UINT8, bitmask=HOMEPLUG_MCTRL_NE)
+
+ # MAC Entry Header
+ hf.add("MAC Management Entry Header", "homeplug.mehdr", FT_NONE, BASE_NONE)
+ hf.add("MAC Entry Version", "homeplug.mehdr.mev", FT_UINT8, bitmask=HOMEPLUG_MEHDR_MEV)
+ hf.add("MAC Entry Type", "homeplug.mehdr.metype", FT_UINT8, BASE_HEX, bitmask=HOMEPLUG_MEHDR_METYPE)
+
+ # MAC Entry Len
+ hf.add("MAC Management Entry Length", "homeplug.melen", FT_UINT8)
+
+ # MAC Management Entry
+ hf.add("MAC Management Entry Data", "homeplug.mmentry", FT_UINT8)
+
+ #
+ # Register Subtrees
+ #
+ subt = tp.subtrees()
+ #subt.add("homeplug") => we let Dissector output the main tree of this protocol
+ subt.add("mctrl")
+ subt.add("mehdr")
+ return tp
diff --git a/epan/wspython/wspy_libws.py b/epan/wspython/wspy_libws.py
new file mode 100644
index 0000000000..fb9bcf9916
--- /dev/null
+++ b/epan/wspython/wspy_libws.py
@@ -0,0 +1,48 @@
+# wspy_libws.py
+#
+# $Id: $
+#
+# Wireshark Protocol Python Binding
+#
+# Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+# Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+from ctypes import cdll
+import platform
+
+__libwireshark = None
+
+def get_libws_libname():
+ system = platform.system()
+ if system == "Darwin":
+ return 'libwireshark.dylib'
+ elif system == "Windows":
+ return 'libwireshark.dll'
+ else:
+ return 'libwireshark.so'
+
+def get_libws_handle():
+ global __libwireshark
+ try:
+ if not __libwireshark:
+ libname = get_libws_libname()
+ __libwireshark = cdll.LoadLibrary(libname)
+ return __libwireshark
+ except Exception, e:
+ print e
+ return None
diff --git a/epan/wspython/wspy_proto.c b/epan/wspython/wspy_proto.c
new file mode 100644
index 0000000000..5bf673e9ce
--- /dev/null
+++ b/epan/wspython/wspy_proto.c
@@ -0,0 +1,92 @@
+/* wspy_proto.c
+ *
+ * $Id: $
+ *
+ * Wireshark Protocol Python Binding
+ *
+ * Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+ * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+
+#include <glib.h>
+
+#include <stdio.h>
+
+#include "proto.h"
+
+
+hf_register_info *hf_register_info_create(const guint8 size)
+{
+ hf_register_info *hf = g_malloc0(sizeof(hf_register_info) * size);
+
+ /**STA TODO :
+ * if (!hf_register_info)
+ * raise exception
+ */
+
+ return hf;
+}
+
+void hf_register_info_destroy(hf_register_info *hf)
+{
+ if (hf) {
+ g_free(hf);
+ }
+}
+
+void hf_register_info_add(hf_register_info *hf, guint8 index,
+ int *p_id, const char *name, const char *abbrev,
+ enum ftenum type, int display, const void *strings,
+ guint32 bitmask, const char *blurb)
+{
+ hf[index].p_id = p_id;
+ hf[index].hfinfo.name = name;
+ hf[index].hfinfo.abbrev = abbrev;
+ hf[index].hfinfo.type = type;
+ hf[index].hfinfo.display = display;
+ hf[index].hfinfo.strings = strings;
+ hf[index].hfinfo.bitmask = bitmask;
+ hf[index].hfinfo.blurb = blurb;
+ hf[index].hfinfo.id = 0;
+ hf[index].hfinfo.parent = 0;
+ hf[index].hfinfo.ref_count = 0;
+ hf[index].hfinfo.bitshift = 0;
+ hf[index].hfinfo.same_name_next = NULL;
+ hf[index].hfinfo.same_name_prev = NULL;
+}
+
+void hf_register_info_print(hf_register_info *hf, guint8 size)
+{
+ guint8 c;
+ if (!hf)
+ return;
+
+ for (c = 0; c < size; c++) {
+ printf("%s : %s : %s\n", hf[c].hfinfo.name,
+ hf[c].hfinfo.abbrev,
+ hf[c].hfinfo.blurb);
+ }
+}
+
+#endif /* HAVE_PYTHON */
diff --git a/epan/wspython/wspy_proto.h b/epan/wspython/wspy_proto.h
new file mode 100644
index 0000000000..4fafdbca20
--- /dev/null
+++ b/epan/wspython/wspy_proto.h
@@ -0,0 +1,46 @@
+/* wspy_proto.h
+ *
+ * $Id: $
+ *
+ * Wireshark Protocol Python Binding
+ *
+ * Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+ * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __WS_PY_PROTO_H__
+#define __WS_PY_PROTO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "config.h"
+
+#ifdef HAVE_PYTHON
+hf_register_info *hf_register_info_create(const guint8 size);
+void hf_register_info_destroy(hf_register_info *hf);
+void hf_register_info_add(hf_register_info *hf, guint8 index,
+ int *p_id, const char *name, const char *abbrev,
+ enum ftenum type, int display, const void *strings,
+ guint32 bitmask, const char *blurb);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WS_PY_PROTO_H__ */
diff --git a/epan/wspython/wspy_register.c b/epan/wspython/wspy_register.c
new file mode 100644
index 0000000000..a6a9b0701b
--- /dev/null
+++ b/epan/wspython/wspy_register.c
@@ -0,0 +1,270 @@
+/* wspy_register.c
+ *
+ * $Id: $
+ *
+ * Wireshark Protocol Python Binding
+ *
+ * Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+ * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+
+#include <glib.h>
+
+#include <stdio.h>
+
+#include "epan.h"
+#include "proto.h"
+#include "packet.h"
+#include "tvbuff.h"
+#include "filesystem.h"
+
+/* hash table containing all the registered python dissectors */
+GHashTable * g_py_dissectors=NULL;
+
+/**
+ * Global objects that python method dissect() will get. Avoid to write a
+ * function for each proto_tree*.
+ * Is it the only way to do that? I can't believe it ... think about it
+ */
+tvbuff_t * g_tvb = NULL;
+packet_info * g_pinfo = NULL;
+proto_tree * g_tree = NULL;
+
+
+/* Initialization of the Python Interpreter */
+inline
+void wspy_init()
+{
+ Py_Initialize();
+}
+
+/* Finalization of the Python Interpreter */
+inline
+void wspy_finalize()
+{
+ Py_Finalize();
+}
+
+/*const char * py_dissector_short_desc(PyObject * py_dissector)
+{
+}*/
+
+/**
+ * Returns the __str__ of the python object
+ */
+char * py_dissector_name(PyObject * py_dissector)
+{
+ PyObject * py_object_name;
+
+ assert(py_dissector);
+ py_object_name = PyObject_Str(py_dissector);
+
+ return PyString_AS_STRING(py_object_name);
+}
+
+/**
+ * Register the dissector
+ */
+void py_dissector_register(PyObject * py_dissector, char * py_name, register_cb cb, gpointer client_data)
+{
+// const char * py_name;
+
+ /* Get the name of the dissector */
+// py_name = py_dissector_name(py_dissector);
+
+ /* Register dissector in register_cb */
+ if (cb)
+ (*cb)(RA_REGISTER, py_name, client_data);
+
+ /**
+ * Register protocol, fields, subtrees
+ *
+ * Done by calling register method of the object
+ */
+ PyObject_CallMethod(py_dissector, "register_protocol", NULL);
+
+}
+
+const char *get_py_register_file()
+{
+ static const char * wspython_register_file = NULL;
+
+ if (!wspython_register_file) {
+#ifdef _WIN32
+ wspython_register_file = g_strdup_printf("%s\\register-dissector.py", get_wspython_dir());
+#else
+ wspython_register_file = g_strdup_printf("%s/register-dissector.py", get_wspython_dir());
+#endif /* _WIN32 */
+ }
+ return wspython_register_file;
+}
+
+/**
+ * Finds out all the python dissectors and register them
+ */
+void register_all_py_protocols_func(register_cb cb, gpointer client_data)
+{
+ FILE * py_reg;
+ PyObject * global_dict, * main_module, * register_fn;
+ PyObject * py_dissectors, * py_dissector;
+ PyObject * py_args;
+ Py_ssize_t index;
+ void * nothing;
+ char * name;
+ nothing = cb;
+ nothing = client_data;
+
+ /* STA TODO : init only if prefs is enabled */
+ wspy_init();
+
+ /* load the python register module */
+ py_reg = fopen(get_py_register_file(), "r");
+ PyRun_SimpleFile(py_reg, get_py_register_file());
+
+ /* Getting the global symbols from the python register module */
+ main_module = PyImport_AddModule("__main__");
+ global_dict = PyModule_GetDict(main_module);
+
+ /* Get the python register function */
+ register_fn = PyDict_GetItemString(global_dict, "register_dissectors");
+
+ /* Execute the python register function */
+ /* This function returns a sequence of python dissectors objects */
+ py_args = Py_BuildValue("(s)", get_wspython_dir());
+ py_dissectors = PyObject_CallObject(register_fn, py_args);
+ //py_dissectors = PyObject_CallObject(register_fn, NULL);
+
+ /* Check that the py_dissectors is really a sequence */
+ if (!PySequence_Check(py_dissectors)) {
+ printf("not registered ...\n");
+ return;
+ }
+
+ /* intialize the hash table where all the python dissectors are kept */
+ g_py_dissectors = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /**
+ * For each dissector, register it in cb and registers all fields, subtrees,
+ * protocol name, etc ...
+ */
+ for (index = 0; ; index++) {
+ py_dissector = PySequence_GetItem(py_dissectors, index);
+ if (!py_dissector)
+ break;
+ assert(py_dissector);
+
+ name = py_dissector_name(py_dissector);
+ py_dissector_register(py_dissector, name, cb, client_data);
+ g_hash_table_insert(g_py_dissectors, (gpointer*)name, py_dissector);
+ }
+}
+
+tvbuff_t *py_tvbuff()
+{
+ return g_tvb;
+}
+
+packet_info * py_pinfo()
+{
+ return g_pinfo;
+}
+
+proto_tree * py_tree()
+{
+ return g_tree;
+}
+
+/*
+ * Generic Python Dissector
+ *
+ * Search the correct PyObject dissector based on
+ * pinfo->current_proto in the hash table py_dissectors.
+ *
+ * We then call the method "dissect" of this PyObject.
+ */
+void py_dissect(tvbuff_t * tvb, packet_info * pinfo,
+ proto_tree * tree)
+{
+ PyObject * py_dissector;
+
+ //printf("pinfo->current_proto : %s\n", pinfo->current_proto);
+ //NOTE => pinfo->current_proto == "HomePlug"
+
+ g_tree = tree;
+ g_pinfo = pinfo;
+ g_tvb = tvb;
+
+ py_dissector = g_hash_table_lookup(g_py_dissectors, pinfo->current_proto);
+ assert(py_dissector);
+
+ PyObject_CallMethod(py_dissector, "pre_dissect", NULL);
+}
+
+/*
+ * Return the pointer to the generic python dissector
+ *
+ * One could think that it could be a PyCObject but it is a
+ * workaround because ctypes is used and it complains later -not
+ * knowing how to conver the parameter - in the Python code when
+ * calling back a C function with a PyCObject as parameter
+ */
+dissector_t py_generic_dissector()
+{
+ return py_dissect;
+}
+
+struct SRegisterHandoffsForeach {
+ register_cb cb;
+ gpointer client_data;
+};
+
+void register_all_py_handoffs_foreach(gpointer key _U_, gpointer value, gpointer user_data)
+{
+ PyObject * py_dissector = (PyObject *)value;
+ struct SRegisterHandoffsForeach *rhf = (struct SRegisterHandoffsForeach*)user_data;
+
+ /* STA TODO : it's the short_desc field ... not really the filter field! */
+ char * handoff_name = g_strdup_printf("handoff_%s", py_dissector_name(py_dissector));
+
+ if (rhf->cb)
+ (*(rhf->cb))(RA_HANDOFF, handoff_name, rhf->client_data);
+
+ PyObject_CallMethod(py_dissector, "register_handoff", NULL);
+}
+
+/**
+ * Finalize the registration of the python protocol dissectors
+ */
+void
+register_all_py_handoffs_func(register_cb cb, gpointer client_data)
+{
+ struct SRegisterHandoffsForeach rhf;
+
+ rhf.cb = cb;
+ rhf.client_data = client_data;
+
+ g_hash_table_foreach(g_py_dissectors, register_all_py_handoffs_foreach, &rhf);
+}
+
+#endif /* HAVE_PYTHON */
diff --git a/epan/wspython/wspy_register.h b/epan/wspython/wspy_register.h
new file mode 100644
index 0000000000..c52d59ac67
--- /dev/null
+++ b/epan/wspython/wspy_register.h
@@ -0,0 +1,42 @@
+/* wspy_register.h
+ *
+ * $Id: $
+ *
+ * Wireshark Protocol Python Binding
+ *
+ * Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+ * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __WS_PY_REGISTER_H__
+#define __WS_PY_REGISTER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "config.h"
+
+#ifdef HAVE_PYTHON
+void register_all_py_protocols_func(register_cb cb, gpointer client_data);
+void register_all_py_handoffs_func(register_cb cb, gpointer client_data);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WS_PY_REGISTER_H__ */