1#!/usr/bin/env python3 2 3# 4# asn2wrs.py 5# ASN.1 to Wireshark dissector compiler 6# Copyright 2004 Tomas Kukosa 7# 8# SPDX-License-Identifier: MIT 9# 10 11"""ASN.1 to Wireshark dissector compiler""" 12 13# 14# Compiler from ASN.1 specification to the Wireshark dissector 15# 16# Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license 17# https://www.pobox.com/~asl2/software/PyZ3950/ 18# (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary) 19# 20# It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3) 21# https://www.dabeaz.com/ply/ 22# 23# 24# ITU-T Recommendation X.680 (07/2002), 25# Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation 26# 27# ITU-T Recommendation X.681 (07/2002), 28# Information technology - Abstract Syntax Notation One (ASN.1): Information object specification 29# 30# ITU-T Recommendation X.682 (07/2002), 31# Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification 32# 33# ITU-T Recommendation X.683 (07/2002), 34# Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications 35# 36# ITU-T Recommendation X.880 (07/1994), 37# Information technology - Remote Operations: Concepts, model and notation 38# 39 40import warnings 41 42import re 43import sys 44import os 45import os.path 46import time 47import getopt 48import traceback 49 50try: 51 from ply import lex 52 from ply import yacc 53except ImportError: 54 # Fallback: use lex.py and yacc from the tools directory within the 55 # Wireshark source tree if python-ply is not installed. 56 import lex 57 import yacc 58 59if sys.version_info[0] < 3: 60 from string import maketrans 61 62 63# OID name -> number conversion table 64oid_names = { 65 '/itu-t' : 0, 66 '/itu' : 0, 67 '/ccitt' : 0, 68 '/itu-r' : 0, 69 '0/recommendation' : 0, 70 '0.0/a' : 1, 71 '0.0/b' : 2, 72 '0.0/c' : 3, 73 '0.0/d' : 4, 74 '0.0/e' : 5, 75 '0.0/f' : 6, 76 '0.0/g' : 7, 77 '0.0/h' : 8, 78 '0.0/i' : 9, 79 '0.0/j' : 10, 80 '0.0/k' : 11, 81 '0.0/l' : 12, 82 '0.0/m' : 13, 83 '0.0/n' : 14, 84 '0.0/o' : 15, 85 '0.0/p' : 16, 86 '0.0/q' : 17, 87 '0.0/r' : 18, 88 '0.0/s' : 19, 89 '0.0/t' : 20, 90 '0.0/tseries' : 20, 91 '0.0/u' : 21, 92 '0.0/v' : 22, 93 '0.0/w' : 23, 94 '0.0/x' : 24, 95 '0.0/y' : 25, 96 '0.0/z' : 26, 97 '0/question' : 1, 98 '0/administration' : 2, 99 '0/network-operator' : 3, 100 '0/identified-organization' : 4, 101 '0/r-recommendation' : 5, 102 '0/data' : 9, 103 '/iso' : 1, 104 '1/standard' : 0, 105 '1/registration-authority' : 1, 106 '1/member-body' : 2, 107 '1/identified-organization' : 3, 108 '/joint-iso-itu-t' : 2, 109 '/joint-iso-ccitt' : 2, 110 '2/presentation' : 0, 111 '2/asn1' : 1, 112 '2/association-control' : 2, 113 '2/reliable-transfer' : 3, 114 '2/remote-operations' : 4, 115 '2/ds' : 5, 116 '2/directory' : 5, 117 '2/mhs' : 6, 118 '2/mhs-motis' : 6, 119 '2/ccr' : 7, 120 '2/oda' : 8, 121 '2/ms' : 9, 122 '2/osi-management' : 9, 123 '2/transaction-processing' : 10, 124 '2/dor' : 11, 125 '2/distinguished-object-reference' : 11, 126 '2/reference-data-transfe' : 12, 127 '2/network-layer' : 13, 128 '2/network-layer-management' : 13, 129 '2/transport-layer' : 14, 130 '2/transport-layer-management' : 14, 131 '2/datalink-layer' : 15, 132 '2/datalink-layer-managemen' : 15, 133 '2/datalink-layer-management-information' : 15, 134 '2/country' : 16, 135 '2/registration-procedures' : 17, 136 '2/registration-procedure' : 17, 137 '2/physical-layer' : 18, 138 '2/physical-layer-management' : 18, 139 '2/mheg' : 19, 140 '2/genericULS' : 20, 141 '2/generic-upper-layers-security' : 20, 142 '2/guls' : 20, 143 '2/transport-layer-security-protocol' : 21, 144 '2/network-layer-security-protocol' : 22, 145 '2/international-organizations' : 23, 146 '2/internationalRA' : 23, 147 '2/sios' : 24, 148 '2/uuid' : 25, 149 '2/odp' : 26, 150 '2/upu' : 40, 151} 152 153ITEM_FIELD_NAME = '_item' 154UNTAG_TYPE_NAME = '_untag' 155 156def asn2c(id): 157 return id.replace('-', '_').replace('.', '_').replace('&', '_') 158 159input_file = None 160g_conform = None 161lexer = None 162in_oid = False 163 164class LexError(Exception): 165 def __init__(self, tok, filename=None): 166 self.tok = tok 167 self.filename = filename 168 self.msg = "Unexpected character %r" % (self.tok.value[0]) 169 Exception.__init__(self, self.msg) 170 def __repr__(self): 171 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg) 172 __str__ = __repr__ 173 174 175class ParseError(Exception): 176 def __init__(self, tok, filename=None): 177 self.tok = tok 178 self.filename = filename 179 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value) 180 Exception.__init__(self, self.msg) 181 def __repr__(self): 182 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg) 183 __str__ = __repr__ 184 185 186class DuplicateError(Exception): 187 def __init__(self, type, ident): 188 self.type = type 189 self.ident = ident 190 self.msg = "Duplicate %s for %s" % (self.type, self.ident) 191 Exception.__init__(self, self.msg) 192 def __repr__(self): 193 return self.msg 194 __str__ = __repr__ 195 196class CompError(Exception): 197 def __init__(self, msg): 198 self.msg = msg 199 Exception.__init__(self, self.msg) 200 def __repr__(self): 201 return self.msg 202 __str__ = __repr__ 203 204 205states = ( 206 ('braceignore','exclusive'), 207) 208 209precedence = ( 210 ('left', 'UNION', 'BAR'), 211 ('left', 'INTERSECTION', 'CIRCUMFLEX'), 212) 213# 11 ASN.1 lexical items 214 215static_tokens = { 216 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item 217 r'\.\.' : 'RANGE', # 11.17 Range separator 218 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis 219 r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets 220 r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets 221 # 11.26 Single character lexical items 222 r'\{' : 'LBRACE', 223 r'\}' : 'RBRACE', 224 r'<' : 'LT', 225 #r'>' : 'GT', 226 r',' : 'COMMA', 227 r'\.' : 'DOT', 228 r'\(' : 'LPAREN', 229 r'\)' : 'RPAREN', 230 r'\[' : 'LBRACK', 231 r'\]' : 'RBRACK', 232 r'-' : 'MINUS', 233 r':' : 'COLON', 234 #r'=' : 'EQ', 235 #r'"' : 'QUOTATION', 236 #r"'" : 'APOSTROPHE', 237 r';' : 'SEMICOLON', 238 r'@' : 'AT', 239 r'\!' : 'EXCLAMATION', 240 r'\^' : 'CIRCUMFLEX', 241 r'\&' : 'AMPERSAND', 242 r'\|' : 'BAR' 243} 244 245# 11.27 Reserved words 246 247# all keys in reserved_words must start w/ upper case 248reserved_words = { 249 'ABSENT' : 'ABSENT', 250 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX', 251 'ALL' : 'ALL', 252 'APPLICATION' : 'APPLICATION', 253 'AUTOMATIC' : 'AUTOMATIC', 254 'BEGIN' : 'BEGIN', 255 'BIT' : 'BIT', 256 'BOOLEAN' : 'BOOLEAN', 257 'BY' : 'BY', 258 'CHARACTER' : 'CHARACTER', 259 'CHOICE' : 'CHOICE', 260 'CLASS' : 'CLASS', 261 'COMPONENT' : 'COMPONENT', 262 'COMPONENTS' : 'COMPONENTS', 263 'CONSTRAINED' : 'CONSTRAINED', 264 'CONTAINING' : 'CONTAINING', 265 'DEFAULT' : 'DEFAULT', 266 'DEFINITIONS' : 'DEFINITIONS', 267 'EMBEDDED' : 'EMBEDDED', 268# 'ENCODED' : 'ENCODED', 269 'END' : 'END', 270 'ENUMERATED' : 'ENUMERATED', 271# 'EXCEPT' : 'EXCEPT', 272 'EXPLICIT' : 'EXPLICIT', 273 'EXPORTS' : 'EXPORTS', 274# 'EXTENSIBILITY' : 'EXTENSIBILITY', 275 'EXTERNAL' : 'EXTERNAL', 276 'FALSE' : 'FALSE', 277 'FROM' : 'FROM', 278 'GeneralizedTime' : 'GeneralizedTime', 279 'IDENTIFIER' : 'IDENTIFIER', 280 'IMPLICIT' : 'IMPLICIT', 281# 'IMPLIED' : 'IMPLIED', 282 'IMPORTS' : 'IMPORTS', 283 'INCLUDES' : 'INCLUDES', 284 'INSTANCE' : 'INSTANCE', 285 'INTEGER' : 'INTEGER', 286 'INTERSECTION' : 'INTERSECTION', 287 'MAX' : 'MAX', 288 'MIN' : 'MIN', 289 'MINUS-INFINITY' : 'MINUS_INFINITY', 290 'NULL' : 'NULL', 291 'OBJECT' : 'OBJECT', 292 'ObjectDescriptor' : 'ObjectDescriptor', 293 'OCTET' : 'OCTET', 294 'OF' : 'OF', 295 'OPTIONAL' : 'OPTIONAL', 296 'PATTERN' : 'PATTERN', 297 'PDV' : 'PDV', 298 'PLUS-INFINITY' : 'PLUS_INFINITY', 299 'PRESENT' : 'PRESENT', 300 'PRIVATE' : 'PRIVATE', 301 'REAL' : 'REAL', 302 'RELATIVE-OID' : 'RELATIVE_OID', 303 'SEQUENCE' : 'SEQUENCE', 304 'SET' : 'SET', 305 'SIZE' : 'SIZE', 306 'STRING' : 'STRING', 307 'SYNTAX' : 'SYNTAX', 308 'TAGS' : 'TAGS', 309 'TRUE' : 'TRUE', 310 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER', 311 'UNION' : 'UNION', 312 'UNIQUE' : 'UNIQUE', 313 'UNIVERSAL' : 'UNIVERSAL', 314 'UTCTime' : 'UTCTime', 315 'WITH' : 'WITH', 316# X.208 obsolete but still used 317 'ANY' : 'ANY', 318 'DEFINED' : 'DEFINED', 319} 320 321for k in list(static_tokens.keys()): 322 if static_tokens [k] is None: 323 static_tokens [k] = k 324 325StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8', 326 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible', 327 'General'] 328 329for s in StringTypes: 330 reserved_words[s + 'String'] = s + 'String' 331 332tokens = list(static_tokens.values()) \ 333 + list(reserved_words.values()) \ 334 + ['BSTRING', 'HSTRING', 'QSTRING', 335 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT', 336 'REAL_NUMBER', 'NUMBER', 'PYQUOTE'] 337 338 339cur_mod = __import__ (__name__) # XXX blech! 340 341for (k, v) in list(static_tokens.items ()): 342 cur_mod.__dict__['t_' + v] = k 343 344# 11.10 Binary strings 345def t_BSTRING (t): 346 r"'[01]*'B" 347 return t 348 349# 11.12 Hexadecimal strings 350def t_HSTRING (t): 351 r"'[0-9A-Fa-f]*'H" 352 return t 353 354def t_QSTRING (t): 355 r'"([^"]|"")*"' 356 return t 357 358def t_UCASE_IDENT (t): 359 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-' 360 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT' 361 if (is_class_syntax(t.value)): t.type = t.value 362 t.type = reserved_words.get(t.value, t.type) 363 return t 364 365lcase_ident_assigned = {} 366def t_LCASE_IDENT (t): 367 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-' 368 if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED' 369 return t 370 371# 11.9 Real numbers 372def t_REAL_NUMBER (t): 373 r"[0-9]+\.[0-9]*(?!\.)" 374 return t 375 376# 11.8 Numbers 377def t_NUMBER (t): 378 r"0|([1-9][0-9]*)" 379 return t 380 381# 11.6 Comments 382pyquote_str = 'PYQUOTE' 383def t_COMMENT(t): 384 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)" 385 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1 386 if t.value[2:2+len (pyquote_str)] == pyquote_str: 387 t.value = t.value[2+len(pyquote_str):] 388 t.value = t.value.lstrip () 389 t.type = pyquote_str 390 return t 391 return None 392 393t_ignore = " \t\r" 394 395def t_NEWLINE(t): 396 r'\n+' 397 t.lexer.lineno += t.value.count("\n") 398 399def t_error(t): 400 global input_file 401 raise LexError(t, input_file) 402 403# state 'braceignore' 404 405def t_braceignore_lbrace(t): 406 r'\{' 407 t.lexer.level +=1 408 409def t_braceignore_rbrace(t): 410 r'\}' 411 t.lexer.level -=1 412 # If closing brace, return token 413 if t.lexer.level == 0: 414 t.type = 'RBRACE' 415 return t 416 417def t_braceignore_QSTRING (t): 418 r'"([^"]|"")*"' 419 t.lexer.lineno += t.value.count("\n") 420 421def t_braceignore_COMMENT(t): 422 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)" 423 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1 424 425def t_braceignore_nonspace(t): 426 r'[^\s\{\}\"-]+|-(?!-)' 427 428t_braceignore_ignore = " \t\r" 429 430def t_braceignore_NEWLINE(t): 431 r'\n+' 432 t.lexer.lineno += t.value.count("\n") 433 434def t_braceignore_error(t): 435 t.lexer.skip(1) 436 437class Ctx: 438 def __init__ (self, defined_dict, indent = 0): 439 self.tags_def = 'EXPLICIT' # default = explicit 440 self.indent_lev = 0 441 self.assignments = {} 442 self.dependencies = {} 443 self.pyquotes = [] 444 self.defined_dict = defined_dict 445 self.name_ctr = 0 446 def spaces (self): 447 return " " * (4 * self.indent_lev) 448 def indent (self): 449 self.indent_lev += 1 450 def outdent (self): 451 self.indent_lev -= 1 452 assert (self.indent_lev >= 0) 453 def register_assignment (self, ident, val, dependencies): 454 if ident in self.assignments: 455 raise DuplicateError("assignment", ident) 456 if ident in self.defined_dict: 457 raise Exception("cross-module duplicates for %s" % ident) 458 self.defined_dict [ident] = 1 459 self.assignments[ident] = val 460 self.dependencies [ident] = dependencies 461 return "" 462 # return "#%s depends on %s" % (ident, str (dependencies)) 463 def register_pyquote (self, val): 464 self.pyquotes.append (val) 465 return "" 466 def output_assignments (self): 467 already_output = {} 468 text_list = [] 469 assign_keys = list(self.assignments.keys()) 470 to_output_count = len (assign_keys) 471 while True: 472 any_output = 0 473 for (ident, val) in list(self.assignments.items ()): 474 if ident in already_output: 475 continue 476 ok = 1 477 for d in self.dependencies [ident]: 478 if ((d not in already_output) and 479 (d in assign_keys)): 480 ok = 0 481 if ok: 482 text_list.append ("%s=%s" % (ident, 483 self.assignments [ident])) 484 already_output [ident] = 1 485 any_output = 1 486 to_output_count -= 1 487 assert (to_output_count >= 0) 488 if not any_output: 489 if to_output_count == 0: 490 break 491 # OK, we detected a cycle 492 cycle_list = [] 493 for ident in list(self.assignments.keys ()): 494 if ident not in already_output: 495 depend_list = [d for d in self.dependencies[ident] if d in assign_keys] 496 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list))) 497 498 text_list.append ("# Cycle XXX " + ",".join (cycle_list)) 499 for (ident, val) in list(self.assignments.items ()): 500 if ident not in already_output: 501 text_list.append ("%s=%s" % (ident, self.assignments [ident])) 502 break 503 504 return "\n".join (text_list) 505 def output_pyquotes (self): 506 return "\n".join (self.pyquotes) 507 def make_new_name (self): 508 self.name_ctr += 1 509 return "_compiler_generated_name_%d" % (self.name_ctr,) 510 511#--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM ------------------------------- 512EF_TYPE = 0x0001 513EF_VALS = 0x0002 514EF_ENUM = 0x0004 515EF_WS_DLL = 0x0010 # exported from shared library 516EF_EXTERN = 0x0020 517EF_NO_PROT = 0x0040 518EF_NO_TYPE = 0x0080 519EF_UCASE = 0x0100 520EF_TABLE = 0x0400 521EF_DEFINE = 0x0800 522EF_MODULE = 0x1000 523 524#--- common dependency computation --- 525# Input : list of items 526# dictionary with lists of dependency 527# 528# 529# Output : list of two outputs: 530# [0] list of items in dependency 531# [1] list of cycle dependency cycles 532def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False): 533 item_ord = [] 534 item_cyc = [] 535 x = {} # already emitted 536 #print '# Dependency computation' 537 for t in items: 538 if map_fn(t) in x: 539 #print 'Continue: %s : %s' % (t, (map_fn(t)) 540 continue 541 stack = [t] 542 stackx = {t : dependency.get(t, [])[:]} 543 #print 'Push: %s : %s' % (t, str(stackx[t])) 544 while stack: 545 if stackx[stack[-1]]: # has dependencies 546 d = stackx[stack[-1]].pop(0) 547 if map_fn(d) in x or ignore_fn(d): 548 continue 549 if d in stackx: # cyclic dependency 550 c = stack[:] 551 c.reverse() 552 c = [d] + c[0:c.index(d)+1] 553 c.reverse() 554 item_cyc.append(c) 555 #print 'Cyclic: %s ' % (' -> '.join(c)) 556 continue 557 stack.append(d) 558 stackx[d] = dependency.get(d, [])[:] 559 #print 'Push: %s : %s' % (d, str(stackx[d])) 560 else: 561 #print 'Pop: %s' % (stack[-1]) 562 del stackx[stack[-1]] 563 e = map_fn(stack.pop()) 564 if e in x: 565 continue 566 #print 'Add: %s' % (e) 567 item_ord.append(e) 568 x[e] = True 569 return (item_ord, item_cyc) 570 571# Given a filename, return a relative path from the current directory 572def relpath(filename): 573 return os.path.relpath(filename) 574 575# Given a filename, return a relative path from epan/dissectors 576def rel_dissector_path(filename): 577 path_parts = os.path.abspath(filename).split(os.sep) 578 while (len(path_parts) > 3 and path_parts[0] != 'asn1'): 579 path_parts.pop(0) 580 path_parts.insert(0, '.') 581 return '/'.join(path_parts) 582 583 584#--- EthCtx ------------------------------------------------------------------- 585class EthCtx: 586 def __init__(self, conform, output, indent = 0): 587 self.conform = conform 588 self.output = output 589 self.conform.ectx = self 590 self.output.ectx = self 591 self.encoding = 'per' 592 self.aligned = False 593 self.default_oid_variant = '' 594 self.default_opentype_variant = '' 595 self.default_containing_variant = '_pdu_new' 596 self.default_embedded_pdv_cb = None 597 self.default_external_type_cb = None 598 self.remove_prefix = None 599 self.srcdir = None 600 self.emitted_pdu = {} 601 self.module = {} 602 self.module_ord = [] 603 self.all_type_attr = {} 604 self.all_tags = {} 605 self.all_vals = {} 606 607 def encp(self): # encoding protocol 608 encp = self.encoding 609 return encp 610 611 # Encoding 612 def Per(self): return self.encoding == 'per' 613 def Ber(self): return self.encoding == 'ber' 614 def Oer(self): return self.encoding == 'oer' 615 def Aligned(self): return self.aligned 616 def Unaligned(self): return not self.aligned 617 def NeedTags(self): return self.tag_opt or self.Ber() 618 def NAPI(self): return False # disable planned features 619 620 def Module(self): # current module name 621 return self.modules[-1][0] 622 623 def groups(self): 624 return self.group_by_prot or (self.conform.last_group > 0) 625 626 def dbg(self, d): 627 if (self.dbgopt.find(d) >= 0): 628 return True 629 else: 630 return False 631 632 def value_max(self, a, b): 633 if (a == 'MAX') or (b == 'MAX'): return 'MAX'; 634 if a == 'MIN': return b; 635 if b == 'MIN': return a; 636 try: 637 if (int(a) > int(b)): 638 return a 639 else: 640 return b 641 except (ValueError, TypeError): 642 pass 643 return "MAX((%s),(%s))" % (a, b) 644 645 def value_min(self, a, b): 646 if (a == 'MIN') or (b == 'MIN'): return 'MIN'; 647 if a == 'MAX': return b; 648 if b == 'MAX': return a; 649 try: 650 if (int(a) < int(b)): 651 return a 652 else: 653 return b 654 except (ValueError, TypeError): 655 pass 656 return "MIN((%s),(%s))" % (a, b) 657 658 def value_get_eth(self, val): 659 if isinstance(val, Value): 660 return val.to_str(self) 661 ethname = val 662 if val in self.value: 663 ethname = self.value[val]['ethname'] 664 return ethname 665 666 def value_get_val(self, nm): 667 val = asn2c(nm) 668 if nm in self.value: 669 if self.value[nm]['import']: 670 v = self.get_val_from_all(nm, self.value[nm]['import']) 671 if v is None: 672 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto']) 673 warnings.warn_explicit(msg, UserWarning, '', 0) 674 else: 675 val = v 676 else: 677 val = self.value[nm]['value'] 678 if isinstance (val, Value): 679 val = val.to_str(self) 680 else: 681 msg = 'Need value of unknown value identifier %s' % (nm) 682 warnings.warn_explicit(msg, UserWarning, '', 0) 683 return val 684 685 def eth_get_type_attr(self, type): 686 #print "eth_get_type_attr(%s)" % (type) 687 types = [type] 688 while (not self.type[type]['import']): 689 val = self.type[type]['val'] 690 #print val 691 ttype = type 692 while (val.type == 'TaggedType'): 693 val = val.val 694 ttype += '/' + UNTAG_TYPE_NAME 695 if (val.type != 'Type_Ref'): 696 if (type != ttype): 697 types.append(ttype) 698 break 699 type = val.val 700 types.append(type) 701 attr = {} 702 #print " ", types 703 while len(types): 704 t = types.pop() 705 if (self.type[t]['import']): 706 attr.update(self.type[t]['attr']) 707 attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import'])) 708 elif (self.type[t]['val'].type == 'SelectionType'): 709 val = self.type[t]['val'] 710 (ftype, display) = val.eth_ftype(self) 711 attr.update({ 'TYPE' : ftype, 'DISPLAY' : display, 712 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }); 713 else: 714 attr.update(self.type[t]['attr']) 715 attr.update(self.eth_type[self.type[t]['ethname']]['attr']) 716 if attr['STRINGS'].startswith('VALS64(') and '|BASE_VAL64_STRING' not in attr['DISPLAY']: 717 attr['DISPLAY'] += '|BASE_VAL64_STRING' 718 #print " ", attr 719 return attr 720 721 def eth_get_type_attr_from_all(self, type, module): 722 attr = {} 723 if module in self.all_type_attr and type in self.all_type_attr[module]: 724 attr = self.all_type_attr[module][type] 725 return attr 726 727 def get_ttag_from_all(self, type, module): 728 ttag = None 729 if module in self.all_tags and type in self.all_tags[module]: 730 ttag = self.all_tags[module][type] 731 return ttag 732 733 def get_val_from_all(self, nm, module): 734 val = None 735 if module in self.all_vals and nm in self.all_vals[module]: 736 val = self.all_vals[module][nm] 737 return val 738 739 def get_obj_repr(self, ident, flds=[], not_flds=[]): 740 def set_type_fn(cls, field, fnfield): 741 obj[fnfield + '_fn'] = 'NULL' 742 obj[fnfield + '_pdu'] = 'NULL' 743 if field in val and isinstance(val[field], Type_Ref): 744 p = val[field].eth_type_default_pars(self, '') 745 obj[fnfield + '_fn'] = p['TYPE_REF_FN'] 746 obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration 747 if (self.conform.check_item('PDU', cls + '.' + field)): 748 obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname'] 749 return 750 # end of get_type_fn() 751 obj = { '_name' : ident, '_ident' : asn2c(ident)} 752 obj['_class'] = self.oassign[ident].cls 753 obj['_module'] = self.oassign[ident].module 754 val = self.oassign[ident].val 755 for f in flds: 756 if f not in val: 757 return None 758 for f in not_flds: 759 if f in val: 760 return None 761 for f in list(val.keys()): 762 if isinstance(val[f], Node): 763 obj[f] = val[f].fld_obj_repr(self) 764 else: 765 obj[f] = str(val[f]) 766 if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'): 767 set_type_fn(obj['_class'], '&Type', '_type') 768 if (obj['_class'] == 'OPERATION'): 769 set_type_fn(obj['_class'], '&ArgumentType', '_argument') 770 set_type_fn(obj['_class'], '&ResultType', '_result') 771 if (obj['_class'] == 'ERROR'): 772 set_type_fn(obj['_class'], '&ParameterType', '_parameter') 773 return obj 774 775 #--- eth_reg_module ----------------------------------------------------------- 776 def eth_reg_module(self, module): 777 #print "eth_reg_module(module='%s')" % (module) 778 name = module.get_name() 779 self.modules.append([name, module.get_proto(self)]) 780 if name in self.module: 781 raise DuplicateError("module", name) 782 self.module[name] = [] 783 self.module_ord.append(name) 784 785 #--- eth_module_dep_add ------------------------------------------------------------ 786 def eth_module_dep_add(self, module, dep): 787 self.module[module].append(dep) 788 789 #--- eth_exports ------------------------------------------------------------ 790 def eth_exports(self, exports): 791 self.exports_all = False 792 if ((len(exports) == 1) and (exports[0] == 'ALL')): 793 self.exports_all = True 794 return 795 for e in (exports): 796 if isinstance(e, Type_Ref): 797 self.exports.append(e.val) 798 elif isinstance(e, Class_Ref): 799 self.cexports.append(e.val) 800 else: 801 self.vexports.append(e) 802 803 #--- eth_reg_assign --------------------------------------------------------- 804 def eth_reg_assign(self, ident, val, virt=False): 805 #print "eth_reg_assign(ident='%s')" % (ident) 806 if ident in self.assign: 807 raise DuplicateError("assignment", ident) 808 self.assign[ident] = { 'val' : val , 'virt' : virt } 809 self.assign_ord.append(ident) 810 if (self.exports_all): 811 self.exports.append(ident) 812 813 #--- eth_reg_vassign -------------------------------------------------------- 814 def eth_reg_vassign(self, vassign): 815 ident = vassign.ident 816 #print "eth_reg_vassign(ident='%s')" % (ident) 817 if ident in self.vassign: 818 raise DuplicateError("value assignment", ident) 819 self.vassign[ident] = vassign 820 self.vassign_ord.append(ident) 821 if (self.exports_all): 822 self.vexports.append(ident) 823 824 #--- eth_reg_oassign -------------------------------------------------------- 825 def eth_reg_oassign(self, oassign): 826 ident = oassign.ident 827 #print "eth_reg_oassign(ident='%s')" % (ident) 828 if ident in self.oassign: 829 if self.oassign[ident] == oassign: 830 return # OK - already defined 831 else: 832 raise DuplicateError("information object assignment", ident) 833 self.oassign[ident] = oassign 834 self.oassign_ord.append(ident) 835 self.oassign_cls.setdefault(oassign.cls, []).append(ident) 836 837 #--- eth_import_type -------------------------------------------------------- 838 def eth_import_type(self, ident, mod, proto): 839 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto) 840 if ident in self.type: 841 #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-')) 842 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) : 843 return # OK - already defined 844 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) : 845 return # OK - already imported 846 else: 847 raise DuplicateError("type", ident) 848 self.type[ident] = {'import' : mod, 'proto' : proto, 849 'ethname' : '' } 850 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE', 851 'STRINGS' : 'NULL', 'BITMASK' : '0' } 852 mident = "$%s$%s" % (mod, ident) 853 if (self.conform.check_item('TYPE_ATTR', mident)): 854 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident)) 855 else: 856 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident)) 857 if (self.conform.check_item('IMPORT_TAG', mident)): 858 self.conform.copy_item('IMPORT_TAG', ident, mident) 859 self.type_imp.append(ident) 860 861 #--- dummy_import_type -------------------------------------------------------- 862 def dummy_import_type(self, ident): 863 # dummy imported 864 if ident in self.type: 865 raise Exception("Try to dummy import for existing type :%s" % ident) 866 ethtype = asn2c(ident) 867 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx', 868 'ethname' : ethtype } 869 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE', 870 'STRINGS' : 'NULL', 'BITMASK' : '0' } 871 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []} 872 print("Dummy imported: %s (%s)" % (ident, ethtype)) 873 return ethtype 874 875 #--- eth_import_class -------------------------------------------------------- 876 def eth_import_class(self, ident, mod, proto): 877 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto) 878 if ident in self.objectclass: 879 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module']) 880 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) : 881 return # OK - already defined 882 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) : 883 return # OK - already imported 884 else: 885 raise DuplicateError("object class", ident) 886 self.objectclass[ident] = {'import' : mod, 'proto' : proto, 887 'ethname' : '' } 888 self.objectclass_imp.append(ident) 889 890 #--- eth_import_value ------------------------------------------------------- 891 def eth_import_value(self, ident, mod, proto): 892 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot) 893 if ident in self.value: 894 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module']) 895 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) : 896 return # OK - already defined 897 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) : 898 return # OK - already imported 899 else: 900 raise DuplicateError("value", ident) 901 self.value[ident] = {'import' : mod, 'proto' : proto, 902 'ethname' : ''} 903 self.value_imp.append(ident) 904 905 #--- eth_sel_req ------------------------------------------------------------ 906 def eth_sel_req(self, typ, sel): 907 key = typ + '.' + sel 908 if key not in self.sel_req: 909 self.sel_req[key] = { 'typ' : typ , 'sel' : sel} 910 self.sel_req_ord.append(key) 911 return key 912 913 #--- eth_comp_req ------------------------------------------------------------ 914 def eth_comp_req(self, type): 915 self.comp_req_ord.append(type) 916 917 #--- eth_dep_add ------------------------------------------------------------ 918 def eth_dep_add(self, type, dep): 919 if type not in self.type_dep: 920 self.type_dep[type] = [] 921 self.type_dep[type].append(dep) 922 923 #--- eth_reg_type ----------------------------------------------------------- 924 def eth_reg_type(self, ident, val, mod=None): 925 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type) 926 if ident in self.type: 927 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) : 928 # replace imported type 929 del self.type[ident] 930 self.type_imp.remove(ident) 931 else: 932 raise DuplicateError("type", ident) 933 val.ident = ident 934 self.type[ident] = { 'val' : val, 'import' : None } 935 self.type[ident]['module'] = self.Module() 936 self.type[ident]['proto'] = self.proto 937 if len(ident.split('/')) > 1: 938 self.type[ident]['tname'] = val.eth_tname() 939 else: 940 self.type[ident]['tname'] = asn2c(ident) 941 if mod : 942 mident = "$%s$%s" % (mod, ident) 943 else: 944 mident = None 945 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident) 946 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident) 947 self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident) 948 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident) 949 if mident and self.conform.check_item('NO_EMIT', mident) : 950 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', mident) 951 else: 952 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident) 953 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname']) 954 self.type[ident]['ethname'] = '' 955 if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') : 956 self.type[ident]['attr'] = {} 957 else: 958 (ftype, display) = val.eth_ftype(self) 959 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display, 960 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' } 961 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident)) 962 self.type_ord.append(ident) 963 # PDU 964 if (self.conform.check_item('PDU', ident)): 965 self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident)) 966 967 #--- eth_reg_objectclass ---------------------------------------------------------- 968 def eth_reg_objectclass(self, ident, val): 969 #print "eth_reg_objectclass(ident='%s')" % (ident) 970 if ident in self.objectclass: 971 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) : 972 # replace imported object class 973 del self.objectclass[ident] 974 self.objectclass_imp.remove(ident) 975 elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \ 976 isinstance(val, Class_Ref) and \ 977 (self.objectclass[ident]['val'].val == val.val): 978 pass # ignore duplicated CLASS1 ::= CLASS2 979 else: 980 raise DuplicateError("object class", ident) 981 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto } 982 self.objectclass[ident]['val'] = val 983 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident) 984 self.objectclass_ord.append(ident) 985 986 #--- eth_reg_value ---------------------------------------------------------- 987 def eth_reg_value(self, ident, type, value, ethname=None): 988 #print "eth_reg_value(ident='%s')" % (ident) 989 if ident in self.value: 990 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) : 991 # replace imported value 992 del self.value[ident] 993 self.value_imp.remove(ident) 994 elif ethname: 995 self.value[ident]['ethname'] = ethname 996 return 997 else: 998 raise DuplicateError("value", ident) 999 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto, 1000 'type' : type, 'value' : value, 1001 'no_emit' : False } 1002 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident) 1003 self.value[ident]['ethname'] = '' 1004 if (ethname): self.value[ident]['ethname'] = ethname 1005 self.value_ord.append(ident) 1006 1007 #--- eth_reg_field ---------------------------------------------------------- 1008 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None): 1009 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type) 1010 if ident in self.field: 1011 if pdu and (type == self.field[ident]['type']): 1012 pass # OK already created PDU 1013 else: 1014 raise DuplicateError("field", ident) 1015 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu, 1016 'modified' : '', 'attr' : {} } 1017 name = ident.split('/')[-1] 1018 if self.remove_prefix and name.startswith(self.remove_prefix): 1019 name = name[len(self.remove_prefix):] 1020 1021 if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type 1022 if len(self.field[ident]['type'].split('/')) > 1: 1023 self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2] 1024 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name) 1025 else: 1026 self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type'] 1027 self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type']) 1028 else: 1029 self.field[ident]['attr']['NAME'] = '"%s"' % name 1030 self.field[ident]['attr']['ABBREV'] = asn2c(name) 1031 if self.conform.check_item('FIELD_ATTR', ident): 1032 self.field[ident]['modified'] = '#' + str(id(self)) 1033 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident)) 1034 if (pdu): 1035 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0) 1036 self.pdu_ord.append(ident) 1037 else: 1038 self.field_ord.append(ident) 1039 if parent: 1040 self.eth_dep_add(parent, type) 1041 1042 def eth_dummy_eag_field_required(self): 1043 if (not self.dummy_eag_field): 1044 self.dummy_eag_field = 'eag_field' 1045 1046 #--- eth_clean -------------------------------------------------------------- 1047 def eth_clean(self): 1048 self.proto = self.proto_opt; 1049 #--- ASN.1 tables ---------------- 1050 self.assign = {} 1051 self.assign_ord = [] 1052 self.field = {} 1053 self.pdu_ord = [] 1054 self.field_ord = [] 1055 self.type = {} 1056 self.type_ord = [] 1057 self.type_imp = [] 1058 self.type_dep = {} 1059 self.sel_req = {} 1060 self.sel_req_ord = [] 1061 self.comp_req_ord = [] 1062 self.vassign = {} 1063 self.vassign_ord = [] 1064 self.value = {} 1065 self.value_ord = [] 1066 self.value_imp = [] 1067 self.objectclass = {} 1068 self.objectclass_ord = [] 1069 self.objectclass_imp = [] 1070 self.oassign = {} 1071 self.oassign_ord = [] 1072 self.oassign_cls = {} 1073 #--- Modules ------------ 1074 self.modules = [] 1075 self.exports_all = False 1076 self.exports = [] 1077 self.cexports = [] 1078 self.vexports = [] 1079 #--- types ------------------- 1080 self.eth_type = {} 1081 self.eth_type_ord = [] 1082 self.eth_export_ord = [] 1083 self.eth_type_dupl = {} 1084 self.named_bit = [] 1085 #--- value dependencies ------------------- 1086 self.value_dep = {} 1087 #--- values ------------------- 1088 self.eth_value = {} 1089 self.eth_value_ord = [] 1090 #--- fields ------------------------- 1091 self.eth_hf = {} 1092 self.eth_hf_ord = [] 1093 self.eth_hfpdu_ord = [] 1094 self.eth_hf_dupl = {} 1095 self.dummy_eag_field = None 1096 #--- type dependencies ------------------- 1097 self.eth_type_ord1 = [] 1098 self.eth_dep_cycle = [] 1099 self.dep_cycle_eth_type = {} 1100 #--- value dependencies and export ------------------- 1101 self.eth_value_ord1 = [] 1102 self.eth_vexport_ord = [] 1103 1104 #--- eth_prepare ------------------------------------------------------------ 1105 def eth_prepare(self): 1106 self.eproto = asn2c(self.proto) 1107 1108 #--- dummy types/fields for PDU registration --- 1109 nm = 'NULL' 1110 if (self.conform.check_item('PDU', nm)): 1111 self.eth_reg_type('_dummy/'+nm, NullType()) 1112 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm)) 1113 1114 #--- required PDUs ---------------------------- 1115 for t in self.type_ord: 1116 pdu = self.type[t]['val'].eth_need_pdu(self) 1117 if not pdu: continue 1118 f = pdu['type'] 1119 pdu['reg'] = None 1120 pdu['hidden'] = False 1121 pdu['need_decl'] = True 1122 if f not in self.field: 1123 self.eth_reg_field(f, f, pdu=pdu) 1124 1125 #--- values -> named values ------------------- 1126 t_for_update = {} 1127 for v in self.value_ord: 1128 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v): 1129 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v): 1130 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v) 1131 else: 1132 tnm = self.value[v]['type'].val 1133 if tnm in self.type \ 1134 and not self.type[tnm]['import'] \ 1135 and (self.type[tnm]['val'].type == 'IntegerType'): 1136 self.type[tnm]['val'].add_named_value(v, self.value[v]['value']) 1137 self.value[v]['no_emit'] = True 1138 t_for_update[tnm] = True 1139 for t in list(t_for_update.keys()): 1140 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings() 1141 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t)) 1142 1143 #--- required components of --------------------------- 1144 #print "self.comp_req_ord = ", self.comp_req_ord 1145 for t in self.comp_req_ord: 1146 self.type[t]['val'].eth_reg_sub(t, self, components_available=True) 1147 1148 #--- required selection types --------------------------- 1149 #print "self.sel_req_ord = ", self.sel_req_ord 1150 for t in self.sel_req_ord: 1151 tt = self.sel_req[t]['typ'] 1152 if tt not in self.type: 1153 self.dummy_import_type(t) 1154 elif self.type[tt]['import']: 1155 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto']) 1156 else: 1157 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self) 1158 1159 #--- types ------------------- 1160 for t in self.type_imp: # imported types 1161 nm = asn2c(t) 1162 self.eth_type[nm] = { 'import' : self.type[t]['import'], 1163 'proto' : asn2c(self.type[t]['proto']), 1164 'attr' : {}, 'ref' : []} 1165 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm)) 1166 self.type[t]['ethname'] = nm 1167 for t in self.type_ord: # dummy import for missing type reference 1168 tp = self.type[t]['val'] 1169 #print "X : %s %s " % (t, tp.type) 1170 if isinstance(tp, TaggedType): 1171 #print "%s : %s " % (tp.type, t) 1172 tp = tp.val 1173 if isinstance(tp, Type_Ref): 1174 #print "%s : %s ::= %s " % (tp.type, t, tp.val) 1175 if tp.val not in self.type: 1176 self.dummy_import_type(tp.val) 1177 for t in self.type_ord: 1178 nm = self.type[t]['tname'] 1179 if ((nm.find('#') >= 0) or 1180 ((len(t.split('/'))>1) and 1181 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or 1182 self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and 1183 not self.conform.check_item('TYPE_RENAME', t))): 1184 if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level 1185 nm = t.split('/')[0] + t.split('/')[1] 1186 elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels 1187 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1] 1188 elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type 1189 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U' 1190 else: 1191 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1]) 1192 nm = asn2c(nm) 1193 if nm in self.eth_type: 1194 if nm in self.eth_type_dupl: 1195 self.eth_type_dupl[nm].append(t) 1196 else: 1197 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t] 1198 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1) 1199 if nm in self.eth_type: 1200 self.eth_type[nm]['ref'].append(t) 1201 else: 1202 self.eth_type_ord.append(nm) 1203 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0, 1204 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS, 1205 'val' : self.type[t]['val'], 1206 'attr' : {}, 'ref' : [t]} 1207 self.type[t]['ethname'] = nm 1208 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export 1209 self.eth_export_ord.append(nm) 1210 self.eth_type[nm]['export'] |= self.type[t]['export'] 1211 self.eth_type[nm]['enum'] |= self.type[t]['enum'] 1212 self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext'] 1213 self.eth_type[nm]['user_def'] &= self.type[t]['user_def'] 1214 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit'] 1215 if self.type[t]['attr'].get('STRINGS') == '$$': 1216 use_ext = self.type[t]['vals_ext'] 1217 if (use_ext): 1218 self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm)) 1219 else: 1220 if self.eth_type[nm]['val'].type == 'IntegerType' \ 1221 and self.eth_type[nm]['val'].HasConstraint() \ 1222 and self.eth_type[nm]['val'].constr.Needs64b(self): 1223 self.eth_type[nm]['attr']['STRINGS'] = 'VALS64(%s)' % (self.eth_vals_nm(nm)) 1224 else: 1225 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm)) 1226 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm)) 1227 for t in self.eth_type_ord: 1228 bits = self.eth_type[t]['val'].eth_named_bits() 1229 if (bits): 1230 old_val = 0 1231 for (val, id) in bits: 1232 self.named_bit.append({'name' : id, 'val' : val, 1233 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)), 1234 'ftype' : 'FT_BOOLEAN', 'display' : '8', 1235 'strings' : 'NULL', 1236 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]}) 1237 old_val = val + 1 1238 if self.eth_type[t]['val'].eth_need_tree(): 1239 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t) 1240 else: 1241 self.eth_type[t]['tree'] = None 1242 1243 #--- register values from enums ------------ 1244 for t in self.eth_type_ord: 1245 if (self.eth_type[t]['val'].eth_has_enum(t, self)): 1246 self.eth_type[t]['val'].reg_enum_vals(t, self) 1247 1248 #--- value dependencies ------------------- 1249 for v in self.value_ord: 1250 if isinstance (self.value[v]['value'], Value): 1251 dep = self.value[v]['value'].get_dep() 1252 else: 1253 dep = self.value[v]['value'] 1254 if dep and dep in self.value: 1255 self.value_dep.setdefault(v, []).append(dep) 1256 1257 #--- exports all necessary values 1258 for v in self.value_ord: 1259 if not self.value[v]['export']: continue 1260 deparr = self.value_dep.get(v, []) 1261 while deparr: 1262 d = deparr.pop() 1263 if not self.value[d]['import']: 1264 if not self.value[d]['export']: 1265 self.value[d]['export'] = EF_TYPE 1266 deparr.extend(self.value_dep.get(d, [])) 1267 1268 #--- values ------------------- 1269 for v in self.value_imp: 1270 nm = asn2c(v) 1271 self.eth_value[nm] = { 'import' : self.value[v]['import'], 1272 'proto' : asn2c(self.value[v]['proto']), 1273 'ref' : []} 1274 self.value[v]['ethname'] = nm 1275 for v in self.value_ord: 1276 if (self.value[v]['ethname']): 1277 continue 1278 if (self.value[v]['no_emit']): 1279 continue 1280 nm = asn2c(v) 1281 self.eth_value[nm] = { 'import' : None, 1282 'proto' : asn2c(self.value[v]['proto']), 1283 'export' : self.value[v]['export'], 'ref' : [v] } 1284 self.eth_value[nm]['value'] = self.value[v]['value'] 1285 self.eth_value_ord.append(nm) 1286 self.value[v]['ethname'] = nm 1287 1288 #--- fields ------------------------- 1289 for f in (self.pdu_ord + self.field_ord): 1290 if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type 1291 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1] 1292 else: 1293 nm = f.split('/')[-1] 1294 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm) 1295 nm = asn2c(nm) 1296 if (self.field[f]['pdu']): 1297 nm += '_PDU' 1298 if (not self.merge_modules or self.field[f]['pdu']['export']): 1299 nm = self.eproto + '_' + nm 1300 t = self.field[f]['type'] 1301 if t in self.type: 1302 ethtype = self.type[t]['ethname'] 1303 else: # undefined type 1304 ethtype = self.dummy_import_type(t) 1305 ethtypemod = ethtype + self.field[f]['modified'] 1306 if nm in self.eth_hf: 1307 if nm in self.eth_hf_dupl: 1308 if ethtypemod in self.eth_hf_dupl[nm]: 1309 nm = self.eth_hf_dupl[nm][ethtypemod] 1310 self.eth_hf[nm]['ref'].append(f) 1311 self.field[f]['ethname'] = nm 1312 continue 1313 else: 1314 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm]))) 1315 self.eth_hf_dupl[nm][ethtype] = nmx 1316 nm = nmx 1317 else: 1318 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod: 1319 self.eth_hf[nm]['ref'].append(f) 1320 self.field[f]['ethname'] = nm 1321 continue 1322 else: 1323 nmx = nm + '_01' 1324 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \ 1325 ethtypemod : nmx} 1326 nm = nmx 1327 if (self.field[f]['pdu']): 1328 self.eth_hfpdu_ord.append(nm) 1329 else: 1330 self.eth_hf_ord.append(nm) 1331 fullname = 'hf_%s_%s' % (self.eproto, nm) 1332 attr = self.eth_get_type_attr(self.field[f]['type']).copy() 1333 attr.update(self.field[f]['attr']) 1334 if (self.NAPI() and 'NAME' in attr): 1335 attr['NAME'] += self.field[f]['idx'] 1336 attr.update(self.conform.use_item('EFIELD_ATTR', nm)) 1337 use_vals_ext = self.eth_type[ethtype].get('vals_ext') 1338 if (use_vals_ext): 1339 attr['DISPLAY'] += '|BASE_EXT_STRING' 1340 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'], 1341 'ethtype' : ethtype, 'modified' : self.field[f]['modified'], 1342 'attr' : attr.copy(), 1343 'ref' : [f]} 1344 self.field[f]['ethname'] = nm 1345 if (self.dummy_eag_field): 1346 # Prepending "dummy_" avoids matching checkhf.pl. 1347 self.dummy_eag_field = 'dummy_hf_%s_%s' % (self.eproto, self.dummy_eag_field) 1348 #--- type dependencies ------------------- 1349 (self.eth_type_ord1, self.eth_dep_cycle) = dependency_compute(self.type_ord, self.type_dep, map_fn = lambda t: self.type[t]['ethname'], ignore_fn = lambda t: self.type[t]['import']) 1350 i = 0 1351 while i < len(self.eth_dep_cycle): 1352 t = self.type[self.eth_dep_cycle[i][0]]['ethname'] 1353 self.dep_cycle_eth_type.setdefault(t, []).append(i) 1354 i += 1 1355 1356 #--- value dependencies and export ------------------- 1357 for v in self.eth_value_ord: 1358 if self.eth_value[v]['export']: 1359 self.eth_vexport_ord.append(v) 1360 else: 1361 self.eth_value_ord1.append(v) 1362 1363 #--- export tags, values, ... --- 1364 for t in self.exports: 1365 if t not in self.type: 1366 continue 1367 if self.type[t]['import']: 1368 continue 1369 m = self.type[t]['module'] 1370 if not self.Per() and not self.Oer(): 1371 if m not in self.all_tags: 1372 self.all_tags[m] = {} 1373 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self) 1374 if m not in self.all_type_attr: 1375 self.all_type_attr[m] = {} 1376 self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy() 1377 for v in self.vexports: 1378 if v not in self.value: 1379 continue 1380 if self.value[v]['import']: 1381 continue 1382 m = self.value[v]['module'] 1383 if m not in self.all_vals: 1384 self.all_vals[m] = {} 1385 vv = self.value[v]['value'] 1386 if isinstance (vv, Value): 1387 vv = vv.to_str(self) 1388 self.all_vals[m][v] = vv 1389 1390 #--- eth_vals_nm ------------------------------------------------------------ 1391 def eth_vals_nm(self, tname): 1392 out = "" 1393 if (not self.eth_type[tname]['export'] & EF_NO_PROT): 1394 out += "%s_" % (self.eproto) 1395 out += "%s_vals" % (tname) 1396 return out 1397 1398 #--- eth_vals --------------------------------------------------------------- 1399 def eth_vals(self, tname, vals): 1400 out = "" 1401 has_enum = self.eth_type[tname]['enum'] & EF_ENUM 1402 use_ext = self.eth_type[tname]['vals_ext'] 1403 if (use_ext): 1404 vals.sort(key=lambda vals_entry: int(vals_entry[0])) 1405 if (not self.eth_type[tname]['export'] & EF_VALS): 1406 out += 'static ' 1407 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE): 1408 out += 'static ' 1409 if self.eth_type[tname]['val'].HasConstraint() and self.eth_type[tname]['val'].constr.Needs64b(self) \ 1410 and self.eth_type[tname]['val'].type == 'IntegerType': 1411 out += "const val64_string %s[] = {\n" % (self.eth_vals_nm(tname)) 1412 else: 1413 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname)) 1414 for (val, id) in vals: 1415 if (has_enum): 1416 vval = self.eth_enum_item(tname, id) 1417 else: 1418 vval = val 1419 out += ' { %3s, "%s" },\n' % (vval, id) 1420 out += " { 0, NULL }\n};\n" 1421 if (use_ext): 1422 out += "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self.eth_vals_nm(tname), self.eth_vals_nm(tname)) 1423 return out 1424 1425 #--- eth_enum_prefix ------------------------------------------------------------ 1426 def eth_enum_prefix(self, tname, type=False): 1427 out = "" 1428 if (self.eth_type[tname]['export'] & EF_ENUM): 1429 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT 1430 else: 1431 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT 1432 if (not no_prot): 1433 out += self.eproto 1434 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type): 1435 if (out): out += '_' 1436 out += tname 1437 if (self.eth_type[tname]['enum'] & EF_UCASE): 1438 out = out.upper() 1439 if (out): out += '_' 1440 return out 1441 1442 #--- eth_enum_nm ------------------------------------------------------------ 1443 def eth_enum_nm(self, tname): 1444 out = self.eth_enum_prefix(tname, type=True) 1445 out += "enum" 1446 return out 1447 1448 #--- eth_enum_item --------------------------------------------------------------- 1449 def eth_enum_item(self, tname, ident): 1450 out = self.eth_enum_prefix(tname) 1451 out += asn2c(ident) 1452 if (self.eth_type[tname]['enum'] & EF_UCASE): 1453 out = out.upper() 1454 return out 1455 1456 #--- eth_enum --------------------------------------------------------------- 1457 def eth_enum(self, tname, vals): 1458 out = "" 1459 if (self.eth_type[tname]['enum'] & EF_DEFINE): 1460 out += "/* enumerated values for %s */\n" % (tname) 1461 for (val, id) in vals: 1462 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val) 1463 else: 1464 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname)) 1465 first_line = 1 1466 for (val, id) in vals: 1467 if (first_line == 1): 1468 first_line = 0 1469 else: 1470 out += ",\n" 1471 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val) 1472 out += "\n} %s;\n" % (self.eth_enum_nm(tname)) 1473 return out 1474 1475 #--- eth_bits --------------------------------------------------------------- 1476 def eth_bits(self, tname, bits): 1477 out = "" 1478 out += "static int * const " 1479 out += "%(TABLE)s[] = {\n" 1480 for (val, id) in bits: 1481 out += ' &hf_%s_%s_%s,\n' % (self.eproto, tname, asn2c(id)) 1482 out += " NULL\n};\n" 1483 return out 1484 1485 #--- eth_type_fn_h ---------------------------------------------------------- 1486 def eth_type_fn_h(self, tname): 1487 out = "" 1488 if (not self.eth_type[tname]['export'] & EF_TYPE): 1489 out += 'static ' 1490 out += "int " 1491 if (self.Ber()): 1492 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname) 1493 elif (self.Per() or self.Oer()): 1494 out += "dissect_%s_%s(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname) 1495 out += ";\n" 1496 return out 1497 1498 #--- eth_fn_call ------------------------------------------------------------ 1499 def eth_fn_call(self, fname, ret=None, indent=2, par=None): 1500 out = indent * ' ' 1501 if (ret): 1502 if (ret == 'return'): 1503 out += 'return ' 1504 else: 1505 out += ret + ' = ' 1506 out += fname + '(' 1507 ind = len(out) 1508 for i in range(len(par)): 1509 if (i>0): out += ind * ' ' 1510 out += ', '.join(par[i]) 1511 if (i<(len(par)-1)): out += ',\n' 1512 out += ');\n' 1513 return out 1514 1515 def output_proto_root(self): 1516 out = '' 1517 if self.conform.proto_root_name: 1518 out += ' proto_item *prot_ti = proto_tree_add_item(tree, ' + self.conform.proto_root_name + ', tvb, 0, -1, ENC_NA);\n' 1519 out += ' proto_item_set_hidden(prot_ti);\n' 1520 return out 1521 1522 #--- eth_type_fn_hdr -------------------------------------------------------- 1523 def eth_type_fn_hdr(self, tname): 1524 out = '\n' 1525 if (not self.eth_type[tname]['export'] & EF_TYPE): 1526 out += 'static ' 1527 out += "int\n" 1528 if (self.Ber()): 1529 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname) 1530 elif (self.Per() or self.Oer()): 1531 out += "dissect_%s_%s(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname) 1532 #if self.conform.get_fn_presence(tname): 1533 # out += self.conform.get_fn_text(tname, 'FN_HDR') 1534 #el 1535 if self.conform.check_item('PDU', tname): 1536 out += self.output_proto_root() 1537 1538 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]): 1539 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR') 1540 return out 1541 1542 #--- eth_type_fn_ftr -------------------------------------------------------- 1543 def eth_type_fn_ftr(self, tname): 1544 out = '\n' 1545 #if self.conform.get_fn_presence(tname): 1546 # out += self.conform.get_fn_text(tname, 'FN_FTR') 1547 #el 1548 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]): 1549 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR') 1550 out += " return offset;\n" 1551 out += "}\n" 1552 return out 1553 1554 #--- eth_type_fn_body ------------------------------------------------------- 1555 def eth_type_fn_body(self, tname, body, pars=None): 1556 out = body 1557 #if self.conform.get_fn_body_presence(tname): 1558 # out = self.conform.get_fn_text(tname, 'FN_BODY') 1559 #el 1560 if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]): 1561 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY') 1562 if pars: 1563 try: 1564 out = out % pars 1565 except (TypeError): 1566 pass 1567 return out 1568 1569 #--- eth_out_pdu_decl ---------------------------------------------------------- 1570 def eth_out_pdu_decl(self, f): 1571 t = self.eth_hf[f]['ethtype'] 1572 out = '' 1573 if (not self.eth_hf[f]['pdu']['export']): 1574 out += 'static ' 1575 out += 'int ' 1576 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n' 1577 return out 1578 1579 #--- eth_output_hf ---------------------------------------------------------- 1580 def eth_output_hf (self): 1581 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return 1582 fx = self.output.file_open('hf') 1583 for f in (self.eth_hfpdu_ord + self.eth_hf_ord): 1584 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype'])) 1585 if (self.named_bit): 1586 fx.write('/* named bits */\n') 1587 for nb in self.named_bit: 1588 fx.write("static int %s = -1;\n" % (nb['ethname'])) 1589 if (self.dummy_eag_field): 1590 fx.write("static int %s = -1; /* never registered */\n" % (self.dummy_eag_field)) 1591 self.output.file_close(fx) 1592 1593 #--- eth_output_hf_arr ------------------------------------------------------ 1594 def eth_output_hf_arr (self): 1595 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return 1596 fx = self.output.file_open('hfarr') 1597 for f in (self.eth_hfpdu_ord + self.eth_hf_ord): 1598 t = self.eth_hf[f]['ethtype'] 1599 if self.remove_prefix and t.startswith(self.remove_prefix): 1600 t = t[len(self.remove_prefix):] 1601 name=self.eth_hf[f]['attr']['NAME'] 1602 try: # Python < 3 1603 trantab = maketrans("- ", "__") 1604 except Exception: 1605 trantab = str.maketrans("- ", "__") 1606 name = name.translate(trantab) 1607 namelower = name.lower() 1608 tquoted_lower = '"' + t.lower() + '"' 1609 # Try to avoid giving blurbs that give no more info than the name 1610 if tquoted_lower == namelower or \ 1611 t == "NULL" or \ 1612 tquoted_lower.replace("t_", "") == namelower: 1613 blurb = 'NULL' 1614 else: 1615 blurb = '"%s"' % (t) 1616 attr = self.eth_hf[f]['attr'].copy() 1617 if attr['TYPE'] == 'FT_NONE': 1618 attr['ABBREV'] = '"%s.%s_element"' % (self.proto, attr['ABBREV']) 1619 else: 1620 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV']) 1621 if 'BLURB' not in attr: 1622 attr['BLURB'] = blurb 1623 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname'])) 1624 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr) 1625 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr) 1626 fx.write(' %(BLURB)s, HFILL }},\n' % attr) 1627 for nb in self.named_bit: 1628 flt_str = nb['ethname'] 1629 # cut out hf_ 1630 flt_str = flt_str[3:] 1631 flt_str = flt_str.replace('_' , '.') 1632 #print("filter string=%s" % (flt_str)) 1633 fx.write(' { &%s,\n' % (nb['ethname'])) 1634 fx.write(' { "%s", "%s",\n' % (nb['name'], flt_str)) 1635 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask'])) 1636 fx.write(' NULL, HFILL }},\n') 1637 self.output.file_close(fx) 1638 1639 #--- eth_output_ett --------------------------------------------------------- 1640 def eth_output_ett (self): 1641 fx = self.output.file_open('ett') 1642 fempty = True 1643 #fx.write("static gint ett_%s = -1;\n" % (self.eproto)) 1644 for t in self.eth_type_ord: 1645 if self.eth_type[t]['tree']: 1646 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree'])) 1647 fempty = False 1648 self.output.file_close(fx, discard=fempty) 1649 1650 #--- eth_output_ett_arr ----------------------------------------------------- 1651 def eth_output_ett_arr(self): 1652 fx = self.output.file_open('ettarr') 1653 fempty = True 1654 #fx.write(" &ett_%s,\n" % (self.eproto)) 1655 for t in self.eth_type_ord: 1656 if self.eth_type[t]['tree']: 1657 fx.write(" &%s,\n" % (self.eth_type[t]['tree'])) 1658 fempty = False 1659 self.output.file_close(fx, discard=fempty) 1660 1661 #--- eth_output_export ------------------------------------------------------ 1662 def eth_output_export(self): 1663 fx = self.output.file_open('exp', ext='h') 1664 for t in self.eth_export_ord: # vals 1665 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self): 1666 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self)) 1667 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals(): 1668 if not self.eth_type[t]['export'] & EF_TABLE: 1669 if self.eth_type[t]['export'] & EF_WS_DLL: 1670 fx.write("WS_DLL_PUBLIC ") 1671 else: 1672 fx.write("extern ") 1673 if self.eth_type[t]['val'].HasConstraint() and self.eth_type[t]['val'].constr.Needs64b(self) \ 1674 and self.eth_type[t]['val'].type == 'IntegerType': 1675 fx.write("const val64_string %s[];\n" % (self.eth_vals_nm(t))) 1676 else: 1677 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t))) 1678 else: 1679 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self)) 1680 for t in self.eth_export_ord: # functions 1681 if (self.eth_type[t]['export'] & EF_TYPE): 1682 if self.eth_type[t]['export'] & EF_EXTERN: 1683 if self.eth_type[t]['export'] & EF_WS_DLL: 1684 fx.write("WS_DLL_PUBLIC ") 1685 else: 1686 fx.write("extern ") 1687 fx.write(self.eth_type_fn_h(t)) 1688 for f in self.eth_hfpdu_ord: # PDUs 1689 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']): 1690 fx.write(self.eth_out_pdu_decl(f)) 1691 self.output.file_close(fx) 1692 1693 #--- eth_output_expcnf ------------------------------------------------------ 1694 def eth_output_expcnf(self): 1695 fx = self.output.file_open('exp', ext='cnf') 1696 fx.write('#.MODULE\n') 1697 maxw = 0 1698 for (m, p) in self.modules: 1699 if (len(m) > maxw): maxw = len(m) 1700 for (m, p) in self.modules: 1701 fx.write("%-*s %s\n" % (maxw, m, p)) 1702 fx.write('#.END\n\n') 1703 for cls in self.objectclass_ord: 1704 if self.objectclass[cls]['export']: 1705 cnm = cls 1706 if self.objectclass[cls]['export'] & EF_MODULE: 1707 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm) 1708 fx.write('#.CLASS %s\n' % (cnm)) 1709 maxw = 2 1710 for fld in self.objectclass[cls]['val'].fields: 1711 w = len(fld.fld_repr()[0]) 1712 if (w > maxw): maxw = w 1713 for fld in self.objectclass[cls]['val'].fields: 1714 repr = fld.fld_repr() 1715 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:]))) 1716 fx.write('#.END\n\n') 1717 if self.Ber(): 1718 fx.write('#.IMPORT_TAG\n') 1719 for t in self.eth_export_ord: # tags 1720 if (self.eth_type[t]['export'] & EF_TYPE): 1721 fx.write('%-24s ' % self.eth_type[t]['ref'][0]) 1722 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self)) 1723 fx.write('#.END\n\n') 1724 fx.write('#.TYPE_ATTR\n') 1725 for t in self.eth_export_ord: # attributes 1726 if (self.eth_type[t]['export'] & EF_TYPE): 1727 tnm = self.eth_type[t]['ref'][0] 1728 if self.eth_type[t]['export'] & EF_MODULE: 1729 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm) 1730 fx.write('%-24s ' % tnm) 1731 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy() 1732 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr) 1733 fx.write('#.END\n\n') 1734 self.output.file_close(fx, keep_anyway=True) 1735 1736 #--- eth_output_val ------------------------------------------------------ 1737 def eth_output_val(self): 1738 fx = self.output.file_open('val', ext='h') 1739 for v in self.eth_value_ord1: 1740 vv = self.eth_value[v]['value'] 1741 if isinstance (vv, Value): 1742 vv = vv.to_str(self) 1743 fx.write("#define %-30s %s\n" % (v, vv)) 1744 for t in self.eth_type_ord1: 1745 if self.eth_type[t]['import']: 1746 continue 1747 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM): 1748 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self)) 1749 self.output.file_close(fx) 1750 1751 #--- eth_output_valexp ------------------------------------------------------ 1752 def eth_output_valexp(self): 1753 if (not len(self.eth_vexport_ord)): return 1754 fx = self.output.file_open('valexp', ext='h') 1755 for v in self.eth_vexport_ord: 1756 vv = self.eth_value[v]['value'] 1757 if isinstance (vv, Value): 1758 vv = vv.to_str(self) 1759 fx.write("#define %-30s %s\n" % (v, vv)) 1760 self.output.file_close(fx) 1761 1762 #--- eth_output_types ------------------------------------------------------- 1763 def eth_output_types(self): 1764 def out_pdu(f): 1765 t = self.eth_hf[f]['ethtype'] 1766 impl = 'FALSE' 1767 out = '' 1768 if (not self.eth_hf[f]['pdu']['export']): 1769 out += 'static ' 1770 out += 'int ' 1771 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n' 1772 out += self.output_proto_root() 1773 1774 out += ' int offset = 0;\n' 1775 off_par = 'offset' 1776 ret_par = 'offset' 1777 if (self.Per()): 1778 if (self.Aligned()): 1779 aligned = 'TRUE' 1780 else: 1781 aligned = 'FALSE' 1782 out += " asn1_ctx_t asn1_ctx;\n" 1783 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),)) 1784 if (self.Ber()): 1785 out += " asn1_ctx_t asn1_ctx;\n" 1786 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),)) 1787 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),) 1788 elif (self.Per()): 1789 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),) 1790 elif (self.Oer()): 1791 out += " asn1_ctx_t asn1_ctx;\n" 1792 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_OER', 'TRUE', 'pinfo'),)) 1793 par=(('tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),) 1794 else: 1795 par=((),) 1796 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par) 1797 if (self.Per()): 1798 out += ' offset += 7; offset >>= 3;\n' 1799 out += ' return offset;\n' 1800 out += '}\n' 1801 return out 1802 #end out_pdu() 1803 fx = self.output.file_open('fn') 1804 pos = fx.tell() 1805 if (len(self.eth_hfpdu_ord)): 1806 first_decl = True 1807 for f in self.eth_hfpdu_ord: 1808 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']): 1809 if first_decl: 1810 fx.write('/*--- PDUs declarations ---*/\n') 1811 first_decl = False 1812 fx.write(self.eth_out_pdu_decl(f)) 1813 if not first_decl: 1814 fx.write('\n') 1815 if self.eth_dep_cycle: 1816 fx.write('/*--- Cyclic dependencies ---*/\n\n') 1817 i = 0 1818 while i < len(self.eth_dep_cycle): 1819 t = self.type[self.eth_dep_cycle[i][0]]['ethname'] 1820 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue 1821 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]])) 1822 if not self.eth_type[t]['export'] & EF_TYPE: 1823 fx.write(self.eth_type_fn_h(t)) 1824 else: 1825 fx.write('/*' + self.eth_type_fn_h(t).strip() + '*/\n') 1826 fx.write('\n') 1827 i += 1 1828 fx.write('\n') 1829 for t in self.eth_type_ord1: 1830 if self.eth_type[t]['import']: 1831 continue 1832 if self.eth_type[t]['val'].eth_has_vals(): 1833 if self.eth_type[t]['no_emit'] & EF_VALS: 1834 pass 1835 elif self.eth_type[t]['user_def'] & EF_VALS: 1836 if self.eth_type[t]['val'].HasConstraint() and self.eth_type[t]['val'].constr.Needs64b(self) \ 1837 and self.eth_type[t]['val'].type == 'IntegerType': 1838 fx.write("extern const val64_string %s[];\n" % (self.eth_vals_nm(t))) 1839 else: 1840 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t))) 1841 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE): 1842 pass 1843 else: 1844 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self)) 1845 if self.eth_type[t]['no_emit'] & EF_TYPE: 1846 pass 1847 elif self.eth_type[t]['user_def'] & EF_TYPE: 1848 fx.write(self.eth_type_fn_h(t)) 1849 else: 1850 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self)) 1851 fx.write('\n') 1852 if (len(self.eth_hfpdu_ord)): 1853 fx.write('/*--- PDUs ---*/\n\n') 1854 for f in self.eth_hfpdu_ord: 1855 if (self.eth_hf[f]['pdu']): 1856 if (f in self.emitted_pdu): 1857 fx.write(" /* %s already emitted */\n" % (f)) 1858 else: 1859 fx.write(out_pdu(f)) 1860 self.emitted_pdu[f] = True 1861 fx.write('\n') 1862 fempty = pos == fx.tell() 1863 self.output.file_close(fx, discard=fempty) 1864 1865 #--- eth_output_dis_hnd ----------------------------------------------------- 1866 def eth_output_dis_hnd(self): 1867 fx = self.output.file_open('dis-hnd') 1868 fempty = True 1869 for f in self.eth_hfpdu_ord: 1870 pdu = self.eth_hf[f]['pdu'] 1871 if (pdu and pdu['reg'] and not pdu['hidden']): 1872 dis = self.proto 1873 if (pdu['reg'] != '.'): 1874 dis += '.' + pdu['reg'] 1875 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis))) 1876 fempty = False 1877 fx.write('\n') 1878 self.output.file_close(fx, discard=fempty) 1879 1880 #--- eth_output_dis_reg ----------------------------------------------------- 1881 def eth_output_dis_reg(self): 1882 fx = self.output.file_open('dis-reg') 1883 fempty = True 1884 for f in self.eth_hfpdu_ord: 1885 pdu = self.eth_hf[f]['pdu'] 1886 if (pdu and pdu['reg']): 1887 new_prefix = '' 1888 if (pdu['new']): new_prefix = 'new_' 1889 dis = self.proto 1890 if (pdu['reg'] != '.'): dis += '.' + pdu['reg'] 1891 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto)) 1892 if (not pdu['hidden']): 1893 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis)) 1894 fempty = False 1895 fx.write('\n') 1896 self.output.file_close(fx, discard=fempty) 1897 1898 #--- eth_output_dis_tab ----------------------------------------------------- 1899 def eth_output_dis_tab(self): 1900 fx = self.output.file_open('dis-tab') 1901 fempty = True 1902 for k in self.conform.get_order('REGISTER'): 1903 reg = self.conform.use_item('REGISTER', k) 1904 if reg['pdu'] not in self.field: continue 1905 f = self.field[reg['pdu']]['ethname'] 1906 pdu = self.eth_hf[f]['pdu'] 1907 new_prefix = '' 1908 if (pdu['new']): new_prefix = 'new_' 1909 if (reg['rtype'] in ('NUM', 'STR')): 1910 rstr = '' 1911 if (reg['rtype'] == 'STR'): 1912 rstr = 'string' 1913 else: 1914 rstr = 'uint' 1915 if (pdu['reg']): 1916 dis = self.proto 1917 if (pdu['reg'] != '.'): dis += '.' + pdu['reg'] 1918 if (not pdu['hidden']): 1919 hnd = '%s_handle' % (asn2c(dis)) 1920 else: 1921 hnd = 'find_dissector("%s")' % (dis) 1922 else: 1923 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto) 1924 rport = self.value_get_eth(reg['rport']) 1925 fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd)) 1926 elif (reg['rtype'] in ('BER', 'PER', 'OER')): 1927 roid = self.value_get_eth(reg['roid']) 1928 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname'])) 1929 fempty = False 1930 fx.write('\n') 1931 self.output.file_close(fx, discard=fempty) 1932 1933 #--- eth_output_syn_reg ----------------------------------------------------- 1934 def eth_output_syn_reg(self): 1935 fx = self.output.file_open('syn-reg') 1936 fempty = True 1937 first_decl = True 1938 for k in self.conform.get_order('SYNTAX'): 1939 reg = self.conform.use_item('SYNTAX', k) 1940 if reg['pdu'] not in self.field: continue 1941 f = self.field[reg['pdu']]['ethname'] 1942 pdu = self.eth_hf[f]['pdu'] 1943 new_prefix = '' 1944 if (pdu['new']): new_prefix = 'new_' 1945 if first_decl: 1946 fx.write(' /*--- Syntax registrations ---*/\n') 1947 first_decl = False 1948 fx.write(' %sregister_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (new_prefix, k, self.eproto, reg['pdu'])); 1949 fempty=False 1950 self.output.file_close(fx, discard=fempty) 1951 1952 #--- eth_output_tables ----------------------------------------------------- 1953 def eth_output_tables(self): 1954 for num in list(self.conform.report.keys()): 1955 fx = self.output.file_open('table' + num) 1956 for rep in self.conform.report[num]: 1957 self.eth_output_table(fx, rep) 1958 self.output.file_close(fx) 1959 1960 #--- eth_output_table ----------------------------------------------------- 1961 def eth_output_table(self, fx, rep): 1962 if rep['type'] == 'HDR': 1963 fx.write('\n') 1964 if rep['var']: 1965 var = rep['var'] 1966 var_list = var.split('.', 1) 1967 cls = var_list[0] 1968 del var_list[0] 1969 flds = [] 1970 not_flds = [] 1971 sort_flds = [] 1972 for f in var_list: 1973 if f[0] == '!': 1974 not_flds.append(f[1:]) 1975 continue 1976 if f[0] == '#': 1977 flds.append(f[1:]) 1978 sort_flds.append(f) 1979 continue 1980 if f[0] == '@': 1981 flds.append(f[1:]) 1982 sort_flds.append(f[1:]) 1983 continue 1984 flds.append(f) 1985 objs = {} 1986 objs_ord = [] 1987 if (cls in self.oassign_cls): 1988 for ident in self.oassign_cls[cls]: 1989 obj = self.get_obj_repr(ident, flds, not_flds) 1990 if not obj: 1991 continue 1992 obj['_LOOP'] = var 1993 obj['_DICT'] = str(obj) 1994 objs[ident] = obj 1995 objs_ord.append(ident) 1996 if (sort_flds): 1997 # Sort identifiers according to the matching object in objs. 1998 # The order is determined by sort_flds, keys prefixed by a 1999 # '#' are compared numerically. 2000 def obj_key_fn(name): 2001 obj = objs[name] 2002 return list( 2003 int(obj[f[1:]]) if f[0] == '#' else obj[f] 2004 for f in sort_flds 2005 ) 2006 objs_ord.sort(key=obj_key_fn) 2007 for ident in objs_ord: 2008 obj = objs[ident] 2009 try: 2010 text = rep['text'] % obj 2011 except (KeyError): 2012 raise sys.exc_info()[0]("%s:%s invalid key %s for information object %s of %s" % (rep['fn'], rep['lineno'], sys.exc_info()[1], ident, var)) 2013 fx.write(text) 2014 else: 2015 fx.write("/* Unknown or empty loop list %s */\n" % (var)) 2016 else: 2017 fx.write(rep['text']) 2018 if rep['type'] == 'FTR': 2019 fx.write('\n') 2020 2021 #--- dupl_report ----------------------------------------------------- 2022 def dupl_report(self): 2023 # types 2024 tmplist = sorted(self.eth_type_dupl.keys()) 2025 for t in tmplist: 2026 msg = "The same type names for different types. Explicit type renaming is recommended.\n" 2027 msg += t + "\n" 2028 for tt in self.eth_type_dupl[t]: 2029 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt) 2030 warnings.warn_explicit(msg, UserWarning, '', 0) 2031 # fields 2032 tmplist = list(self.eth_hf_dupl.keys()) 2033 tmplist.sort() 2034 for f in tmplist: 2035 msg = "The same field names for different types. Explicit field renaming is recommended.\n" 2036 msg += f + "\n" 2037 for tt in list(self.eth_hf_dupl[f].keys()): 2038 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt) 2039 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref']) 2040 msg += "\n" 2041 warnings.warn_explicit(msg, UserWarning, '', 0) 2042 2043 #--- eth_do_output ------------------------------------------------------------ 2044 def eth_do_output(self): 2045 if self.dbg('a'): 2046 print("\n# Assignments") 2047 for a in self.assign_ord: 2048 v = ' ' 2049 if (self.assign[a]['virt']): v = '*' 2050 print('{} {}'.format(v, a)) 2051 print("\n# Value assignments") 2052 for a in self.vassign_ord: 2053 print(' {}'.format(a)) 2054 print("\n# Information object assignments") 2055 for a in self.oassign_ord: 2056 print(" %-12s (%s)" % (a, self.oassign[a].cls)) 2057 if self.dbg('t'): 2058 print("\n# Imported Types") 2059 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) 2060 print("-" * 100) 2061 for t in self.type_imp: 2062 print("%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])) 2063 print("\n# Imported Values") 2064 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) 2065 print("-" * 100) 2066 for t in self.value_imp: 2067 print("%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])) 2068 print("\n# Imported Object Classes") 2069 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) 2070 print("-" * 100) 2071 for t in self.objectclass_imp: 2072 print("%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])) 2073 print("\n# Exported Types") 2074 print("%-31s %s" % ("Wireshark type", "Export Flag")) 2075 print("-" * 100) 2076 for t in self.eth_export_ord: 2077 print("%-31s 0x%02X" % (t, self.eth_type[t]['export'])) 2078 print("\n# Exported Values") 2079 print("%-40s %s" % ("Wireshark name", "Value")) 2080 print("-" * 100) 2081 for v in self.eth_vexport_ord: 2082 vv = self.eth_value[v]['value'] 2083 if isinstance (vv, Value): 2084 vv = vv.to_str(self) 2085 print("%-40s %s" % (v, vv)) 2086 print("\n# ASN.1 Object Classes") 2087 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")) 2088 print("-" * 100) 2089 for t in self.objectclass_ord: 2090 print("%-40s " % (t)) 2091 print("\n# ASN.1 Types") 2092 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")) 2093 print("-" * 100) 2094 for t in self.type_ord: 2095 print("%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])) 2096 print("\n# Wireshark Types") 2097 print("Wireshark type References (ASN.1 types)") 2098 print("-" * 100) 2099 for t in self.eth_type_ord: 2100 sys.stdout.write("%-31s %d" % (t, len(self.eth_type[t]['ref']))) 2101 print(', '.join(self.eth_type[t]['ref'])) 2102 print("\n# ASN.1 Values") 2103 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value")) 2104 print("-" * 100) 2105 for v in self.value_ord: 2106 vv = self.value[v]['value'] 2107 if isinstance (vv, Value): 2108 vv = vv.to_str(self) 2109 print("%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname'])) 2110 #print "\n# Wireshark Values" 2111 #print "%-40s %s" % ("Wireshark name", "Value") 2112 #print "-" * 100 2113 #for v in self.eth_value_ord: 2114 # vv = self.eth_value[v]['value'] 2115 # if isinstance (vv, Value): 2116 # vv = vv.to_str(self) 2117 # print "%-40s %s" % (v, vv) 2118 print("\n# ASN.1 Fields") 2119 print("ASN.1 unique name Wireshark name ASN.1 type") 2120 print("-" * 100) 2121 for f in (self.pdu_ord + self.field_ord): 2122 print("%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])) 2123 print("\n# Wireshark Fields") 2124 print("Wireshark name Wireshark type References (ASN.1 fields)") 2125 print("-" * 100) 2126 for f in (self.eth_hfpdu_ord + self.eth_hf_ord): 2127 sys.stdout.write("%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref']))) 2128 print(', '.join(self.eth_hf[f]['ref'])) 2129 #print "\n# Order after dependencies" 2130 #print '\n'.join(self.eth_type_ord1) 2131 print("\n# Cyclic dependencies") 2132 for c in self.eth_dep_cycle: 2133 print(' -> '.join(c)) 2134 self.dupl_report() 2135 self.output.outnm = self.outnm_opt 2136 if (not self.output.outnm): 2137 self.output.outnm = self.proto 2138 self.output.outnm = self.output.outnm.replace('.', '-') 2139 if not self.justexpcnf: 2140 self.eth_output_hf() 2141 self.eth_output_ett() 2142 self.eth_output_types() 2143 self.eth_output_hf_arr() 2144 self.eth_output_ett_arr() 2145 self.eth_output_export() 2146 self.eth_output_val() 2147 self.eth_output_valexp() 2148 self.eth_output_dis_hnd() 2149 self.eth_output_dis_reg() 2150 self.eth_output_dis_tab() 2151 self.eth_output_syn_reg() 2152 self.eth_output_tables() 2153 if self.expcnf: 2154 self.eth_output_expcnf() 2155 2156 def dbg_modules(self): 2157 def print_mod(m): 2158 sys.stdout.write("%-30s " % (m)) 2159 dep = self.module[m][:] 2160 for i in range(len(dep)): 2161 if dep[i] not in self.module: 2162 dep[i] = '*' + dep[i] 2163 print(', '.join(dep)) 2164 # end of print_mod() 2165 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module) 2166 print("\n# ASN.1 Moudules") 2167 print("Module name Dependency") 2168 print("-" * 100) 2169 new_ord = False 2170 for m in (self.module_ord): 2171 print_mod(m) 2172 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m)) 2173 if new_ord: 2174 print("\n# ASN.1 Moudules - in dependency order") 2175 print("Module name Dependency") 2176 print("-" * 100) 2177 for m in (mod_ord): 2178 print_mod(m) 2179 if mod_cyc: 2180 print("\nCyclic dependencies:") 2181 for i in (list(range(len(mod_cyc)))): 2182 print("%02d: %s" % (i + 1, str(mod_cyc[i]))) 2183 2184 2185#--- EthCnf ------------------------------------------------------------------- 2186class EthCnf: 2187 def __init__(self): 2188 self.ectx = None 2189 self.tblcfg = {} 2190 self.table = {} 2191 self.order = {} 2192 self.fn = {} 2193 self.report = {} 2194 self.suppress_line = False 2195 self.include_path = [] 2196 self.proto_root_name = None 2197 # Value name Default value Duplicity check Usage check 2198 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } 2199 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } 2200 self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } 2201 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2202 self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2203 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2204 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } 2205 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True } 2206 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False } 2207 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True } 2208 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True } 2209 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2210 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2211 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2212 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2213 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False } 2214 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True } 2215 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False } 2216 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False } 2217 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True } 2218 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True } 2219 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False } 2220 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True } 2221 2222 for k in list(self.tblcfg.keys()) : 2223 self.table[k] = {} 2224 self.order[k] = [] 2225 2226 def add_item(self, table, key, fn, lineno, **kw): 2227 if self.tblcfg[table]['chk_dup'] and key in self.table[table]: 2228 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" % 2229 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']), 2230 UserWarning, fn, lineno) 2231 return 2232 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False} 2233 self.table[table][key].update(kw) 2234 self.order[table].append(key) 2235 2236 def update_item(self, table, key, fn, lineno, **kw): 2237 if key not in self.table[table]: 2238 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False} 2239 self.order[table].append(key) 2240 self.table[table][key][self.tblcfg[table]['val_nm']] = {} 2241 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']]) 2242 2243 def get_order(self, table): 2244 return self.order[table] 2245 2246 def check_item(self, table, key): 2247 return key in self.table[table] 2248 2249 def copy_item(self, table, dst_key, src_key): 2250 if (src_key in self.table[table]): 2251 self.table[table][dst_key] = self.table[table][src_key] 2252 2253 def check_item_value(self, table, key, **kw): 2254 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key] 2255 2256 def use_item(self, table, key, **kw): 2257 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt']) 2258 if key not in self.table[table]: return vdflt 2259 vname = kw.get('val_nm', self.tblcfg[table]['val_nm']) 2260 #print "use_item() - set used for %s %s" % (table, key) 2261 self.table[table][key]['used'] = True 2262 return self.table[table][key].get(vname, vdflt) 2263 2264 def omit_assignment(self, type, ident, module): 2265 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident): 2266 return True 2267 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \ 2268 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \ 2269 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \ 2270 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module): 2271 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident) 2272 return False 2273 2274 def add_fn_line(self, name, ctx, line, fn, lineno): 2275 if name not in self.fn: 2276 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None} 2277 if (self.fn[name][ctx]): 2278 self.fn[name][ctx]['text'] += line 2279 else: 2280 self.fn[name][ctx] = {'text' : line, 'used' : False, 2281 'fn' : fn, 'lineno' : lineno} 2282 def get_fn_presence(self, name): 2283 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name))) 2284 #if self.fn.has_key(name): print self.fn[name] 2285 return name in self.fn 2286 def get_fn_body_presence(self, name): 2287 return name in self.fn and self.fn[name]['FN_BODY'] 2288 def get_fn_text(self, name, ctx): 2289 if (name not in self.fn): 2290 return ''; 2291 if (not self.fn[name][ctx]): 2292 return ''; 2293 self.fn[name][ctx]['used'] = True 2294 out = self.fn[name][ctx]['text'] 2295 if (not self.suppress_line): 2296 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out); 2297 return out 2298 2299 def add_pdu(self, par, fn, lineno): 2300 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno) 2301 (reg, hidden) = (None, False) 2302 if (len(par) > 1): reg = par[1] 2303 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True) 2304 attr = {'new' : False, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False} 2305 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno) 2306 return 2307 2308 def add_syntax(self, par, fn, lineno): 2309 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno) 2310 if( (len(par) >=2)): 2311 name = par[1] 2312 else: 2313 name = '"'+par[0]+'"' 2314 attr = { 'pdu' : par[0] } 2315 self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno) 2316 return 2317 2318 def add_register(self, pdu, par, fn, lineno): 2319 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno) 2320 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2) 2321 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2) 2322 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2) 2323 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2) 2324 elif (par[0] in ('O', 'OER')): rtype = 'OER'; (pmin, pmax) = (1, 2) 2325 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return 2326 if ((len(par)-1) < pmin): 2327 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno) 2328 return 2329 if ((len(par)-1) > pmax): 2330 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno) 2331 attr = {'pdu' : pdu, 'rtype' : rtype} 2332 if (rtype in ('NUM', 'STR')): 2333 attr['rtable'] = par[1] 2334 attr['rport'] = par[2] 2335 rkey = '/'.join([rtype, attr['rtable'], attr['rport']]) 2336 elif (rtype in ('BER', 'PER', 'OER')): 2337 attr['roid'] = par[1] 2338 attr['roidname'] = '""' 2339 if (len(par)>=3): 2340 attr['roidname'] = par[2] 2341 elif attr['roid'][0] != '"': 2342 attr['roidname'] = '"' + attr['roid'] + '"' 2343 rkey = '/'.join([rtype, attr['roid']]) 2344 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno) 2345 2346 def check_par(self, par, pmin, pmax, fn, lineno): 2347 for i in range(len(par)): 2348 if par[i] == '-': 2349 par[i] = None 2350 continue 2351 if par[i][0] == '#': 2352 par[i:] = [] 2353 break 2354 if len(par) < pmin: 2355 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno) 2356 return None 2357 if (pmax >= 0) and (len(par) > pmax): 2358 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno) 2359 return par[0:pmax] 2360 return par 2361 2362 def read(self, fn): 2363 def get_par(line, pmin, pmax, fn, lineno): 2364 par = line.split(None, pmax) 2365 par = self.check_par(par, pmin, pmax, fn, lineno) 2366 return par 2367 2368 def get_par_nm(line, pmin, pmax, fn, lineno): 2369 if pmax: 2370 par = line.split(None, pmax) 2371 else: 2372 par = [line,] 2373 for i in range(len(par)): 2374 if par[i][0] == '#': 2375 par[i:] = [] 2376 break 2377 if len(par) < pmin: 2378 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno) 2379 return None 2380 if len(par) > pmax: 2381 nmpar = par[pmax] 2382 else: 2383 nmpar = '' 2384 nmpars = {} 2385 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*') 2386 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*') 2387 nmpar_end = re.compile(r'\s*$') 2388 result = nmpar_first.search(nmpar) 2389 pos = 0 2390 while result: 2391 k = result.group('attr') 2392 pos = result.end() 2393 result = nmpar_next.search(nmpar, pos) 2394 p1 = pos 2395 if result: 2396 p2 = result.start() 2397 else: 2398 p2 = nmpar_end.search(nmpar, pos).start() 2399 v = nmpar[p1:p2] 2400 nmpars[k] = v 2401 if len(par) > pmax: 2402 par[pmax] = nmpars 2403 return par 2404 2405 f = open(fn, "r") 2406 lineno = 0 2407 is_import = False 2408 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)') 2409 cdirective = re.compile(r'^\s*##') 2410 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$') 2411 comment = re.compile(r'^\s*#[^.#]') 2412 empty = re.compile(r'^\s*$') 2413 ctx = None 2414 name = '' 2415 default_flags = 0x00 2416 stack = [] 2417 while True: 2418 if not f.closed: 2419 line = f.readline() 2420 lineno += 1 2421 else: 2422 line = None 2423 if not line: 2424 if not f.closed: 2425 f.close() 2426 if stack: 2427 frec = stack.pop() 2428 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import'] 2429 continue 2430 else: 2431 break 2432 if comment.search(line): continue 2433 result = directive.search(line) 2434 if result: # directive 2435 rep_result = report.search(result.group('name')) 2436 if result.group('name') == 'END_OF_CNF': 2437 f.close() 2438 elif result.group('name') == 'OPT': 2439 ctx = result.group('name') 2440 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno) 2441 if not par: continue 2442 self.set_opt(par[0], par[1:], fn, lineno) 2443 ctx = None 2444 elif result.group('name') in ('PDU', 'REGISTER', 2445 'MODULE', 'MODULE_IMPORT', 2446 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN', 2447 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE', 2448 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG', 2449 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR', 2450 'SYNTAX'): 2451 ctx = result.group('name') 2452 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT', 2453 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 2454 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'): 2455 ctx = result.group('name') 2456 key = '*' 2457 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'): 2458 key += 'T' 2459 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'): 2460 key += 'V' 2461 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno) 2462 if par: 2463 key += '/' + par[0] 2464 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno) 2465 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'): 2466 ctx = 'NO_OMIT_ASSGN' 2467 else: 2468 ctx = None 2469 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'): 2470 ctx = result.group('name') 2471 default_flags = EF_TYPE|EF_VALS 2472 if ctx == 'MODULE_EXPORTS': 2473 ctx = 'EXPORTS' 2474 default_flags |= EF_MODULE 2475 if ctx == 'EXPORTS': 2476 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno) 2477 else: 2478 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno) 2479 if not par: continue 2480 p = 1 2481 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS 2482 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_VALS 2483 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS 2484 elif (ctx == 'EXPORTS'): p = 0 2485 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno) 2486 for i in range(p, len(par)): 2487 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM 2488 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM 2489 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE 2490 elif (par[i] == 'WS_DLL'): default_flags |= EF_WS_DLL 2491 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN 2492 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT 2493 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) 2494 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'): 2495 ctx = result.group('name') 2496 default_flags = EF_ENUM 2497 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE 2498 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE 2499 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno) 2500 for i in range(0, len(par)): 2501 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT 2502 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT 2503 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE 2504 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE 2505 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE 2506 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE 2507 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) 2508 elif result.group('name') == 'USE_VALS_EXT': 2509 ctx = result.group('name') 2510 default_flags = 0xFF 2511 elif result.group('name') == 'FN_HDR': 2512 minp = 1 2513 if (ctx in ('FN_PARS',)) and name: minp = 0 2514 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno) 2515 if (not par) and (minp > 0): continue 2516 ctx = result.group('name') 2517 if par: name = par[0] 2518 elif result.group('name') == 'FN_FTR': 2519 minp = 1 2520 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0 2521 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno) 2522 if (not par) and (minp > 0): continue 2523 ctx = result.group('name') 2524 if par: name = par[0] 2525 elif result.group('name') == 'FN_BODY': 2526 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno) 2527 if not par: continue 2528 ctx = result.group('name') 2529 name = par[0] 2530 if len(par) > 1: 2531 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno) 2532 elif result.group('name') == 'FN_PARS': 2533 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno) 2534 ctx = result.group('name') 2535 if not par: 2536 name = None 2537 elif len(par) == 1: 2538 name = par[0] 2539 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno) 2540 elif len(par) > 1: 2541 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno) 2542 ctx = None 2543 elif result.group('name') == 'CLASS': 2544 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) 2545 if not par: continue 2546 ctx = result.group('name') 2547 name = par[0] 2548 add_class_ident(name) 2549 if not name.split('$')[-1].isupper(): 2550 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name), 2551 UserWarning, fn, lineno) 2552 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER': 2553 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) 2554 if not par: continue 2555 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno) 2556 elif rep_result: # Reports 2557 num = rep_result.group('num') 2558 type = rep_result.group('type') 2559 if type == 'BODY': 2560 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) 2561 if not par: continue 2562 else: 2563 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno) 2564 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno } 2565 if len(par) > 0: 2566 rep['var'] = par[0] 2567 self.report.setdefault(num, []).append(rep) 2568 ctx = 'TABLE' 2569 name = num 2570 elif result.group('name') in ('INCLUDE', 'IMPORT') : 2571 is_imp = result.group('name') == 'IMPORT' 2572 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno) 2573 if not par: 2574 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno) 2575 continue 2576 fname = par[0] 2577 #print "Try include: %s" % (fname) 2578 if (not os.path.exists(fname)): 2579 fname = os.path.join(os.path.split(fn)[0], par[0]) 2580 #print "Try include: %s" % (fname) 2581 i = 0 2582 while not os.path.exists(fname) and (i < len(self.include_path)): 2583 fname = os.path.join(self.include_path[i], par[0]) 2584 #print "Try include: %s" % (fname) 2585 i += 1 2586 if (not os.path.exists(fname)): 2587 if is_imp: 2588 continue # just ignore 2589 else: 2590 fname = par[0] # report error 2591 fnew = open(fname, "r") 2592 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import}) 2593 fn, f, lineno, is_import = par[0], fnew, 0, is_imp 2594 elif result.group('name') == 'END': 2595 ctx = None 2596 else: 2597 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno) 2598 continue 2599 if not ctx: 2600 if not empty.match(line): 2601 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno) 2602 elif ctx == 'OPT': 2603 if empty.match(line): continue 2604 par = get_par(line, 1, -1, fn=fn, lineno=lineno) 2605 if not par: continue 2606 self.set_opt(par[0], par[1:], fn, lineno) 2607 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'): 2608 if empty.match(line): continue 2609 if ctx == 'EXPORTS': 2610 par = get_par(line, 1, 6, fn=fn, lineno=lineno) 2611 else: 2612 par = get_par(line, 1, 2, fn=fn, lineno=lineno) 2613 if not par: continue 2614 flags = default_flags 2615 p = 2 2616 if (len(par)>=2): 2617 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS 2618 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_VALS 2619 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS 2620 elif (ctx == 'EXPORTS'): p = 1 2621 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno) 2622 for i in range(p, len(par)): 2623 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM 2624 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM 2625 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE 2626 elif (par[i] == 'WS_DLL'): flags |= EF_WS_DLL 2627 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN 2628 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT 2629 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) 2630 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno) 2631 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'): 2632 if empty.match(line): continue 2633 par = get_par(line, 1, 4, fn=fn, lineno=lineno) 2634 if not par: continue 2635 flags = default_flags 2636 for i in range(1, len(par)): 2637 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT 2638 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT 2639 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE 2640 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE 2641 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE 2642 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE 2643 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno) 2644 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno) 2645 elif ctx == 'USE_VALS_EXT': 2646 if empty.match(line): continue 2647 par = get_par(line, 1, 1, fn=fn, lineno=lineno) 2648 if not par: continue 2649 flags = default_flags 2650 self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno) 2651 elif ctx == 'PDU': 2652 if empty.match(line): continue 2653 par = get_par(line, 1, 5, fn=fn, lineno=lineno) 2654 if not par: continue 2655 self.add_pdu(par[0:2], fn, lineno) 2656 if (len(par)>=3): 2657 self.add_register(par[0], par[2:5], fn, lineno) 2658 elif ctx == 'SYNTAX': 2659 if empty.match(line): continue 2660 par = get_par(line, 1, 2, fn=fn, lineno=lineno) 2661 if not par: continue 2662 if not self.check_item('PDU', par[0]): 2663 self.add_pdu(par[0:1], fn, lineno) 2664 self.add_syntax(par, fn, lineno) 2665 elif ctx == 'REGISTER': 2666 if empty.match(line): continue 2667 par = get_par(line, 3, 4, fn=fn, lineno=lineno) 2668 if not par: continue 2669 if not self.check_item('PDU', par[0]): 2670 self.add_pdu(par[0:1], fn, lineno) 2671 self.add_register(par[0], par[1:4], fn, lineno) 2672 elif ctx in ('MODULE', 'MODULE_IMPORT'): 2673 if empty.match(line): continue 2674 par = get_par(line, 2, 2, fn=fn, lineno=lineno) 2675 if not par: continue 2676 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno) 2677 elif ctx == 'IMPORT_TAG': 2678 if empty.match(line): continue 2679 par = get_par(line, 3, 3, fn=fn, lineno=lineno) 2680 if not par: continue 2681 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno) 2682 elif ctx == 'OMIT_ASSIGNMENT': 2683 if empty.match(line): continue 2684 par = get_par(line, 1, 1, fn=fn, lineno=lineno) 2685 if not par: continue 2686 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno) 2687 elif ctx == 'NO_OMIT_ASSGN': 2688 if empty.match(line): continue 2689 par = get_par(line, 1, 1, fn=fn, lineno=lineno) 2690 if not par: continue 2691 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno) 2692 elif ctx == 'VIRTUAL_ASSGN': 2693 if empty.match(line): continue 2694 par = get_par(line, 2, -1, fn=fn, lineno=lineno) 2695 if not par: continue 2696 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]): 2697 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno) 2698 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno) 2699 for nm in par[2:]: 2700 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno) 2701 if not par[0][0].isupper(): 2702 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]), 2703 UserWarning, fn, lineno) 2704 elif ctx == 'SET_TYPE': 2705 if empty.match(line): continue 2706 par = get_par(line, 2, 2, fn=fn, lineno=lineno) 2707 if not par: continue 2708 if not self.check_item('VIRTUAL_ASSGN', par[0]): 2709 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno) 2710 if not par[1][0].isupper(): 2711 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]), 2712 UserWarning, fn, lineno) 2713 elif ctx == 'ASSIGN_VALUE_TO_TYPE': 2714 if empty.match(line): continue 2715 par = get_par(line, 2, 2, fn=fn, lineno=lineno) 2716 if not par: continue 2717 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno) 2718 elif ctx == 'TYPE_RENAME': 2719 if empty.match(line): continue 2720 par = get_par(line, 2, 2, fn=fn, lineno=lineno) 2721 if not par: continue 2722 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno) 2723 if not par[1][0].isupper(): 2724 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]), 2725 UserWarning, fn, lineno) 2726 elif ctx == 'FIELD_RENAME': 2727 if empty.match(line): continue 2728 par = get_par(line, 2, 2, fn=fn, lineno=lineno) 2729 if not par: continue 2730 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno) 2731 if not par[1][0].islower(): 2732 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]), 2733 UserWarning, fn, lineno) 2734 elif ctx == 'TF_RENAME': 2735 if empty.match(line): continue 2736 par = get_par(line, 2, 2, fn=fn, lineno=lineno) 2737 if not par: continue 2738 tmpu = par[1][0].upper() + par[1][1:] 2739 tmpl = par[1][0].lower() + par[1][1:] 2740 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno) 2741 if not tmpu[0].isupper(): 2742 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]), 2743 UserWarning, fn, lineno) 2744 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno) 2745 if not tmpl[0].islower(): 2746 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]), 2747 UserWarning, fn, lineno) 2748 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'): 2749 if empty.match(line): continue 2750 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno) 2751 if not par: continue 2752 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno) 2753 elif ctx == 'FN_PARS': 2754 if empty.match(line): continue 2755 if name: 2756 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno) 2757 else: 2758 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno) 2759 if not par: continue 2760 if name: 2761 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno) 2762 else: 2763 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno) 2764 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'): 2765 result = cdirective.search(line) 2766 if result: # directive 2767 line = '#' + line[result.end():] 2768 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno) 2769 elif ctx == 'CLASS': 2770 if empty.match(line): continue 2771 par = get_par(line, 1, 3, fn=fn, lineno=lineno) 2772 if not par: continue 2773 if not set_type_to_class(name, par[0], par[1:]): 2774 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]), 2775 UserWarning, fn, lineno) 2776 elif ctx == 'TABLE': 2777 self.report[name][-1]['text'] += line 2778 2779 def set_opt(self, opt, par, fn, lineno): 2780 #print("set_opt: %s, %s" % (opt, par)) 2781 if opt in ("-I",): 2782 par = self.check_par(par, 1, 1, fn, lineno) 2783 if not par: return 2784 self.include_path.append(relpath(par[0])) 2785 elif opt in ("-b", "BER", "CER", "DER"): 2786 par = self.check_par(par, 0, 0, fn, lineno) 2787 self.ectx.encoding = 'ber' 2788 elif opt in ("PER",): 2789 par = self.check_par(par, 0, 0, fn, lineno) 2790 self.ectx.encoding = 'per' 2791 elif opt in ("OER",): 2792 par = self.check_par(par, 0, 0, fn, lineno) 2793 self.ectx.encoding = 'oer' 2794 elif opt in ("-p", "PROTO"): 2795 par = self.check_par(par, 1, 1, fn, lineno) 2796 if not par: return 2797 self.ectx.proto_opt = par[0] 2798 self.ectx.merge_modules = True 2799 elif opt in ("ALIGNED",): 2800 par = self.check_par(par, 0, 0, fn, lineno) 2801 self.ectx.aligned = True 2802 elif opt in ("-u", "UNALIGNED"): 2803 par = self.check_par(par, 0, 0, fn, lineno) 2804 self.ectx.aligned = False 2805 elif opt in ("PROTO_ROOT_NAME"): 2806 par = self.check_par(par, 1, 1, fn, lineno) 2807 if not par: return 2808 self.proto_root_name = par[0] 2809 elif opt in ("-d",): 2810 par = self.check_par(par, 1, 1, fn, lineno) 2811 if not par: return 2812 self.ectx.dbgopt = par[0] 2813 elif opt in ("-e",): 2814 par = self.check_par(par, 0, 0, fn, lineno) 2815 self.ectx.expcnf = True 2816 elif opt in ("-S",): 2817 par = self.check_par(par, 0, 0, fn, lineno) 2818 self.ectx.merge_modules = True 2819 elif opt in ("GROUP_BY_PROT",): 2820 par = self.check_par(par, 0, 0, fn, lineno) 2821 self.ectx.group_by_prot = True 2822 elif opt in ("-o",): 2823 par = self.check_par(par, 1, 1, fn, lineno) 2824 if not par: return 2825 self.ectx.outnm_opt = par[0] 2826 elif opt in ("-O",): 2827 par = self.check_par(par, 1, 1, fn, lineno) 2828 if not par: return 2829 self.ectx.output.outdir = relpath(par[0]) 2830 elif opt in ("-s",): 2831 par = self.check_par(par, 1, 1, fn, lineno) 2832 if not par: return 2833 self.ectx.output.single_file = relpath(par[0]) 2834 elif opt in ("-k",): 2835 par = self.check_par(par, 0, 0, fn, lineno) 2836 self.ectx.output.keep = True 2837 elif opt in ("-L",): 2838 par = self.check_par(par, 0, 0, fn, lineno) 2839 self.suppress_line = True 2840 elif opt in ("EMBEDDED_PDV_CB",): 2841 par = self.check_par(par, 1, 1, fn, lineno) 2842 if not par: return 2843 self.ectx.default_embedded_pdv_cb = par[0] 2844 elif opt in ("EXTERNAL_TYPE_CB",): 2845 par = self.check_par(par, 1, 1, fn, lineno) 2846 if not par: return 2847 self.ectx.default_external_type_cb = par[0] 2848 elif opt in ("-r",): 2849 par = self.check_par(par, 1, 1, fn, lineno) 2850 if not par: return 2851 self.ectx.remove_prefix = par[0] 2852 else: 2853 warnings.warn_explicit("Unknown option %s" % (opt), 2854 UserWarning, fn, lineno) 2855 2856 def dbg_print(self): 2857 print("\n# Conformance values") 2858 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")) 2859 print("-" * 100) 2860 tbls = sorted(self.table.keys()) 2861 for t in tbls: 2862 keys = sorted(self.table[t].keys()) 2863 for k in keys: 2864 print("%-15s %4s %-15s %-20s %s" % ( 2865 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))) 2866 2867 def unused_report(self): 2868 tbls = sorted(self.table.keys()) 2869 for t in tbls: 2870 if not self.tblcfg[t]['chk_use']: continue 2871 keys = sorted(self.table[t].keys()) 2872 for k in keys: 2873 if not self.table[t][k]['used']: 2874 warnings.warn_explicit("Unused %s for %s" % (t, k), 2875 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno']) 2876 fnms = list(self.fn.keys()) 2877 fnms.sort() 2878 for f in fnms: 2879 keys = sorted(self.fn[f].keys()) 2880 for k in keys: 2881 if not self.fn[f][k]: continue 2882 if not self.fn[f][k]['used']: 2883 warnings.warn_explicit("Unused %s for %s" % (k, f), 2884 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno']) 2885 2886#--- EthOut ------------------------------------------------------------------- 2887class EthOut: 2888 def __init__(self): 2889 self.ectx = None 2890 self.outnm = None 2891 self.outdir = '.' 2892 self.single_file = None 2893 self.created_files = {} 2894 self.created_files_ord = [] 2895 self.keep = False 2896 2897 def outcomment(self, ln, comment=None): 2898 if comment: 2899 return '%s %s\n' % (comment, ln) 2900 else: 2901 return '/* %-74s */\n' % (ln) 2902 2903 def created_file_add(self, name, keep_anyway): 2904 name = os.path.normcase(os.path.abspath(name)) 2905 if name not in self.created_files: 2906 self.created_files_ord.append(name) 2907 self.created_files[name] = keep_anyway 2908 else: 2909 self.created_files[name] = self.created_files[name] or keep_anyway 2910 2911 def created_file_exists(self, name): 2912 name = os.path.normcase(os.path.abspath(name)) 2913 return name in self.created_files 2914 2915 #--- output_fname ------------------------------------------------------- 2916 def output_fname(self, ftype, ext='c'): 2917 fn = '' 2918 if not ext in ('cnf',): 2919 fn += 'packet-' 2920 fn += self.outnm 2921 if (ftype): 2922 fn += '-' + ftype 2923 fn += '.' + ext 2924 return fn 2925 #--- file_open ------------------------------------------------------- 2926 def file_open(self, ftype, ext='c'): 2927 fn = self.output_fname(ftype, ext=ext) 2928 if self.created_file_exists(fn): 2929 fx = open(fn, 'a') 2930 else: 2931 fx = open(fn, 'w') 2932 comment = None 2933 if ext in ('cnf',): 2934 comment = '#' 2935 fx.write(self.fhdr(fn, comment = comment)) 2936 else: 2937 if (not self.single_file and not self.created_file_exists(fn)): 2938 fx.write(self.fhdr(fn)) 2939 if not self.ectx.merge_modules: 2940 fx.write('\n') 2941 mstr = "--- " 2942 if self.ectx.groups(): 2943 mstr += "Module" 2944 if (len(self.ectx.modules) > 1): 2945 mstr += "s" 2946 for (m, p) in self.ectx.modules: 2947 mstr += " %s" % (m) 2948 else: 2949 mstr += "Module %s" % (self.ectx.Module()) 2950 mstr += " --- --- ---" 2951 fx.write(self.outcomment(mstr, comment)) 2952 fx.write('\n') 2953 return fx 2954 #--- file_close ------------------------------------------------------- 2955 def file_close(self, fx, discard=False, keep_anyway=False): 2956 fx.close() 2957 if discard and not self.created_file_exists(fx.name): 2958 os.unlink(fx.name) 2959 else: 2960 self.created_file_add(fx.name, keep_anyway) 2961 #--- fhdr ------------------------------------------------------- 2962 def fhdr(self, fn, comment=None): 2963 out = '' 2964 out += self.outcomment('Do not modify this file. Changes will be overwritten.', comment) 2965 out += self.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment) 2966 out += self.outcomment(os.path.basename(fn), comment) 2967 out += self.outcomment(' '.join(['asn2wrs.py'] + sys.argv[1:]), comment) 2968 out += '\n' 2969 # Make Windows path separator look like Unix path separator 2970 out = out.replace('\\', '/') 2971 # Change absolute paths and relative paths generated outside 2972 # source directory to paths relative to asn1/<proto> subdir. 2973 out = re.sub(r'(\s)[./A-Z]\S*/dissectors\b', r'\1../..', out) 2974 out = re.sub(r'(\s)[./A-Z]\S*/asn1/\S*?([\s/])', r'\1.\2', out) 2975 return out 2976 2977 #--- dbg_print ------------------------------------------------------- 2978 def dbg_print(self): 2979 print("\n# Output files") 2980 print("\n".join(self.created_files_ord)) 2981 print("\n") 2982 2983 #--- make_single_file ------------------------------------------------------- 2984 def make_single_file(self): 2985 if (not self.single_file): return 2986 in_nm = self.single_file + '.c' 2987 out_nm = os.path.join(self.outdir, self.output_fname('')) 2988 self.do_include(out_nm, in_nm) 2989 in_nm = self.single_file + '.h' 2990 if (os.path.exists(in_nm)): 2991 out_nm = os.path.join(self.outdir, self.output_fname('', ext='h')) 2992 self.do_include(out_nm, in_nm) 2993 if (not self.keep): 2994 for fn in self.created_files_ord: 2995 if not self.created_files[fn]: 2996 os.unlink(fn) 2997 2998 #--- do_include ------------------------------------------------------- 2999 def do_include(self, out_nm, in_nm): 3000 def check_file(fn, fnlist): 3001 fnfull = os.path.normcase(os.path.abspath(fn)) 3002 if (fnfull in fnlist and os.path.exists(fnfull)): 3003 return os.path.normpath(fn) 3004 return None 3005 fin = open(in_nm, "r") 3006 fout = open(out_nm, "w") 3007 fout.write(self.fhdr(out_nm)) 3008 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n') 3009 fout.write('\n') 3010 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm))) 3011 3012 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE) 3013 3014 cont_linenum = 0; 3015 3016 while (True): 3017 cont_linenum = cont_linenum + 1; 3018 line = fin.readline() 3019 if (line == ''): break 3020 ifile = None 3021 result = include.search(line) 3022 #if (result): print os.path.normcase(os.path.abspath(result.group('fname'))) 3023 if (result): 3024 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files) 3025 if (not ifile): 3026 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files) 3027 if (not ifile): 3028 ifile = check_file(result.group('fname'), self.created_files) 3029 if (ifile): 3030 fout.write('\n') 3031 fout.write('/*--- Included file: ' + ifile + ' ---*/\n') 3032 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile))) 3033 finc = open(ifile, "r") 3034 fout.write(finc.read()) 3035 fout.write('\n') 3036 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n') 3037 fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) ) 3038 finc.close() 3039 else: 3040 fout.write(line) 3041 3042 fout.close() 3043 fin.close() 3044 3045 3046#--- Node --------------------------------------------------------------------- 3047class Node: 3048 def __init__(self,*args, **kw): 3049 if len (args) == 0: 3050 self.type = self.__class__.__name__ 3051 else: 3052 assert (len(args) == 1) 3053 self.type = args[0] 3054 self.__dict__.update (kw) 3055 def str_child (self, key, child, depth): 3056 indent = " " * (2 * depth) 3057 keystr = indent + key + ": " 3058 if key == 'type': # already processed in str_depth 3059 return "" 3060 if isinstance (child, Node): # ugh 3061 return keystr + "\n" + child.str_depth (depth+1) 3062 if isinstance(child, type ([])): 3063 l = [] 3064 for x in child: 3065 if isinstance (x, Node): 3066 l.append (x.str_depth (depth+1)) 3067 else: 3068 l.append (indent + " " + str(x) + "\n") 3069 return keystr + "[\n" + ''.join(l) + indent + "]\n" 3070 else: 3071 return keystr + str (child) + "\n" 3072 def str_depth (self, depth): # ugh 3073 indent = " " * (2 * depth) 3074 l = ["%s%s" % (indent, self.type)] 3075 l.append ("".join ([self.str_child (k_v[0], k_v[1], depth + 1) for k_v in list(self.__dict__.items ())])) 3076 return "\n".join (l) 3077 def __repr__(self): 3078 return "\n" + self.str_depth (0) 3079 def to_python (self, ctx): 3080 return self.str_depth (ctx.indent_lev) 3081 3082 def eth_reg(self, ident, ectx): 3083 pass 3084 3085 def fld_obj_repr(self, ectx): 3086 return "/* TO DO %s */" % (str(self)) 3087 3088 3089#--- ValueAssignment ------------------------------------------------------------- 3090class ValueAssignment (Node): 3091 def __init__(self,*args, **kw) : 3092 Node.__init__ (self,*args, **kw) 3093 3094 def eth_reg(self, ident, ectx): 3095 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit 3096 ectx.eth_reg_vassign(self) 3097 ectx.eth_reg_value(self.ident, self.typ, self.val) 3098 3099#--- ObjectAssignment ------------------------------------------------------------- 3100class ObjectAssignment (Node): 3101 def __init__(self,*args, **kw) : 3102 Node.__init__ (self,*args, **kw) 3103 3104 def __eq__(self, other): 3105 if self.cls != other.cls: 3106 return False 3107 if len(self.val) != len(other.val): 3108 return False 3109 for f in (list(self.val.keys())): 3110 if f not in other.val: 3111 return False 3112 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node): 3113 if not self.val[f].fld_obj_eq(other.val[f]): 3114 return False 3115 else: 3116 if str(self.val[f]) != str(other.val[f]): 3117 return False 3118 return True 3119 3120 def eth_reg(self, ident, ectx): 3121 def make_virtual_type(cls, field, prefix): 3122 if isinstance(self.val, str): return 3123 if field in self.val and not isinstance(self.val[field], Type_Ref): 3124 vnm = prefix + '-' + self.ident 3125 virtual_tr = Type_Ref(val = vnm) 3126 t = self.val[field] 3127 self.val[field] = virtual_tr 3128 ectx.eth_reg_assign(vnm, t, virt=True) 3129 ectx.eth_reg_type(vnm, t) 3130 t.eth_reg_sub(vnm, ectx) 3131 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field): 3132 ectx.eth_reg_field(self.val[field].val, self.val[field].val, impl=self.val[field].HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', cls + '.' + field)) 3133 return 3134 # end of make_virtual_type() 3135 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit 3136 self.module = ectx.Module() 3137 ectx.eth_reg_oassign(self) 3138 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'): 3139 make_virtual_type(self.cls, '&Type', 'TYPE') 3140 if (self.cls == 'OPERATION'): 3141 make_virtual_type(self.cls, '&ArgumentType', 'ARG') 3142 make_virtual_type(self.cls, '&ResultType', 'RES') 3143 if (self.cls == 'ERROR'): 3144 make_virtual_type(self.cls, '&ParameterType', 'PAR') 3145 3146 3147#--- Type --------------------------------------------------------------------- 3148class Type (Node): 3149 def __init__(self,*args, **kw) : 3150 self.name = None 3151 self.constr = None 3152 self.tags = [] 3153 self.named_list = None 3154 Node.__init__ (self,*args, **kw) 3155 3156 def IsNamed(self): 3157 if self.name is None : 3158 return False 3159 else: 3160 return True 3161 3162 def HasConstraint(self): 3163 if self.constr is None : 3164 return False 3165 else : 3166 return True 3167 3168 def HasSizeConstraint(self): 3169 return self.HasConstraint() and self.constr.IsSize() 3170 3171 def HasValueConstraint(self): 3172 return self.HasConstraint() and self.constr.IsValue() 3173 3174 def HasPermAlph(self): 3175 return self.HasConstraint() and self.constr.IsPermAlph() 3176 3177 def HasContentsConstraint(self): 3178 return self.HasConstraint() and self.constr.IsContents() 3179 3180 def HasOwnTag(self): 3181 return len(self.tags) > 0 3182 3183 def HasImplicitTag(self, ectx): 3184 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx)) 3185 3186 def IndetermTag(self, ectx): 3187 return False 3188 3189 def AddTag(self, tag): 3190 self.tags[0:0] = [tag] 3191 3192 def GetTag(self, ectx): 3193 #print "GetTag(%s)\n" % self.name; 3194 if (self.HasOwnTag()): 3195 return self.tags[0].GetTag(ectx) 3196 else: 3197 return self.GetTTag(ectx) 3198 3199 def GetTTag(self, ectx): 3200 print("#Unhandled GetTTag() in %s" % (self.type)) 3201 print(self.str_depth(1)) 3202 return ('BER_CLASS_unknown', 'TAG_unknown') 3203 3204 def SetName(self, name): 3205 self.name = name 3206 3207 def AddConstraint(self, constr): 3208 if not self.HasConstraint(): 3209 self.constr = constr 3210 else: 3211 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr]) 3212 3213 def eth_tname(self): 3214 return '#' + self.type + '_' + str(id(self)) 3215 3216 def eth_ftype(self, ectx): 3217 return ('FT_NONE', 'BASE_NONE') 3218 3219 def eth_strings(self): 3220 return 'NULL' 3221 3222 def eth_omit_field(self): 3223 return False 3224 3225 def eth_need_tree(self): 3226 return False 3227 3228 def eth_has_vals(self): 3229 return False 3230 3231 def eth_has_enum(self, tname, ectx): 3232 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM) 3233 3234 def eth_need_pdu(self, ectx): 3235 return None 3236 3237 def eth_named_bits(self): 3238 return None 3239 3240 def eth_reg_sub(self, ident, ectx): 3241 pass 3242 3243 def get_components(self, ectx): 3244 print("#Unhandled get_components() in %s" % (self.type)) 3245 print(self.str_depth(1)) 3246 return [] 3247 3248 def sel_req(self, sel, ectx): 3249 print("#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)) 3250 print(self.str_depth(1)) 3251 3252 def fld_obj_eq(self, other): 3253 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname()) 3254 3255 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None): 3256 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent)) 3257 #print " ", self 3258 if (ectx.NeedTags() and (len(self.tags) > tstrip)): 3259 tagged_type = self 3260 for i in range(len(self.tags)-1, tstrip-1, -1): 3261 tagged_type = TaggedType(val=tagged_type, tstrip=i) 3262 tagged_type.AddTag(self.tags[i]) 3263 if not tagflag: # 1st tagged level 3264 if self.IsNamed() and not selflag: 3265 tagged_type.SetName(self.name) 3266 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent) 3267 return 3268 nm = '' 3269 if ident and self.IsNamed() and not tagflag and not selflag: 3270 nm = ident + '/' + self.name 3271 elif ident: 3272 nm = ident 3273 elif self.IsNamed(): 3274 nm = self.name 3275 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit 3276 if not ident: # Assignment 3277 ectx.eth_reg_assign(nm, self) 3278 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx): 3279 ectx.eth_reg_type(nm, self) 3280 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm)) 3281 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm): 3282 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag): 3283 if ectx.conform.check_item('SET_TYPE', nm): 3284 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference 3285 else: 3286 ectx.eth_reg_type(nm, self) # new type 3287 trnm = nm 3288 elif ectx.conform.check_item('SET_TYPE', nm): 3289 trnm = ectx.conform.use_item('SET_TYPE', nm) 3290 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx): 3291 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints 3292 trnm = nm 3293 else: 3294 trnm = self.val 3295 else: 3296 ectx.eth_reg_type(nm, self, mod = ectx.Module()) 3297 trnm = nm 3298 if ectx.conform.check_item('VIRTUAL_ASSGN', nm): 3299 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm) 3300 ectx.eth_reg_assign(vnm, self, virt=True) 3301 ectx.eth_reg_type(vnm, self) 3302 self.eth_reg_sub(vnm, ectx) 3303 if parent and (ectx.type[parent]['val'].type == 'TaggedType'): 3304 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx) 3305 if ident and not tagflag and not self.eth_omit_field(): 3306 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx)) 3307 if ectx.conform.check_item('SET_TYPE', nm): 3308 virtual_tr.eth_reg_sub(nm, ectx) 3309 else: 3310 self.eth_reg_sub(nm, ectx) 3311 3312 def eth_get_size_constr(self, ectx): 3313 (minv, maxv, ext) = ('MIN', 'MAX', False) 3314 if self.HasSizeConstraint(): 3315 if self.constr.IsSize(): 3316 (minv, maxv, ext) = self.constr.GetSize(ectx) 3317 if (self.constr.type == 'Intersection'): 3318 if self.constr.subtype[0].IsSize(): 3319 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx) 3320 elif self.constr.subtype[1].IsSize(): 3321 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx) 3322 if minv == 'MIN': minv = 'NO_BOUND' 3323 if maxv == 'MAX': maxv = 'NO_BOUND' 3324 if (ext): ext = 'TRUE' 3325 else: ext = 'FALSE' 3326 return (minv, maxv, ext) 3327 3328 def eth_get_value_constr(self, ectx): 3329 (minv, maxv, ext) = ('MIN', 'MAX', False) 3330 if self.HasValueConstraint(): 3331 (minv, maxv, ext) = self.constr.GetValue(ectx) 3332 if minv == 'MIN': minv = 'NO_BOUND' 3333 if maxv == 'MAX': maxv = 'NO_BOUND' 3334 if str(minv).isdigit(): 3335 minv += 'U' 3336 elif (str(minv)[0] == "-") and str(minv)[1:].isdigit(): 3337 if (int(minv) == -(2**31)): 3338 minv = "G_MININT32" 3339 elif (int(minv) < -(2**31)): 3340 minv = "G_GINT64_CONSTANT(%s)" % (str(minv)) 3341 if str(maxv).isdigit(): 3342 if (int(maxv) >= 2**32): 3343 maxv = "G_GUINT64_CONSTANT(%s)" % (str(maxv)) 3344 else: 3345 maxv += 'U' 3346 if (ext): ext = 'TRUE' 3347 else: ext = 'FALSE' 3348 return (minv, maxv, ext) 3349 3350 def eth_get_alphabet_constr(self, ectx): 3351 (alph, alphlen) = ('NULL', '0') 3352 if self.HasPermAlph(): 3353 alph = self.constr.GetPermAlph(ectx) 3354 if not alph: 3355 alph = 'NULL' 3356 if (alph != 'NULL'): 3357 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))): 3358 alphlen = str(len(alph) - 2) 3359 else: 3360 alphlen = 'strlen(%s)' % (alph) 3361 return (alph, alphlen) 3362 3363 def eth_type_vals(self, tname, ectx): 3364 if self.eth_has_vals(): 3365 print("#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)) 3366 print(self.str_depth(1)) 3367 return '' 3368 3369 def eth_type_enum(self, tname, ectx): 3370 if self.eth_has_enum(tname, ectx): 3371 print("#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)) 3372 print(self.str_depth(1)) 3373 return '' 3374 3375 def eth_type_default_table(self, ectx, tname): 3376 return '' 3377 3378 def eth_type_default_body(self, ectx): 3379 print("#Unhandled eth_type_default_body() in %s" % (self.type)) 3380 print(self.str_depth(1)) 3381 return '' 3382 3383 def eth_type_default_pars(self, ectx, tname): 3384 pars = { 3385 'TNAME' : tname, 3386 'ER' : ectx.encp(), 3387 'FN_VARIANT' : '', 3388 'TREE' : 'tree', 3389 'TVB' : 'tvb', 3390 'OFFSET' : 'offset', 3391 'ACTX' : 'actx', 3392 'HF_INDEX' : 'hf_index', 3393 'VAL_PTR' : 'NULL', 3394 'IMPLICIT_TAG' : 'implicit_tag', 3395 } 3396 if (ectx.eth_type[tname]['tree']): 3397 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree'] 3398 if (ectx.merge_modules): 3399 pars['PROTOP'] = '' 3400 else: 3401 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_' 3402 return pars 3403 3404 def eth_type_fn(self, proto, tname, ectx): 3405 body = self.eth_type_default_body(ectx, tname) 3406 pars = self.eth_type_default_pars(ectx, tname) 3407 if ectx.conform.check_item('FN_PARS', tname): 3408 pars.update(ectx.conform.use_item('FN_PARS', tname)) 3409 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]): 3410 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0])) 3411 pars['DEFAULT_BODY'] = body 3412 for i in range(4): 3413 for k in list(pars.keys()): 3414 try: 3415 pars[k] = pars[k] % pars 3416 except (ValueError,TypeError): 3417 raise sys.exc_info()[0]("%s\n%s" % (str(pars), sys.exc_info()[1])) 3418 out = '\n' 3419 out += self.eth_type_default_table(ectx, tname) % pars 3420 out += ectx.eth_type_fn_hdr(tname) 3421 out += ectx.eth_type_fn_body(tname, body, pars=pars) 3422 out += ectx.eth_type_fn_ftr(tname) 3423 return out 3424 3425#--- Value -------------------------------------------------------------------- 3426class Value (Node): 3427 def __init__(self,*args, **kw) : 3428 self.name = None 3429 Node.__init__ (self,*args, **kw) 3430 3431 def SetName(self, name) : 3432 self.name = name 3433 3434 def to_str(self, ectx): 3435 return str(self.val) 3436 3437 def get_dep(self): 3438 return None 3439 3440 def fld_obj_repr(self, ectx): 3441 return self.to_str(ectx) 3442 3443#--- Value_Ref ----------------------------------------------------------------- 3444class Value_Ref (Value): 3445 def to_str(self, ectx): 3446 return asn2c(self.val) 3447 3448#--- ObjectClass --------------------------------------------------------------------- 3449class ObjectClass (Node): 3450 def __init__(self,*args, **kw) : 3451 self.name = None 3452 Node.__init__ (self,*args, **kw) 3453 3454 def SetName(self, name): 3455 self.name = name 3456 add_class_ident(self.name) 3457 3458 def eth_reg(self, ident, ectx): 3459 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit 3460 ectx.eth_reg_objectclass(self.name, self) 3461 3462#--- Class_Ref ----------------------------------------------------------------- 3463class Class_Ref (ObjectClass): 3464 pass 3465 3466#--- ObjectClassDefn --------------------------------------------------------------------- 3467class ObjectClassDefn (ObjectClass): 3468 def reg_types(self): 3469 for fld in self.fields: 3470 repr = fld.fld_repr() 3471 set_type_to_class(self.name, repr[0], repr[1:]) 3472 3473 3474#--- Tag --------------------------------------------------------------- 3475class Tag (Node): 3476 def to_python (self, ctx): 3477 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls, 3478 self.tag_typ, 3479 self.tag.num), 3480 self.typ.to_python (ctx)) 3481 def IsImplicit(self, ectx): 3482 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT'))) 3483 3484 def GetTag(self, ectx): 3485 tc = '' 3486 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI' 3487 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP' 3488 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON' 3489 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI' 3490 return (tc, self.num) 3491 3492 def eth_tname(self): 3493 n = '' 3494 if (self.cls == 'UNIVERSAL'): n = 'U' 3495 elif (self.cls == 'APPLICATION'): n = 'A' 3496 elif (self.cls == 'CONTEXT'): n = 'C' 3497 elif (self.cls == 'PRIVATE'): n = 'P' 3498 return n + str(self.num) 3499 3500#--- Constraint --------------------------------------------------------------- 3501constr_cnt = 0 3502class Constraint (Node): 3503 def to_python (self, ctx): 3504 print("Ignoring constraint:", self.type) 3505 return self.subtype.typ.to_python (ctx) 3506 def __str__ (self): 3507 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype) 3508 3509 def eth_tname(self): 3510 return '#' + self.type + '_' + str(id(self)) 3511 3512 def IsSize(self): 3513 return (self.type == 'Size' and self.subtype.IsValue()) \ 3514 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \ 3515 3516 def GetSize(self, ectx): 3517 (minv, maxv, ext) = ('MIN', 'MAX', False) 3518 if self.IsSize(): 3519 if self.type == 'Size': 3520 (minv, maxv, ext) = self.subtype.GetValue(ectx) 3521 ext = ext or (hasattr(self, 'ext') and self.ext) 3522 elif self.type == 'Intersection': 3523 if self.subtype[0].IsSize() and not self.subtype[1].IsSize(): 3524 (minv, maxv, ext) = self.subtype[0].GetSize(ectx) 3525 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize(): 3526 (minv, maxv, ext) = self.subtype[1].GetSize(ectx) 3527 return (minv, maxv, ext) 3528 3529 def IsValue(self): 3530 return self.type == 'SingleValue' \ 3531 or self.type == 'ValueRange' \ 3532 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \ 3533 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue())) 3534 3535 def GetValue(self, ectx): 3536 (minv, maxv, ext) = ('MIN', 'MAX', False) 3537 if self.IsValue(): 3538 if self.type == 'SingleValue': 3539 minv = ectx.value_get_eth(self.subtype) 3540 maxv = ectx.value_get_eth(self.subtype) 3541 ext = hasattr(self, 'ext') and self.ext 3542 elif self.type == 'ValueRange': 3543 minv = ectx.value_get_eth(self.subtype[0]) 3544 maxv = ectx.value_get_eth(self.subtype[1]) 3545 ext = hasattr(self, 'ext') and self.ext 3546 elif self.type == 'Intersection': 3547 if self.subtype[0].IsValue() and not self.subtype[1].IsValue(): 3548 (minv, maxv, ext) = self.subtype[0].GetValue(ectx) 3549 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue(): 3550 (minv, maxv, ext) = self.subtype[1].GetValue(ectx) 3551 elif self.subtype[0].IsValue() and self.subtype[1].IsValue(): 3552 v0 = self.subtype[0].GetValue(ectx) 3553 v1 = self.subtype[1].GetValue(ectx) 3554 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2]) 3555 elif self.type == 'Union': 3556 if self.subtype[0].IsValue() and self.subtype[1].IsValue(): 3557 v0 = self.subtype[0].GetValue(ectx) 3558 v1 = self.subtype[1].GetValue(ectx) 3559 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), hasattr(self, 'ext') and self.ext) 3560 return (minv, maxv, ext) 3561 3562 def IsAlphabet(self): 3563 return self.type == 'SingleValue' \ 3564 or self.type == 'ValueRange' \ 3565 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \ 3566 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet())) 3567 3568 def GetAlphabet(self, ectx): 3569 alph = None 3570 if self.IsAlphabet(): 3571 if self.type == 'SingleValue': 3572 alph = ectx.value_get_eth(self.subtype) 3573 elif self.type == 'ValueRange': 3574 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \ 3575 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')): 3576 alph = '"' 3577 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1): 3578 alph += chr(c) 3579 alph += '"' 3580 elif self.type == 'Union': 3581 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet(): 3582 a0 = self.subtype[0].GetAlphabet(ectx) 3583 a1 = self.subtype[1].GetAlphabet(ectx) 3584 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \ 3585 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)): 3586 alph = '"' + a0[1:-1] + a1[1:-1] + '"' 3587 else: 3588 alph = a0 + ' ' + a1 3589 return alph 3590 3591 def IsPermAlph(self): 3592 return self.type == 'From' and self.subtype.IsAlphabet() \ 3593 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \ 3594 3595 def GetPermAlph(self, ectx): 3596 alph = None 3597 if self.IsPermAlph(): 3598 if self.type == 'From': 3599 alph = self.subtype.GetAlphabet(ectx) 3600 elif self.type == 'Intersection': 3601 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph(): 3602 alph = self.subtype[0].GetPermAlph(ectx) 3603 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph(): 3604 alph = self.subtype[1].GetPermAlph(ectx) 3605 return alph 3606 3607 def IsContents(self): 3608 return self.type == 'Contents' \ 3609 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \ 3610 3611 def GetContents(self, ectx): 3612 contents = None 3613 if self.IsContents(): 3614 if self.type == 'Contents': 3615 if self.subtype.type == 'Type_Ref': 3616 contents = self.subtype.val 3617 elif self.type == 'Intersection': 3618 if self.subtype[0].IsContents() and not self.subtype[1].IsContents(): 3619 contents = self.subtype[0].GetContents(ectx) 3620 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents(): 3621 contents = self.subtype[1].GetContents(ectx) 3622 return contents 3623 3624 def IsNegativ(self): 3625 def is_neg(sval): 3626 return isinstance(sval, str) and (sval[0] == '-') 3627 if self.type == 'SingleValue': 3628 return is_neg(self.subtype) 3629 elif self.type == 'ValueRange': 3630 if self.subtype[0] == 'MIN': return True 3631 return is_neg(self.subtype[0]) 3632 return False 3633 3634 def eth_constrname(self): 3635 def int2str(val): 3636 if isinstance(val, Value_Ref): 3637 return asn2c(val.val) 3638 try: 3639 if (int(val) < 0): 3640 return 'M' + str(-int(val)) 3641 else: 3642 return str(int(val)) 3643 except (ValueError, TypeError): 3644 return asn2c(str(val)) 3645 3646 ext = '' 3647 if hasattr(self, 'ext') and self.ext: 3648 ext = '_' 3649 if self.type == 'SingleValue': 3650 return int2str(self.subtype) + ext 3651 elif self.type == 'ValueRange': 3652 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext 3653 elif self.type == 'Size': 3654 return 'SIZE_' + self.subtype.eth_constrname() + ext 3655 else: 3656 if (not hasattr(self, 'constr_num')): 3657 global constr_cnt 3658 constr_cnt += 1 3659 self.constr_num = constr_cnt 3660 return 'CONSTR%03d%s' % (self.constr_num, ext) 3661 3662 def Needs64b(self, ectx): 3663 (minv, maxv, ext) = self.GetValue(ectx) 3664 if ((str(minv).isdigit() or ((str(minv)[0] == "-") and str(minv)[1:].isdigit())) \ 3665 and str(maxv).isdigit() and (abs(int(maxv) - int(minv)) >= 2**32)) \ 3666 or (maxv == 'MAX') or (minv == 'MIN'): 3667 return True 3668 return False 3669 3670class Module (Node): 3671 def to_python (self, ctx): 3672 ctx.tag_def = self.tag_def.dfl_tag 3673 return """#%s 3674 %s""" % (self.ident, self.body.to_python (ctx)) 3675 3676 def get_name(self): 3677 return self.ident.val 3678 3679 def get_proto(self, ectx): 3680 if (ectx.proto): 3681 prot = ectx.proto 3682 else: 3683 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name()) 3684 return prot 3685 3686 def to_eth(self, ectx): 3687 ectx.tags_def = 'EXPLICIT' # default = explicit 3688 ectx.proto = self.get_proto(ectx) 3689 ectx.tag_def = self.tag_def.dfl_tag 3690 ectx.eth_reg_module(self) 3691 self.body.to_eth(ectx) 3692 3693class Module_Body (Node): 3694 def to_python (self, ctx): 3695 # XXX handle exports, imports. 3696 l = [x.to_python (ctx) for x in self.assign_list] 3697 l = [a for a in l if a != ''] 3698 return "\n".join (l) 3699 3700 def to_eth(self, ectx): 3701 # Exports 3702 ectx.eth_exports(self.exports) 3703 # Imports 3704 for i in self.imports: 3705 mod = i.module.val 3706 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod) 3707 ectx.eth_module_dep_add(ectx.Module(), mod) 3708 for s in i.symbol_list: 3709 if isinstance(s, Type_Ref): 3710 ectx.eth_import_type(s.val, mod, proto) 3711 elif isinstance(s, Value_Ref): 3712 ectx.eth_import_value(s.val, mod, proto) 3713 elif isinstance(s, Class_Ref): 3714 ectx.eth_import_class(s.val, mod, proto) 3715 else: 3716 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod) 3717 warnings.warn_explicit(msg, UserWarning, '', 0) 3718 # AssignmentList 3719 for a in self.assign_list: 3720 a.eth_reg('', ectx) 3721 3722class Default_Tags (Node): 3723 def to_python (self, ctx): # not to be used directly 3724 assert (0) 3725 3726# XXX should just calculate dependencies as we go along. 3727def calc_dependencies (node, dict, trace = 0): 3728 if not hasattr (node, '__dict__'): 3729 if trace: print("#returning, node=", node) 3730 return 3731 if isinstance (node, Type_Ref): 3732 dict [node.val] = 1 3733 if trace: print("#Setting", node.val) 3734 return 3735 for (a, val) in list(node.__dict__.items ()): 3736 if trace: print("# Testing node ", node, "attr", a, " val", val) 3737 if a[0] == '_': 3738 continue 3739 elif isinstance (val, Node): 3740 calc_dependencies (val, dict, trace) 3741 elif isinstance (val, type ([])): 3742 for v in val: 3743 calc_dependencies (v, dict, trace) 3744 3745 3746class Type_Assign (Node): 3747 def __init__ (self, *args, **kw): 3748 Node.__init__ (self, *args, **kw) 3749 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag) 3750 to_test = self.val.typ 3751 else: 3752 to_test = self.val 3753 if isinstance (to_test, SequenceType): 3754 to_test.sequence_name = self.name.name 3755 3756 def to_python (self, ctx): 3757 dep_dict = {} 3758 calc_dependencies (self.val, dep_dict, 0) 3759 depend_list = list(dep_dict.keys ()) 3760 return ctx.register_assignment (self.name.name, 3761 self.val.to_python (ctx), 3762 depend_list) 3763 3764class PyQuote (Node): 3765 def to_python (self, ctx): 3766 return ctx.register_pyquote (self.val) 3767 3768#--- Type_Ref ----------------------------------------------------------------- 3769class Type_Ref (Type): 3770 def to_python (self, ctx): 3771 return self.val 3772 3773 def eth_reg_sub(self, ident, ectx): 3774 ectx.eth_dep_add(ident, self.val) 3775 3776 def eth_tname(self): 3777 if self.HasSizeConstraint(): 3778 return asn2c(self.val) + '_' + self.constr.eth_constrname() 3779 else: 3780 return asn2c(self.val) 3781 3782 def tr_need_own_fn(self, ectx): 3783 return (ectx.Per() or ectx.Oer()) and self.HasSizeConstraint() 3784 3785 def fld_obj_repr(self, ectx): 3786 return self.val 3787 3788 def get_components(self, ectx): 3789 if self.val not in ectx.type or ectx.type[self.val]['import']: 3790 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val) 3791 warnings.warn_explicit(msg, UserWarning, '', 0) 3792 return [] 3793 else: 3794 return ectx.type[self.val]['val'].get_components(ectx) 3795 3796 def GetTTag(self, ectx): 3797 #print "GetTTag(%s)\n" % self.val; 3798 if (ectx.type[self.val]['import']): 3799 if 'ttag' not in ectx.type[self.val]: 3800 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import']) 3801 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val): 3802 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto']) 3803 warnings.warn_explicit(msg, UserWarning, '', 0) 3804 ttag = ('-1/*imported*/', '-1/*imported*/') 3805 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag) 3806 return ectx.type[self.val]['ttag'] 3807 else: 3808 return ectx.type[self.val]['val'].GetTag(ectx) 3809 3810 def IndetermTag(self, ectx): 3811 if (ectx.type[self.val]['import']): 3812 return False 3813 else: 3814 return ectx.type[self.val]['val'].IndetermTag(ectx) 3815 3816 def eth_type_default_pars(self, ectx, tname): 3817 if tname: 3818 pars = Type.eth_type_default_pars(self, ectx, tname) 3819 else: 3820 pars = {} 3821 t = ectx.type[self.val]['ethname'] 3822 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] 3823 pars['TYPE_REF_TNAME'] = t 3824 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' 3825 if self.HasSizeConstraint(): 3826 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) 3827 return pars 3828 3829 def eth_type_default_body(self, ectx, tname): 3830 if (ectx.Ber()): 3831 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', 3832 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) 3833 elif (ectx.Per() or ectx.Oer()): 3834 if self.HasSizeConstraint(): 3835 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset', 3836 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',), 3837 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) 3838 else: 3839 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', 3840 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) 3841 else: 3842 body = '#error Can not decode %s' % (tname) 3843 return body 3844 3845#--- SelectionType ------------------------------------------------------------ 3846class SelectionType (Type): 3847 def to_python (self, ctx): 3848 return self.val 3849 3850 def sel_of_typeref(self): 3851 return self.typ.type == 'Type_Ref' 3852 3853 def eth_reg_sub(self, ident, ectx): 3854 if not self.sel_of_typeref(): 3855 self.seltype = '' 3856 return 3857 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel) 3858 ectx.eth_dep_add(ident, self.seltype) 3859 3860 def eth_ftype(self, ectx): 3861 (ftype, display) = ('FT_NONE', 'BASE_NONE') 3862 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']: 3863 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx) 3864 return (ftype, display) 3865 3866 def GetTTag(self, ectx): 3867 #print "GetTTag(%s)\n" % self.seltype; 3868 if (ectx.type[self.seltype]['import']): 3869 if 'ttag' not in ectx.type[self.seltype]: 3870 if not ectx.conform.check_item('IMPORT_TAG', self.seltype): 3871 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto']) 3872 warnings.warn_explicit(msg, UserWarning, '', 0) 3873 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/')) 3874 return ectx.type[self.seltype]['ttag'] 3875 else: 3876 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx) 3877 3878 def eth_type_default_pars(self, ectx, tname): 3879 pars = Type.eth_type_default_pars(self, ectx, tname) 3880 if self.sel_of_typeref(): 3881 t = ectx.type[self.seltype]['ethname'] 3882 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] 3883 pars['TYPE_REF_TNAME'] = t 3884 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' 3885 return pars 3886 3887 def eth_type_default_body(self, ectx, tname): 3888 if not self.sel_of_typeref(): 3889 body = '#error Can not decode %s' % (tname) 3890 elif (ectx.Ber()): 3891 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', 3892 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) 3893 elif (ectx.Per() or ectx.Oer()): 3894 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset', 3895 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) 3896 else: 3897 body = '#error Can not decode %s' % (tname) 3898 return body 3899 3900#--- TaggedType ----------------------------------------------------------------- 3901class TaggedType (Type): 3902 def eth_tname(self): 3903 tn = '' 3904 for i in range(self.tstrip, len(self.val.tags)): 3905 tn += self.val.tags[i].eth_tname() 3906 tn += '_' 3907 tn += self.val.eth_tname() 3908 return tn 3909 3910 def eth_set_val_name(self, ident, val_name, ectx): 3911 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name) 3912 self.val_name = val_name 3913 ectx.eth_dep_add(ident, self.val_name) 3914 3915 def eth_reg_sub(self, ident, ectx): 3916 self.val_name = ident + '/' + UNTAG_TYPE_NAME 3917 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident) 3918 3919 def GetTTag(self, ectx): 3920 #print "GetTTag(%s)\n" % self.seltype; 3921 return self.GetTag(ectx) 3922 3923 def eth_ftype(self, ectx): 3924 return self.val.eth_ftype(ectx) 3925 3926 def eth_type_default_pars(self, ectx, tname): 3927 pars = Type.eth_type_default_pars(self, ectx, tname) 3928 t = ectx.type[self.val_name]['ethname'] 3929 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] 3930 pars['TYPE_REF_TNAME'] = t 3931 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' 3932 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx) 3933 if self.HasImplicitTag(ectx): 3934 pars['TAG_IMPL'] = 'TRUE' 3935 else: 3936 pars['TAG_IMPL'] = 'FALSE' 3937 return pars 3938 3939 def eth_type_default_body(self, ectx, tname): 3940 if (ectx.Ber()): 3941 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset', 3942 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 3943 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),)) 3944 else: 3945 body = '#error Can not decode %s' % (tname) 3946 return body 3947 3948#--- SqType ----------------------------------------------------------- 3949class SqType (Type): 3950 def out_item(self, f, val, optional, ext, ectx): 3951 if (val.eth_omit_field()): 3952 t = ectx.type[val.ident]['ethname'] 3953 fullname = ectx.dummy_eag_field 3954 else: 3955 ef = ectx.field[f]['ethname'] 3956 t = ectx.eth_hf[ef]['ethtype'] 3957 fullname = ectx.eth_hf[ef]['fullname'] 3958 if (ectx.Ber()): 3959 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx))) 3960 #print val.str_depth(1) 3961 opt = '' 3962 if (optional): 3963 opt = 'BER_FLAGS_OPTIONAL' 3964 if (not val.HasOwnTag()): 3965 if (opt): opt += '|' 3966 opt += 'BER_FLAGS_NOOWNTAG' 3967 elif (val.HasImplicitTag(ectx)): 3968 if (opt): opt += '|' 3969 opt += 'BER_FLAGS_IMPLTAG' 3970 if (val.IndetermTag(ectx)): 3971 if (opt): opt += '|' 3972 opt += 'BER_FLAGS_NOTCHKTAG' 3973 if (not opt): opt = '0' 3974 else: 3975 if optional: 3976 opt = 'ASN1_OPTIONAL' 3977 else: 3978 opt = 'ASN1_NOT_OPTIONAL' 3979 if (ectx.Ber()): 3980 (tc, tn) = val.GetTag(ectx) 3981 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \ 3982 % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t) 3983 elif (ectx.Per() or ectx.Oer()): 3984 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \ 3985 % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t) 3986 else: 3987 out = '' 3988 return out 3989 3990#--- SeqType ----------------------------------------------------------- 3991class SeqType (SqType): 3992 3993 def all_components(self): 3994 lst = self.elt_list[:] 3995 if hasattr(self, 'ext_list'): 3996 lst.extend(self.ext_list) 3997 if hasattr(self, 'elt_list2'): 3998 lst.extend(self.elt_list2) 3999 return lst 4000 4001 def need_components(self): 4002 lst = self.all_components() 4003 for e in (lst): 4004 if e.type == 'components_of': 4005 return True 4006 return False 4007 4008 def expand_components(self, ectx): 4009 while self.need_components(): 4010 for i in range(len(self.elt_list)): 4011 if self.elt_list[i].type == 'components_of': 4012 comp = self.elt_list[i].typ.get_components(ectx) 4013 self.elt_list[i:i+1] = comp 4014 break 4015 if hasattr(self, 'ext_list'): 4016 for i in range(len(self.ext_list)): 4017 if self.ext_list[i].type == 'components_of': 4018 comp = self.ext_list[i].typ.get_components(ectx) 4019 self.ext_list[i:i+1] = comp 4020 break 4021 if hasattr(self, 'elt_list2'): 4022 for i in range(len(self.elt_list2)): 4023 if self.elt_list2[i].type == 'components_of': 4024 comp = self.elt_list2[i].typ.get_components(ectx) 4025 self.elt_list2[i:i+1] = comp 4026 break 4027 4028 def get_components(self, ectx): 4029 lst = self.elt_list[:] 4030 if hasattr(self, 'elt_list2'): 4031 lst.extend(self.elt_list2) 4032 return lst 4033 4034 def eth_reg_sub(self, ident, ectx, components_available=False): 4035 # check if autotag is required 4036 autotag = False 4037 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')): 4038 autotag = True 4039 lst = self.all_components() 4040 for e in (self.elt_list): 4041 if e.val.HasOwnTag(): autotag = False; break; 4042 # expand COMPONENTS OF 4043 if self.need_components(): 4044 if components_available: 4045 self.expand_components(ectx) 4046 else: 4047 ectx.eth_comp_req(ident) 4048 return 4049 # extension addition groups 4050 if hasattr(self, 'ext_list'): 4051 if (ectx.Per() or ectx.Oer()): # add names 4052 eag_num = 1 4053 for e in (self.ext_list): 4054 if isinstance(e.val, ExtensionAdditionGroup): 4055 e.val.parent_ident = ident 4056 e.val.parent_tname = ectx.type[ident]['tname'] 4057 if (e.val.ver): 4058 e.val.SetName("eag_v%s" % (e.val.ver)) 4059 else: 4060 e.val.SetName("eag_%d" % (eag_num)) 4061 eag_num += 1; 4062 else: # expand 4063 new_ext_list = [] 4064 for e in (self.ext_list): 4065 if isinstance(e.val, ExtensionAdditionGroup): 4066 new_ext_list.extend(e.val.elt_list) 4067 else: 4068 new_ext_list.append(e) 4069 self.ext_list = new_ext_list 4070 # do autotag 4071 if autotag: 4072 atag = 0 4073 for e in (self.elt_list): 4074 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) 4075 atag += 1 4076 if autotag and hasattr(self, 'elt_list2'): 4077 for e in (self.elt_list2): 4078 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) 4079 atag += 1 4080 if autotag and hasattr(self, 'ext_list'): 4081 for e in (self.ext_list): 4082 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) 4083 atag += 1 4084 # register components 4085 for e in (self.elt_list): 4086 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident) 4087 if hasattr(self, 'ext_list'): 4088 for e in (self.ext_list): 4089 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident) 4090 if hasattr(self, 'elt_list2'): 4091 for e in (self.elt_list2): 4092 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident) 4093 4094 def eth_type_default_table(self, ectx, tname): 4095 #print ("eth_type_default_table(tname='%s')" % (tname)) 4096 fname = ectx.eth_type[tname]['ref'][0] 4097 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n" 4098 if hasattr(self, 'ext_list'): 4099 ext = 'ASN1_EXTENSION_ROOT' 4100 else: 4101 ext = 'ASN1_NO_EXTENSIONS' 4102 empty_ext_flag = '0' 4103 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0) and (not hasattr(self, 'elt_list2') or (len(self.elt_list2)==0)): 4104 empty_ext_flag = ext 4105 for e in (self.elt_list): 4106 f = fname + '/' + e.val.name 4107 table += self.out_item(f, e.val, e.optional, ext, ectx) 4108 if hasattr(self, 'ext_list'): 4109 for e in (self.ext_list): 4110 f = fname + '/' + e.val.name 4111 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx) 4112 if hasattr(self, 'elt_list2'): 4113 for e in (self.elt_list2): 4114 f = fname + '/' + e.val.name 4115 table += self.out_item(f, e.val, e.optional, ext, ectx) 4116 if (ectx.Ber()): 4117 table += " { NULL, 0, 0, 0, NULL }\n};\n" 4118 else: 4119 table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag) 4120 return table 4121 4122#--- SeqOfType ----------------------------------------------------------- 4123class SeqOfType (SqType): 4124 def eth_type_default_table(self, ectx, tname): 4125 #print "eth_type_default_table(tname='%s')" % (tname) 4126 fname = ectx.eth_type[tname]['ref'][0] 4127 if self.val.IsNamed (): 4128 f = fname + '/' + self.val.name 4129 else: 4130 f = fname + '/' + ITEM_FIELD_NAME 4131 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n" 4132 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx) 4133 table += "};\n" 4134 return table 4135 4136#--- SequenceOfType ----------------------------------------------------------- 4137class SequenceOfType (SeqOfType): 4138 def to_python (self, ctx): 4139 # name, tag (None for no tag, EXPLICIT() for explicit), typ) 4140 # or '' + (1,) for optional 4141 sizestr = '' 4142 if self.size_constr is not None: 4143 print("#Ignoring size constraint:", self.size_constr.subtype) 4144 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (), 4145 self.val.to_python (ctx), 4146 sizestr) 4147 4148 def eth_reg_sub(self, ident, ectx): 4149 itmnm = ident 4150 if not self.val.IsNamed (): 4151 itmnm += '/' + ITEM_FIELD_NAME 4152 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident) 4153 4154 def eth_tname(self): 4155 if self.val.type != 'Type_Ref': 4156 return '#' + self.type + '_' + str(id(self)) 4157 if not self.HasConstraint(): 4158 return "SEQUENCE_OF_" + self.val.eth_tname() 4159 elif self.constr.IsSize(): 4160 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname() 4161 else: 4162 return '#' + self.type + '_' + str(id(self)) 4163 4164 def eth_ftype(self, ectx): 4165 return ('FT_UINT32', 'BASE_DEC') 4166 4167 def eth_need_tree(self): 4168 return True 4169 4170 def GetTTag(self, ectx): 4171 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE') 4172 4173 def eth_type_default_pars(self, ectx, tname): 4174 pars = Type.eth_type_default_pars(self, ectx, tname) 4175 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) 4176 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of' 4177 return pars 4178 4179 def eth_type_default_body(self, ectx, tname): 4180 if (ectx.Ber()): 4181 if (ectx.constraints_check and self.HasSizeConstraint()): 4182 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset', 4183 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4184 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) 4185 else: 4186 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset', 4187 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4188 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) 4189 elif ((ectx.Per() or ectx.Oer()) and not self.HasConstraint()): 4190 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset', 4191 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4192 ('%(ETT_INDEX)s', '%(TABLE)s',),)) 4193 elif ((ectx.Per() or ectx.Oer()) and self.constr.type == 'Size'): 4194 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset', 4195 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4196 ('%(ETT_INDEX)s', '%(TABLE)s',), 4197 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),)) 4198 else: 4199 body = '#error Can not decode %s' % (tname) 4200 return body 4201 4202 4203#--- SetOfType ---------------------------------------------------------------- 4204class SetOfType (SeqOfType): 4205 def eth_reg_sub(self, ident, ectx): 4206 itmnm = ident 4207 if not self.val.IsNamed (): 4208 itmnm += '/' + ITEM_FIELD_NAME 4209 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident) 4210 4211 def eth_tname(self): 4212 if self.val.type != 'Type_Ref': 4213 return '#' + self.type + '_' + str(id(self)) 4214 if not self.HasConstraint(): 4215 return "SET_OF_" + self.val.eth_tname() 4216 elif self.constr.IsSize(): 4217 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname() 4218 else: 4219 return '#' + self.type + '_' + str(id(self)) 4220 4221 def eth_ftype(self, ectx): 4222 return ('FT_UINT32', 'BASE_DEC') 4223 4224 def eth_need_tree(self): 4225 return True 4226 4227 def GetTTag(self, ectx): 4228 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET') 4229 4230 def eth_type_default_pars(self, ectx, tname): 4231 pars = Type.eth_type_default_pars(self, ectx, tname) 4232 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) 4233 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of' 4234 return pars 4235 4236 def eth_type_default_body(self, ectx, tname): 4237 if (ectx.Ber()): 4238 if (ectx.constraints_check and self.HasSizeConstraint()): 4239 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset', 4240 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4241 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) 4242 else: 4243 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset', 4244 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4245 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) 4246 elif (ectx.Per() and not self.HasConstraint()): 4247 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset', 4248 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4249 ('%(ETT_INDEX)s', '%(TABLE)s',),)) 4250 elif (ectx.Per() and self.constr.type == 'Size'): 4251 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset', 4252 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4253 ('%(ETT_INDEX)s', '%(TABLE)s',), 4254 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),)) 4255 else: 4256 body = '#error Can not decode %s' % (tname) 4257 return body 4258 4259def mk_tag_str (ctx, cls, typ, num): 4260 4261 # XXX should do conversion to int earlier! 4262 val = int (num) 4263 typ = typ.upper() 4264 if typ == 'DEFAULT': 4265 typ = ctx.tags_def 4266 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned 4267 4268#--- SequenceType ------------------------------------------------------------- 4269class SequenceType (SeqType): 4270 def to_python (self, ctx): 4271 # name, tag (None for no tag, EXPLICIT() for explicit), typ) 4272 # or '' + (1,) for optional 4273 # XXX should also collect names for SEQUENCE inside SEQUENCE or 4274 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come 4275 # from? for others, element or arm name would be fine) 4276 seq_name = getattr (self, 'sequence_name', None) 4277 if seq_name is None: 4278 seq_name = 'None' 4279 else: 4280 seq_name = "'" + seq_name + "'" 4281 if 'ext_list' in self.__dict__: 4282 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (), 4283 self.elts_to_py (self.elt_list, ctx), 4284 self.elts_to_py (self.ext_list, ctx), seq_name) 4285 else: 4286 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (), 4287 self.elts_to_py (self.elt_list, ctx), seq_name) 4288 def elts_to_py (self, list, ctx): 4289 # we have elt_type, val= named_type, maybe default=, optional= 4290 # named_type node: either ident = or typ = 4291 # need to dismember these in order to generate Python output syntax. 4292 ctx.indent () 4293 def elt_to_py (e): 4294 assert (e.type == 'elt_type') 4295 nt = e.val 4296 optflag = e.optional 4297 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT! 4298 assert (nt.type == 'named_type') 4299 tagstr = 'None' 4300 identstr = nt.ident 4301 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh 4302 tagstr = mk_tag_str (ctx,nt.typ.tag.cls, 4303 nt.typ.tag.tag_typ,nt.typ.tag.num) 4304 4305 4306 nt = nt.typ 4307 return "('%s',%s,%s,%d)" % (identstr, tagstr, 4308 nt.typ.to_python (ctx), optflag) 4309 indentstr = ",\n" + ctx.spaces () 4310 rv = indentstr.join ([elt_to_py (e) for e in list]) 4311 ctx.outdent () 4312 return rv 4313 4314 def eth_need_tree(self): 4315 return True 4316 4317 def GetTTag(self, ectx): 4318 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE') 4319 4320 def eth_type_default_pars(self, ectx, tname): 4321 pars = Type.eth_type_default_pars(self, ectx, tname) 4322 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence' 4323 return pars 4324 4325 def eth_type_default_body(self, ectx, tname): 4326 if (ectx.Ber()): 4327 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset', 4328 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4329 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) 4330 elif (ectx.Per() or ectx.Oer()): 4331 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset', 4332 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4333 ('%(ETT_INDEX)s', '%(TABLE)s',),)) 4334 else: 4335 body = '#error Can not decode %s' % (tname) 4336 return body 4337 4338#--- ExtensionAdditionGroup --------------------------------------------------- 4339class ExtensionAdditionGroup (SeqType): 4340 def __init__(self,*args, **kw) : 4341 self.parent_ident = None 4342 self.parent_tname = None 4343 SeqType.__init__ (self,*args, **kw) 4344 4345 def eth_omit_field(self): 4346 return True 4347 4348 def eth_tname(self): 4349 if (self.parent_tname and self.IsNamed()): 4350 return self.parent_tname + "_" + self.name 4351 else: 4352 return SeqType.eth_tname(self) 4353 4354 def eth_reg_sub(self, ident, ectx): 4355 ectx.eth_dummy_eag_field_required() 4356 ectx.eth_dep_add(self.parent_ident, ident) 4357 SeqType.eth_reg_sub(self, ident, ectx) 4358 4359 def eth_type_default_pars(self, ectx, tname): 4360 pars = Type.eth_type_default_pars(self, ectx, tname) 4361 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence' 4362 return pars 4363 4364 def eth_type_default_body(self, ectx, tname): 4365 if (ectx.Per()): 4366 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset', 4367 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),)) 4368 else: 4369 body = '#error Can not decode %s' % (tname) 4370 return body 4371 4372 4373#--- SetType ------------------------------------------------------------------ 4374class SetType (SeqType): 4375 4376 def eth_need_tree(self): 4377 return True 4378 4379 def GetTTag(self, ectx): 4380 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET') 4381 4382 def eth_type_default_pars(self, ectx, tname): 4383 pars = Type.eth_type_default_pars(self, ectx, tname) 4384 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set' 4385 return pars 4386 4387 def eth_type_default_body(self, ectx, tname): 4388 if (ectx.Ber()): 4389 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset', 4390 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4391 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),)) 4392 elif (ectx.Per()): 4393 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset', 4394 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4395 ('%(ETT_INDEX)s', '%(TABLE)s',),)) 4396 else: 4397 body = '#error Can not decode %s' % (tname) 4398 return body 4399 4400#--- ChoiceType --------------------------------------------------------------- 4401class ChoiceType (Type): 4402 def to_python (self, ctx): 4403 # name, tag (None for no tag, EXPLICIT() for explicit), typ) 4404 # or '' + (1,) for optional 4405 if 'ext_list' in self.__dict__: 4406 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (), 4407 self.elts_to_py (self.elt_list, ctx), 4408 self.elts_to_py (self.ext_list, ctx)) 4409 else: 4410 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx)) 4411 def elts_to_py (self, list, ctx): 4412 ctx.indent () 4413 def elt_to_py (nt): 4414 assert (nt.type == 'named_type') 4415 tagstr = 'None' 4416 if hasattr (nt, 'ident'): 4417 identstr = nt.ident 4418 else: 4419 if hasattr (nt.typ, 'val'): 4420 identstr = nt.typ.val # XXX, making up name 4421 elif hasattr (nt.typ, 'name'): 4422 identstr = nt.typ.name 4423 else: 4424 identstr = ctx.make_new_name () 4425 4426 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh 4427 tagstr = mk_tag_str (ctx,nt.typ.tag.cls, 4428 nt.typ.tag.tag_typ,nt.typ.tag.num) 4429 4430 4431 nt = nt.typ 4432 return "('%s',%s,%s)" % (identstr, tagstr, 4433 nt.typ.to_python (ctx)) 4434 indentstr = ",\n" + ctx.spaces () 4435 rv = indentstr.join ([elt_to_py (e) for e in list]) 4436 ctx.outdent () 4437 return rv 4438 4439 def eth_reg_sub(self, ident, ectx): 4440 #print "eth_reg_sub(ident='%s')" % (ident) 4441 # check if autotag is required 4442 autotag = False 4443 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')): 4444 autotag = True 4445 for e in (self.elt_list): 4446 if e.HasOwnTag(): autotag = False; break; 4447 if autotag and hasattr(self, 'ext_list'): 4448 for e in (self.ext_list): 4449 if e.HasOwnTag(): autotag = False; break; 4450 # do autotag 4451 if autotag: 4452 atag = 0 4453 for e in (self.elt_list): 4454 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) 4455 atag += 1 4456 if autotag and hasattr(self, 'ext_list'): 4457 for e in (self.ext_list): 4458 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT')) 4459 atag += 1 4460 for e in (self.elt_list): 4461 e.eth_reg(ident, ectx, tstrip=1, parent=ident) 4462 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name): 4463 ectx.eth_sel_req(ident, e.name) 4464 if hasattr(self, 'ext_list'): 4465 for e in (self.ext_list): 4466 e.eth_reg(ident, ectx, tstrip=1, parent=ident) 4467 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name): 4468 ectx.eth_sel_req(ident, e.name) 4469 4470 def sel_item(self, ident, sel, ectx): 4471 lst = self.elt_list[:] 4472 if hasattr(self, 'ext_list'): 4473 lst.extend(self.ext_list) 4474 ee = None 4475 for e in (self.elt_list): 4476 if e.IsNamed() and (e.name == sel): 4477 ee = e 4478 break 4479 if not ee: 4480 print("#CHOICE %s does not contain item %s" % (ident, sel)) 4481 return ee 4482 4483 def sel_req(self, ident, sel, ectx): 4484 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self)) 4485 ee = self.sel_item(ident, sel, ectx) 4486 if ee: 4487 ee.eth_reg(ident, ectx, tstrip=0, selflag=True) 4488 4489 def eth_ftype(self, ectx): 4490 return ('FT_UINT32', 'BASE_DEC') 4491 4492 def eth_ftype_sel(self, sel, ectx): 4493 ee = self.sel_item('', sel, ectx) 4494 if ee: 4495 return ee.eth_ftype(ectx) 4496 else: 4497 return ('FT_NONE', 'BASE_NONE') 4498 4499 def eth_strings(self): 4500 return '$$' 4501 4502 def eth_need_tree(self): 4503 return True 4504 4505 def eth_has_vals(self): 4506 return True 4507 4508 def GetTTag(self, ectx): 4509 lst = self.elt_list 4510 cls = 'BER_CLASS_ANY/*choice*/' 4511 #if hasattr(self, 'ext_list'): 4512 # lst.extend(self.ext_list) 4513 #if (len(lst) > 0): 4514 # cls = lst[0].GetTag(ectx)[0] 4515 #for e in (lst): 4516 # if (e.GetTag(ectx)[0] != cls): 4517 # cls = '-1/*choice*/' 4518 return (cls, '-1/*choice*/') 4519 4520 def GetTTagSel(self, sel, ectx): 4521 ee = self.sel_item('', sel, ectx) 4522 if ee: 4523 return ee.GetTag(ectx) 4524 else: 4525 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/') 4526 4527 def IndetermTag(self, ectx): 4528 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag())) 4529 return not self.HasOwnTag() 4530 4531 def detect_tagval(self, ectx): 4532 tagval = False 4533 lst = self.elt_list[:] 4534 if hasattr(self, 'ext_list'): 4535 lst.extend(self.ext_list) 4536 if (len(lst) > 0) and (not (ectx.Per() or ectx.Oer()) or lst[0].HasOwnTag()): 4537 t = lst[0].GetTag(ectx)[0] 4538 tagval = True 4539 else: 4540 t = '' 4541 tagval = False 4542 if (t == 'BER_CLASS_UNI'): 4543 tagval = False 4544 for e in (lst): 4545 if not (ectx.Per() or ectx.Oer()) or e.HasOwnTag(): 4546 tt = e.GetTag(ectx)[0] 4547 else: 4548 tt = '' 4549 tagval = False 4550 if (tt != t): 4551 tagval = False 4552 return tagval 4553 4554 def get_vals(self, ectx): 4555 tagval = self.detect_tagval(ectx) 4556 vals = [] 4557 cnt = 0 4558 for e in (self.elt_list): 4559 if (tagval): val = e.GetTag(ectx)[1] 4560 else: val = str(cnt) 4561 vals.append((val, e.name)) 4562 cnt += 1 4563 if hasattr(self, 'ext_list'): 4564 for e in (self.ext_list): 4565 if (tagval): val = e.GetTag(ectx)[1] 4566 else: val = str(cnt) 4567 vals.append((val, e.name)) 4568 cnt += 1 4569 return vals 4570 4571 def eth_type_vals(self, tname, ectx): 4572 out = '\n' 4573 vals = self.get_vals(ectx) 4574 out += ectx.eth_vals(tname, vals) 4575 return out 4576 4577 def reg_enum_vals(self, tname, ectx): 4578 vals = self.get_vals(ectx) 4579 for (val, id) in vals: 4580 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id)) 4581 4582 def eth_type_enum(self, tname, ectx): 4583 out = '\n' 4584 vals = self.get_vals(ectx) 4585 out += ectx.eth_enum(tname, vals) 4586 return out 4587 4588 def eth_type_default_pars(self, ectx, tname): 4589 pars = Type.eth_type_default_pars(self, ectx, tname) 4590 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice' 4591 return pars 4592 4593 def eth_type_default_table(self, ectx, tname): 4594 def out_item(val, e, ext, ectx): 4595 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM 4596 if (has_enum): 4597 vval = ectx.eth_enum_item(tname, e.name) 4598 else: 4599 vval = val 4600 f = fname + '/' + e.name 4601 ef = ectx.field[f]['ethname'] 4602 t = ectx.eth_hf[ef]['ethtype'] 4603 if (ectx.Ber()): 4604 opt = '' 4605 if (not e.HasOwnTag()): 4606 opt = 'BER_FLAGS_NOOWNTAG' 4607 elif (e.HasImplicitTag(ectx)): 4608 if (opt): opt += '|' 4609 opt += 'BER_FLAGS_IMPLTAG' 4610 if (not opt): opt = '0' 4611 if (ectx.Ber()): 4612 (tc, tn) = e.GetTag(ectx) 4613 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \ 4614 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t) 4615 elif (ectx.Per() or ectx.Oer()): 4616 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \ 4617 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t) 4618 else: 4619 out = '' 4620 return out 4621 # end out_item() 4622 #print "eth_type_default_table(tname='%s')" % (tname) 4623 fname = ectx.eth_type[tname]['ref'][0] 4624 tagval = self.detect_tagval(ectx) 4625 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n" 4626 cnt = 0 4627 if hasattr(self, 'ext_list'): 4628 ext = 'ASN1_EXTENSION_ROOT' 4629 else: 4630 ext = 'ASN1_NO_EXTENSIONS' 4631 empty_ext_flag = '0' 4632 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0): 4633 empty_ext_flag = ext 4634 for e in (self.elt_list): 4635 if (tagval): val = e.GetTag(ectx)[1] 4636 else: val = str(cnt) 4637 table += out_item(val, e, ext, ectx) 4638 cnt += 1 4639 if hasattr(self, 'ext_list'): 4640 for e in (self.ext_list): 4641 if (tagval): val = e.GetTag(ectx)[1] 4642 else: val = str(cnt) 4643 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx) 4644 cnt += 1 4645 if (ectx.Ber()): 4646 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n" 4647 else: 4648 table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag) 4649 return table 4650 4651 def eth_type_default_body(self, ectx, tname): 4652 if (ectx.Ber()): 4653 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset', 4654 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4655 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'), 4656 ('%(VAL_PTR)s',),)) 4657 elif (ectx.Per() or ectx.Oer()): 4658 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset', 4659 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4660 ('%(ETT_INDEX)s', '%(TABLE)s',), 4661 ('%(VAL_PTR)s',),)) 4662 else: 4663 body = '#error Can not decode %s' % (tname) 4664 return body 4665 4666#--- ChoiceValue ---------------------------------------------------- 4667class ChoiceValue (Value): 4668 def to_str(self, ectx): 4669 return self.val.to_str(ectx) 4670 4671 def fld_obj_eq(self, other): 4672 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val)) 4673 4674#--- EnumeratedType ----------------------------------------------------------- 4675class EnumeratedType (Type): 4676 def to_python (self, ctx): 4677 def strify_one (named_num): 4678 return "%s=%s" % (named_num.ident, named_num.val) 4679 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val)) 4680 4681 def eth_ftype(self, ectx): 4682 return ('FT_UINT32', 'BASE_DEC') 4683 4684 def eth_strings(self): 4685 return '$$' 4686 4687 def eth_has_vals(self): 4688 return True 4689 4690 def GetTTag(self, ectx): 4691 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED') 4692 4693 def get_vals_etc(self, ectx): 4694 vals = [] 4695 lastv = 0 4696 used = {} 4697 maxv = 0 4698 root_num = 0 4699 ext_num = 0 4700 map_table = [] 4701 for e in (self.val): 4702 if e.type == 'NamedNumber': 4703 used[int(e.val)] = True 4704 for e in (self.val): 4705 if e.type == 'NamedNumber': 4706 val = int(e.val) 4707 else: 4708 while lastv in used: 4709 lastv += 1 4710 val = lastv 4711 used[val] = True 4712 vals.append((val, e.ident)) 4713 map_table.append(val) 4714 root_num += 1 4715 if val > maxv: 4716 maxv = val 4717 if self.ext is not None: 4718 for e in (self.ext): 4719 if e.type == 'NamedNumber': 4720 used[int(e.val)] = True 4721 for e in (self.ext): 4722 if e.type == 'NamedNumber': 4723 val = int(e.val) 4724 else: 4725 while lastv in used: 4726 lastv += 1 4727 val = lastv 4728 used[val] = True 4729 vals.append((val, e.ident)) 4730 map_table.append(val) 4731 ext_num += 1 4732 if val > maxv: 4733 maxv = val 4734 need_map = False 4735 for i in range(len(map_table)): 4736 need_map = need_map or (map_table[i] != i) 4737 if (not need_map): 4738 map_table = None 4739 return (vals, root_num, ext_num, map_table) 4740 4741 def eth_type_vals(self, tname, ectx): 4742 out = '\n' 4743 vals = self.get_vals_etc(ectx)[0] 4744 out += ectx.eth_vals(tname, vals) 4745 return out 4746 4747 def reg_enum_vals(self, tname, ectx): 4748 vals = self.get_vals_etc(ectx)[0] 4749 for (val, id) in vals: 4750 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id)) 4751 4752 def eth_type_enum(self, tname, ectx): 4753 out = '\n' 4754 vals = self.get_vals_etc(ectx)[0] 4755 out += ectx.eth_enum(tname, vals) 4756 return out 4757 4758 def eth_type_default_pars(self, ectx, tname): 4759 pars = Type.eth_type_default_pars(self, ectx, tname) 4760 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:] 4761 if self.ext is not None: 4762 ext = 'TRUE' 4763 else: 4764 ext = 'FALSE' 4765 pars['ROOT_NUM'] = str(root_num) 4766 pars['EXT'] = ext 4767 pars['EXT_NUM'] = str(ext_num) 4768 if (map_table): 4769 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map' 4770 else: 4771 pars['TABLE'] = 'NULL' 4772 return pars 4773 4774 def eth_type_default_table(self, ectx, tname): 4775 if (not ectx.Per() and not ectx.Oer()): return '' 4776 map_table = self.get_vals_etc(ectx)[3] 4777 if map_table is None: return '' 4778 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {" 4779 table += ", ".join([str(v) for v in map_table]) 4780 table += "};\n" 4781 return table 4782 4783 def eth_type_default_body(self, ectx, tname): 4784 if (ectx.Ber()): 4785 if (ectx.constraints_check and self.HasValueConstraint()): 4786 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset', 4787 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 4788 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 4789 else: 4790 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset', 4791 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), 4792 ('%(VAL_PTR)s',),)) 4793 elif (ectx.Per() or ectx.Oer()): 4794 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset', 4795 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 4796 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),)) 4797 else: 4798 body = '#error Can not decode %s' % (tname) 4799 return body 4800 4801#--- EmbeddedPDVType ----------------------------------------------------------- 4802class EmbeddedPDVType (Type): 4803 def eth_tname(self): 4804 return 'EMBEDDED_PDV' 4805 4806 def eth_ftype(self, ectx): 4807 return ('FT_NONE', 'BASE_NONE') 4808 4809 def GetTTag(self, ectx): 4810 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV') 4811 4812 def eth_type_default_pars(self, ectx, tname): 4813 pars = Type.eth_type_default_pars(self, ectx, tname) 4814 if ectx.default_embedded_pdv_cb: 4815 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb 4816 else: 4817 pars['TYPE_REF_FN'] = 'NULL' 4818 return pars 4819 4820 def eth_type_default_body(self, ectx, tname): 4821 if (ectx.Ber()): 4822 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset', 4823 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) 4824 elif (ectx.Per()): 4825 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset', 4826 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) 4827 else: 4828 body = '#error Can not decode %s' % (tname) 4829 return body 4830 4831#--- ExternalType ----------------------------------------------------------- 4832class ExternalType (Type): 4833 def eth_tname(self): 4834 return 'EXTERNAL' 4835 4836 def eth_ftype(self, ectx): 4837 return ('FT_NONE', 'BASE_NONE') 4838 4839 def GetTTag(self, ectx): 4840 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL') 4841 4842 def eth_type_default_pars(self, ectx, tname): 4843 pars = Type.eth_type_default_pars(self, ectx, tname) 4844 if ectx.default_external_type_cb: 4845 pars['TYPE_REF_FN'] = ectx.default_external_type_cb 4846 else: 4847 pars['TYPE_REF_FN'] = 'NULL' 4848 return pars 4849 4850 def eth_type_default_body(self, ectx, tname): 4851 if (ectx.Ber()): 4852 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset', 4853 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) 4854 elif (ectx.Per()): 4855 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset', 4856 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) 4857 else: 4858 body = '#error Can not decode %s' % (tname) 4859 return body 4860 4861#--- OpenType ----------------------------------------------------------- 4862class OpenType (Type): 4863 def to_python (self, ctx): 4864 return "asn1.ANY" 4865 4866 def single_type(self): 4867 if (self.HasConstraint() and 4868 self.constr.type == 'Type' and 4869 self.constr.subtype.type == 'Type_Ref'): 4870 return self.constr.subtype.val 4871 return None 4872 4873 def eth_reg_sub(self, ident, ectx): 4874 t = self.single_type() 4875 if t: 4876 ectx.eth_dep_add(ident, t) 4877 4878 def eth_tname(self): 4879 t = self.single_type() 4880 if t: 4881 return 'OpenType_' + t 4882 else: 4883 return Type.eth_tname(self) 4884 4885 def eth_ftype(self, ectx): 4886 return ('FT_NONE', 'BASE_NONE') 4887 4888 def GetTTag(self, ectx): 4889 return ('BER_CLASS_ANY', '0') 4890 4891 def eth_type_default_pars(self, ectx, tname): 4892 pars = Type.eth_type_default_pars(self, ectx, tname) 4893 pars['FN_VARIANT'] = ectx.default_opentype_variant 4894 t = self.single_type() 4895 if t: 4896 t = ectx.type[t]['ethname'] 4897 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] 4898 pars['TYPE_REF_TNAME'] = t 4899 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' 4900 else: 4901 pars['TYPE_REF_FN'] = 'NULL' 4902 return pars 4903 4904 def eth_type_default_body(self, ectx, tname): 4905 if (ectx.Per()): 4906 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset', 4907 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) 4908 else: 4909 body = '#error Can not decode %s' % (tname) 4910 return body 4911 4912#--- InstanceOfType ----------------------------------------------------------- 4913class InstanceOfType (Type): 4914 def eth_tname(self): 4915 return 'INSTANCE_OF' 4916 4917 def eth_ftype(self, ectx): 4918 return ('FT_NONE', 'BASE_NONE') 4919 4920 def GetTTag(self, ectx): 4921 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL') 4922 4923 def eth_type_default_pars(self, ectx, tname): 4924 pars = Type.eth_type_default_pars(self, ectx, tname) 4925 if ectx.default_external_type_cb: 4926 pars['TYPE_REF_FN'] = ectx.default_external_type_cb 4927 else: 4928 pars['TYPE_REF_FN'] = 'NULL' 4929 return pars 4930 4931 def eth_type_default_body(self, ectx, tname): 4932 if (ectx.Ber()): 4933 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset', 4934 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),)) 4935 else: 4936 body = '#error Can not decode %s' % (tname) 4937 return body 4938 4939#--- AnyType ----------------------------------------------------------- 4940class AnyType (Type): 4941 def to_python (self, ctx): 4942 return "asn1.ANY" 4943 4944 def eth_ftype(self, ectx): 4945 return ('FT_NONE', 'BASE_NONE') 4946 4947 def GetTTag(self, ectx): 4948 return ('BER_CLASS_ANY', '0') 4949 4950 def eth_type_default_body(self, ectx, tname): 4951 body = '#error Can not decode %s' % (tname) 4952 return body 4953 4954class Literal (Node): 4955 def to_python (self, ctx): 4956 return self.val 4957 4958#--- NullType ----------------------------------------------------------------- 4959class NullType (Type): 4960 def to_python (self, ctx): 4961 return 'asn1.NULL' 4962 4963 def eth_tname(self): 4964 return 'NULL' 4965 4966 def GetTTag(self, ectx): 4967 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL') 4968 4969 def eth_type_default_body(self, ectx, tname): 4970 if (ectx.Ber()): 4971 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset', 4972 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),)) 4973 elif (ectx.Per() or ectx.Oer()): 4974 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset', 4975 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) 4976 else: 4977 body = '#error Can not decode %s' % (tname) 4978 return body 4979 4980#--- NullValue ---------------------------------------------------- 4981class NullValue (Value): 4982 def to_str(self, ectx): 4983 return 'NULL' 4984 4985#--- RealType ----------------------------------------------------------------- 4986class RealType (Type): 4987 def to_python (self, ctx): 4988 return 'asn1.REAL' 4989 4990 def eth_tname(self): 4991 return 'REAL' 4992 4993 def GetTTag(self, ectx): 4994 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL') 4995 4996 def eth_ftype(self, ectx): 4997 return ('FT_DOUBLE', 'BASE_NONE') 4998 4999 def eth_type_default_body(self, ectx, tname): 5000 if (ectx.Ber()): 5001 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset', 5002 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), 5003 ('%(VAL_PTR)s',),)) 5004 elif (ectx.Per()): 5005 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset', 5006 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5007 else: 5008 body = '#error Can not decode %s' % (tname) 5009 return body 5010 5011#--- BooleanType -------------------------------------------------------------- 5012class BooleanType (Type): 5013 def to_python (self, ctx): 5014 return 'asn1.BOOLEAN' 5015 5016 def eth_tname(self): 5017 return 'BOOLEAN' 5018 5019 def GetTTag(self, ectx): 5020 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN') 5021 5022 def eth_ftype(self, ectx): 5023 return ('FT_BOOLEAN', 'BASE_NONE') 5024 5025 def eth_type_default_body(self, ectx, tname): 5026 if (ectx.Ber()): 5027 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset', 5028 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),)) 5029 elif (ectx.Per()): 5030 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset', 5031 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5032 elif (ectx.Oer()): 5033 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset', 5034 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5035 else: 5036 body = '#error Can not decode %s' % (tname) 5037 return body 5038 5039#--- OctetStringType ---------------------------------------------------------- 5040class OctetStringType (Type): 5041 def to_python (self, ctx): 5042 return 'asn1.OCTSTRING' 5043 5044 def eth_tname(self): 5045 if not self.HasConstraint(): 5046 return 'OCTET_STRING' 5047 elif self.constr.type == 'Size': 5048 return 'OCTET_STRING' + '_' + self.constr.eth_constrname() 5049 else: 5050 return '#' + self.type + '_' + str(id(self)) 5051 5052 def eth_ftype(self, ectx): 5053 return ('FT_BYTES', 'BASE_NONE') 5054 5055 def GetTTag(self, ectx): 5056 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING') 5057 5058 def eth_need_pdu(self, ectx): 5059 pdu = None 5060 if self.HasContentsConstraint(): 5061 t = self.constr.GetContents(ectx) 5062 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')): 5063 pdu = { 'type' : t, 5064 'new' : ectx.default_containing_variant == '_pdu_new' } 5065 return pdu 5066 5067 def eth_type_default_pars(self, ectx, tname): 5068 pars = Type.eth_type_default_pars(self, ectx, tname) 5069 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) 5070 if self.HasContentsConstraint(): 5071 pars['FN_VARIANT'] = ectx.default_containing_variant 5072 t = self.constr.GetContents(ectx) 5073 if t: 5074 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'): 5075 t = ectx.field[t]['ethname'] 5076 pars['TYPE_REF_PROTO'] = '' 5077 pars['TYPE_REF_TNAME'] = t 5078 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s' 5079 else: 5080 t = ectx.type[t]['ethname'] 5081 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] 5082 pars['TYPE_REF_TNAME'] = t 5083 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' 5084 else: 5085 pars['TYPE_REF_FN'] = 'NULL' 5086 return pars 5087 5088 def eth_type_default_body(self, ectx, tname): 5089 if (ectx.Ber()): 5090 if (ectx.constraints_check and self.HasSizeConstraint()): 5091 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret='offset', 5092 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 5093 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5094 else: 5095 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset', 5096 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), 5097 ('%(VAL_PTR)s',),)) 5098 elif (ectx.Per() or ectx.Oer()): 5099 if self.HasContentsConstraint(): 5100 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset', 5101 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5102 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),)) 5103 else: 5104 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset', 5105 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5106 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),)) 5107 else: 5108 body = '#error Can not decode %s' % (tname) 5109 return body 5110 5111#--- CharacterStringType ------------------------------------------------------ 5112class CharacterStringType (Type): 5113 def eth_tname(self): 5114 if not self.HasConstraint(): 5115 return self.eth_tsname() 5116 elif self.constr.type == 'Size': 5117 return self.eth_tsname() + '_' + self.constr.eth_constrname() 5118 else: 5119 return '#' + self.type + '_' + str(id(self)) 5120 5121 def eth_ftype(self, ectx): 5122 return ('FT_STRING', 'BASE_NONE') 5123 5124class RestrictedCharacterStringType (CharacterStringType): 5125 def to_python (self, ctx): 5126 return 'asn1.' + self.eth_tsname() 5127 5128 def GetTTag(self, ectx): 5129 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname()) 5130 5131 def eth_type_default_pars(self, ectx, tname): 5132 pars = Type.eth_type_default_pars(self, ectx, tname) 5133 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) 5134 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1]) 5135 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx) 5136 return pars 5137 5138 def eth_type_default_body(self, ectx, tname): 5139 if (ectx.Ber()): 5140 if (ectx.constraints_check and self.HasSizeConstraint()): 5141 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret='offset', 5142 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'), 5143 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 5144 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5145 else: 5146 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset', 5147 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'), 5148 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), 5149 ('%(VAL_PTR)s',),)) 5150 elif (ectx.Per() and self.HasPermAlph()): 5151 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset', 5152 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5153 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'), 5154 ('%(VAL_PTR)s',),)) 5155 elif (ectx.Per()): 5156 if (self.eth_tsname() == 'GeneralString'): 5157 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', 5158 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),)) 5159 elif (self.eth_tsname() == 'GeneralizedTime' or self.eth_tsname() == 'UTCTime'): 5160 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset', 5161 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5162 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) 5163 else: 5164 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', 5165 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5166 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) 5167 elif (ectx.Oer()): 5168 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', 5169 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5170 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),)) 5171 else: 5172 body = '#error Can not decode %s' % (tname) 5173 return body 5174 5175class BMPStringType (RestrictedCharacterStringType): 5176 def eth_tsname(self): 5177 return 'BMPString' 5178 5179class GeneralStringType (RestrictedCharacterStringType): 5180 def eth_tsname(self): 5181 return 'GeneralString' 5182 5183class GraphicStringType (RestrictedCharacterStringType): 5184 def eth_tsname(self): 5185 return 'GraphicString' 5186 5187class IA5StringType (RestrictedCharacterStringType): 5188 def eth_tsname(self): 5189 return 'IA5String' 5190 5191class NumericStringType (RestrictedCharacterStringType): 5192 def eth_tsname(self): 5193 return 'NumericString' 5194 5195class PrintableStringType (RestrictedCharacterStringType): 5196 def eth_tsname(self): 5197 return 'PrintableString' 5198 5199class TeletexStringType (RestrictedCharacterStringType): 5200 def eth_tsname(self): 5201 return 'TeletexString' 5202 5203class T61StringType (RestrictedCharacterStringType): 5204 def eth_tsname(self): 5205 return 'T61String' 5206 def GetTTag(self, ectx): 5207 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString') 5208 5209class UniversalStringType (RestrictedCharacterStringType): 5210 def eth_tsname(self): 5211 return 'UniversalString' 5212 5213class UTF8StringType (RestrictedCharacterStringType): 5214 def eth_tsname(self): 5215 return 'UTF8String' 5216 5217class VideotexStringType (RestrictedCharacterStringType): 5218 def eth_tsname(self): 5219 return 'VideotexString' 5220 5221class VisibleStringType (RestrictedCharacterStringType): 5222 def eth_tsname(self): 5223 return 'VisibleString' 5224 5225class ISO646StringType (RestrictedCharacterStringType): 5226 def eth_tsname(self): 5227 return 'ISO646String' 5228 def GetTTag(self, ectx): 5229 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString') 5230 5231class UnrestrictedCharacterStringType (CharacterStringType): 5232 def to_python (self, ctx): 5233 return 'asn1.UnrestrictedCharacterString' 5234 def eth_tsname(self): 5235 return 'CHARACTER_STRING' 5236 5237#--- UsefulType --------------------------------------------------------------- 5238class GeneralizedTime (RestrictedCharacterStringType): 5239 def eth_tsname(self): 5240 return 'GeneralizedTime' 5241 5242 def eth_type_default_body(self, ectx, tname): 5243 if (ectx.Ber()): 5244 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', 5245 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),)) 5246 return body 5247 else: 5248 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname) 5249 5250class UTCTime (RestrictedCharacterStringType): 5251 def eth_tsname(self): 5252 return 'UTCTime' 5253 5254 def eth_type_default_body(self, ectx, tname): 5255 if (ectx.Ber()): 5256 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset', 5257 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', 'NULL', 'NULL'),)) 5258 return body 5259 else: 5260 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname) 5261 5262class ObjectDescriptor (RestrictedCharacterStringType): 5263 def eth_tsname(self): 5264 return 'ObjectDescriptor' 5265 5266 def eth_type_default_body(self, ectx, tname): 5267 if (ectx.Ber()): 5268 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname) 5269 elif (ectx.Per()): 5270 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset', 5271 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5272 else: 5273 body = '#error Can not decode %s' % (tname) 5274 return body 5275 5276#--- ObjectIdentifierType ----------------------------------------------------- 5277class ObjectIdentifierType (Type): 5278 def to_python (self, ctx): 5279 return 'asn1.OBJECT_IDENTIFIER' 5280 5281 def eth_tname(self): 5282 return 'OBJECT_IDENTIFIER' 5283 5284 def eth_ftype(self, ectx): 5285 return ('FT_OID', 'BASE_NONE') 5286 5287 def GetTTag(self, ectx): 5288 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID') 5289 5290 def eth_type_default_pars(self, ectx, tname): 5291 pars = Type.eth_type_default_pars(self, ectx, tname) 5292 pars['FN_VARIANT'] = ectx.default_oid_variant 5293 return pars 5294 5295 def eth_type_default_body(self, ectx, tname): 5296 if (ectx.Ber()): 5297 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset', 5298 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5299 elif (ectx.Per()): 5300 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset', 5301 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5302 else: 5303 body = '#error Can not decode %s' % (tname) 5304 return body 5305 5306#--- ObjectIdentifierValue ---------------------------------------------------- 5307class ObjectIdentifierValue (Value): 5308 def get_num(self, path, val): 5309 return str(oid_names.get(path + '/' + val, val)) 5310 5311 def to_str(self, ectx): 5312 out = '' 5313 path = '' 5314 first = True 5315 sep = '' 5316 for v in self.comp_list: 5317 if isinstance(v, Node) and (v.type == 'name_and_number'): 5318 vstr = v.number 5319 elif v.isdigit(): 5320 vstr = v 5321 else: 5322 vstr = self.get_num(path, v) 5323 if not first and not vstr.isdigit(): 5324 vstr = ectx.value_get_val(vstr) 5325 if first: 5326 if vstr.isdigit(): 5327 out += '"' + vstr 5328 else: 5329 out += ectx.value_get_eth(vstr) + '"' 5330 else: 5331 out += sep + vstr 5332 path += sep + vstr 5333 first = False 5334 sep = '.' 5335 out += '"' 5336 return out 5337 5338 def get_dep(self): 5339 v = self.comp_list[0] 5340 if isinstance(v, Node) and (v.type == 'name_and_number'): 5341 return None 5342 elif v.isdigit(): 5343 return None 5344 else: 5345 vstr = self.get_num('', v) 5346 if vstr.isdigit(): 5347 return None 5348 else: 5349 return vstr 5350 5351class NamedNumber(Node): 5352 def to_python (self, ctx): 5353 return "('%s',%s)" % (self.ident, self.val) 5354 def __lt__(self, other): 5355 return int(self.val) < int(other.val) 5356 5357class NamedNumListBase(Node): 5358 def to_python (self, ctx): 5359 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join ( 5360 [x.to_python (ctx) for x in self.named_list])) 5361 5362#--- RelativeOIDType ---------------------------------------------------------- 5363class RelativeOIDType (Type): 5364 5365 def eth_tname(self): 5366 return 'RELATIVE_OID' 5367 5368 def eth_ftype(self, ectx): 5369 return ('FT_REL_OID', 'BASE_NONE') 5370 5371 def GetTTag(self, ectx): 5372 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID') 5373 5374 def eth_type_default_pars(self, ectx, tname): 5375 pars = Type.eth_type_default_pars(self, ectx, tname) 5376 pars['FN_VARIANT'] = ectx.default_oid_variant 5377 return pars 5378 5379 def eth_type_default_body(self, ectx, tname): 5380 if (ectx.Ber()): 5381 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset', 5382 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5383 elif (ectx.Per()): 5384 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset', 5385 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5386 else: 5387 body = '#error Can not decode %s' % (tname) 5388 return body 5389 5390 5391#--- IntegerType -------------------------------------------------------------- 5392class IntegerType (Type): 5393 def to_python (self, ctx): 5394 return "asn1.INTEGER_class ([%s])" % (",".join ( 5395 [x.to_python (ctx) for x in self.named_list])) 5396 5397 def add_named_value(self, ident, val): 5398 e = NamedNumber(ident = ident, val = val) 5399 if not self.named_list: 5400 self.named_list = [] 5401 self.named_list.append(e) 5402 5403 def eth_tname(self): 5404 if self.named_list: 5405 return Type.eth_tname(self) 5406 if not self.HasConstraint(): 5407 return 'INTEGER' 5408 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange': 5409 return 'INTEGER' + '_' + self.constr.eth_constrname() 5410 else: 5411 return 'INTEGER' + '_' + self.constr.eth_tname() 5412 5413 def GetTTag(self, ectx): 5414 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER') 5415 5416 5417 def eth_ftype(self, ectx): 5418 if self.HasConstraint(): 5419 if not self.constr.IsNegativ(): 5420 if self.constr.Needs64b(ectx): 5421 return ('FT_UINT64', 'BASE_DEC') 5422 else: 5423 return ('FT_UINT32', 'BASE_DEC') 5424 if self.constr.Needs64b(ectx): 5425 return ('FT_INT64', 'BASE_DEC') 5426 return ('FT_INT32', 'BASE_DEC') 5427 5428 def eth_strings(self): 5429 if (self.named_list): 5430 return '$$' 5431 else: 5432 return 'NULL' 5433 5434 def eth_has_vals(self): 5435 if (self.named_list): 5436 return True 5437 else: 5438 return False 5439 5440 def get_vals(self, ectx): 5441 vals = [] 5442 for e in (self.named_list): 5443 vals.append((int(e.val), e.ident)) 5444 return vals 5445 5446 def eth_type_vals(self, tname, ectx): 5447 if not self.eth_has_vals(): return '' 5448 out = '\n' 5449 vals = self.get_vals(ectx) 5450 out += ectx.eth_vals(tname, vals) 5451 return out 5452 5453 def reg_enum_vals(self, tname, ectx): 5454 vals = self.get_vals(ectx) 5455 for (val, id) in vals: 5456 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id)) 5457 5458 def eth_type_enum(self, tname, ectx): 5459 if not self.eth_has_enum(tname, ectx): return '' 5460 out = '\n' 5461 vals = self.get_vals(ectx) 5462 out += ectx.eth_enum(tname, vals) 5463 return out 5464 5465 def eth_type_default_pars(self, ectx, tname): 5466 pars = Type.eth_type_default_pars(self, ectx, tname) 5467 if self.HasValueConstraint(): 5468 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx) 5469 if (pars['FN_VARIANT'] == '') and self.constr.Needs64b(ectx): 5470 if ectx.Ber(): pars['FN_VARIANT'] = '64' 5471 else: 5472 if (ectx.Oer() and pars['MAX_VAL'] == 'NO_BOUND'): 5473 pars['FN_VARIANT'] = '_64b_no_ub' 5474 else: 5475 pars['FN_VARIANT'] = '_64b' 5476 return pars 5477 5478 def eth_type_default_body(self, ectx, tname): 5479 if (ectx.Ber()): 5480 if (ectx.constraints_check and self.HasValueConstraint()): 5481 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset', 5482 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 5483 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),)) 5484 else: 5485 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset', 5486 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'), 5487 ('%(VAL_PTR)s',),)) 5488 elif (ectx.Per() or ectx.Oer()): 5489 if (self.HasValueConstraint()): 5490 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset', 5491 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5492 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),)) 5493 else: 5494 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset', 5495 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),)) 5496 else: 5497 body = '#error Can not decode %s' % (tname) 5498 return body 5499 5500#--- BitStringType ------------------------------------------------------------ 5501class BitStringType (Type): 5502 def to_python (self, ctx): 5503 return "asn1.BITSTRING_class ([%s])" % (",".join ( 5504 [x.to_python (ctx) for x in self.named_list])) 5505 5506 def eth_tname(self): 5507 if self.named_list: 5508 return Type.eth_tname(self) 5509 elif not self.HasConstraint(): 5510 return 'BIT_STRING' 5511 elif self.constr.IsSize(): 5512 return 'BIT_STRING' + '_' + self.constr.eth_constrname() 5513 else: 5514 return '#' + self.type + '_' + str(id(self)) 5515 5516 def GetTTag(self, ectx): 5517 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING') 5518 5519 def eth_ftype(self, ectx): 5520 return ('FT_BYTES', 'BASE_NONE') 5521 5522 def eth_need_tree(self): 5523 return self.named_list 5524 5525 def eth_need_pdu(self, ectx): 5526 pdu = None 5527 if self.HasContentsConstraint(): 5528 t = self.constr.GetContents(ectx) 5529 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')): 5530 pdu = { 'type' : t, 5531 'new' : ectx.default_containing_variant == '_pdu_new' } 5532 return pdu 5533 5534 def sortNamedBits(self): 5535 return self.named_list.val 5536 5537 def eth_named_bits(self): 5538 bits = [] 5539 if (self.named_list): 5540 sorted_list = self.named_list 5541 sorted_list.sort() 5542 expected_bit_no = 0; 5543 for e in (sorted_list): 5544 # Fill the table with "spare_bit" for "un named bits" 5545 if (int(e.val) != 0) and (expected_bit_no != int(e.val)): 5546 while ( expected_bit_no < int(e.val)): 5547 bits.append((expected_bit_no, ("spare_bit%u" % (expected_bit_no)))) 5548 expected_bit_no = expected_bit_no + 1 5549 #print ("Adding named bits to list %s bit no %d" % (e.ident, int (e.val))) 5550 bits.append((int(e.val), e.ident)) 5551 expected_bit_no = int(e.val) + 1 5552 return bits 5553 5554 def eth_type_default_pars(self, ectx, tname): 5555 pars = Type.eth_type_default_pars(self, ectx, tname) 5556 pars['LEN_PTR'] = 'NULL' 5557 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx) 5558 if 'ETT_INDEX' not in pars: 5559 pars['ETT_INDEX'] = '-1' 5560 pars['TABLE'] = 'NULL' 5561 if self.eth_named_bits(): 5562 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits' 5563 if self.HasContentsConstraint(): 5564 pars['FN_VARIANT'] = ectx.default_containing_variant 5565 t = self.constr.GetContents(ectx) 5566 if t: 5567 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'): 5568 t = ectx.field[t]['ethname'] 5569 pars['TYPE_REF_PROTO'] = '' 5570 pars['TYPE_REF_TNAME'] = t 5571 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s' 5572 else: 5573 t = ectx.type[t]['ethname'] 5574 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto'] 5575 pars['TYPE_REF_TNAME'] = t 5576 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s' 5577 else: 5578 pars['TYPE_REF_FN'] = 'NULL' 5579 return pars 5580 5581 def eth_type_default_table(self, ectx, tname): 5582 #print ("eth_type_default_table(tname='%s')" % (tname)) 5583 table = '' 5584 bits = self.eth_named_bits() 5585 if (bits): 5586 table = ectx.eth_bits(tname, bits) 5587 return table 5588 5589 def eth_type_default_body(self, ectx, tname): 5590 bits = self.eth_named_bits() 5591 if (ectx.Ber()): 5592 if (ectx.constraints_check and self.HasSizeConstraint()): 5593 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret='offset', 5594 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 5595 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%s' % len(bits),'%(HF_INDEX)s', '%(ETT_INDEX)s',), 5596 ('%(VAL_PTR)s',),)) 5597 else: 5598 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset', 5599 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'), 5600 ('%(TABLE)s', '%s' % len(bits), '%(HF_INDEX)s', '%(ETT_INDEX)s',), 5601 ('%(VAL_PTR)s',),)) 5602 elif (ectx.Per() or ectx.Oer()): 5603 if self.HasContentsConstraint(): 5604 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset', 5605 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5606 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),)) 5607 else: 5608 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset', 5609 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'), 5610 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s','%(TABLE)s', '%s' % len(bits), '%(VAL_PTR)s', '%(LEN_PTR)s'),)) 5611 else: 5612 body = '#error Can not decode %s' % (tname) 5613 return body 5614 5615#--- BStringValue ------------------------------------------------------------ 5616bstring_tab = { 5617 '0000' : '0', 5618 '0001' : '1', 5619 '0010' : '2', 5620 '0011' : '3', 5621 '0100' : '4', 5622 '0101' : '5', 5623 '0110' : '6', 5624 '0111' : '7', 5625 '1000' : '8', 5626 '1001' : '9', 5627 '1010' : 'A', 5628 '1011' : 'B', 5629 '1100' : 'C', 5630 '1101' : 'D', 5631 '1110' : 'E', 5632 '1111' : 'F', 5633} 5634class BStringValue (Value): 5635 def to_str(self, ectx): 5636 v = self.val[1:-2] 5637 if len(v) % 8: 5638 v += '0' * (8 - len(v) % 8) 5639 vv = '0x' 5640 for i in (list(range(0, len(v), 4))): 5641 vv += bstring_tab[v[i:i+4]] 5642 return vv 5643 5644#--- HStringValue ------------------------------------------------------------ 5645class HStringValue (Value): 5646 def to_str(self, ectx): 5647 vv = '0x' 5648 vv += self.val[1:-2] 5649 return vv 5650 def __int__(self): 5651 return int(self.val[1:-2], 16) 5652 5653#--- FieldSpec ---------------------------------------------------------------- 5654class FieldSpec (Node): 5655 def __init__(self,*args, **kw) : 5656 self.name = None 5657 Node.__init__ (self,*args, **kw) 5658 5659 def SetName(self, name): 5660 self.name = name 5661 5662 def get_repr(self): 5663 return ['#UNSUPPORTED_' + self.type] 5664 5665 def fld_repr(self): 5666 repr = [self.name] 5667 repr.extend(self.get_repr()) 5668 return repr 5669 5670class TypeFieldSpec (FieldSpec): 5671 def get_repr(self): 5672 return [] 5673 5674class FixedTypeValueFieldSpec (FieldSpec): 5675 def get_repr(self): 5676 if isinstance(self.typ, Type_Ref): 5677 repr = ['TypeReference', self.typ.val] 5678 else: 5679 repr = [self.typ.type] 5680 return repr 5681 5682class VariableTypeValueFieldSpec (FieldSpec): 5683 def get_repr(self): 5684 return ['_' + self.type] 5685 5686class FixedTypeValueSetFieldSpec (FieldSpec): 5687 def get_repr(self): 5688 return ['_' + self.type] 5689 5690class ObjectFieldSpec (FieldSpec): 5691 def get_repr(self): 5692 return ['ClassReference', self.cls.val] 5693 5694class ObjectSetFieldSpec (FieldSpec): 5695 def get_repr(self): 5696 return ['ClassReference', self.cls.val] 5697 5698#============================================================================== 5699 5700def p_module_list_1 (t): 5701 'module_list : module_list ModuleDefinition' 5702 t[0] = t[1] + [t[2]] 5703 5704def p_module_list_2 (t): 5705 'module_list : ModuleDefinition' 5706 t[0] = [t[1]] 5707 5708 5709#--- ITU-T Recommendation X.680 ----------------------------------------------- 5710 5711 5712# 11 ASN.1 lexical items -------------------------------------------------------- 5713 5714# 11.2 Type references 5715def p_type_ref (t): 5716 'type_ref : UCASE_IDENT' 5717 t[0] = Type_Ref(val=t[1]) 5718 5719# 11.3 Identifiers 5720def p_identifier (t): 5721 'identifier : LCASE_IDENT' 5722 t[0] = t[1] 5723 5724# 11.4 Value references 5725# cause reduce/reduce conflict 5726#def p_valuereference (t): 5727# 'valuereference : LCASE_IDENT' 5728# t[0] = Value_Ref(val=t[1]) 5729 5730# 11.5 Module references 5731def p_modulereference (t): 5732 'modulereference : UCASE_IDENT' 5733 t[0] = t[1] 5734 5735 5736# 12 Module definition -------------------------------------------------------- 5737 5738# 12.1 5739def p_ModuleDefinition (t): 5740 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END' 5741 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7]) 5742 5743def p_ModuleBegin (t): 5744 'ModuleBegin : ' 5745 if t[-4].val == 'Remote-Operations-Information-Objects': 5746 x880_module_begin() 5747 5748def p_TagDefault_1 (t): 5749 '''TagDefault : EXPLICIT TAGS 5750 | IMPLICIT TAGS 5751 | AUTOMATIC TAGS ''' 5752 t[0] = Default_Tags (dfl_tag = t[1]) 5753 5754def p_TagDefault_2 (t): 5755 'TagDefault : ' 5756 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty". 5757 t[0] = Default_Tags (dfl_tag = 'EXPLICIT') 5758 5759def p_ModuleIdentifier_1 (t): 5760 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid 5761 t [0] = Node('module_ident', val = t[1], ident = t[2]) 5762 5763def p_ModuleIdentifier_2 (t): 5764 'ModuleIdentifier : modulereference' # name, oid 5765 t [0] = Node('module_ident', val = t[1], ident = None) 5766 5767def p_DefinitiveIdentifier (t): 5768 'DefinitiveIdentifier : ObjectIdentifierValue' 5769 t[0] = t[1] 5770 5771#def p_module_ref (t): 5772# 'module_ref : UCASE_IDENT' 5773# t[0] = t[1] 5774 5775def p_ModuleBody_1 (t): 5776 'ModuleBody : Exports Imports AssignmentList' 5777 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3]) 5778 5779def p_ModuleBody_2 (t): 5780 'ModuleBody : ' 5781 t[0] = Node ('module_body', exports = [], imports = [], assign_list = []) 5782 5783def p_Exports_1 (t): 5784 'Exports : EXPORTS syms_exported SEMICOLON' 5785 t[0] = t[2] 5786 5787def p_Exports_2 (t): 5788 'Exports : EXPORTS ALL SEMICOLON' 5789 t[0] = [ 'ALL' ] 5790 5791def p_Exports_3 (t): 5792 'Exports : ' 5793 t[0] = [ 'ALL' ] 5794 5795def p_syms_exported_1 (t): 5796 'syms_exported : exp_sym_list' 5797 t[0] = t[1] 5798 5799def p_syms_exported_2 (t): 5800 'syms_exported : ' 5801 t[0] = [] 5802 5803def p_exp_sym_list_1 (t): 5804 'exp_sym_list : Symbol' 5805 t[0] = [t[1]] 5806 5807def p_exp_sym_list_2 (t): 5808 'exp_sym_list : exp_sym_list COMMA Symbol' 5809 t[0] = t[1] + [t[3]] 5810 5811 5812def p_Imports_1 (t): 5813 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON' 5814 t[0] = t[3] 5815 global lcase_ident_assigned 5816 lcase_ident_assigned = {} 5817 5818def p_importsbegin (t): 5819 'importsbegin : ' 5820 global lcase_ident_assigned 5821 global g_conform 5822 lcase_ident_assigned = {} 5823 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER')) 5824 5825def p_Imports_2 (t): 5826 'Imports : ' 5827 t[0] = [] 5828 5829def p_SymbolsImported_1(t): 5830 'SymbolsImported : ' 5831 t[0] = [] 5832 5833def p_SymbolsImported_2 (t): 5834 'SymbolsImported : SymbolsFromModuleList' 5835 t[0] = t[1] 5836 5837def p_SymbolsFromModuleList_1 (t): 5838 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule' 5839 t[0] = t[1] + [t[2]] 5840 5841def p_SymbolsFromModuleList_2 (t): 5842 'SymbolsFromModuleList : SymbolsFromModule' 5843 t[0] = [t[1]] 5844 5845def p_SymbolsFromModule (t): 5846 'SymbolsFromModule : SymbolList FROM GlobalModuleReference' 5847 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3]) 5848 for s in (t[0].symbol_list): 5849 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3] 5850 import_symbols_from_module(t[0].module, t[0].symbol_list) 5851 5852def import_symbols_from_module(module, symbol_list): 5853 if module.val == 'Remote-Operations-Information-Objects': 5854 for i in range(len(symbol_list)): 5855 s = symbol_list[i] 5856 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref): 5857 x880_import(s.val) 5858 if isinstance(s, Type_Ref) and is_class_ident(s.val): 5859 symbol_list[i] = Class_Ref (val = s.val) 5860 return 5861 for i in range(len(symbol_list)): 5862 s = symbol_list[i] 5863 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)): 5864 import_class_from_module(module.val, s.val) 5865 if isinstance(s, Type_Ref) and is_class_ident(s.val): 5866 symbol_list[i] = Class_Ref (val = s.val) 5867 5868def p_GlobalModuleReference (t): 5869 'GlobalModuleReference : modulereference AssignedIdentifier' 5870 t [0] = Node('module_ident', val = t[1], ident = t[2]) 5871 5872def p_AssignedIdentifier_1 (t): 5873 'AssignedIdentifier : ObjectIdentifierValue' 5874 t[0] = t[1] 5875 5876def p_AssignedIdentifier_2 (t): 5877 'AssignedIdentifier : LCASE_IDENT_ASSIGNED' 5878 t[0] = t[1] 5879 5880def p_AssignedIdentifier_3 (t): 5881 'AssignedIdentifier : ' 5882 pass 5883 5884def p_SymbolList_1 (t): 5885 'SymbolList : Symbol' 5886 t[0] = [t[1]] 5887 5888def p_SymbolList_2 (t): 5889 'SymbolList : SymbolList COMMA Symbol' 5890 t[0] = t[1] + [t[3]] 5891 5892def p_Symbol (t): 5893 '''Symbol : Reference 5894 | ParameterizedReference''' 5895 t[0] = t[1] 5896 5897def p_Reference_1 (t): 5898 '''Reference : type_ref 5899 | objectclassreference ''' 5900 t[0] = t[1] 5901 5902def p_Reference_2 (t): 5903 '''Reference : LCASE_IDENT_ASSIGNED 5904 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict 5905 t[0] = Value_Ref(val=t[1]) 5906 5907def p_AssignmentList_1 (t): 5908 'AssignmentList : AssignmentList Assignment' 5909 t[0] = t[1] + [t[2]] 5910 5911def p_AssignmentList_2 (t): 5912 'AssignmentList : Assignment SEMICOLON' 5913 t[0] = [t[1]] 5914 5915def p_AssignmentList_3 (t): 5916 'AssignmentList : Assignment' 5917 t[0] = [t[1]] 5918 5919def p_Assignment (t): 5920 '''Assignment : TypeAssignment 5921 | ValueAssignment 5922 | ValueSetTypeAssignment 5923 | ObjectClassAssignment 5924 | ObjectAssignment 5925 | ObjectSetAssignment 5926 | ParameterizedAssignment 5927 | pyquote ''' 5928 t[0] = t[1] 5929 5930 5931# 13 Referencing type and value definitions ----------------------------------- 5932 5933# 13.1 5934def p_DefinedType (t): 5935 '''DefinedType : ExternalTypeReference 5936 | type_ref 5937 | ParameterizedType''' 5938 t[0] = t[1] 5939 5940def p_DefinedValue_1(t): 5941 '''DefinedValue : ExternalValueReference''' 5942 t[0] = t[1] 5943 5944def p_DefinedValue_2(t): 5945 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict 5946 t[0] = Value_Ref(val=t[1]) 5947 5948# 13.6 5949def p_ExternalTypeReference (t): 5950 'ExternalTypeReference : modulereference DOT type_ref' 5951 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3]) 5952 5953def p_ExternalValueReference (t): 5954 'ExternalValueReference : modulereference DOT identifier' 5955 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3]) 5956 5957 5958# 15 Assigning types and values ----------------------------------------------- 5959 5960# 15.1 5961def p_TypeAssignment (t): 5962 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type' 5963 t[0] = t[3] 5964 t[0].SetName(t[1]) 5965 5966# 15.2 5967def p_ValueAssignment (t): 5968 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value' 5969 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4]) 5970 5971# only "simple" types are supported to simplify grammer 5972def p_ValueType (t): 5973 '''ValueType : type_ref 5974 | BooleanType 5975 | IntegerType 5976 | ObjectIdentifierType 5977 | OctetStringType 5978 | RealType ''' 5979 5980 t[0] = t[1] 5981 5982# 15.6 5983def p_ValueSetTypeAssignment (t): 5984 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet' 5985 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4]) 5986 5987# 15.7 5988def p_ValueSet (t): 5989 'ValueSet : lbraceignore rbraceignore' 5990 t[0] = None 5991 5992 5993# 16 Definition of types and values ------------------------------------------- 5994 5995# 16.1 5996def p_Type (t): 5997 '''Type : BuiltinType 5998 | ReferencedType 5999 | ConstrainedType''' 6000 t[0] = t[1] 6001 6002# 16.2 6003def p_BuiltinType (t): 6004 '''BuiltinType : AnyType 6005 | BitStringType 6006 | BooleanType 6007 | CharacterStringType 6008 | ChoiceType 6009 | EmbeddedPDVType 6010 | EnumeratedType 6011 | ExternalType 6012 | InstanceOfType 6013 | IntegerType 6014 | NullType 6015 | ObjectClassFieldType 6016 | ObjectIdentifierType 6017 | OctetStringType 6018 | RealType 6019 | RelativeOIDType 6020 | SequenceType 6021 | SequenceOfType 6022 | SetType 6023 | SetOfType 6024 | TaggedType''' 6025 t[0] = t[1] 6026 6027# 16.3 6028def p_ReferencedType (t): 6029 '''ReferencedType : DefinedType 6030 | UsefulType 6031 | SelectionType''' 6032 t[0] = t[1] 6033 6034# 16.5 6035def p_NamedType (t): 6036 'NamedType : identifier Type' 6037 t[0] = t[2] 6038 t[0].SetName (t[1]) 6039 6040# 16.7 6041def p_Value (t): 6042 '''Value : BuiltinValue 6043 | ReferencedValue 6044 | ObjectClassFieldValue''' 6045 t[0] = t[1] 6046 6047# 16.9 6048def p_BuiltinValue (t): 6049 '''BuiltinValue : BooleanValue 6050 | ChoiceValue 6051 | IntegerValue 6052 | ObjectIdentifierValue 6053 | RealValue 6054 | SequenceValue 6055 | hex_string 6056 | binary_string 6057 | char_string''' # XXX we don't support {data} here 6058 t[0] = t[1] 6059 6060# 16.11 6061def p_ReferencedValue (t): 6062 '''ReferencedValue : DefinedValue 6063 | ValueFromObject''' 6064 t[0] = t[1] 6065 6066# 16.13 6067#def p_NamedValue (t): 6068# 'NamedValue : identifier Value' 6069# t[0] = Node ('NamedValue', ident = t[1], value = t[2]) 6070 6071 6072# 17 Notation for the boolean type -------------------------------------------- 6073 6074# 17.1 6075def p_BooleanType (t): 6076 'BooleanType : BOOLEAN' 6077 t[0] = BooleanType () 6078 6079# 17.2 6080def p_BooleanValue (t): 6081 '''BooleanValue : TRUE 6082 | FALSE''' 6083 t[0] = t[1] 6084 6085 6086# 18 Notation for the integer type -------------------------------------------- 6087 6088# 18.1 6089def p_IntegerType_1 (t): 6090 'IntegerType : INTEGER' 6091 t[0] = IntegerType (named_list = None) 6092 6093def p_IntegerType_2 (t): 6094 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE' 6095 t[0] = IntegerType(named_list = t[3]) 6096 6097def p_NamedNumberList_1 (t): 6098 'NamedNumberList : NamedNumber' 6099 t[0] = [t[1]] 6100 6101def p_NamedNumberList_2 (t): 6102 'NamedNumberList : NamedNumberList COMMA NamedNumber' 6103 t[0] = t[1] + [t[3]] 6104 6105def p_NamedNumber (t): 6106 '''NamedNumber : identifier LPAREN SignedNumber RPAREN 6107 | identifier LPAREN DefinedValue RPAREN''' 6108 t[0] = NamedNumber(ident = t[1], val = t[3]) 6109 6110def p_SignedNumber_1 (t): 6111 'SignedNumber : NUMBER' 6112 t[0] = t [1] 6113 6114def p_SignedNumber_2 (t): 6115 'SignedNumber : MINUS NUMBER' 6116 t[0] = '-' + t[2] 6117 6118# 18.9 6119def p_IntegerValue (t): 6120 'IntegerValue : SignedNumber' 6121 t[0] = t [1] 6122 6123# 19 Notation for the enumerated type ----------------------------------------- 6124 6125# 19.1 6126def p_EnumeratedType (t): 6127 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE' 6128 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext']) 6129 6130def p_Enumerations_1 (t): 6131 'Enumerations : Enumeration' 6132 t[0] = { 'val' : t[1], 'ext' : None } 6133 6134def p_Enumerations_2 (t): 6135 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec' 6136 t[0] = { 'val' : t[1], 'ext' : [] } 6137 6138def p_Enumerations_3 (t): 6139 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration' 6140 t[0] = { 'val' : t[1], 'ext' : t[6] } 6141 6142def p_Enumeration_1 (t): 6143 'Enumeration : EnumerationItem' 6144 t[0] = [t[1]] 6145 6146def p_Enumeration_2 (t): 6147 'Enumeration : Enumeration COMMA EnumerationItem' 6148 t[0] = t[1] + [t[3]] 6149 6150def p_EnumerationItem (t): 6151 '''EnumerationItem : Identifier 6152 | NamedNumber''' 6153 t[0] = t[1] 6154 6155def p_Identifier (t): 6156 'Identifier : identifier' 6157 t[0] = Node ('Identifier', ident = t[1]) 6158 6159 6160# 20 Notation for the real type ----------------------------------------------- 6161 6162# 20.1 6163def p_RealType (t): 6164 'RealType : REAL' 6165 t[0] = RealType () 6166 6167# 20.6 6168def p_RealValue (t): 6169 '''RealValue : REAL_NUMBER 6170 | SpecialRealValue''' 6171 t[0] = t [1] 6172 6173def p_SpecialRealValue (t): 6174 '''SpecialRealValue : PLUS_INFINITY 6175 | MINUS_INFINITY''' 6176 t[0] = t[1] 6177 6178 6179# 21 Notation for the bitstring type ------------------------------------------ 6180 6181# 21.1 6182def p_BitStringType_1 (t): 6183 'BitStringType : BIT STRING' 6184 t[0] = BitStringType (named_list = None) 6185 6186def p_BitStringType_2 (t): 6187 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE' 6188 t[0] = BitStringType (named_list = t[4]) 6189 6190def p_NamedBitList_1 (t): 6191 'NamedBitList : NamedBit' 6192 t[0] = [t[1]] 6193 6194def p_NamedBitList_2 (t): 6195 'NamedBitList : NamedBitList COMMA NamedBit' 6196 t[0] = t[1] + [t[3]] 6197 6198def p_NamedBit (t): 6199 '''NamedBit : identifier LPAREN NUMBER RPAREN 6200 | identifier LPAREN DefinedValue RPAREN''' 6201 t[0] = NamedNumber (ident = t[1], val = t[3]) 6202 6203 6204# 22 Notation for the octetstring type ---------------------------------------- 6205 6206# 22.1 6207def p_OctetStringType (t): 6208 'OctetStringType : OCTET STRING' 6209 t[0] = OctetStringType () 6210 6211 6212# 23 Notation for the null type ----------------------------------------------- 6213 6214# 23.1 6215def p_NullType (t): 6216 'NullType : NULL' 6217 t[0] = NullType () 6218 6219# 23.3 6220def p_NullValue (t): 6221 'NullValue : NULL' 6222 t[0] = NullValue () 6223 6224 6225# 24 Notation for sequence types ---------------------------------------------- 6226 6227# 24.1 6228def p_SequenceType_1 (t): 6229 'SequenceType : SEQUENCE LBRACE RBRACE' 6230 t[0] = SequenceType (elt_list = []) 6231 6232def p_SequenceType_2 (t): 6233 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE' 6234 t[0] = SequenceType (elt_list = t[3]['elt_list']) 6235 if 'ext_list' in t[3]: 6236 t[0].ext_list = t[3]['ext_list'] 6237 if 'elt_list2' in t[3]: 6238 t[0].elt_list2 = t[3]['elt_list2'] 6239 6240def p_ExtensionAndException_1 (t): 6241 'ExtensionAndException : ELLIPSIS' 6242 t[0] = [] 6243 6244def p_OptionalExtensionMarker_1 (t): 6245 'OptionalExtensionMarker : COMMA ELLIPSIS' 6246 t[0] = True 6247 6248def p_OptionalExtensionMarker_2 (t): 6249 'OptionalExtensionMarker : ' 6250 t[0] = False 6251 6252def p_ComponentTypeLists_1 (t): 6253 'ComponentTypeLists : ComponentTypeList' 6254 t[0] = {'elt_list' : t[1]} 6255 6256def p_ComponentTypeLists_2 (t): 6257 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker' 6258 t[0] = {'elt_list' : t[1], 'ext_list' : []} 6259 6260def p_ComponentTypeLists_3 (t): 6261 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker' 6262 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]} 6263 6264def p_ComponentTypeLists_4 (t): 6265 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList' 6266 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]} 6267 6268def p_ComponentTypeLists_5 (t): 6269 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList' 6270 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]} 6271 6272def p_ComponentTypeLists_6 (t): 6273 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker' 6274 t[0] = {'elt_list' : [], 'ext_list' : []} 6275 6276def p_ComponentTypeLists_7 (t): 6277 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker' 6278 t[0] = {'elt_list' : [], 'ext_list' : t[2]} 6279 6280def p_ExtensionEndMarker (t): 6281 'ExtensionEndMarker : COMMA ELLIPSIS' 6282 pass 6283 6284def p_ExtensionAdditionList_1 (t): 6285 'ExtensionAdditionList : COMMA ExtensionAddition' 6286 t[0] = [t[2]] 6287 6288def p_ExtensionAdditionList_2 (t): 6289 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition' 6290 t[0] = t[1] + [t[3]] 6291 6292def p_ExtensionAddition_1 (t): 6293 'ExtensionAddition : ExtensionAdditionGroup' 6294 t[0] = Node ('elt_type', val = t[1], optional = 0) 6295 6296def p_ExtensionAddition_2 (t): 6297 'ExtensionAddition : ComponentType' 6298 t[0] = t[1] 6299 6300def p_ExtensionAdditionGroup (t): 6301 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK' 6302 t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3]) 6303 6304def p_VersionNumber_1 (t): 6305 'VersionNumber : ' 6306 6307def p_VersionNumber_2 (t): 6308 'VersionNumber : NUMBER COLON' 6309 t[0] = t[1] 6310 6311def p_ComponentTypeList_1 (t): 6312 'ComponentTypeList : ComponentType' 6313 t[0] = [t[1]] 6314 6315def p_ComponentTypeList_2 (t): 6316 'ComponentTypeList : ComponentTypeList COMMA ComponentType' 6317 t[0] = t[1] + [t[3]] 6318 6319def p_ComponentType_1 (t): 6320 'ComponentType : NamedType' 6321 t[0] = Node ('elt_type', val = t[1], optional = 0) 6322 6323def p_ComponentType_2 (t): 6324 'ComponentType : NamedType OPTIONAL' 6325 t[0] = Node ('elt_type', val = t[1], optional = 1) 6326 6327def p_ComponentType_3 (t): 6328 'ComponentType : NamedType DEFAULT DefaultValue' 6329 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3]) 6330 6331def p_ComponentType_4 (t): 6332 'ComponentType : COMPONENTS OF Type' 6333 t[0] = Node ('components_of', typ = t[3]) 6334 6335def p_DefaultValue_1 (t): 6336 '''DefaultValue : ReferencedValue 6337 | BooleanValue 6338 | ChoiceValue 6339 | IntegerValue 6340 | RealValue 6341 | hex_string 6342 | binary_string 6343 | char_string 6344 | ObjectClassFieldValue''' 6345 t[0] = t[1] 6346 6347def p_DefaultValue_2 (t): 6348 'DefaultValue : lbraceignore rbraceignore' 6349 t[0] = '' 6350 6351# 24.17 6352def p_SequenceValue_1 (t): 6353 'SequenceValue : LBRACE RBRACE' 6354 t[0] = [] 6355 6356 6357#def p_SequenceValue_2 (t): 6358# 'SequenceValue : LBRACE ComponentValueList RBRACE' 6359# t[0] = t[2] 6360 6361#def p_ComponentValueList_1 (t): 6362# 'ComponentValueList : NamedValue' 6363# t[0] = [t[1]] 6364 6365#def p_ComponentValueList_2 (t): 6366# 'ComponentValueList : ComponentValueList COMMA NamedValue' 6367# t[0] = t[1] + [t[3]] 6368 6369 6370# 25 Notation for sequence-of types ------------------------------------------- 6371 6372# 25.1 6373def p_SequenceOfType (t): 6374 '''SequenceOfType : SEQUENCE OF Type 6375 | SEQUENCE OF NamedType''' 6376 t[0] = SequenceOfType (val = t[3], size_constr = None) 6377 6378 6379# 26 Notation for set types --------------------------------------------------- 6380 6381# 26.1 6382def p_SetType_1 (t): 6383 'SetType : SET LBRACE RBRACE' 6384 t[0] = SetType (elt_list = []) 6385 6386def p_SetType_2 (t): 6387 'SetType : SET LBRACE ComponentTypeLists RBRACE' 6388 t[0] = SetType (elt_list = t[3]['elt_list']) 6389 if 'ext_list' in t[3]: 6390 t[0].ext_list = t[3]['ext_list'] 6391 if 'elt_list2' in t[3]: 6392 t[0].elt_list2 = t[3]['elt_list2'] 6393 6394 6395# 27 Notation for set-of types ------------------------------------------------ 6396 6397# 27.1 6398def p_SetOfType (t): 6399 '''SetOfType : SET OF Type 6400 | SET OF NamedType''' 6401 t[0] = SetOfType (val = t[3]) 6402 6403# 28 Notation for choice types ------------------------------------------------ 6404 6405# 28.1 6406def p_ChoiceType (t): 6407 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE' 6408 if 'ext_list' in t[3]: 6409 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list']) 6410 else: 6411 t[0] = ChoiceType (elt_list = t[3]['elt_list']) 6412 6413def p_AlternativeTypeLists_1 (t): 6414 'AlternativeTypeLists : AlternativeTypeList' 6415 t[0] = {'elt_list' : t[1]} 6416 6417def p_AlternativeTypeLists_2 (t): 6418 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker' 6419 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]} 6420 6421def p_ExtensionAdditionAlternatives_1 (t): 6422 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList' 6423 t[0] = t[1] 6424 6425def p_ExtensionAdditionAlternatives_2 (t): 6426 'ExtensionAdditionAlternatives : ' 6427 t[0] = [] 6428 6429def p_ExtensionAdditionAlternativesList_1 (t): 6430 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative' 6431 t[0] = t[2] 6432 6433def p_ExtensionAdditionAlternativesList_2 (t): 6434 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative' 6435 t[0] = t[1] + t[3] 6436 6437def p_ExtensionAdditionAlternative_1 (t): 6438 'ExtensionAdditionAlternative : NamedType' 6439 t[0] = [t[1]] 6440 6441def p_ExtensionAdditionAlternative_2 (t): 6442 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup' 6443 t[0] = t[1] 6444 6445def p_ExtensionAdditionAlternativesGroup (t): 6446 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK' 6447 t[0] = t[3] 6448 6449def p_AlternativeTypeList_1 (t): 6450 'AlternativeTypeList : NamedType' 6451 t[0] = [t[1]] 6452 6453def p_AlternativeTypeList_2 (t): 6454 'AlternativeTypeList : AlternativeTypeList COMMA NamedType' 6455 t[0] = t[1] + [t[3]] 6456 6457# 28.10 6458def p_ChoiceValue_1 (t): 6459 '''ChoiceValue : identifier COLON Value 6460 | identifier COLON NullValue ''' 6461 val = t[3] 6462 if not isinstance(val, Value): 6463 val = Value(val=val) 6464 t[0] = ChoiceValue (choice = t[1], val = val) 6465 6466# 29 Notation for selection types 6467 6468# 29.1 6469def p_SelectionType (t): # 6470 'SelectionType : identifier LT Type' 6471 t[0] = SelectionType (typ = t[3], sel = t[1]) 6472 6473# 30 Notation for tagged types ------------------------------------------------ 6474 6475# 30.1 6476def p_TaggedType_1 (t): 6477 'TaggedType : Tag Type' 6478 t[1].mode = 'default' 6479 t[0] = t[2] 6480 t[0].AddTag(t[1]) 6481 6482def p_TaggedType_2 (t): 6483 '''TaggedType : Tag IMPLICIT Type 6484 | Tag EXPLICIT Type''' 6485 t[1].mode = t[2] 6486 t[0] = t[3] 6487 t[0].AddTag(t[1]) 6488 6489def p_Tag (t): 6490 'Tag : LBRACK Class ClassNumber RBRACK' 6491 t[0] = Tag(cls = t[2], num = t[3]) 6492 6493def p_ClassNumber_1 (t): 6494 'ClassNumber : number' 6495 t[0] = t[1] 6496 6497def p_ClassNumber_2 (t): 6498 'ClassNumber : DefinedValue' 6499 t[0] = t[1] 6500 6501def p_Class_1 (t): 6502 '''Class : UNIVERSAL 6503 | APPLICATION 6504 | PRIVATE''' 6505 t[0] = t[1] 6506 6507def p_Class_2 (t): 6508 'Class :' 6509 t[0] = 'CONTEXT' 6510 6511 6512# 31 Notation for the object identifier type ---------------------------------- 6513 6514# 31.1 6515def p_ObjectIdentifierType (t): 6516 'ObjectIdentifierType : OBJECT IDENTIFIER' 6517 t[0] = ObjectIdentifierType() 6518 6519# 31.3 6520def p_ObjectIdentifierValue (t): 6521 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE' 6522 t[0] = ObjectIdentifierValue (comp_list=t[2]) 6523 6524def p_oid_comp_list_1 (t): 6525 'oid_comp_list : oid_comp_list ObjIdComponents' 6526 t[0] = t[1] + [t[2]] 6527 6528def p_oid_comp_list_2 (t): 6529 'oid_comp_list : ObjIdComponents' 6530 t[0] = [t[1]] 6531 6532def p_ObjIdComponents (t): 6533 '''ObjIdComponents : NameForm 6534 | NumberForm 6535 | NameAndNumberForm''' 6536 t[0] = t[1] 6537 6538def p_NameForm (t): 6539 '''NameForm : LCASE_IDENT 6540 | LCASE_IDENT_ASSIGNED''' 6541 t [0] = t[1] 6542 6543def p_NumberForm (t): 6544 '''NumberForm : NUMBER''' 6545# | DefinedValue''' 6546 t [0] = t[1] 6547 6548def p_NameAndNumberForm (t): 6549 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN 6550 | LCASE_IDENT LPAREN NumberForm RPAREN''' 6551 t[0] = Node('name_and_number', ident = t[1], number = t[3]) 6552 6553# 32 Notation for the relative object identifier type ------------------------- 6554 6555# 32.1 6556def p_RelativeOIDType (t): 6557 'RelativeOIDType : RELATIVE_OID' 6558 t[0] = RelativeOIDType() 6559 6560# 33 Notation for the embedded-pdv type --------------------------------------- 6561 6562# 33.1 6563def p_EmbeddedPDVType (t): 6564 'EmbeddedPDVType : EMBEDDED PDV' 6565 t[0] = EmbeddedPDVType() 6566 6567# 34 Notation for the external type ------------------------------------------- 6568 6569# 34.1 6570def p_ExternalType (t): 6571 'ExternalType : EXTERNAL' 6572 t[0] = ExternalType() 6573 6574# 36 Notation for character string types -------------------------------------- 6575 6576# 36.1 6577def p_CharacterStringType (t): 6578 '''CharacterStringType : RestrictedCharacterStringType 6579 | UnrestrictedCharacterStringType''' 6580 t[0] = t[1] 6581 6582 6583# 37 Definition of restricted character string types -------------------------- 6584 6585def p_RestrictedCharacterStringType_1 (t): 6586 'RestrictedCharacterStringType : BMPString' 6587 t[0] = BMPStringType () 6588def p_RestrictedCharacterStringType_2 (t): 6589 'RestrictedCharacterStringType : GeneralString' 6590 t[0] = GeneralStringType () 6591def p_RestrictedCharacterStringType_3 (t): 6592 'RestrictedCharacterStringType : GraphicString' 6593 t[0] = GraphicStringType () 6594def p_RestrictedCharacterStringType_4 (t): 6595 'RestrictedCharacterStringType : IA5String' 6596 t[0] = IA5StringType () 6597def p_RestrictedCharacterStringType_5 (t): 6598 'RestrictedCharacterStringType : ISO646String' 6599 t[0] = ISO646StringType () 6600def p_RestrictedCharacterStringType_6 (t): 6601 'RestrictedCharacterStringType : NumericString' 6602 t[0] = NumericStringType () 6603def p_RestrictedCharacterStringType_7 (t): 6604 'RestrictedCharacterStringType : PrintableString' 6605 t[0] = PrintableStringType () 6606def p_RestrictedCharacterStringType_8 (t): 6607 'RestrictedCharacterStringType : TeletexString' 6608 t[0] = TeletexStringType () 6609def p_RestrictedCharacterStringType_9 (t): 6610 'RestrictedCharacterStringType : T61String' 6611 t[0] = T61StringType () 6612def p_RestrictedCharacterStringType_10 (t): 6613 'RestrictedCharacterStringType : UniversalString' 6614 t[0] = UniversalStringType () 6615def p_RestrictedCharacterStringType_11 (t): 6616 'RestrictedCharacterStringType : UTF8String' 6617 t[0] = UTF8StringType () 6618def p_RestrictedCharacterStringType_12 (t): 6619 'RestrictedCharacterStringType : VideotexString' 6620 t[0] = VideotexStringType () 6621def p_RestrictedCharacterStringType_13 (t): 6622 'RestrictedCharacterStringType : VisibleString' 6623 t[0] = VisibleStringType () 6624 6625 6626# 40 Definition of unrestricted character string types ------------------------ 6627 6628# 40.1 6629def p_UnrestrictedCharacterStringType (t): 6630 'UnrestrictedCharacterStringType : CHARACTER STRING' 6631 t[0] = UnrestrictedCharacterStringType () 6632 6633 6634# 41 Notation for types defined in clauses 42 to 44 --------------------------- 6635 6636# 42 Generalized time --------------------------------------------------------- 6637 6638def p_UsefulType_1 (t): 6639 'UsefulType : GeneralizedTime' 6640 t[0] = GeneralizedTime() 6641 6642# 43 Universal time ----------------------------------------------------------- 6643 6644def p_UsefulType_2 (t): 6645 'UsefulType : UTCTime' 6646 t[0] = UTCTime() 6647 6648# 44 The object descriptor type ----------------------------------------------- 6649 6650def p_UsefulType_3 (t): 6651 'UsefulType : ObjectDescriptor' 6652 t[0] = ObjectDescriptor() 6653 6654 6655# 45 Constrained types -------------------------------------------------------- 6656 6657# 45.1 6658def p_ConstrainedType_1 (t): 6659 'ConstrainedType : Type Constraint' 6660 t[0] = t[1] 6661 t[0].AddConstraint(t[2]) 6662 6663def p_ConstrainedType_2 (t): 6664 'ConstrainedType : TypeWithConstraint' 6665 t[0] = t[1] 6666 6667# 45.5 6668def p_TypeWithConstraint_1 (t): 6669 '''TypeWithConstraint : SET Constraint OF Type 6670 | SET SizeConstraint OF Type''' 6671 t[0] = SetOfType (val = t[4], constr = t[2]) 6672 6673def p_TypeWithConstraint_2 (t): 6674 '''TypeWithConstraint : SEQUENCE Constraint OF Type 6675 | SEQUENCE SizeConstraint OF Type''' 6676 t[0] = SequenceOfType (val = t[4], constr = t[2]) 6677 6678def p_TypeWithConstraint_3 (t): 6679 '''TypeWithConstraint : SET Constraint OF NamedType 6680 | SET SizeConstraint OF NamedType''' 6681 t[0] = SetOfType (val = t[4], constr = t[2]) 6682 6683def p_TypeWithConstraint_4 (t): 6684 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType 6685 | SEQUENCE SizeConstraint OF NamedType''' 6686 t[0] = SequenceOfType (val = t[4], constr = t[2]) 6687 6688# 45.6 6689# 45.7 6690def p_Constraint (t): 6691 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN' 6692 t[0] = t[2] 6693 6694def p_ConstraintSpec (t): 6695 '''ConstraintSpec : ElementSetSpecs 6696 | GeneralConstraint''' 6697 t[0] = t[1] 6698 6699# 46 Element set specification ------------------------------------------------ 6700 6701# 46.1 6702def p_ElementSetSpecs_1 (t): 6703 'ElementSetSpecs : RootElementSetSpec' 6704 t[0] = t[1] 6705 6706def p_ElementSetSpecs_2 (t): 6707 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS' 6708 t[0] = t[1] 6709 t[0].ext = True 6710 6711def p_ElementSetSpecs_3 (t): 6712 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec' 6713 t[0] = t[1] 6714 t[0].ext = True 6715 6716def p_RootElementSetSpec (t): 6717 'RootElementSetSpec : ElementSetSpec' 6718 t[0] = t[1] 6719 6720def p_AdditionalElementSetSpec (t): 6721 'AdditionalElementSetSpec : ElementSetSpec' 6722 t[0] = t[1] 6723 6724def p_ElementSetSpec (t): 6725 'ElementSetSpec : Unions' 6726 t[0] = t[1] 6727 6728def p_Unions_1 (t): 6729 'Unions : Intersections' 6730 t[0] = t[1] 6731 6732def p_Unions_2 (t): 6733 'Unions : UElems UnionMark Intersections' 6734 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]]) 6735 6736def p_UElems (t): 6737 'UElems : Unions' 6738 t[0] = t[1] 6739 6740def p_Intersections_1 (t): 6741 'Intersections : IntersectionElements' 6742 t[0] = t[1] 6743 6744def p_Intersections_2 (t): 6745 'Intersections : IElems IntersectionMark IntersectionElements' 6746 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]]) 6747 6748def p_IElems (t): 6749 'IElems : Intersections' 6750 t[0] = t[1] 6751 6752def p_IntersectionElements (t): 6753 'IntersectionElements : Elements' 6754 t[0] = t[1] 6755 6756def p_UnionMark (t): 6757 '''UnionMark : BAR 6758 | UNION''' 6759 6760def p_IntersectionMark (t): 6761 '''IntersectionMark : CIRCUMFLEX 6762 | INTERSECTION''' 6763 6764# 46.5 6765def p_Elements_1 (t): 6766 'Elements : SubtypeElements' 6767 t[0] = t[1] 6768 6769def p_Elements_2 (t): 6770 'Elements : LPAREN ElementSetSpec RPAREN' 6771 t[0] = t[2] 6772 6773# 47 Subtype elements --------------------------------------------------------- 6774 6775# 47.1 General 6776def p_SubtypeElements (t): 6777 '''SubtypeElements : SingleValue 6778 | ContainedSubtype 6779 | ValueRange 6780 | PermittedAlphabet 6781 | SizeConstraint 6782 | TypeConstraint 6783 | InnerTypeConstraints 6784 | PatternConstraint''' 6785 t[0] = t[1] 6786 6787# 47.2 Single value 6788# 47.2.1 6789def p_SingleValue (t): 6790 'SingleValue : Value' 6791 t[0] = Constraint(type = 'SingleValue', subtype = t[1]) 6792 6793# 47.3 Contained subtype 6794# 47.3.1 6795def p_ContainedSubtype (t): 6796 'ContainedSubtype : Includes Type' 6797 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2]) 6798 6799def p_Includes (t): 6800 '''Includes : INCLUDES 6801 | ''' 6802 6803# 47.4 Value range 6804# 47.4.1 6805def p_ValueRange (t): 6806 'ValueRange : LowerEndpoint RANGE UpperEndpoint' 6807 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]]) 6808 6809# 47.4.3 6810def p_LowerEndpoint_1 (t): 6811 'LowerEndpoint : LowerEndValue' 6812 t[0] = t[1] 6813 6814def p_LowerEndpoint_2 (t): 6815 'LowerEndpoint : LowerEndValue LT' 6816 t[0] = t[1] # but not inclusive range 6817 6818def p_UpperEndpoint_1 (t): 6819 'UpperEndpoint : UpperEndValue' 6820 t[0] = t[1] 6821 6822def p_UpperEndpoint_2 (t): 6823 'UpperEndpoint : LT UpperEndValue' 6824 t[0] = t[1] # but not inclusive range 6825 6826# 47.4.4 6827def p_LowerEndValue (t): 6828 '''LowerEndValue : Value 6829 | MIN''' 6830 t[0] = t[1] # XXX 6831 6832def p_UpperEndValue (t): 6833 '''UpperEndValue : Value 6834 | MAX''' 6835 t[0] = t[1] 6836 6837# 47.5 Size constraint 6838# 47.5.1 6839def p_SizeConstraint (t): 6840 'SizeConstraint : SIZE Constraint' 6841 t[0] = Constraint (type = 'Size', subtype = t[2]) 6842 6843# 47.6 Type constraint 6844# 47.6.1 6845def p_TypeConstraint (t): 6846 'TypeConstraint : Type' 6847 t[0] = Constraint (type = 'Type', subtype = t[1]) 6848 6849# 47.7 Permitted alphabet 6850# 47.7.1 6851def p_PermittedAlphabet (t): 6852 'PermittedAlphabet : FROM Constraint' 6853 t[0] = Constraint (type = 'From', subtype = t[2]) 6854 6855# 47.8 Inner subtyping 6856# 47.8.1 6857def p_InnerTypeConstraints (t): 6858 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint 6859 | WITH COMPONENTS MultipleTypeConstraints''' 6860 pass # ignore PER invisible constraint 6861 6862# 47.8.3 6863def p_SingleTypeConstraint (t): 6864 'SingleTypeConstraint : Constraint' 6865 t[0] = t[1] 6866 6867# 47.8.4 6868def p_MultipleTypeConstraints (t): 6869 '''MultipleTypeConstraints : FullSpecification 6870 | PartialSpecification''' 6871 t[0] = t[1] 6872 6873def p_FullSpecification (t): 6874 'FullSpecification : LBRACE TypeConstraints RBRACE' 6875 t[0] = t[2] 6876 6877def p_PartialSpecification (t): 6878 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE' 6879 t[0] = t[4] 6880 6881def p_TypeConstraints_1 (t): 6882 'TypeConstraints : named_constraint' 6883 t [0] = [t[1]] 6884 6885def p_TypeConstraints_2 (t): 6886 'TypeConstraints : TypeConstraints COMMA named_constraint' 6887 t[0] = t[1] + [t[3]] 6888 6889def p_named_constraint_1 (t): 6890 'named_constraint : identifier constraint' 6891 return Node ('named_constraint', ident = t[1], constr = t[2]) 6892 6893def p_named_constraint_2 (t): 6894 'named_constraint : constraint' 6895 return Node ('named_constraint', constr = t[1]) 6896 6897def p_constraint (t): 6898 'constraint : value_constraint presence_constraint' 6899 t[0] = Node ('constraint', value = t[1], presence = t[2]) 6900 6901def p_value_constraint_1 (t): 6902 'value_constraint : Constraint' 6903 t[0] = t[1] 6904 6905def p_value_constraint_2 (t): 6906 'value_constraint : ' 6907 pass 6908 6909def p_presence_constraint_1 (t): 6910 '''presence_constraint : PRESENT 6911 | ABSENT 6912 | OPTIONAL''' 6913 t[0] = t[1] 6914 6915def p_presence_constraint_2 (t): 6916 '''presence_constraint : ''' 6917 pass 6918 6919# 47.9 Pattern constraint 6920# 47.9.1 6921def p_PatternConstraint (t): 6922 'PatternConstraint : PATTERN Value' 6923 t[0] = Constraint (type = 'Pattern', subtype = t[2]) 6924 6925# 49 The exception identifier 6926 6927# 49.4 6928def p_ExceptionSpec_1 (t): 6929 'ExceptionSpec : EXCLAMATION ExceptionIdentification' 6930 pass 6931 6932def p_ExceptionSpec_2 (t): 6933 'ExceptionSpec : ' 6934 pass 6935 6936def p_ExceptionIdentification (t): 6937 '''ExceptionIdentification : SignedNumber 6938 | DefinedValue 6939 | Type COLON Value ''' 6940 pass 6941 6942# /*-----------------------------------------------------------------------*/ 6943# /* Value Notation Productions */ 6944# /*-----------------------------------------------------------------------*/ 6945 6946 6947 6948def p_binary_string (t): 6949 'binary_string : BSTRING' 6950 t[0] = BStringValue(val = t[1]) 6951 6952def p_hex_string (t): 6953 'hex_string : HSTRING' 6954 t[0] = HStringValue(val = t[1]) 6955 6956def p_char_string (t): 6957 'char_string : QSTRING' 6958 t[0] = t[1] 6959 6960def p_number (t): 6961 'number : NUMBER' 6962 t[0] = t[1] 6963 6964 6965#--- ITU-T Recommendation X.208 ----------------------------------------------- 6966 6967# 27 Notation for the any type ------------------------------------------------ 6968 6969# 27.1 6970def p_AnyType (t): 6971 '''AnyType : ANY 6972 | ANY DEFINED BY identifier''' 6973 t[0] = AnyType() 6974 6975#--- ITU-T Recommendation X.681 ----------------------------------------------- 6976 6977# 7 ASN.1 lexical items ------------------------------------------------------- 6978 6979# 7.1 Information object class references 6980 6981def p_objectclassreference (t): 6982 'objectclassreference : CLASS_IDENT' 6983 t[0] = Class_Ref(val=t[1]) 6984 6985# 7.2 Information object references 6986 6987def p_objectreference (t): 6988 'objectreference : LCASE_IDENT' 6989 t[0] = t[1] 6990 6991# 7.3 Information object set references 6992 6993#def p_objectsetreference (t): 6994# 'objectsetreference : UCASE_IDENT' 6995# t[0] = t[1] 6996 6997# 7.4 Type field references 6998# ucasefieldreference 6999# 7.5 Value field references 7000# lcasefieldreference 7001# 7.6 Value set field references 7002# ucasefieldreference 7003# 7.7 Object field references 7004# lcasefieldreference 7005# 7.8 Object set field references 7006# ucasefieldreference 7007 7008def p_ucasefieldreference (t): 7009 'ucasefieldreference : AMPERSAND UCASE_IDENT' 7010 t[0] = '&' + t[2] 7011 7012def p_lcasefieldreference (t): 7013 'lcasefieldreference : AMPERSAND LCASE_IDENT' 7014 t[0] = '&' + t[2] 7015 7016# 8 Referencing definitions 7017 7018# 8.1 7019def p_DefinedObjectClass (t): 7020 '''DefinedObjectClass : objectclassreference 7021 | UsefulObjectClassReference''' 7022 t[0] = t[1] 7023 global obj_class 7024 obj_class = t[0].val 7025 7026def p_DefinedObject (t): 7027 '''DefinedObject : objectreference''' 7028 t[0] = t[1] 7029 7030# 8.4 7031def p_UsefulObjectClassReference (t): 7032 '''UsefulObjectClassReference : TYPE_IDENTIFIER 7033 | ABSTRACT_SYNTAX''' 7034 t[0] = Class_Ref(val=t[1]) 7035 7036# 9 Information object class definition and assignment 7037 7038# 9.1 7039def p_ObjectClassAssignment (t): 7040 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass 7041 | UCASE_IDENT ASSIGNMENT ObjectClass''' 7042 t[0] = t[3] 7043 t[0].SetName(t[1]) 7044 if isinstance(t[0], ObjectClassDefn): 7045 t[0].reg_types() 7046 7047# 9.2 7048def p_ObjectClass (t): 7049 '''ObjectClass : DefinedObjectClass 7050 | ObjectClassDefn 7051 | ParameterizedObjectClass ''' 7052 t[0] = t[1] 7053 7054# 9.3 7055def p_ObjectClassDefn (t): 7056 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE 7057 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec''' 7058 t[0] = ObjectClassDefn(fields = t[3]) 7059 7060def p_FieldSpecs_1 (t): 7061 'FieldSpecs : FieldSpec' 7062 t[0] = [t[1]] 7063 7064def p_FieldSpecs_2 (t): 7065 'FieldSpecs : FieldSpecs COMMA FieldSpec' 7066 t[0] = t[1] + [t[3]] 7067 7068def p_WithSyntaxSpec (t): 7069 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore' 7070 t[0] = None 7071 7072# 9.4 7073def p_FieldSpec (t): 7074 '''FieldSpec : TypeFieldSpec 7075 | FixedTypeValueFieldSpec 7076 | VariableTypeValueFieldSpec 7077 | FixedTypeValueSetFieldSpec 7078 | ObjectFieldSpec 7079 | ObjectSetFieldSpec ''' 7080 t[0] = t[1] 7081 7082# 9.5 7083def p_TypeFieldSpec (t): 7084 '''TypeFieldSpec : ucasefieldreference 7085 | ucasefieldreference TypeOptionalitySpec ''' 7086 t[0] = TypeFieldSpec() 7087 t[0].SetName(t[1]) 7088 7089def p_TypeOptionalitySpec_1 (t): 7090 'TypeOptionalitySpec ::= OPTIONAL' 7091 pass 7092 7093def p_TypeOptionalitySpec_2 (t): 7094 'TypeOptionalitySpec ::= DEFAULT Type' 7095 pass 7096 7097# 9.6 7098def p_FixedTypeValueFieldSpec (t): 7099 '''FixedTypeValueFieldSpec : lcasefieldreference Type 7100 | lcasefieldreference Type UNIQUE 7101 | lcasefieldreference Type ValueOptionalitySpec 7102 | lcasefieldreference Type UNIQUE ValueOptionalitySpec ''' 7103 t[0] = FixedTypeValueFieldSpec(typ = t[2]) 7104 t[0].SetName(t[1]) 7105 7106def p_ValueOptionalitySpec_1 (t): 7107 'ValueOptionalitySpec ::= OPTIONAL' 7108 pass 7109 7110def p_ValueOptionalitySpec_2 (t): 7111 'ValueOptionalitySpec ::= DEFAULT Value' 7112 pass 7113 7114# 9.8 7115 7116def p_VariableTypeValueFieldSpec (t): 7117 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName 7118 | lcasefieldreference FieldName ValueOptionalitySpec ''' 7119 t[0] = VariableTypeValueFieldSpec() 7120 t[0].SetName(t[1]) 7121 7122# 9.9 7123def p_FixedTypeValueSetFieldSpec (t): 7124 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type 7125 | ucasefieldreference Type ValueSetOptionalitySpec ''' 7126 t[0] = FixedTypeValueSetFieldSpec() 7127 t[0].SetName(t[1]) 7128 7129def p_ValueSetOptionalitySpec_1 (t): 7130 'ValueSetOptionalitySpec ::= OPTIONAL' 7131 pass 7132 7133def p_ValueSetOptionalitySpec_2 (t): 7134 'ValueSetOptionalitySpec ::= DEFAULT ValueSet' 7135 pass 7136 7137# 9.11 7138def p_ObjectFieldSpec (t): 7139 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass 7140 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec ''' 7141 t[0] = ObjectFieldSpec(cls=t[2]) 7142 t[0].SetName(t[1]) 7143 global obj_class 7144 obj_class = None 7145 7146def p_ObjectOptionalitySpec_1 (t): 7147 'ObjectOptionalitySpec ::= OPTIONAL' 7148 pass 7149 7150def p_ObjectOptionalitySpec_2 (t): 7151 'ObjectOptionalitySpec ::= DEFAULT Object' 7152 pass 7153 7154# 9.12 7155def p_ObjectSetFieldSpec (t): 7156 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass 7157 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec ''' 7158 t[0] = ObjectSetFieldSpec(cls=t[2]) 7159 t[0].SetName(t[1]) 7160 7161def p_ObjectSetOptionalitySpec_1 (t): 7162 'ObjectSetOptionalitySpec ::= OPTIONAL' 7163 pass 7164 7165def p_ObjectSetOptionalitySpec_2 (t): 7166 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet' 7167 pass 7168 7169# 9.13 7170def p_PrimitiveFieldName (t): 7171 '''PrimitiveFieldName : ucasefieldreference 7172 | lcasefieldreference ''' 7173 t[0] = t[1] 7174 7175# 9.13 7176def p_FieldName_1 (t): 7177 'FieldName : PrimitiveFieldName' 7178 t[0] = t[1] 7179 7180def p_FieldName_2 (t): 7181 'FieldName : FieldName DOT PrimitiveFieldName' 7182 t[0] = t[1] + '.' + t[3] 7183 7184# 11 Information object definition and assignment 7185 7186# 11.1 7187def p_ObjectAssignment (t): 7188 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object' 7189 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4]) 7190 global obj_class 7191 obj_class = None 7192 7193# 11.3 7194def p_Object (t): 7195 '''Object : DefinedObject 7196 | ObjectDefn 7197 | ParameterizedObject''' 7198 t[0] = t[1] 7199 7200# 11.4 7201def p_ObjectDefn (t): 7202 'ObjectDefn : lbraceobject bodyobject rbraceobject' 7203 t[0] = t[2] 7204 7205# {...} block of object definition 7206def p_lbraceobject(t): 7207 'lbraceobject : braceobjectbegin LBRACE' 7208 t[0] = t[1] 7209 7210def p_braceobjectbegin(t): 7211 'braceobjectbegin : ' 7212 global lexer 7213 global obj_class 7214 if set_class_syntax(obj_class): 7215 state = 'INITIAL' 7216 else: 7217 lexer.level = 1 7218 state = 'braceignore' 7219 lexer.push_state(state) 7220 7221def p_rbraceobject(t): 7222 'rbraceobject : braceobjectend RBRACE' 7223 t[0] = t[2] 7224 7225def p_braceobjectend(t): 7226 'braceobjectend : ' 7227 global lexer 7228 lexer.pop_state() 7229 set_class_syntax(None) 7230 7231def p_bodyobject_1 (t): 7232 'bodyobject : ' 7233 t[0] = { } 7234 7235def p_bodyobject_2 (t): 7236 'bodyobject : cls_syntax_list' 7237 t[0] = t[1] 7238 7239def p_cls_syntax_list_1 (t): 7240 'cls_syntax_list : cls_syntax_list cls_syntax' 7241 t[0] = t[1] 7242 t[0].update(t[2]) 7243 7244def p_cls_syntax_list_2 (t): 7245 'cls_syntax_list : cls_syntax' 7246 t[0] = t[1] 7247 7248# X.681 7249def p_cls_syntax_1 (t): 7250 'cls_syntax : Type IDENTIFIED BY Value' 7251 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] } 7252 7253def p_cls_syntax_2 (t): 7254 'cls_syntax : HAS PROPERTY Value' 7255 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] } 7256 7257# X.880 7258def p_cls_syntax_3 (t): 7259 '''cls_syntax : ERRORS ObjectSet 7260 | LINKED ObjectSet 7261 | RETURN RESULT BooleanValue 7262 | SYNCHRONOUS BooleanValue 7263 | INVOKE PRIORITY Value 7264 | RESULT_PRIORITY Value 7265 | PRIORITY Value 7266 | ALWAYS RESPONDS BooleanValue 7267 | IDEMPOTENT BooleanValue ''' 7268 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] } 7269 7270def p_cls_syntax_4 (t): 7271 '''cls_syntax : ARGUMENT Type 7272 | RESULT Type 7273 | PARAMETER Type ''' 7274 t[0] = { get_class_fieled(t[1]) : t[2] } 7275 7276def p_cls_syntax_5 (t): 7277 'cls_syntax : CODE Value' 7278 fld = get_class_fieled(t[1]); 7279 t[0] = { fld : t[2] } 7280 if isinstance(t[2], ChoiceValue): 7281 fldt = fld + '.' + t[2].choice 7282 t[0][fldt] = t[2] 7283 7284def p_cls_syntax_6 (t): 7285 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue 7286 | RESULT Type OPTIONAL BooleanValue 7287 | PARAMETER Type OPTIONAL BooleanValue ''' 7288 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] } 7289 7290# 12 Information object set definition and assignment 7291 7292# 12.1 7293def p_ObjectSetAssignment (t): 7294 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet' 7295 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4]) 7296 7297# 12.3 7298def p_ObjectSet (t): 7299 'ObjectSet : lbraceignore rbraceignore' 7300 t[0] = None 7301 7302# 14 Notation for the object class field type --------------------------------- 7303 7304# 14.1 7305def p_ObjectClassFieldType (t): 7306 'ObjectClassFieldType : DefinedObjectClass DOT FieldName' 7307 t[0] = get_type_from_class(t[1], t[3]) 7308 7309# 14.6 7310def p_ObjectClassFieldValue (t): 7311 '''ObjectClassFieldValue : OpenTypeFieldVal''' 7312 t[0] = t[1] 7313 7314def p_OpenTypeFieldVal (t): 7315 '''OpenTypeFieldVal : Type COLON Value 7316 | NullType COLON NullValue''' 7317 t[0] = t[3] 7318 7319 7320# 15 Information from objects ------------------------------------------------- 7321 7322# 15.1 7323 7324def p_ValueFromObject (t): 7325 'ValueFromObject : LCASE_IDENT DOT FieldName' 7326 t[0] = t[1] + '.' + t[3] 7327 7328 7329# Annex C - The instance-of type ---------------------------------------------- 7330 7331# C.2 7332def p_InstanceOfType (t): 7333 'InstanceOfType : INSTANCE OF DefinedObjectClass' 7334 t[0] = InstanceOfType() 7335 7336 7337# --- tables --- 7338 7339useful_object_class_types = { 7340 # Annex A 7341 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(), 7342 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(), 7343 # Annex B 7344 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(), 7345 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(), 7346 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(), 7347} 7348 7349object_class_types = { } 7350 7351object_class_typerefs = { } 7352 7353object_class_classrefs = { } 7354 7355# dummy types 7356class _VariableTypeValueFieldSpec (AnyType): 7357 pass 7358 7359class _FixedTypeValueSetFieldSpec (AnyType): 7360 pass 7361 7362class_types_creator = { 7363 'BooleanType' : lambda : BooleanType(), 7364 'IntegerType' : lambda : IntegerType(), 7365 'ObjectIdentifierType' : lambda : ObjectIdentifierType(), 7366 'OpenType' : lambda : OpenType(), 7367 # dummy types 7368 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(), 7369 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(), 7370} 7371 7372class_names = { } 7373 7374x681_syntaxes = { 7375 'TYPE-IDENTIFIER' : { 7376 ' ' : '&Type', 7377 'IDENTIFIED' : 'IDENTIFIED', 7378 #'BY' : 'BY', 7379 'IDENTIFIED BY' : '&id', 7380 }, 7381 'ABSTRACT-SYNTAX' : { 7382 ' ' : '&Type', 7383 'IDENTIFIED' : 'IDENTIFIED', 7384 #'BY' : 'BY', 7385 'IDENTIFIED BY' : '&id', 7386 'HAS' : 'HAS', 7387 'PROPERTY' : 'PROPERTY', 7388 'HAS PROPERTY' : '&property', 7389 }, 7390} 7391 7392class_syntaxes_enabled = { 7393 'TYPE-IDENTIFIER' : True, 7394 'ABSTRACT-SYNTAX' : True, 7395} 7396 7397class_syntaxes = { 7398 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'], 7399 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'], 7400} 7401 7402class_current_syntax = None 7403 7404def get_syntax_tokens(syntaxes): 7405 tokens = { } 7406 for s in (syntaxes): 7407 for k in (list(syntaxes[s].keys())): 7408 if k.find(' ') < 0: 7409 tokens[k] = k 7410 tokens[k] = tokens[k].replace('-', '_') 7411 return list(tokens.values()) 7412 7413tokens = tokens + get_syntax_tokens(x681_syntaxes) 7414 7415def set_class_syntax(syntax): 7416 global class_syntaxes_enabled 7417 global class_current_syntax 7418 #print "set_class_syntax", syntax, class_current_syntax 7419 if class_syntaxes_enabled.get(syntax, False): 7420 class_current_syntax = syntax 7421 return True 7422 else: 7423 class_current_syntax = None 7424 return False 7425 7426def is_class_syntax(name): 7427 global class_syntaxes 7428 global class_current_syntax 7429 #print "is_class_syntax", name, class_current_syntax 7430 if not class_current_syntax: 7431 return False 7432 return name in class_syntaxes[class_current_syntax] 7433 7434def get_class_fieled(name): 7435 if not class_current_syntax: 7436 return None 7437 return class_syntaxes[class_current_syntax][name] 7438 7439def is_class_ident(name): 7440 return name in class_names 7441 7442def add_class_ident(name): 7443 #print "add_class_ident", name 7444 class_names[name] = name 7445 7446def get_type_from_class(cls, fld): 7447 flds = fld.split('.') 7448 if (isinstance(cls, Class_Ref)): 7449 key = cls.val + '.' + flds[0] 7450 else: 7451 key = cls + '.' + flds[0] 7452 7453 if key in object_class_classrefs: 7454 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:])) 7455 7456 if key in object_class_typerefs: 7457 return Type_Ref(val=object_class_typerefs[key]) 7458 7459 creator = lambda : AnyType() 7460 creator = useful_object_class_types.get(key, creator) 7461 creator = object_class_types.get(key, creator) 7462 return creator() 7463 7464def set_type_to_class(cls, fld, pars): 7465 #print "set_type_to_class", cls, fld, pars 7466 key = cls + '.' + fld 7467 typename = 'OpenType' 7468 if (len(pars) > 0): 7469 typename = pars[0] 7470 else: 7471 pars.append(typename) 7472 typeref = None 7473 if (len(pars) > 1): 7474 if (isinstance(pars[1], Class_Ref)): 7475 pars[1] = pars[1].val 7476 typeref = pars[1] 7477 7478 msg = None 7479 if key in object_class_types: 7480 msg = object_class_types[key]().type 7481 if key in object_class_typerefs: 7482 msg = "TypeReference " + object_class_typerefs[key] 7483 if key in object_class_classrefs: 7484 msg = "ClassReference " + object_class_classrefs[key] 7485 7486 if msg == ' '.join(pars): 7487 msg = None 7488 7489 if msg: 7490 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars)) 7491 msg1 = "Already defined as '%s'" % (msg) 7492 raise CompError(msg0 + msg1) 7493 7494 if (typename == 'ClassReference'): 7495 if not typeref: return False 7496 object_class_classrefs[key] = typeref 7497 return True 7498 7499 if (typename == 'TypeReference'): 7500 if not typeref: return False 7501 object_class_typerefs[key] = typeref 7502 return True 7503 7504 creator = class_types_creator.get(typename) 7505 if creator: 7506 object_class_types[key] = creator 7507 return True 7508 else: 7509 return False 7510 7511def import_class_from_module(mod, cls): 7512 add_class_ident(cls) 7513 mcls = "$%s$%s" % (mod, cls) 7514 for k in list(object_class_classrefs.keys()): 7515 kk = k.split('.', 1) 7516 if kk[0] == mcls: 7517 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k] 7518 for k in list(object_class_typerefs.keys()): 7519 kk = k.split('.', 1) 7520 if kk[0] == mcls: 7521 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k] 7522 for k in list(object_class_types.keys()): 7523 kk = k.split('.', 1) 7524 if kk[0] == mcls: 7525 object_class_types[cls + '.' + kk[0]] = object_class_types[k] 7526 7527#--- ITU-T Recommendation X.682 ----------------------------------------------- 7528 7529# 8 General constraint specification ------------------------------------------ 7530 7531# 8.1 7532def p_GeneralConstraint (t): 7533 '''GeneralConstraint : UserDefinedConstraint 7534 | TableConstraint 7535 | ContentsConstraint''' 7536 t[0] = t[1] 7537 7538# 9 User-defined constraints -------------------------------------------------- 7539 7540# 9.1 7541def p_UserDefinedConstraint (t): 7542 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE' 7543 t[0] = Constraint(type = 'UserDefined', subtype = t[4]) 7544 7545def p_UserDefinedConstraintParameterList_1 (t): 7546 'UserDefinedConstraintParameterList : ' 7547 t[0] = [] 7548 7549def p_UserDefinedConstraintParameterList_2 (t): 7550 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter' 7551 t[0] = [t[1]] 7552 7553def p_UserDefinedConstraintParameterList_3 (t): 7554 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter' 7555 t[0] = t[1] + [t[3]] 7556 7557# 9.3 7558def p_UserDefinedConstraintParameter (t): 7559 'UserDefinedConstraintParameter : Type' 7560 t[0] = t[1] 7561 7562# 10 Table constraints, including component relation constraints -------------- 7563 7564# 10.3 7565def p_TableConstraint (t): 7566 '''TableConstraint : SimpleTableConstraint 7567 | ComponentRelationConstraint''' 7568 t[0] = Constraint(type = 'Table', subtype = t[1]) 7569 7570def p_SimpleTableConstraint (t): 7571 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE' 7572 t[0] = t[2] 7573 7574# 10.7 7575def p_ComponentRelationConstraint (t): 7576 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE' 7577 t[0] = t[2] + str(t[5]) 7578 7579def p_AtNotations_1 (t): 7580 'AtNotations : AtNotation' 7581 t[0] = [t[1]] 7582 7583def p_AtNotations_2 (t): 7584 'AtNotations : AtNotations COMMA AtNotation' 7585 t[0] = t[1] + [t[3]] 7586 7587def p_AtNotation_1 (t): 7588 'AtNotation : AT ComponentIdList' 7589 t[0] = '@' + t[2] 7590 7591def p_AtNotation_2 (t): 7592 'AtNotation : AT DOT Level ComponentIdList' 7593 t[0] = '@.' + t[3] + t[4] 7594 7595def p_Level_1 (t): 7596 'Level : DOT Level' 7597 t[0] = '.' + t[2] 7598 7599def p_Level_2 (t): 7600 'Level : ' 7601 t[0] = '' 7602 7603def p_ComponentIdList_1 (t): 7604 'ComponentIdList : LCASE_IDENT' 7605 t[0] = t[1] 7606 7607def p_ComponentIdList_2 (t): 7608 'ComponentIdList : ComponentIdList DOT LCASE_IDENT' 7609 t[0] = t[1] + '.' + t[3] 7610 7611# 11 Contents constraints ----------------------------------------------------- 7612 7613# 11.1 7614def p_ContentsConstraint (t): 7615 'ContentsConstraint : CONTAINING type_ref' 7616 t[0] = Constraint(type = 'Contents', subtype = t[2]) 7617 7618 7619#--- ITU-T Recommendation X.683 ----------------------------------------------- 7620 7621# 8 Parameterized assignments ------------------------------------------------- 7622 7623# 8.1 7624def p_ParameterizedAssignment (t): 7625 '''ParameterizedAssignment : ParameterizedTypeAssignment 7626 | ParameterizedObjectClassAssignment 7627 | ParameterizedObjectAssignment 7628 | ParameterizedObjectSetAssignment''' 7629 t[0] = t[1] 7630 7631# 8.2 7632def p_ParameterizedTypeAssignment (t): 7633 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type' 7634 t[0] = t[4] 7635 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx') 7636 7637def p_ParameterizedObjectClassAssignment (t): 7638 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass 7639 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass''' 7640 t[0] = t[4] 7641 t[0].SetName(t[1]) 7642 if isinstance(t[0], ObjectClassDefn): 7643 t[0].reg_types() 7644 7645def p_ParameterizedObjectAssignment (t): 7646 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object' 7647 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5]) 7648 global obj_class 7649 obj_class = None 7650 7651def p_ParameterizedObjectSetAssignment (t): 7652 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet' 7653 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5]) 7654 7655# 8.3 7656def p_ParameterList (t): 7657 'ParameterList : lbraceignore rbraceignore' 7658 7659#def p_ParameterList (t): 7660# 'ParameterList : LBRACE Parameters RBRACE' 7661# t[0] = t[2] 7662 7663#def p_Parameters_1 (t): 7664# 'Parameters : Parameter' 7665# t[0] = [t[1]] 7666 7667#def p_Parameters_2 (t): 7668# 'Parameters : Parameters COMMA Parameter' 7669# t[0] = t[1] + [t[3]] 7670 7671#def p_Parameter_1 (t): 7672# 'Parameter : Type COLON Reference' 7673# t[0] = [t[1], t[3]] 7674 7675#def p_Parameter_2 (t): 7676# 'Parameter : Reference' 7677# t[0] = t[1] 7678 7679 7680# 9 Referencing parameterized definitions ------------------------------------- 7681 7682# 9.1 7683def p_ParameterizedReference (t): 7684 'ParameterizedReference : Reference LBRACE RBRACE' 7685 t[0] = t[1] 7686 #t[0].val += 'xxx' 7687 7688# 9.2 7689def p_ParameterizedType (t): 7690 'ParameterizedType : type_ref ActualParameterList' 7691 t[0] = t[1] 7692 #t[0].val += 'xxx' 7693 7694 7695def p_ParameterizedObjectClass (t): 7696 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList' 7697 t[0] = t[1] 7698 #t[0].val += 'xxx' 7699 7700def p_ParameterizedObject (t): 7701 'ParameterizedObject : DefinedObject ActualParameterList' 7702 t[0] = t[1] 7703 #t[0].val += 'xxx' 7704 7705# 9.5 7706def p_ActualParameterList (t): 7707 'ActualParameterList : lbraceignore rbraceignore' 7708 7709#def p_ActualParameterList (t): 7710# 'ActualParameterList : LBRACE ActualParameters RBRACE' 7711# t[0] = t[2] 7712 7713#def p_ActualParameters_1 (t): 7714# 'ActualParameters : ActualParameter' 7715# t[0] = [t[1]] 7716 7717#def p_ActualParameters_2 (t): 7718# 'ActualParameters : ActualParameters COMMA ActualParameter' 7719# t[0] = t[1] + [t[3]] 7720 7721#def p_ActualParameter (t): 7722# '''ActualParameter : Type 7723# | Value''' 7724# t[0] = t[1] 7725 7726 7727#--- ITU-T Recommendation X.880 ----------------------------------------------- 7728 7729x880_classes = { 7730 'OPERATION' : { 7731 '&ArgumentType' : [], 7732 '&argumentTypeOptional' : [ 'BooleanType' ], 7733 '&returnResult' : [ 'BooleanType' ], 7734 '&ResultType' : [], 7735 '&resultTypeOptional' : [ 'BooleanType' ], 7736 '&Errors' : [ 'ClassReference', 'ERROR' ], 7737 '&Linked' : [ 'ClassReference', 'OPERATION' ], 7738 '&synchronous' : [ 'BooleanType' ], 7739 '&idempotent' : [ 'BooleanType' ], 7740 '&alwaysReturns' : [ 'BooleanType' ], 7741 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ], 7742 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ], 7743 '&operationCode' : [ 'TypeReference', 'Code' ], 7744 }, 7745 'ERROR' : { 7746 '&ParameterType' : [], 7747 '¶meterTypeOptional' : [ 'BooleanType' ], 7748 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ], 7749 '&errorCode' : [ 'TypeReference', 'Code' ], 7750 }, 7751 'OPERATION-PACKAGE' : { 7752 '&Both' : [ 'ClassReference', 'OPERATION' ], 7753 '&Consumer' : [ 'ClassReference', 'OPERATION' ], 7754 '&Supplier' : [ 'ClassReference', 'OPERATION' ], 7755 '&id' : [ 'ObjectIdentifierType' ], 7756 }, 7757 'CONNECTION-PACKAGE' : { 7758 '&bind' : [ 'ClassReference', 'OPERATION' ], 7759 '&unbind' : [ 'ClassReference', 'OPERATION' ], 7760 '&responderCanUnbind' : [ 'BooleanType' ], 7761 '&unbindCanFail' : [ 'BooleanType' ], 7762 '&id' : [ 'ObjectIdentifierType' ], 7763 }, 7764 'CONTRACT' : { 7765 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ], 7766 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ], 7767 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ], 7768 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ], 7769 '&id' : [ 'ObjectIdentifierType' ], 7770 }, 7771 'ROS-OBJECT-CLASS' : { 7772 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ], 7773 '&Initiates' : [ 'ClassReference', 'CONTRACT' ], 7774 '&Responds' : [ 'ClassReference', 'CONTRACT' ], 7775 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ], 7776 '&id' : [ 'ObjectIdentifierType' ], 7777 }, 7778} 7779 7780x880_syntaxes = { 7781 'OPERATION' : { 7782 'ARGUMENT' : '&ArgumentType', 7783 'ARGUMENT OPTIONAL' : '&argumentTypeOptional', 7784 'RESULT' : '&ResultType', 7785 'RESULT OPTIONAL' : '&resultTypeOptional', 7786 'RETURN' : 'RETURN', 7787 'RETURN RESULT' : '&returnResult', 7788 'ERRORS' : '&Errors', 7789 'LINKED' : '&Linked', 7790 'SYNCHRONOUS' : '&synchronous', 7791 'IDEMPOTENT' : '&idempotent', 7792 'ALWAYS' : 'ALWAYS', 7793 'RESPONDS' : 'RESPONDS', 7794 'ALWAYS RESPONDS' : '&alwaysReturns', 7795 'INVOKE' : 'INVOKE', 7796 'PRIORITY' : 'PRIORITY', 7797 'INVOKE PRIORITY' : '&InvokePriority', 7798 'RESULT-PRIORITY': '&ResultPriority', 7799 'CODE' : '&operationCode', 7800 }, 7801 'ERROR' : { 7802 'PARAMETER' : '&ParameterType', 7803 'PARAMETER OPTIONAL' : '¶meterTypeOptional', 7804 'PRIORITY' : '&ErrorPriority', 7805 'CODE' : '&errorCode', 7806 }, 7807# 'OPERATION-PACKAGE' : { 7808# }, 7809# 'CONNECTION-PACKAGE' : { 7810# }, 7811# 'CONTRACT' : { 7812# }, 7813# 'ROS-OBJECT-CLASS' : { 7814# }, 7815} 7816 7817def x880_module_begin(): 7818 #print "x880_module_begin()" 7819 for name in list(x880_classes.keys()): 7820 add_class_ident(name) 7821 7822def x880_import(name): 7823 if name in x880_syntaxes: 7824 class_syntaxes_enabled[name] = True 7825 class_syntaxes[name] = x880_syntaxes[name] 7826 if name in x880_classes: 7827 add_class_ident(name) 7828 for f in (list(x880_classes[name].keys())): 7829 set_type_to_class(name, f, x880_classes[name][f]) 7830 7831tokens = tokens + get_syntax_tokens(x880_syntaxes) 7832 7833# {...} OID value 7834#def p_lbrace_oid(t): 7835# 'lbrace_oid : brace_oid_begin LBRACE' 7836# t[0] = t[1] 7837 7838#def p_brace_oid_begin(t): 7839# 'brace_oid_begin : ' 7840# global in_oid 7841# in_oid = True 7842 7843#def p_rbrace_oid(t): 7844# 'rbrace_oid : brace_oid_end RBRACE' 7845# t[0] = t[2] 7846 7847#def p_brace_oid_end(t): 7848# 'brace_oid_end : ' 7849# global in_oid 7850# in_oid = False 7851 7852# {...} block to be ignored 7853def p_lbraceignore(t): 7854 'lbraceignore : braceignorebegin LBRACE' 7855 t[0] = t[1] 7856 7857def p_braceignorebegin(t): 7858 'braceignorebegin : ' 7859 global lexer 7860 lexer.level = 1 7861 lexer.push_state('braceignore') 7862 7863def p_rbraceignore(t): 7864 'rbraceignore : braceignoreend RBRACE' 7865 t[0] = t[2] 7866 7867def p_braceignoreend(t): 7868 'braceignoreend : ' 7869 global lexer 7870 lexer.pop_state() 7871 7872def p_error(t): 7873 global input_file 7874 raise ParseError(t, input_file) 7875 7876def p_pyquote (t): 7877 '''pyquote : PYQUOTE''' 7878 t[0] = PyQuote (val = t[1]) 7879 7880 7881def testlex (s): 7882 lexer.input (s) 7883 while True: 7884 token = lexer.token () 7885 if not token: 7886 break 7887 print(token) 7888 7889 7890def do_module (ast, defined_dict): 7891 assert (ast.type == 'Module') 7892 ctx = Ctx (defined_dict) 7893 print(ast.to_python (ctx)) 7894 print(ctx.output_assignments ()) 7895 print(ctx.output_pyquotes ()) 7896 7897def eth_do_module (ast, ectx): 7898 assert (ast.type == 'Module') 7899 if ectx.dbg('s'): print(ast.str_depth(0)) 7900 ast.to_eth(ectx) 7901 7902def testyacc(s, fn, defined_dict): 7903 ast = yacc.parse(s, debug=0) 7904 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) 7905 print("""#!/usr/bin/env python 7906# Auto-generated from %s at %s 7907from PyZ3950 import asn1""" % (fn, time_str)) 7908 for module in ast: 7909 eth_do_module (module, defined_dict) 7910 7911 7912# Wireshark compiler 7913def eth_usage(): 7914 print(""" 7915 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ... 7916 -h|? : Usage 7917 -b : BER (default is PER) 7918 -u : Unaligned (default is aligned) 7919 -p proto : Protocol name (implies -S). Default is module-name 7920 from input_file (renamed by #.MODULE if present) 7921 -o name : Output files name core (default is <proto>) 7922 -O dir : Output directory for dissector 7923 -c cnf_file : Conformance file 7924 -I path : Path for conformance file includes 7925 -e : Create conformance file for exported types 7926 -E : Just create conformance file for exported types 7927 -S : Single output for multiple modules 7928 -s template : Single file output (template is input file 7929 without .c/.h extension) 7930 -k : Keep intermediate files though single file output is used 7931 -L : Suppress #line directive from .cnf file 7932 -D dir : Directory for input_file(s) (default: '.') 7933 -C : Add check for SIZE constraints 7934 -r prefix : Remove the prefix from type names 7935 7936 input_file(s) : Input ASN.1 file(s) 7937 7938 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o] 7939 l - lex 7940 y - yacc 7941 p - parsing 7942 s - internal ASN.1 structure 7943 a - list of assignments 7944 t - tables 7945 c - conformance values 7946 m - list of compiled modules with dependency 7947 o - list of output files 7948 """) 7949 7950def eth_main(): 7951 global input_file 7952 global g_conform 7953 global lexer 7954 print("ASN.1 to Wireshark dissector compiler"); 7955 try: 7956 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:"); 7957 except getopt.GetoptError: 7958 eth_usage(); sys.exit(2) 7959 if len(args) < 1: 7960 eth_usage(); sys.exit(2) 7961 7962 conform = EthCnf() 7963 conf_to_read = None 7964 output = EthOut() 7965 ectx = EthCtx(conform, output) 7966 ectx.encoding = 'per' 7967 ectx.proto_opt = None 7968 ectx.fld_opt = {} 7969 ectx.tag_opt = False 7970 ectx.outnm_opt = None 7971 ectx.aligned = True 7972 ectx.dbgopt = '' 7973 ectx.new = True 7974 ectx.expcnf = False 7975 ectx.justexpcnf = False 7976 ectx.merge_modules = False 7977 ectx.group_by_prot = False 7978 ectx.conform.last_group = 0 7979 ectx.conform.suppress_line = False; 7980 ectx.output.outnm = None 7981 ectx.output.single_file = None 7982 ectx.constraints_check = False; 7983 for o, a in opts: 7984 if o in ("-h", "-?"): 7985 eth_usage(); sys.exit(2) 7986 if o in ("-c",): 7987 conf_to_read = relpath(a) 7988 if o in ("-I",): 7989 ectx.conform.include_path.append(relpath(a)) 7990 if o in ("-E",): 7991 ectx.expcnf = True 7992 ectx.justexpcnf = True 7993 if o in ("-D",): 7994 ectx.srcdir = relpath(a) 7995 if o in ("-C",): 7996 ectx.constraints_check = True 7997 if o in ("-X",): 7998 warnings.warn("Command line option -X is obsolete and can be removed") 7999 if o in ("-T",): 8000 warnings.warn("Command line option -T is obsolete and can be removed") 8001 8002 if conf_to_read: 8003 ectx.conform.read(conf_to_read) 8004 8005 for o, a in opts: 8006 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-X", "-T"): 8007 pass # already processed 8008 else: 8009 par = [] 8010 if a: par.append(a) 8011 ectx.conform.set_opt(o, par, "commandline", 0) 8012 8013 (ld, yd, pd) = (0, 0, 0); 8014 if ectx.dbg('l'): ld = 1 8015 if ectx.dbg('y'): yd = 1 8016 if ectx.dbg('p'): pd = 2 8017 lexer = lex.lex(debug=ld) 8018 parser = yacc.yacc(method='LALR', debug=yd, outputdir='.') 8019 parser.defaulted_states = {} 8020 g_conform = ectx.conform 8021 ast = [] 8022 for fn in args: 8023 input_file = fn 8024 lexer.lineno = 1 8025 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn 8026 # Read ASN.1 definition, trying one of the common encodings. 8027 data = open(fn, "rb").read() 8028 for encoding in ('utf-8', 'windows-1252'): 8029 try: 8030 data = data.decode(encoding) 8031 break 8032 except Exception: 8033 warnings.warn_explicit("Decoding %s as %s failed, trying next." % (fn, encoding), UserWarning, '', 0) 8034 # Py2 compat, name.translate in eth_output_hf_arr fails with unicode 8035 if not isinstance(data, str): 8036 data = data.encode('utf-8') 8037 ast.extend(yacc.parse(data, lexer=lexer, debug=pd)) 8038 ectx.eth_clean() 8039 if (ectx.merge_modules): # common output for all module 8040 ectx.eth_clean() 8041 for module in ast: 8042 eth_do_module(module, ectx) 8043 ectx.eth_prepare() 8044 ectx.eth_do_output() 8045 elif (ectx.groups()): # group by protocols/group 8046 groups = [] 8047 pr2gr = {} 8048 if (ectx.group_by_prot): # group by protocols 8049 for module in ast: 8050 prot = module.get_proto(ectx) 8051 if prot not in pr2gr: 8052 pr2gr[prot] = len(groups) 8053 groups.append([]) 8054 groups[pr2gr[prot]].append(module) 8055 else: # group by groups 8056 pass 8057 for gm in (groups): 8058 ectx.eth_clean() 8059 for module in gm: 8060 eth_do_module(module, ectx) 8061 ectx.eth_prepare() 8062 ectx.eth_do_output() 8063 else: # output for each module 8064 for module in ast: 8065 ectx.eth_clean() 8066 eth_do_module(module, ectx) 8067 ectx.eth_prepare() 8068 ectx.eth_do_output() 8069 8070 if ectx.dbg('m'): 8071 ectx.dbg_modules() 8072 8073 if ectx.dbg('c'): 8074 ectx.conform.dbg_print() 8075 if not ectx.justexpcnf: 8076 ectx.conform.unused_report() 8077 8078 if ectx.dbg('o'): 8079 ectx.output.dbg_print() 8080 ectx.output.make_single_file() 8081 8082 8083# Python compiler 8084def main(): 8085 if sys.version_info[0] < 3: 8086 print("This requires Python 3") 8087 sys.exit(2) 8088 8089 testfn = testyacc 8090 if len (sys.argv) == 1: 8091 while True: 8092 s = eval(input ('Query: ')) 8093 if len (s) == 0: 8094 break 8095 testfn (s, 'console', {}) 8096 else: 8097 defined_dict = {} 8098 for fn in sys.argv [1:]: 8099 f = open (fn, "r") 8100 testfn (f.read (), fn, defined_dict) 8101 f.close () 8102 lexer.lineno = 1 8103 8104 8105#--- BODY --------------------------------------------------------------------- 8106 8107if __name__ == '__main__': 8108 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')): 8109 eth_main() 8110 else: 8111 main() 8112 8113#------------------------------------------------------------------------------ 8114# 8115# Editor modelines - https://www.wireshark.org/tools/modelines.html 8116# 8117# c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil 8118# vi: set shiftwidth=4 tabstop=8 expandtab: 8119# :indentSize=4:tabSize=8:noTabs=true: 8120