PageRenderTime 72ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/cmpt471/a2/wireshark/epan/wspython/wspy_dissector.py

http://cwoodruf-sfu-cmpt.googlecode.com/
Python | 443 lines | 310 code | 62 blank | 71 comment | 48 complexity | 090a373403377521b10cb9e84c976e39 MD5 | raw file
  1. # wspy_dissector.py
  2. #
  3. # $Id: wspy_dissector.py 32287 2010-03-25 22:22:45Z wmeier $
  4. #
  5. # Wireshark Protocol Python Binding
  6. #
  7. # Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
  8. # Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
  9. #
  10. # This program is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU General Public License
  12. # as published by the Free Software Foundation; either version 2
  13. # of the License, or (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program; if not, write to the Free Software
  22. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. from ctypes import c_int, pointer, POINTER, py_object
  24. from wspy_libws import get_libws_handle
  25. # From epan/proto.h
  26. # ? STA ? : is there a better way to include/define these constants?
  27. # (duplicating definition is not a good thing)
  28. (BASE_NONE,
  29. BASE_DEC,
  30. BASE_HEX,
  31. BASE_OCT,
  32. BASE_DEC_HEX,
  33. BASE_HEX_DEC,
  34. BASE_CUSTOM) = map(int, xrange(7))
  35. # field types, see epan/ftypes/ftypes.h
  36. (FT_NONE,
  37. FT_PROTOCOL,
  38. FT_BOOLEAN,
  39. FT_UINT8,
  40. FT_UINT16,
  41. FT_UINT24,
  42. FT_UINT32,
  43. FT_UINT64,
  44. FT_INT8,
  45. FT_INT16,
  46. FT_INT24,
  47. FT_INT32,
  48. FT_INT64,
  49. FT_FLOAT,
  50. FT_DOUBLE,
  51. FT_ABSOLUTE_TIME,
  52. FT_RELATIVE_TIME,
  53. FT_STRING,
  54. FT_STRINGZ,
  55. FT_EBCDIC,
  56. FT_UINT_STRING,
  57. FT_ETHER,
  58. FT_BYTES,
  59. FT_UINT_BYTES,
  60. FT_IPv4,
  61. FT_IPv6,
  62. FT_IPXNET,
  63. FT_FRAMENUM,
  64. FT_PCRE,
  65. FT_GUID,
  66. FT_OID) = map(int, xrange(31))
  67. # hf_register_info from usual dissectors
  68. class register_info(object):
  69. def __init__(self, wsl):
  70. self.__protocol = None
  71. self.__wsl = wsl
  72. self.__hf_register = None
  73. self.__registers = []
  74. def add(self, name, short_desc, \
  75. type=FT_UINT32, display=BASE_DEC, \
  76. strings=None, bitmask=0x0, desc=None):
  77. if not desc:
  78. desc = name
  79. self.__registers.append( (name, short_desc, \
  80. type, display, strings, bitmask, desc) )
  81. def register(self, protocol):
  82. self.__protocol = protocol
  83. hf = self.__registers
  84. lr = len(hf)
  85. if not lr:
  86. return None
  87. self.__hf_register = self.__wsl.hf_register_info_create(lr)
  88. chf = self.__hf_register
  89. if not self.__hf_register:
  90. return None
  91. for i in xrange(lr):
  92. n, sd, t, d, st, bm, ld = hf[i]
  93. sdn = sd.replace('.', '_')
  94. self.__dict__[sdn] = c_int(-1)
  95. p_id = pointer(self.__dict__[sdn])
  96. self.__wsl.hf_register_info_add(chf, i, p_id, n , sd, t, d, st, bm, ld)
  97. self.__wsl.proto_register_field_array(self.__protocol, chf, lr)
  98. def display(self):
  99. self.__wsl.hf_register_info_print(self.__hf_register, \
  100. len(self.__registers))
  101. def get(self):
  102. return self.__hf_register, len(self.__registers)
  103. def __del__(self):
  104. self.__wsl.hf_register_info_destroy(self.__hf_register)
  105. #Subtrees definition
  106. #Every subtree added can be accesses as an attribute after having been
  107. #registered
  108. class Subtree(object):
  109. def __init__(self, wsl, protocol):
  110. self.__wsl = wsl
  111. self.__protocol = protocol
  112. self.__st = {}
  113. self.__user_defined_protocol_tree = False
  114. def add(self, name):
  115. if name == self.__protocol:
  116. self.__user_defined_protocol_tree = True
  117. self.__st[name] = c_int(-1)
  118. def has_user_defined_protocol_tree(self):
  119. return self.__user_defined_protocol_tree
  120. def register(self):
  121. if not self.__user_defined_protocol_tree:
  122. self.__st[self.__protocol] = c_int(-1)
  123. ls = len(self.__st)
  124. if not ls:
  125. return
  126. CSubtrees = POINTER(c_int) * ls
  127. p_sts = CSubtrees()
  128. k = self.__st.keys()
  129. for i in xrange(ls):
  130. p_sts[i] = pointer(self.__st[k[i]])
  131. self.__wsl.proto_register_subtree_array(p_sts, ls)
  132. def __getattr__(self, name):
  133. if self.__st.has_key(name):
  134. return self.__st[name]
  135. #raise KeyError
  136. #Dissector class : base class to write a dissector in python
  137. class Dissector(object):
  138. def __init__(self, protocol_name, short_desc, short):
  139. self.__protocol_name = protocol_name
  140. self.__short_desc = short_desc
  141. self.__short = short
  142. self.__tvb = None
  143. self.__pinfo = None
  144. self.__tree = None
  145. self.__Tree = None
  146. self.__offset = 0
  147. self.__wsl = get_libws_handle()
  148. self.__hf = None
  149. self.__subtree = None
  150. def _fields(self):
  151. '''hf property : hf_register_info fields. every defined field is available
  152. as an attribute of this object'''
  153. if not self.__hf:
  154. self.__hf = register_info(self.__wsl)
  155. return self.__hf
  156. hf = property(_fields)
  157. def _subtrees(self):
  158. '''subtrees property : subtress definition. every subtree added is
  159. accessible as an attribute of this object'''
  160. if not self.__subtree:
  161. self.__subtree = Subtree(self.__wsl, self.__short)
  162. return self.__subtree
  163. subtrees = property(_subtrees)
  164. def _tree(self):
  165. '''tree property : initial tree at the start of the dissection'''
  166. if not self.__Tree:
  167. self.__Tree = Tree(self.__tree, self)
  168. return self.__Tree
  169. tree = property(_tree)
  170. def display(self):
  171. print self.__short
  172. def _libhandle(self):
  173. '''libhandle property : return a handle to the libwireshark lib. You don't
  174. want to use this in normal situation. Use it only if you know what you're
  175. doing.'''
  176. return self.__wsl
  177. libhandle = property(_libhandle)
  178. def _raw_tree(self):
  179. '''raw_tree property : returns the raw tree pointer. You can use this with
  180. libhandle. You don't want to use this in normal situation. Use it only if
  181. you know what you're doing.'''
  182. return self.__tree
  183. raw_tree = property(_raw_tree)
  184. def _raw_pinfo(self):
  185. '''raw_pinfo property : return the raw pinfo pointer. You can use this with
  186. libhandle. You don't want to use this in normal situation. Use it only if
  187. you know what you're doing.'''
  188. return self.__pinfo
  189. raw_pinfo = property(_raw_pinfo)
  190. def _raw_tvb(self):
  191. '''raw_tvb property : returns the raw tvb pointer. You can use this with
  192. libhandle. You don't want to use this in normal situation. Use it only if
  193. you know what you're doing.'''
  194. return self.__tvb
  195. raw_tvb = property(_raw_tvb)
  196. def __str__(self):
  197. # STA TODO : keep with short_desc because used in the hash table of
  198. # dissectors in C code. If it is modified, it won't work anymore
  199. return self.__short_desc
  200. def __unicode__(self):
  201. return self.__short
  202. def __hash__(self):
  203. return hash(self.__short)
  204. def protocol(self):
  205. return self.__protocol
  206. def register_protocol(self):
  207. '''private function called by libwireshark when registering all
  208. protocols'''
  209. self.__protocol = \
  210. self.__wsl.proto_register_protocol( \
  211. self.__protocol_name, self.__short_desc, \
  212. self.__short)
  213. self.__hf.register(self.__protocol)
  214. #self.__hf.display()
  215. self.__subtree.register()
  216. def dissect(self):
  217. '''point of entry when starting dissecting a packet. This method must be
  218. therefore overloaded by the object implementing the dissector of a specific
  219. protocol.'''
  220. pass
  221. def pre_dissect(self):
  222. '''private method executed right before dissect in order to retrieve some
  223. internal information and enabling the possibility to add the base tree of
  224. this protocol dissection to the tree without any user intervention'''
  225. self.__tvb = self.__wsl.py_tvbuff()
  226. self.__pinfo = self.__wsl.py_pinfo()
  227. self.__tree = self.__wsl.py_tree()
  228. #self.__wsl.print_current_proto(py_object(pinfo))
  229. subt = self.subtrees
  230. try:
  231. if not subt.has_user_defined_protocol_tree():
  232. p_tree = self.tree.add_item(self.protocol())
  233. self.__Tree = p_tree.add_subtree(subt.homeplug)
  234. except:
  235. print e
  236. self.dissect()
  237. def protocol_ids(self):
  238. '''defined a list of tuples containing three values. Each tuple is defining
  239. the parameters of dissector_add(). This function MUST be defined when
  240. implementing the dissector of a specific protocol.'''
  241. return [ (None, 0, None) ]
  242. def create_dissector_handle(self, protocol=None):
  243. '''create_dissector_handle : see proto.h'''
  244. gdissector = self.__wsl.py_generic_dissector()
  245. if not protocol:
  246. protocol = self.__protocol
  247. return self.__wsl.create_dissector_handle(gdissector, protocol)
  248. def find_dissector(self, protocol):
  249. '''find_dissector : see proto.h'''
  250. return self.__wsl.find_dissector(protocol)
  251. def register_handoff(self):
  252. '''private method used during the registration of protocol dissectors'''
  253. #TODO STA : think how we would use dissector_add in an easy way *and* with
  254. #the possibility to add the same dissector for TCP and UDP (extend
  255. #py_generic_dissector)
  256. private_handle = None
  257. try:
  258. ids = self.protocol_ids()
  259. for type, protocol_id, handle in self.protocol_ids():
  260. if not type:
  261. continue
  262. if not handle:
  263. if not private_handle:
  264. handle = \
  265. self.create_dissector_handle(self.__protocol)
  266. else:
  267. handle = private_handle
  268. self.__wsl.dissector_add(type, protocol_id, handle)
  269. except Exception, e:
  270. print "creating dissector failed", e
  271. raise
  272. def advance(self, step):
  273. '''method used to change the value of the offset'''
  274. self.__offset += step
  275. def _offset(self):
  276. '''offset property : if is the current offset computed from the
  277. dissection.'''
  278. return self.__offset
  279. offset = property(_offset)
  280. #Tree class implementation
  281. #see proto.h
  282. class Tree(object):
  283. def __init__(self, tree, dissector):
  284. self.__dissector = dissector
  285. self.__tree = tree
  286. self.__wsl = dissector.libhandle
  287. self.__tvb = dissector.raw_tvb
  288. def _raw_tree(self):
  289. return self.__tree
  290. raw_tree = property(_raw_tree)
  291. def add_item(self, field, offset=0, length=-1, little_endian=False, adv=True):
  292. '''add an item to the tree'''
  293. try:
  294. tree = self.__wsl.proto_tree_add_item(self.__tree, \
  295. field, self.__tvb, self.__dissector.offset, length, \
  296. little_endian)
  297. except Exception, e:
  298. print e
  299. else:
  300. if length > 0 and adv:
  301. self.__dissector.advance(length)
  302. return Tree(tree, self.__dissector)
  303. def add_uint(self, field, value, offset=0, length=4, adv=True):
  304. '''add unsigned integer to the tree'''
  305. try:
  306. tree = self.__wsl.proto_tree_add_uint(self.__tree, field, self.__tvb, self.__dissector.offset, length, value)
  307. except Exception, e:
  308. print e
  309. else:
  310. if adv:
  311. self.__dissector.advance(length)
  312. return Tree(tree, self.__dissector)
  313. def add_text(self, string, offset=0, length=-1, adv=True):
  314. '''add text to the tree'''
  315. try:
  316. tree = self.__wsl.proto_tree_add_text(self.__tree, self.__tvb, self.__dissector.offset, length, string)
  317. except Exception, e:
  318. print e
  319. else:
  320. if length > 0 and adv:
  321. self.__dissector.advance(length)
  322. return Tree(tree, self.__dissector)
  323. def add_subtree(self, subtree):
  324. '''add a subtree to the tree'''
  325. try:
  326. tree = self.__wsl.proto_item_add_subtree(self.__tree, subtree)
  327. except Exception, e:
  328. print e
  329. else:
  330. return Tree(tree, self.__dissector)
  331. #tvb class implementation
  332. #see proto.h
  333. class TVB(object):
  334. def __init__(self, wsl, tvb, dissector):
  335. self.__tvb = tvb
  336. self.__wsl = wsl
  337. self.__dissector = dissector
  338. def length(self):
  339. return self.__wsl.length(self.__wsl)
  340. def length_remaining(self, offset=-1):
  341. if offset < 0:
  342. offset = self.__dissector.offset
  343. return self.__wsl.tvb_length_remaining(self.__tvb, offset)
  344. def reported_length(self):
  345. return self.__wsl.tvb_reported_length(self.__tvb)
  346. def reported_length_remaining(self, offset=-1):
  347. if offset < 0:
  348. offset = self.__dissector.offset
  349. return self.__wsl.tvb_length_remaining(self.__tvb, offset)
  350. def get_guint8(self, offset=-1):
  351. if offset < 0:
  352. offset = self.__dissector.offset
  353. return self.__wsl.tvb_get_guint8(self.__tvb)
  354. def get_ntohs(self, offset=-1):
  355. if offset < 0:
  356. offset = self.__dissector.offset
  357. return self.__wsl.tvb_get_ntohs(self.__tvb, offset)
  358. def get_ntohl(self, offset=-1):
  359. if offset < 0:
  360. offset = self.__dissector.offset
  361. return self.__wsl.tvb_get_ntohl(self.__tvb, offset)
  362. def get_letohl(self, offset=-1):
  363. if offset < 0:
  364. offset = self.__dissector.offset
  365. return self.__wsl.tvb_get_letohl(self.__tvb, offset)
  366. def get_letohs(self, offset=-1):
  367. if offset < 0:
  368. offset = self.__dissector.offset
  369. return self.__wsl.tvb_get_letohs(self.__tvb, offset)
  370. #STA TODO : check that we can do that
  371. def get_ptr(self, offset=-1):
  372. if offset < 0:
  373. offset = self.__dissector.offset
  374. return self.__wsl.tvb_get_ptr(self.__tvb, offset)
  375. #how to get this working ??? check how application uses this!
  376. #def new_subset(self, offset=0):
  377. # return self.__wsl.tvb_get_new_subset(self.tvb, offset)