1# 2# Wireshark Dissector Generator for SkinnyProtocolOptimized.xml 3# 4# Author: Diederik de Groot <ddegroot@user.sf.net> 5# Date: 2014-7-22 6# Skinny Protocol Versions: 0 through 22 7# 8# Heritage: 9# xml2obj based on https://code.activestate.com/recipes/149368-xml2obj/ 10# 11# Dependencies: 12# python / xml / sax 13# 14# Called By: 15# cog.py + packet-skinny.c.in for inplace code generation 16# See: https://nedbatchelder.com/code/cog/ 17# 18# 19# SPDX-License-Identifier: GPL-2.0-or-later 20# 21 22import re 23import xml.sax.handler 24 25indentation = 0 26indent_str = '' 27fieldsArray = {} 28si_fields = { 29 "callReference" : "si->callId", 30 "lineInstance": "si->lineId", 31 "passThroughPartyId" : "si->passThroughPartyId", 32 "callState" : "si->callState", 33 "callingParty" : "si->callingParty", 34 "calledParty" : "si->calledParty", 35 "mediaReceptionStatus" : "si->mediaReceptionStatus", 36 "mediaTransmissionStatus" : "si->mediaTransmissionStatus", 37 "multimediaReceptionStatus" : "si->multimediaReceptionStatus", 38 "multimediaTransmissionStatus" : "si->multimediaTransmissionStatus", 39 "multicastReceptionStatus" : "si->multicastReceptionStatus", 40} 41 42debug = 0 43 44def xml2obj(src): 45 """ 46 A function to converts XML data into native Python objects. 47 48 """ 49 non_id_char = re.compile('[^_0-9a-zA-Z]') 50 51 def _name_mangle(name): 52 return non_id_char.sub('_', 53 name) 54 55 class DataNode(object): 56 def __init__(self): 57 self._attrs = {} # XML attributes and child elements 58 self.data = None # child text data 59 self.parent = None 60 self.basemessage = None 61 self.intsize = 0 62 self._children = [] 63 self.declared = [] 64 65 def __len__(self): 66 # treat single element as a list of 1 67 return 1 68 def __getitem__(self, key): 69 if isinstance(key, basestring): 70 return self._attrs.get(key,None) 71 else: 72 return [self][key] 73 74 def __contains__(self, name): 75 return self._attrs.has_key(name) 76 77 def __nonzero__(self): 78 return bool(self._attrs or self.data) 79 80 def __getattr__(self, name): 81 if name.startswith('__'): 82 # need to do this for Python special methods??? 83 raise AttributeError(name) 84 return self._attrs.get(name,None) 85 86 def _add_xml_attr(self, name, value): 87 if name in self._attrs: 88 # multiple attribute of the same name are represented by a list 89 children = self._attrs[name] 90 if not isinstance(children, list): 91 children = [children] 92 self._attrs[name] = children 93 children.append(value) 94 else: 95 self._attrs[name] = value 96 97 def _add_child(self, name, value): 98 #print "adding : %s / %s to %s" %(name,value, self.__class__) 99 self._children.append(value) 100 101 def __str__(self): 102 return '%s:%s' %(self.__class__,self.name) 103 104 def keys(self): 105 return self._attrs.keys() 106 107 def __repr__(self): 108 items = {} 109 if self.data: 110 items.append(('data', self.data)) 111 return u'{%s}' % ', '.join([u'%s:%s' % (k,repr(v)) for k,v in items]) 112 113 def __setitem__(self, key, value): 114 self._attrs[key] = value 115 116 def getfieldnames(self): 117 return '' 118 119 def get_req_resp_keys(self, req_resp_keys): 120 return [] 121 122 def get_req_resp_key(self): 123 if self.req_resp_key == "1": 124 return self.name 125 return None 126 127 def declaration(self): 128 global fieldsArray 129 if self.name not in fieldsArray: 130 fieldsArray[self.name] = '/* UNKNOWN { &hf_skinny_%s,\n {\n"%s", "skinny.%s", FT_UINT32, BASE_DEC, NULL, 0x0,\n "%s", HFILL }}, */\n' %(self.name, self.name, self.name, self.comment) 131 return '' 132 133 def dissect(self): 134 return self.name or '' 135 136 def incr_indent(self): 137 global indentation 138 global indent_str 139 indentation += 1 140 indent_str = '' 141 for x in range(0, indentation): 142 indent_str += ' ' 143 144 def decr_indent(self): 145 global indentation 146 global indent_str 147 indentation -= 1 148 indent_str = '' 149 for x in range(0, indentation): 150 indent_str += ' ' 151 152 def indent_out(self, string): 153 return indent_str + string 154 155 156 class Message(DataNode): 157 ''' Message ''' 158 def __str__(self): 159 return self.name 160 161 def gen_handler(self): 162 if self.fields is None: 163 # skip whole message and return NULL as handler 164 return 'NULL' 165 return 'handle_%s' %self.name 166 167 def dissect(self): 168 ret = '' 169 declarations = 0 170 fixed = 0 171 172 if (self.fields is not None): 173 ret += self.indent_out("/*\n") 174 ret += self.indent_out(" * Message: %s\n" %self.name) 175 ret += self.indent_out(" * Opcode: %s\n" %self.opcode) 176 ret += self.indent_out(" * Type: %s\n" %self.type) 177 ret += self.indent_out(" * Direction: %s\n" %self.direction) 178 ret += self.indent_out(" * VarLength: %s\n" %self.dynamic) 179 ret += self.indent_out(" * MsgType: %s\n" %self.msgtype) 180 if self.comment: 181 ret += self.indent_out(" * Comment: %s\n" %self.comment) 182 ret += self.indent_out(" */\n") 183 ret += self.indent_out("static void\n") 184 ret += self.indent_out("handle_%s(ptvcursor_t *cursor, packet_info * pinfo _U_, skinny_conv_info_t * skinny_conv _U_)\n" %self.name) 185 ret += self.indent_out("{\n") 186 self.incr_indent() 187 188 for fields in self.fields: 189 if fields.size_lt or fields.size_gt: 190 if self.basemessage.declared is None or "hdr_data_length" not in self.basemessage.declared: 191 ret += self.indent_out("guint32 hdr_data_length = tvb_get_letohl(ptvcursor_tvbuff(cursor), 0);\n") 192 self.basemessage.declared.append("hdr_data_length") 193 declarations += 1 194 if fields.fixed == "yes": 195 fixed = 1 196 197 if not declarations or fixed == 1: 198 for fields in self.fields[1:]: 199 if self.basemessage.declared is None or "hdr_version" not in self.basemessage.declared: 200 ret += self.indent_out("guint32 hdr_version = tvb_get_letohl(ptvcursor_tvbuff(cursor), 4);\n") 201 self.basemessage.declared.append("hdr_version") 202 declarations += 1 203 204 req_resp_keys = [] 205 for fields in self.fields: 206 fields.get_req_resp_keys(req_resp_keys) 207 ret += '%s' %fields.declaration() 208 declarations += 1 209 210 if declarations > 1: 211 ret += "\n" 212 213 if self.fields is not None: 214 for fields in self.fields: 215 ret += '%s' %fields.dissect() 216 217 # setup request/response 218 if self.msgtype == "request": 219 if req_resp_keys and req_resp_keys[0] != '': 220 ret += self.indent_out('skinny_reqrep_add_request(cursor, pinfo, skinny_conv, %s ^ %s);\n' %(self.opcode, req_resp_keys[0])) 221 else: 222 ret += self.indent_out('skinny_reqrep_add_request(cursor, pinfo, skinny_conv, %s);\n' %(self.opcode)) 223 224 if self.msgtype == "response": 225 if req_resp_keys and req_resp_keys[0] != '': 226 ret += self.indent_out('skinny_reqrep_add_response(cursor, pinfo, skinny_conv, %s ^ %s);\n' %(self.request, req_resp_keys[0])) 227 else: 228 ret += self.indent_out('skinny_reqrep_add_response(cursor, pinfo, skinny_conv, %s);\n' %(self.request)) 229 230 self.decr_indent() 231 232 ret += "}\n\n" 233 return ret 234 235 class Fields(DataNode): 236 ''' Fields ''' 237 size_fieldnames= [] 238 239 def get_req_resp_keys(self, req_resp): 240 for field in self._children: 241 key = field.get_req_resp_key() 242 if not key is None and not key in req_resp: 243 req_resp.append(key) 244 245 def declaration(self): 246 ret = '' 247 248 for field in self._children: 249 ret += '%s' %(field.declaration()) 250 self.intsize += field.intsize 251 return ret 252 253 def dissect(self, lookupguide=""): 254 ret = '' 255 ifstarted = 0 256 #ret += "/* [PARENT: %s, BASEMESSAGE: %s] */\n" %(self.parent.name,self.basemessage.name) 257 258 if ((self.beginversion or self.endversion) and (self.beginversion != "0" or self.endversion != "22")): 259 260 ifstarted = 1 261 ret += self.indent_out('if (') 262 if (self.beginversion and self.beginversion != "0"): 263 if (not self.endversion or self.endversion == "22"): 264 ret += 'hdr_version >= V%s_MSG_TYPE) {\n' %self.beginversion 265 else: 266 ret += 'hdr_version >= V%s_MSG_TYPE && ' %self.beginversion 267 if (self.endversion and self.endversion != "22"): 268 ret += 'hdr_version <= V%s_MSG_TYPE) {\n' %self.endversion 269 self.incr_indent() 270 271 if self.size_lt: 272 ret += self.indent_out('if (hdr_data_length < %s) {\n' %self.size_lt) 273 self.incr_indent() 274 275 if self.size_gt: 276 ret += self.indent_out('if (hdr_data_length > %s) {\n' %self.size_gt) 277 self.incr_indent() 278 279 # generate dissection 280 for field in self._children: 281 ret += '%s' %(field.dissect()) 282 283 if self.size_lt: 284 self.decr_indent() 285 ret += self.indent_out('}\n') 286 287 if self.size_gt: 288 self.decr_indent() 289 ret += self.indent_out('}\n') 290 291 if ifstarted: 292 self.decr_indent() 293 ret += self.indent_out('}\n') 294 295 return ret; 296 297 class Integer(DataNode): 298 def __init__(self): 299 DataNode.__init__(self) 300 self.intsize = 0 301 self.endian = "ENC_LITTLE_ENDIAN" 302 303 def __str__(self): 304 return '%s:%s' %(self.__class__,self.name) 305 306 def declaration(self): 307 ret = '' 308 309 int_sizes = {'uint32':4,'uint16':2,'uint8':1,'int32':4,'int16':2,'int8':1,'ipport':4} 310 if self.endianness == "big": 311 self.endian = "ENC_BIG_ENDIAN" 312 if self.type in int_sizes: 313 self.intsize = int_sizes[self.type] 314 else: 315 print("ERROR integer %s with type: %s, could not be found" %(self.name, self.type)) 316 317 if self.declare == "yes" or self.make_additional_info == "yes": 318 if self.basemessage.declared is None or self.name not in self.basemessage.declared: 319 ret += self.indent_out('guint%s %s = 0;\n' %(self.intsize * 8, self.name)) 320 self.basemessage.declared.append(self.name) 321 322 global fieldsArray 323 if self.name not in fieldsArray: 324 fieldsArray[self.name] ='{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_UINT%d, BASE_DEC, NULL, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), self.intsize * 8, '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 325 return ret 326 327 def dissect(self): 328 ret = '' 329 330 size = 0 331 if self.size_fieldname: 332 if self.basemessage.dynamic == "yes": 333 size = self.size_fieldname 334 else: 335 size = self.maxsize 336 elif self.size: 337 size = self.size 338 339 if size: 340 if self.size_fieldname: 341 ret += self.indent_out('if (%s <= %s) {%s\n' %(self.size_fieldname, size, ' /* tvb integer size guard */' if debug else '')) 342 else: 343 ret += self.indent_out('{\n') 344 self.incr_indent() 345 variable = 'counter_%d' %indentation 346 ret += self.indent_out('guint32 %s = 0;\n' %(variable)); 347 if self.size_fieldname: 348 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [ref:%s = %%d, max:%s]", %s);\n' %(self.name, self.size_fieldname, size, self.size_fieldname)) 349 else: 350 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [max:%s]");\n' %(self.name, size)) 351 ret += self.indent_out('for (%s = 0; %s < %s; %s++) {\n' %(variable, variable, size, variable)); 352 if self.basemessage.dynamic == "no" and self.size_fieldname: 353 self.incr_indent() 354 ret += self.indent_out('if (%s < %s) {\n' %(variable,self.size_fieldname)) 355 self.incr_indent() 356 357 if self.declare == "yes" or self.make_additional_info == "yes": 358 if self.endianness == "big": 359 if (self.intsize == 4): 360 ret += self.indent_out('%s = tvb_get_ntohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 361 elif (self.intsize == 2): 362 ret += self.indent_out('%s = tvb_get_ntohs(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 363 else: 364 ret += self.indent_out('%s = tvb_get_guint8(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 365 else: 366 if (self.intsize == 4): 367 ret += self.indent_out('%s = tvb_get_letohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 368 elif (self.intsize == 2): 369 ret += self.indent_out('%s = tvb_get_letohs(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 370 else: 371 ret += self.indent_out('%s = tvb_get_guint8(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 372 373 if self.name in si_fields.keys(): 374 if self.endianness == "big": 375 ret += self.indent_out('%s = tvb_get_ntohs(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(si_fields[self.name])) 376 else: 377 ret += self.indent_out('%s = tvb_get_letohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(si_fields[self.name])) 378 379 ret += self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, %d, %s);\n' %(self.name, self.intsize, self.endian)) 380 381 if size: 382 if self.basemessage.dynamic == "no" and self.size_fieldname: 383 self.decr_indent() 384 ret += self.indent_out('} else {\n') 385 ret += self.indent_out(' ptvcursor_advance(cursor, %d);\n' %self.intsize) 386 ret += self.indent_out('}\n') 387 self.decr_indent() 388 ret += self.indent_out('}\n') 389 if debug: 390 ret += self.indent_out('ptvcursor_pop_subtree(cursor); /* end for loop tree: %s */\n' %(self.name)) 391 else: 392 ret += self.indent_out('ptvcursor_pop_subtree(cursor);\n') 393 self.decr_indent() 394 if self.size_fieldname: 395 ret += self.indent_out('} else {\n') 396 self.incr_indent() 397 ret += self.indent_out('ptvcursor_advance(cursor, (%s * %s));%s\n' %(size, self.intsize, ' /* guard kicked in -> skip the rest */;' if debug else '')) 398 self.decr_indent() 399 ret += self.indent_out('}\n') 400 401 if self.make_additional_info == "yes": 402 ret += self.indent_out('srtp_add_address(pinfo, PT_UDP, &%s, %s, 0, "SKINNY", pinfo->num, false, NULL, NULL, NULL);\n' %(self.use_param, self.name)) 403 ret += self.indent_out('%s_str = address_to_display(NULL, &%s);\n' % (self.use_param, self.use_param)) 404 ret += self.indent_out('si->additionalInfo = g_strdup_printf("%%s:%%d", %s_str, %s);\n' % (self.use_param, self.name)) 405 ret += self.indent_out('wmem_free(NULL, %s_str);\n' % (self.use_param)) 406 407 return ret 408 409 class Enum(DataNode): 410 def __init__(self): 411 DataNode.__init__(self) 412 self.intsize = 0 413 self.sparse = 0 414 415 def __str__(self): 416 return '%s:%s' %(self.__class__,self.name) 417 418 def declaration(self): 419 ret = '' 420 prevvalue = 0 421 enum_sizes = {'uint32':4,'uint16':2,'uint8':1} 422 if self.type in enum_sizes: 423 self.intsize = enum_sizes[self.type] 424 else: 425 print("ERROR enum %s with type: %s, could not be found" %(self.name, self.type)) 426 427 if self.declare == "yes": 428 if self.basemessage.declared is None or self.name not in self.basemessage.declared: 429 ret += self.indent_out('g%s %s = 0;\n' %(self.type, self.name)) 430 self.basemessage.declared.append(self.name) 431 432 global fieldsArray 433 if self.name not in fieldsArray: 434 fieldsArray[self.name] ='{&hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_UINT%d, BASE_HEX | BASE_EXT_STRING, &%s_ext, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), self.intsize * 8, self.subtype[0].upper() + self.subtype[1:], '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 435 return ret 436 437 def dissect(self): 438 ret = '' 439 endian = "ENC_LITTLE_ENDIAN" 440 size = 0 441 if self.size_fieldname: 442 if self.basemessage.dynamic == "yes": 443 size = self.size_fieldname 444 else: 445 size = self.maxsize 446 elif self.size: 447 size = self.size 448 449 if self.make_additional_info == "yes": 450 ret += self.indent_out('si->additionalInfo = g_strdup_printf("\\"%s\\"",\n') 451 self.incr_indent() 452 ret += self.indent_out('try_val_to_str_ext(\n') 453 self.incr_indent() 454 ret += self.indent_out('tvb_get_letohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor)),\n') 455 ret += self.indent_out('&%s_ext\n' %(self.subtype[0].upper() + self.subtype[1:])) 456 self.decr_indent() 457 ret += self.indent_out(')\n') 458 self.decr_indent() 459 ret += self.indent_out(');\n') 460 461 if self.make_additional_info_short == "yes": 462 ret += self.indent_out('si->additionalInfo = g_strdup_printf("\\"%s\\"",\n') 463 self.incr_indent() 464 ret += self.indent_out('try_val_to_str_ext(\n') 465 self.incr_indent() 466 ret += self.indent_out('tvb_get_letohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor)),\n') 467 ret += self.indent_out('&%s_short_ext\n' %(self.subtype[0].upper() + self.subtype[1:])) 468 self.decr_indent() 469 ret += self.indent_out(')\n') 470 self.decr_indent() 471 ret += self.indent_out(');\n') 472 473 if size: 474 if self.size_fieldname: 475 ret += self.indent_out('if (%s <= %s) { /* tvb enum size guard */\n' %(self.size_fieldname, self.maxsize)) 476 else: 477 ret += self.indent_out('{\n') 478 self.incr_indent() 479 variable = 'counter_%d' %indentation 480 ret += self.indent_out('guint32 %s = 0;\n' %(variable)); 481 if self.size_fieldname: 482 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [ref: %s = %%d, max:%s]", %s);\n' %(self.name, self.size_fieldname, size, self.size_fieldname)) 483 else: 484 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [max:%s]");\n' %(self.name, size)) 485 ret += self.indent_out('for (%s = 0; %s < %s; %s++) {\n' %(variable, variable, size, variable)); 486 if self.basemessage.dynamic == "no" and self.size_fieldname: 487 self.incr_indent() 488 ret += self.indent_out('if (%s < %s) {\n' %(variable,self.size_fieldname)) 489 self.incr_indent() 490 491 if self.name in si_fields.keys(): 492 ret += self.indent_out('%s = tvb_get_letohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(si_fields[self.name])) 493 494 if self.declare == "yes": 495 if (self.intsize == 4): 496 ret += self.indent_out('%s = tvb_get_letohl(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 497 elif (self.intsize == 2): 498 ret += self.indent_out('%s = tvb_get_letohs(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 499 else: 500 ret += self.indent_out('%s = tvb_get_guint8(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));\n' %(self.name)) 501 502 ret += self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, %d, %s);\n' %(self.name, self.intsize, endian)) 503 504 if size: 505 if self.basemessage.dynamic == "no" and self.size_fieldname: 506 self.decr_indent() 507 ret += self.indent_out('} else {\n') 508 ret += self.indent_out(' ptvcursor_advance(cursor, 4);\n') 509 ret += self.indent_out('}\n') 510 self.decr_indent() 511 ret += self.indent_out('}\n') 512 if debug: 513 ret += self.indent_out('ptvcursor_pop_subtree(cursor); /* end for loop tree: %s */\n' %(self.name)) 514 else: 515 ret += self.indent_out('ptvcursor_pop_subtree(cursor);\n') 516 self.decr_indent() 517 if self.size_fieldname: 518 ret += self.indent_out('} else {\n') 519 self.incr_indent() 520 ret += self.indent_out('ptvcursor_advance(cursor, (%s * %s)); /* guard kicked in -> skip the rest */;\n' %(size, self.intsize)) 521 self.decr_indent() 522 ret += self.indent_out('}\n') 523 524 return ret 525 526 class String(DataNode): 527 def __init__(self): 528 DataNode.__init__(self) 529 530 def __str__(self): 531 return '%s:%s' %(self.__class__,self.name) 532 533 def get_req_resp_key(self): 534 if self.req_resp_key == "1": 535 return 'wmem_str_hash(%s)' %self.name 536 return None 537 538 def declaration(self): 539 ret = '' 540 self.intsize = 0 541 if self.size: 542 if self.size=="VariableDirnumSize": 543 self.intsize = 24 544 else: 545 self.intsize = int(self.size) 546 elif self.maxsize and self.basemessage.dynamic == "no": 547 self.intsize = int(self.maxsize) 548 549 if self.declare == "yes": 550 if self.size=="VariableDirnumSize": 551 if self.basemessage.declared is None or "VariableDirnumSize" not in self.basemessage.declared: 552 if self.basemessage.declared is None or "hdr_version" not in self.basemessage.declared: 553 #if (self.basemessage.fields is not None and len(self.basemessage.fields) == 1): 554 ret += self.indent_out('guint32 hdr_version = tvb_get_letohl(ptvcursor_tvbuff(cursor), 4);\n') 555 self.basemessage.declared.append("hdr_version") 556 ret += self.indent_out('guint32 VariableDirnumSize = (hdr_version >= V18_MSG_TYPE) ? 25 : 24;\n') 557 self.basemessage.declared.append("VariableDirnumSize") 558 #else: 559 # if self.basemessage.declared is None or self.name not in self.basemessage.declared: 560 # ret += self.indent_out('gchar *%s = NULL;\n' %self.name) 561 # self.basemessage.declared.append(self.name) 562 563 if self.basemessage.dynamic == "yes" and not self.subtype == "DisplayLabel": 564 if self.basemessage.declared is None or self.name + '_len' not in self.basemessage.declared: 565 ret += self.indent_out('guint32 %s_len = 0;\n' %self.name) 566 self.basemessage.declared.append(self.name + '_len') 567 568 global fieldsArray 569 if self.name not in fieldsArray: 570 fieldsArray[self.name] = '{&hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_STRING, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 571 return ret 572 573 def dissect(self): 574 ret = '' 575 576 if self.declare == "yes" and self.size != "VariableDirnumSize": 577 ret += self.indent_out('const gchar * %s = g_strdup(tvb_format_stringzpad(pinfo->pool, ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), %s));\n' %(self.name, self.size)) 578 579 if self.subtype == "DisplayLabel": 580 if self.basemessage.dynamic == "yes": 581 ret += self.indent_out('dissect_skinny_displayLabel(cursor, pinfo, hf_skinny_%s, 0);\n' %(self.name)) 582 elif self.size_fieldname: 583 ret += self.indent_out('dissect_skinny_displayLabel(cursor, pinfo, hf_skinny_%s, %s);\n' %(self.name, self.size_fieldname)) 584 else: 585 ret += self.indent_out('dissect_skinny_displayLabel(cursor, pinfo, hf_skinny_%s, %s);\n' %(self.name, self.size)) 586 587 elif self.basemessage.dynamic == "yes": 588 ret += self.indent_out('%s_len = tvb_strnlen(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), -1)+1;\n' %self.name) 589 ret += self.indent_out('if (%s_len > 1) {\n' %self.name) 590 if self.name in si_fields.keys(): 591 ret += self.indent_out(' %s = g_strdup(tvb_format_stringzpad(pinfo->pool, ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), %s_len));\n' %(si_fields[self.name], self.name)) 592 ret += self.indent_out(' ptvcursor_add(cursor, hf_skinny_%s, %s_len, ENC_ASCII|ENC_NA);\n' %(self.name, self.name)) 593 ret += self.indent_out('} else {\n') 594 ret += self.indent_out(' ptvcursor_advance(cursor, 1);\n') 595 ret += self.indent_out('}\n') 596 elif self.size_fieldname: 597 if self.name in si_fields.keys(): 598 ret += self.indent_out('%s = g_strdup(tvb_format_stringzpad(pinfo->pool, ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), %s));\n' %(si_fields[self.name], self.size_fieldname)) 599 ret += self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, %s, ENC_ASCII|ENC_NA);\n' %(self.name, self.size_fieldname)) 600 else: 601 if self.name in si_fields.keys(): 602 ret += self.indent_out('%s = g_strdup(tvb_format_stringzpad(pinfo->pool, ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), %s));\n' %(si_fields[self.name], self.size)) 603 if self.make_additional_info == "yes": 604 ret += self.indent_out('guint32 %s_len;\n' %(self.name)) 605 if self.size=="VariableDirnumSize": 606 ret += self.indent_out('%s_len = tvb_strnlen(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), VariableDirnumSize)+1;\n' %(self.name)) 607 else: 608 ret += self.indent_out('%s_len = tvb_strnlen(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), 24)+1;\n' %(self.name)) 609 ret += self.indent_out('if (%s_len > 1) {\n' %(self.name)) 610 self.incr_indent() 611 ret += self.indent_out('si->additionalInfo = g_strdup_printf("\\"%%s\\"", tvb_format_stringzpad(pinfo->pool, ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), %s_len));\n' %(self.name)) 612 self.decr_indent() 613 ret += self.indent_out('}\n') 614 615 ret += self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, %s, ENC_ASCII|ENC_NA);\n' %(self.name, self.size)) 616 617 return ret 618 619 class Ether(DataNode): 620 def __init__(self): 621 DataNode.__init__(self) 622 623 def __str__(self): 624 return '%s:%s' %(self.__class__,self.name) 625 626 def declaration(self): 627 ret = '' 628 self.intsize = 6 629 if self.size: 630 self.intsize = int(self.size) 631 elif self.maxsize and self.basemessage.dynamic == "no": 632 self.intsize = int(self.maxsize) 633 634 if self.declare == "yes": 635 if self.basemessage.declared is None or self.name not in self.basemessage.declared: 636 ret += self.indent_out('guint32 %s = 0;\n' %self.name) 637 self.basemessage.declared.append(self.name) 638 639 if self.basemessage.dynamic == "yes": 640 if self.basemessage.declared is None or self.name + '_len' not in self.basemessage.declared: 641 ret += self.indent_out('guint32 %s_len = 0;\n' %self.name) 642 self.basemessage.declared.append(self.name + '_len') 643 644 global fieldsArray 645 if self.name not in fieldsArray: 646 fieldsArray[self.name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_ETHER, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 647 return ret 648 649 def dissect(self): 650 ret = '' 651 652 if self.basemessage.dynamic == "yes": 653 ret += self.indent_out('%s_len = tvb_strnlen(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor), -1)+1;\n' %self.name) 654 ret += self.indent_out('if (%s_len > 1) {\n' %self.name) 655 ret += self.indent_out(' ptvcursor_add(cursor, hf_skinny_%s, 6, ENC_NA);\n' %(self.name, self.name)) 656 ret += self.indent_out(' ptvcursor_advance(cursor, %s_len - 6);\n' %(self.name)) 657 ret += self.indent_out('} else {\n') 658 ret += self.indent_out(' ptvcursor_advance(cursor, 1);\n') 659 ret += self.indent_out('}\n') 660 elif self.size_fieldname: 661 ret += self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, 6, ENC_NA);\n' %(self.name)) 662 ret += self.indent_out('ptvcursor_advance(cursor, %s - 6);\n' %(self.size_fieldname)) 663 else: 664 ret += self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, 6, ENC_NA);\n' %(self.name)) 665 ret += self.indent_out('ptvcursor_advance(cursor, %s - 6);\n' %(self.size)) 666 return ret 667 668 class BitField(DataNode): 669 def __init__(self): 670 DataNode.__init__(self) 671 672 def __str__(self): 673 return '%s:%s' %(self.__class__,self.name) 674 675 def declaration(self): 676 global fieldsArray 677 ret = '' 678 int_sizes = {'uint32':4,'uint16':2,'uint8':1,'int32':4,'int16':2,'int8':1} 679 self.intsize = 0 680 if self.size in int_sizes: 681 self.intsize = int_sizes[self.size] 682 683 for entries in self.entries: 684 for entry in entries.entry: 685 if entry.name not in fieldsArray: 686 fieldsArray[entry.name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_BOOLEAN, %d, TFS(&tfs_yes_no), %s,\n %s, HFILL }},\n' %(entry.name, entry.text, entry.name.replace("_","."), self.intsize * 8, entry.value, '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 687 688 return ret 689 690 def dissect(self): 691 ret = '' 692 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s");\n' %(self.name)) 693 for entries in self.entries: 694 for entry in entries.entry: 695 ret += self.indent_out('ptvcursor_add_no_advance(cursor, hf_skinny_%s, %d, ENC_LITTLE_ENDIAN);\n' %(entry.name, self.intsize)) 696 ret += self.indent_out('ptvcursor_advance(cursor, %d);\n' %(self.intsize)) 697 ret += self.indent_out('ptvcursor_pop_subtree(cursor); /* end bitfield: %s */\n' %(self.name)) 698 699 700 return ret 701 702 class Ip(DataNode): 703 def __init__(self): 704 DataNode.__init__(self) 705 self.intsize = 4 706 if self.type == "ipv6": 707 self.intsize = 16 708 709 def __str__(self): 710 return '%s:%s' %(self.__class__,self.name) 711 712 def declaration(self): 713 global fieldsArray 714 if self.name not in fieldsArray: 715 if self.type == "ipv4": 716 fieldsArray[self.name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_IPv4, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 717 else: 718 fieldsArray[self.name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_IPv6, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 719 return '' 720 721 def dissect(self): 722 if self.type == "ipv4": 723 return self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, 4, ENC_BIG_ENDIAN);\n' %self.name) 724 else: 725 return self.indent_out('ptvcursor_add(cursor, hf_skinny_%s, 16, ENC_NA);\n' %self.name) 726 727 class Ipv4or6(DataNode): 728 def __init__(self): 729 DataNode.__init__(self) 730 self.intsize = 4 731 if self.endianness is None: 732 self.intsize += 16 733 734 def __str__(self): 735 return '%s:%s' %(self.__class__,self.name) 736 737 def declaration(self): 738 global fieldsArray 739 740 ret = '' 741 name = self.name + '_ipv4' 742 if name not in fieldsArray: 743 fieldsArray[name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_IPv4, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(name, self.name + ' IPv4 Address', name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 744 name = self.name + '_ipv6' 745 if name not in fieldsArray: 746 fieldsArray[name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_IPv6, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(name, self.name + ' IPv6 Address', name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 747 if self.make_additional_info == "yes": 748 if self.basemessage.declared is None or self.name not in self.basemessage.declared: 749 ret += self.indent_out('address %s;\n' %(self.name)) 750 ret += self.indent_out('char *%s_str = NULL;\n' %(self.name)) 751 self.basemessage.declared.append(self.name) 752 753 return ret 754 755 def dissect(self): 756 ret = '' 757 if self.make_additional_info == "yes": 758 ret += self.indent_out('read_skinny_ipv4or6(cursor, &%s);\n' %(self.name)); 759 ret += self.indent_out('dissect_skinny_ipv4or6(cursor, hf_skinny_%s_ipv4, hf_skinny_%s_ipv6);\n' %(self.name, self.name)); 760 return ret; 761 762 class XML(DataNode): 763 def __init__(self): 764 DataNode.__init__(self) 765 self.intsize = 0 766 767 def __str__(self): 768 return '%s:%s' %(self.__class__,self.name) 769 770 def declaration(self): 771 global fieldsArray 772 773 if self.size: 774 self.intsize = int(self.size) 775 elif self.maxsize: 776 self.intsize = int(self.maxsize) 777 778 if self.name not in fieldsArray: 779 fieldsArray[self.name] = '{ &hf_skinny_%s,\n {\n "%s", "skinny.%s", FT_STRING, BASE_NONE, NULL, 0x0,\n %s, HFILL }},\n' %(self.name, self.comment if (self.comment and self.longcomment) else self.name, self.name.replace("_","."), '"' + self.longcomment + '"' if self.longcomment else '"' + self.comment + '"' if self.comment else 'NULL') 780 return '' 781 782 def dissect(self): 783 ret = '' 784 if self.size_fieldname: 785 ret += self.indent_out('dissect_skinny_xml(cursor, hf_skinny_%s, pinfo, %s, %d);\n' %(self.name, self.size_fieldname, self.intsize)) 786 else: 787 ret += self.indent_out('dissect_skinny_xml(cursor, hf_skinny_%s, pinfo, 0, %d);\n' %(self.name, self.intsize)) 788 return ret 789 790 class Code(DataNode): 791 def __init__(self): 792 DataNode.__init__(self) 793 794 def __str__(self): 795 return '%s:%s' %(self.__class__,self.name) 796 797 def declaration(self): 798 return '' 799 800 def dissect(self): 801 ret = '' 802 if self.type == "calling_and_called_party": 803 params = self.use_param.split(',') 804 ret += self.indent_out('if (si->%s && si->%s) {\n' %(params[0], params[1])) 805 self.incr_indent() 806 ret += self.indent_out('si->additionalInfo = g_strdup_printf("\\"%%s -> %%s\\"", si->%s, si->%s);\n' %(params[0], params[1])) 807 self.decr_indent() 808 ret += self.indent_out('}\n') 809 return ret 810 811 class Struct(DataNode): 812 def __str__(self): 813 return '// Struct : %s / %s / %s / %s\n' %(self.name, self.size, self.field_sizename, self.maxsize) 814 815 def declaration(self): 816 ret = '' 817 818 if (self.fields is not None and len(self.fields)): 819 if (len(self.fields) > 1): 820 if self.basemessage.declared is None or "hdr_version" not in self.basemessage.declared: 821 ret += self.indent_out("guint32 hdr_version = tvb_get_letohl(ptvcursor_tvbuff(cursor), 4);\n") 822 self.basemessage.declared.append("hdr_version") 823 for fields in self.fields: 824 ret += '%s' %fields.declaration() 825 #self.intsize += fields.intsize 826 self.intsize = fields.intsize 827 return ret 828 829 def dissect(self): 830 ret = '' 831 variable = 'counter_%d' %indentation 832 size = 0 833 834 if self.size_fieldname: 835 #if self.basemessage.dynamic == "yes": 836 # size = self.size_fieldname 837 #else: 838 # size = self.maxsize 839 size = self.maxsize 840 elif self.size: 841 size = self.size 842 843 if size: 844 if self.size_fieldname: 845 ret += self.indent_out('if (%s <= %s) {%s\n' %(self.size_fieldname, size, ' /* tvb struct size guard */' if debug else '')) 846 else: 847 ret += self.indent_out('{\n') 848 self.incr_indent() 849 if debug: 850 ret += self.indent_out('/* start struct : %s / size: %d */\n' %(self.name, self.intsize)) 851 ret += self.indent_out('guint32 %s = 0;\n' %(variable)); 852 if self.size_fieldname: 853 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [ref:%s = %%d, max:%s]", %s);\n' %(self.name, self.size_fieldname, self.maxsize, self.size_fieldname)) 854 if self.maxsize: 855 ret += self.indent_out('if (%s && tvb_get_letohl(ptvcursor_tvbuff(cursor), 0) + 8 >= ptvcursor_current_offset(cursor) + (%s * %s) && %s <= %s) {%s\n' %(self.size_fieldname, self.size_fieldname, self.intsize, self.size_fieldname, self.maxsize, '/* tvb counter size guard */' if debug else '')) 856 else: 857 ret += self.indent_out('if (%s && tvb_get_letohl(ptvcursor_tvbuff(cursor), 0) + 8 >= ptvcursor_current_offset(cursor) + (%s * %s)) {%s\n' %(self.size_fieldname, self.size_fieldname, self.intsize, '/* tvb counter size guard */' if debug else '')) 858 self.incr_indent() 859 else: 860 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [max:%s]");\n' %(self.name, size)) 861 862 ret += self.indent_out('for (%s = 0; %s < %s; %s++) {\n' %(variable, variable, size, variable)); 863 if self.basemessage.dynamic == "no" and self.size_fieldname: 864 self.incr_indent() 865 ret += self.indent_out('if (%s < %s) {\n' %(variable,self.size_fieldname)) 866 self.incr_indent() 867 else: 868 if debug: 869 ret += self.indent_out('{ /* start struct : %s / size: %d */\n' %(self.name, self.intsize)) 870 else: 871 ret += self.indent_out('{\n') 872 self.incr_indent() 873 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s");\n' %(self.name)) 874 875 if size: 876 if self.size_fieldname: 877 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [%%d / %%d]", %s + 1, %s);\n' %(self.name, variable, self.size_fieldname)) 878 else: 879 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s [%%d / %%d]", %s + 1, %s);\n' %(self.name, variable, size)) 880 881 if (self.fields is not None and len(self.fields)): 882 for fields in self.fields: 883 ret += '%s' %fields.dissect() 884 885 if self.basemessage.dynamic == "no" and self.size_fieldname: 886 self.decr_indent() 887 ret += self.indent_out('} else {\n') 888 ret += self.indent_out(' ptvcursor_advance(cursor, %d);\n' %(self.intsize)) 889 ret += self.indent_out('}\n') 890 891 if size: 892 ret += self.indent_out('ptvcursor_pop_subtree(cursor);\n') 893 self.decr_indent() 894 if debug: 895 ret += self.indent_out('} /* end for loop tree: %s */\n' %self.name) 896 else: 897 ret += self.indent_out('}\n') 898 if self.size_fieldname: 899 self.decr_indent() 900 ret += self.indent_out('} /* end counter tvb size guard */\n' if debug else '}\n') 901 902 ret += self.indent_out('ptvcursor_pop_subtree(cursor);\n') 903 if debug: 904 ret += self.indent_out('/* end struct: %s */\n' %self.name) 905 self.decr_indent() 906 if self.size_fieldname: 907 ret += self.indent_out('} else {\n') 908 self.incr_indent() 909 ret += self.indent_out('ptvcursor_advance(cursor, (%s * %s));%s\n' %(self.size_fieldname, self.intsize, ' /* guard kicked in -> skip the rest */' if debug else '')); 910 self.decr_indent() 911 ret += self.indent_out('} /* end struct size guard */\n' if debug else '}\n') 912 913 return ret 914 915 class Union(DataNode): 916 def __str__(self): 917 return '%s:%s' %(self.__class__,self.name) 918 919 def declaration(self): 920 ret = '' 921 self.maxsize = 0 922 if (self.fields is not None and len(self.fields)): 923 if (len(self.fields) > 1): 924 if self.basemessage.declared is None or "hdr_version" not in self.basemessage.declared: 925 ret += self.indent_out("guint32 hdr_version = tvb_get_letohl(ptvcursor_tvbuff(cursor), 4);\n") 926 self.basemessage.declared.append("hdr_version") 927 for fields in self.fields: 928 ret += '%s' %fields.declaration() 929 previous_lookup_eq = fields._children[0].lookup_eq 930 previous_lookup_le = fields._children[0].lookup_le 931 previous_lookup_ge = fields._children[0].lookup_ge 932 self.runningtotal = 0 933 for field in fields._children: 934 if previous_lookup_eq != field.lookup_eq or previous_lookup_le != field.lookup_le or previous_lookup_ge == field.lookup_ge: 935 previous_lookup_eq = field.lookup_eq 936 previous_lookup_le = field.lookup_le 937 previous_lookup_ge = field.lookup_ge 938 self.runningtotal = 0 939 940 self.runningtotal += field.intsize 941 if self.runningtotal > self.maxsize: 942 self.maxsize = self.runningtotal 943 944 self.intsize = self.maxsize 945 946 return ret 947 948 def dissect(self): 949 ret = '' 950 ifblock = self.indent_out('if') 951 skip = 0 952 #ret += self.indent_out('/* Union : %s / maxsize: %s */\n' %(self.name, self.maxsize)) 953 954 if (self.fields is not None and len(self.fields)): 955 for fields in self.fields: 956 for field in fields._children: 957 if self.lookup_guide and (field.lookup_ge or field.lookup_le or field.lookup_eq): 958 lookupguide = self.lookup_guide 959 # start block 960 subtree_text = '' 961 if field.lookup_ge and field.lookup_le: 962 ret += '%s (%s >= %s && %s <= %s)' %(ifblock, lookupguide, field.lookup_ge.upper(), lookupguide, field.lookup_le.upper()) 963 subtree_text = "%s <= %s <= %s" %(field.lookup_ge, lookupguide, field.lookup_le) 964 elif field.lookup_ge: 965 ret += '%s (%s >= %s)' %(ifblock, lookupguide, field.lookup_ge.upper()) 966 subtree_text = "%s >= %s" %(lookupguide, field.lookup_ge) 967 elif field.lookup_le: 968 ret += '%s (%s <= %s)' %(ifblock, lookupguide, field.lookup_le.upper()) 969 subtree_text = "%s <= %s" %(lookupguide, field.lookup_le) 970 elif field.lookup_eq: 971 if field.lookup_eq == "*": 972 ret += ' else' 973 subtree_text = "any %s" %(lookupguide) 974 elif field.lookup_eq == "skip": 975 continue 976 else: 977 ret += '%s (%s == %s)' %(ifblock, lookupguide, field.lookup_eq.upper()) 978 subtree_text = "%s is %s" %(lookupguide, field.lookup_eq) 979 980 ret += self.indent_out(' {\n') 981 self.incr_indent() 982 if debug: 983 ret += self.indent_out('/* start union : %s / maxsize: %s */\n' %(self.name, self.maxsize)) 984 currsize = 0 985 # dissect field 986 987 ret += self.indent_out('ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH, ett_skinny_tree, "%s");\n' %subtree_text) 988 ret += '%s' %field.dissect() 989 ret += self.indent_out('ptvcursor_pop_subtree(cursor);\n') 990 991 currsize += field.intsize 992 993 # compensate length 994 if (self.maxsize - currsize) > 0: 995 ret += self.indent_out('ptvcursor_advance(cursor, %d);\n' %(self.maxsize - currsize)) 996 997 self.decr_indent() 998 999 # close block 1000 ret += self.indent_out('}') 1001 ifblock = ' else if' 1002 else: 1003 ret += '/* ERROR %s, missing lookup_guide */' %field.dissect() 1004 ret += '\n' 1005 1006 return ret 1007 1008 class TreeBuilder(xml.sax.handler.ContentHandler): 1009 def __init__(self): 1010 self.stack = [] 1011 self.root = DataNode() 1012 self.previous = self.root 1013 self.current = self.root 1014 self.basemessage = None 1015 self.text_parts = [] 1016 def startElement(self, name, attrs): 1017 objecttype = {"message": Message(), "fields": Fields(), "enum" : Enum(), "bitfield" : BitField(), "struct": Struct(), "union": Union(), "integer": Integer(), "string": String(), "ether": Ether(), "ip": Ip(), "ipv4or6": Ipv4or6(), "xml": XML(), "code": Code()} 1018 self.previous = self.current 1019 self.stack.append((self.current, self.text_parts)) 1020 if name in objecttype.keys(): 1021 self.current = objecttype[name] 1022 else: 1023 self.current = DataNode() 1024 if name == "message": 1025 self.basemessage = self.current 1026 self.text_parts = [] 1027 #self.children = [] 1028 self.current.parent = self.previous 1029 self.current.basemessage = self.basemessage 1030 # xml attributes --> python attributes 1031 for k, v in attrs.items(): 1032 self.current._add_xml_attr(_name_mangle(k), v) 1033 1034 def endElement(self, name): 1035 text = ''.join(self.text_parts).strip() 1036 if text: 1037 self.current.data = text 1038 if self.current._attrs: 1039 obj = self.current 1040 else: 1041 # a text only node is simply represented by the string 1042 obj = text or '' 1043 self.current, self.text_parts = self.stack.pop() 1044 self.current._add_xml_attr(_name_mangle(name), obj) 1045 self.current._add_child(_name_mangle(name), obj) 1046 def characters(self, content): 1047 self.text_parts.append(content) 1048 1049 builder = TreeBuilder() 1050 xml.sax.parse(src, builder) 1051 return builder.root._attrs.values()[0] 1052 1053# skinny = xml2obj('SkinnyProtocolOptimized.xml') 1054# for message in skinny.message: 1055# print '%s' %message.dissect() 1056 1057#if __name__ == '__main__': 1058# import timeit 1059# print(timeit.timeit("generateMessageDissectors()", setup="from __main__ import generateMessageDissectors")) 1060 1061 1062#skinny = xml2obj('SkinnyProtocolOptimized.xml') 1063#for message in skinny.message: 1064# print(message) 1065# message.dissect() 1066 1067#for key,value in fieldsArray.items(): 1068# print "%s : %s" %(key,value) 1069#print '%r\n' %fieldsArray 1070 1071#skinny = xml2obj('SkinnyProtocolOptimized.xml') 1072#for message in skinny.message: 1073# print message.declaration() 1074