5 # ASN.1 to Wireshark dissector compiler
11 """ASN.1 to Wireshark dissector compiler"""
14 # Compiler from ASN.1 specification to the Wireshark dissector
16 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
17 # http://www.pobox.com/~asl2/software/PyZ3950/
18 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
20 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
21 # http://www.dabeaz.com/ply/
24 # ITU-T Recommendation X.680 (07/2002),
25 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
27 # ITU-T Recommendation X.681 (07/2002),
28 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
30 # ITU-T Recommendation X.682 (07/2002),
31 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
33 # ITU-T Recommendation X.683 (07/2002),
34 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
37 from __future__ import nested_scopes
48 import __main__ # XXX blech!
52 # OID name -> number conversion table
58 '0/recommendation' : 0,
87 '0/administration' : 2,
88 '0/network-operator' : 3,
89 '0/identified-organization' : 4,
90 '0/r-recommendation' : 5,
94 '1/registration-authority' : 1,
96 '1/identified-organization' : 3,
97 '/joint-iso-itu-t' : 2,
98 '/joint-iso-ccitt' : 2,
101 '2/association-control' : 2,
102 '2/reliable-transfer' : 3,
103 '2/remote-operations' : 4,
111 '2/osi-management' : 9,
112 '2/transaction-processing' : 10,
114 '2/distinguished-object-reference' : 11,
115 '2/reference-data-transfe' : 12,
116 '2/network-layer' : 13,
117 '2/network-layer-management' : 13,
118 '2/transport-layer' : 14,
119 '2/transport-layer-management' : 14,
120 '2/datalink-layer' : 15,
121 '2/datalink-layer-managemen' : 15,
122 '2/datalink-layer-management-information' : 15,
124 '2/registration-procedures' : 17,
125 '2/registration-procedure' : 17,
126 '2/physical-layer' : 18,
127 '2/physical-layer-management' : 18,
130 '2/generic-upper-layers-security' : 20,
132 '2/transport-layer-security-protocol' : 21,
133 '2/network-layer-security-protocol' : 22,
134 '2/international-organizations' : 23,
135 '2/internationalRA' : 23,
143 return id.replace('-', '_').replace('.', '_')
148 class LexError(Exception):
149 def __init__(self, tok, filename=None):
151 self.filename = filename
152 self.msg = "Unexpected character %r" % (self.tok.value[0])
153 Exception.__init__(self, self.msg)
155 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
159 class ParseError(Exception):
160 def __init__(self, tok, filename=None):
162 self.filename = filename
163 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
164 Exception.__init__(self, self.msg)
166 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
171 ('braceignore','exclusive'),
174 # 11 ASN.1 lexical items
177 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
178 r'\.\.' : 'RANGE', # 11.17 Range separator
179 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
180 #r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
181 #r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
182 # 11.26 Single character lexical items
197 #r"'" : 'APOSTROPHE',
200 #r'\!' : 'EXCLAMATION',
201 r'\^' : 'CIRCUMFLEX',
205 # 11.27 Reserved words
207 # all keys in reserved_words must start w/ upper case
210 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
212 'APPLICATION' : 'APPLICATION',
213 'AUTOMATIC' : 'AUTOMATIC',
216 'BOOLEAN' : 'BOOLEAN',
218 'CHARACTER' : 'CHARACTER',
221 'COMPONENT' : 'COMPONENT',
222 'COMPONENTS' : 'COMPONENTS',
223 'CONSTRAINED' : 'CONSTRAINED',
224 # 'CONTAINING' : 'CONTAINING',
225 'DEFAULT' : 'DEFAULT',
226 'DEFINITIONS' : 'DEFINITIONS',
227 # 'EMBEDDED' : 'EMBEDDED',
228 # 'ENCODED' : 'ENCODED',
230 'ENUMERATED' : 'ENUMERATED',
231 # 'EXCEPT' : 'EXCEPT',
232 'EXPLICIT' : 'EXPLICIT',
233 'EXPORTS' : 'EXPORTS',
234 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
235 'EXTERNAL' : 'EXTERNAL',
238 'GeneralizedTime' : 'GeneralizedTime',
239 'IDENTIFIER' : 'IDENTIFIER',
240 'IMPLICIT' : 'IMPLICIT',
241 # 'IMPLIED' : 'IMPLIED',
242 'IMPORTS' : 'IMPORTS',
243 'INCLUDES' : 'INCLUDES',
244 # 'INSTANCE' : 'INSTANCE',
245 'INTEGER' : 'INTEGER',
246 'INTERSECTION' : 'INTERSECTION',
249 'MINUS-INFINITY' : 'MINUS_INFINITY',
252 'ObjectDescriptor' : 'ObjectDescriptor',
255 'OPTIONAL' : 'OPTIONAL',
256 'PATTERN' : 'PATTERN',
258 'PLUS-INFINITY' : 'PLUS_INFINITY',
259 'PRESENT' : 'PRESENT',
260 'PRIVATE' : 'PRIVATE',
262 # 'RELATIVE-OID' : 'RELATIVE-OID',
263 'SEQUENCE' : 'SEQUENCE',
270 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
272 # 'UNIQUE' : 'UNIQUE',
273 'UNIVERSAL' : 'UNIVERSAL',
274 'UTCTime' : 'UTCTime',
276 # obsolete but still used
280 for k in static_tokens.keys ():
281 if static_tokens [k] == None:
282 static_tokens [k] = k
284 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
285 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
288 for s in StringTypes:
289 reserved_words[s + 'String'] = s + 'String'
291 tokens = static_tokens.values() \
292 + reserved_words.values() \
293 + ['BSTRING', 'HSTRING', 'QSTRING',
294 'UCASE_IDENT', 'LCASE_IDENT', 'CLASS_IDENT',
295 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
298 for (k, v) in static_tokens.items ():
299 __main__.__dict__['t_' + v] = k
301 # 11.10 Binary strings
306 # 11.12 Hexadecimal strings
315 def t_UCASE_IDENT (t):
316 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
317 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
318 t.type = reserved_words.get(t.value, t.type)
321 def t_LCASE_IDENT (t):
322 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
326 def t_REAL_NUMBER (t):
327 r"[0-9]+\.[0-9]*(?!\.)"
336 pyquote_str = 'PYQUOTE'
338 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
339 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
340 if t.value[2:2+len (pyquote_str)] == pyquote_str:
341 t.value = t.value[2+len(pyquote_str):]
342 t.value = t.value.lstrip ()
351 t.lexer.lineno += t.value.count("\n")
355 raise LexError(t, input_file)
357 # state 'braceignore'
359 def t_braceignore_lbrace(t):
363 def t_braceignore_rbrace(t):
366 # If closing brace, return token
367 if t.lexer.level == 0:
371 def t_braceignore_QSTRING (t):
374 def t_braceignore_COMMENT(t):
375 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
376 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
378 def t_braceignore_nonspace(t):
379 r'[^\s\{\}\"-]+|-(?!-)'
381 t_braceignore_ignore = " \t\r"
383 def t_braceignore_NEWLINE(t):
385 t.lexer.lineno += t.value.count("\n")
387 def t_braceignore_error(t):
391 def __init__ (self, defined_dict, indent = 0):
392 self.tags_def = 'EXPLICIT' # default = explicit
394 self.assignments = {}
395 self.dependencies = {}
397 self.defined_dict = defined_dict
400 return " " * (4 * self.indent_lev)
405 assert (self.indent_lev >= 0)
406 def register_assignment (self, ident, val, dependencies):
407 if self.assignments.has_key (ident):
408 raise "Duplicate assignment for " + ident
409 if self.defined_dict.has_key (ident):
410 raise "cross-module duplicates for " + ident
411 self.defined_dict [ident] = 1
412 self.assignments[ident] = val
413 self.dependencies [ident] = dependencies
415 # return "#%s depends on %s" % (ident, str (dependencies))
416 def register_pyquote (self, val):
417 self.pyquotes.append (val)
419 def output_assignments (self):
422 assign_keys = self.assignments.keys()
423 to_output_count = len (assign_keys)
426 for (ident, val) in self.assignments.iteritems ():
427 if already_output.has_key (ident):
430 for d in self.dependencies [ident]:
431 if (not already_output.has_key (d) and
435 text_list.append ("%s=%s" % (ident,
436 self.assignments [ident]))
437 already_output [ident] = 1
440 assert (to_output_count >= 0)
442 if to_output_count == 0:
444 # OK, we detected a cycle
446 for ident in self.assignments.iterkeys ():
447 if not already_output.has_key (ident):
448 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
449 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
451 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
452 for (ident, val) in self.assignments.iteritems ():
453 if not already_output.has_key (ident):
454 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
457 return "\n".join (text_list)
458 def output_pyquotes (self):
459 return "\n".join (self.pyquotes)
460 def make_new_name (self):
462 return "_compiler_generated_name_%d" % (self.name_ctr,)
464 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
476 #--- EthCtx -------------------------------------------------------------------
478 def __init__(self, conform, output, indent = 0):
479 self.conform = conform
481 self.conform.ectx = self
482 self.output.ectx = self
484 def encp(self): # encoding protocol
489 def Per(self): return self.encoding == 'per'
490 def Ber(self): return self.encoding == 'ber'
491 def Aligned(self): return self.aligned
492 def Unaligned(self): return not self.aligned
493 def Fld(self, tnm='*'): return self.fld_opt.get('*', False) or self.fld_opt.get(tnm, False) or self.Ber()
494 def Tag(self): return self.tag_opt # or self.Ber() - temporary comment out (experimental feature)
495 def NAPI(self): return False # disable planned features
497 def module(self): # current module name
498 return self.modules[-1][0]
501 if (self.dbgopt.find(d) >= 0):
506 def eth_get_type_attr(self, type):
508 while (not self.type[type]['import']
509 and self.type[type]['val'].type == 'Type_Ref'):
510 type = self.type[type]['val'].val
515 attr.update(self.type[t]['attr'])
516 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
519 #--- eth_reg_assign ---------------------------------------------------------
520 def eth_reg_assign(self, ident, val, virt=False):
521 #print "eth_reg_assign(ident='%s')" % (ident)
522 if self.assign.has_key(ident):
523 raise "Duplicate assignment for " + ident
524 self.assign[ident] = { 'val' : val , 'virt' : virt }
525 self.assign_ord.append(ident)
527 #--- eth_reg_vassign --------------------------------------------------------
528 def eth_reg_vassign(self, vassign):
529 ident = vassign.ident
530 #print "eth_reg_vassign(ident='%s')" % (ident)
531 if self.vassign.has_key(ident):
532 raise "Duplicate value assignment for " + ident
533 self.vassign[ident] = vassign
534 self.vassign_ord.append(ident)
536 #--- eth_import_type --------------------------------------------------------
537 def eth_import_type(self, ident, mod, proto):
538 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
539 if self.type.has_key(ident):
540 #print "already defined import=%s, module=%s" % (str(self.type[ident]['import']), self.type[ident]['module'])
541 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
542 return # OK - already defined
543 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
544 return # OK - already imported
546 raise "Duplicate type for " + ident
547 self.type[ident] = {'import' : mod, 'proto' : proto,
549 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
550 'STRINGS' : 'NULL', 'BITMASK' : '0' }
551 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
552 self.type_imp.append(ident)
554 #--- eth_import_class --------------------------------------------------------
555 def eth_import_class(self, ident, mod, proto):
556 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
557 if self.objectclass.has_key(ident):
558 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
559 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
560 return # OK - already defined
561 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
562 return # OK - already imported
564 raise "Duplicate object class for " + ident
565 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
567 self.objectclass_imp.append(ident)
569 #--- eth_import_value -------------------------------------------------------
570 def eth_import_value(self, ident, mod, proto):
571 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
572 if self.type.has_key(ident):
573 raise "Duplicate value for " + ident
574 self.value[ident] = {'import' : mod, 'proto' : proto,
576 self.value_imp.append(ident)
578 #--- eth_dep_add ------------------------------------------------------------
579 def eth_dep_add(self, type, dep):
580 if not self.type_dep.has_key(type):
581 self.type_dep[type] = []
582 self.type_dep[type].append(dep)
584 #--- eth_reg_type -----------------------------------------------------------
585 def eth_reg_type(self, ident, val):
586 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
587 if self.type.has_key(ident):
588 if self.type[ident]['import'] and (self.type[ident]['import'] == self.module()) :
589 # replace imported type
591 self.type_imp.remove(ident)
593 raise "Duplicate type for " + ident
594 self.type[ident] = { 'val' : val, 'import' : None }
595 self.type[ident]['module'] = self.module()
596 self.type[ident]['proto'] = self.proto
597 if len(ident.split('/')) > 1:
598 self.type[ident]['tname'] = val.eth_tname()
600 self.type[ident]['tname'] = asn2c(ident)
601 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
602 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
603 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
604 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
605 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
606 self.type[ident]['ethname'] = ''
607 if val.type == 'Type_Ref':
608 self.type[ident]['attr'] = {}
610 (ftype, display) = val.eth_ftype(self)
611 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
612 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
613 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
614 self.type_ord.append(ident)
616 #--- eth_reg_value ----------------------------------------------------------
617 def eth_reg_value(self, ident, type, value):
618 #print "eth_reg_value(ident='%s')" % (ident)
619 if self.value.has_key(ident):
620 raise "Duplicate value for " + ident
621 self.value[ident] = { 'import' : None, 'proto' : self.proto,
622 'type' : type, 'value' : value }
623 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
624 self.value[ident]['ethname'] = ''
625 self.value_ord.append(ident)
627 #--- eth_reg_field ----------------------------------------------------------
628 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
629 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
630 if self.field.has_key(ident):
631 raise "Duplicate field for " + ident
632 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
633 'modified' : '', 'attr' : {} , 'create_field' : False }
634 name = ident.split('/')[-1]
635 if len(ident.split('/')) > 1 and name == '_item': # Sequnce/Set of type
636 self.field[ident]['attr']['NAME'] = '"Item"'
637 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
639 self.field[ident]['attr']['NAME'] = '"%s"' % name
640 self.field[ident]['attr']['ABBREV'] = asn2c(name)
641 if self.conform.check_item('FIELD_ATTR', ident):
642 self.field[ident]['modified'] = '#' + str(id(self))
643 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
645 self.pdu_ord.append(ident)
647 self.field_ord.append(ident)
649 self.field[ident]['create_field'] = self.Fld(parent)
650 self.eth_dep_add(parent, type)
652 #--- eth_clean --------------------------------------------------------------
654 self.proto = self.proto_opt;
655 #--- ASN.1 tables ----------------
666 self.vassign_ord = []
670 self.objectclass = {}
671 self.objectclass_ord = []
672 self.objectclass_imp = []
673 #--- Modules ------------
675 #--- types -------------------
677 self.eth_type_ord = []
678 self.eth_export_ord = []
679 self.eth_type_dupl = {}
681 #--- value dependencies -------------------
683 #--- values -------------------
685 self.eth_value_ord = []
686 #--- fields -------------------------
689 self.eth_hfpdu_ord = []
690 self.eth_hf_dupl = {}
691 #--- type dependencies -------------------
692 self.eth_type_ord1 = []
693 self.eth_dep_cycle = []
694 self.dep_cycle_eth_type = {}
695 #--- value dependencies and export -------------------
696 self.eth_value_ord1 = []
697 self.eth_vexport_ord = []
699 #--- eth_prepare ------------------------------------------------------------
700 def eth_prepare(self):
701 self.eproto = asn2c(self.proto)
703 #--- dummy types/fields for PDU registration ---
705 if (self.conform.check_item('PDU', nm)):
706 self.eth_reg_type('_dummy/'+nm, NullType())
707 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
709 #--- values -> named values -------------------
711 for v in self.value_ord:
712 if (self.value[v]['type'].type == 'Type_Ref'):
713 tnm = self.value[v]['type'].val
714 if self.type.has_key(tnm) \
715 and not self.type[tnm]['import'] \
716 and (self.type[tnm]['val'].type == 'IntegerType'):
717 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
718 v_for_remove.append(v)
719 for v in v_for_remove:
720 self.value_ord.remove(v)
723 #--- types -------------------
724 for t in self.type_imp:
726 self.eth_type[nm] = { 'import' : self.type[t]['import'],
727 'proto' : asn2c(self.type[t]['proto']),
728 'attr' : {}, 'create_field' : False, 'ref' : []}
729 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
730 self.type[t]['ethname'] = nm
731 for t in self.type_ord:
732 nm = self.type[t]['tname']
733 if ((nm.find('#') >= 0) or
734 ((len(t.split('/'))>1) and
735 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t)) and
736 not self.conform.check_item('TYPE_RENAME', t))):
737 if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequnce of type at the 1st level
738 nm = t.split('/')[0] + t.split('/')[1]
739 elif t.split('/')[-1] == '_item': # Sequnce/Set of type at next levels
740 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
741 elif t.split('/')[-1] == '_untag': # Untagged type
742 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
744 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
746 if self.eth_type.has_key(nm):
747 if self.eth_type_dupl.has_key(nm):
748 self.eth_type_dupl[nm].append(t)
750 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
751 nm += str(len(self.eth_type_dupl[nm])-1)
752 if self.eth_type.has_key(nm):
753 self.eth_type[nm]['ref'].append(t)
755 self.eth_type_ord.append(nm)
756 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
757 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
758 'val' : self.type[t]['val'],
760 'create_field' : False, 'ref' : [t]}
761 self.type[t]['ethname'] = nm
762 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
763 self.eth_export_ord.append(nm)
764 self.eth_type[nm]['export'] |= self.type[t]['export']
765 self.eth_type[nm]['enum'] |= self.type[t]['enum']
766 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
767 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
768 if self.type[t]['attr'].get('STRINGS') == '$$':
769 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
770 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
771 for t in self.eth_type_ord:
772 bits = self.eth_type[t]['val'].eth_named_bits()
774 for (val, id) in bits:
775 self.named_bit.append({'name' : id, 'val' : val,
776 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
777 'ftype' : 'FT_BOOLEAN', 'display' : '8',
779 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
780 if self.eth_type[t]['val'].eth_need_tree():
781 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
783 self.eth_type[t]['tree'] = None
785 #--- value dependencies -------------------
786 for v in self.value_ord:
787 if isinstance (self.value[v]['value'], Value):
788 dep = self.value[v]['value'].get_dep()
790 dep = self.value[v]['value']
791 if dep and self.value.has_key(dep):
792 self.value_dep.setdefault(v, []).append(dep)
794 #--- exports all necessary values
795 for v in self.value_ord:
796 if not self.value[v]['export']: continue
797 deparr = self.value_dep.get(v, [])
800 if not self.value[d]['import']:
801 if not self.value[d]['export']:
802 self.value[d]['export'] = EF_TYPE
803 deparr.extend(self.value_dep.get(d, []))
805 #--- values -------------------
806 for v in self.value_imp:
808 self.eth_value[nm] = { 'import' : self.value[v]['import'],
809 'proto' : asn2c(self.value[v]['proto']),
811 self.value[v]['ethname'] = nm
812 for v in self.value_ord:
814 self.eth_value[nm] = { 'import' : None,
815 'proto' : asn2c(self.value[v]['proto']),
816 'export' : self.value[v]['export'], 'ref' : [v] }
817 if isinstance (self.value[v]['value'], Value):
818 self.eth_value[nm]['value'] = self.value[v]['value'].to_str()
820 self.eth_value[nm]['value'] = self.value[v]['value']
821 self.eth_value_ord.append(nm)
822 self.value[v]['ethname'] = nm
824 #--- fields -------------------------
825 for f in (self.pdu_ord + self.field_ord):
826 if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequnce/Set of type
827 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
829 nm = f.split('/')[-1]
830 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
832 if (self.field[f]['pdu']):
834 t = self.field[f]['type']
835 if self.type.has_key(t):
836 ethtype = self.type[t]['ethname']
837 else: # undefined type
839 print "Dummy imported: ", t
840 self.type[t] = {'import' : 'xxx', 'proto' : 'xxx',
842 self.type[t]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
843 'STRINGS' : 'NULL', 'BITMASK' : '0' }
844 self.eth_type[t] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'create_field' : False, 'ref' : []}
846 ethtypemod = ethtype + self.field[f]['modified']
847 if self.eth_hf.has_key(nm):
848 if self.eth_hf_dupl.has_key(nm):
849 if self.eth_hf_dupl[nm].has_key(ethtypemod):
850 nm = self.eth_hf_dupl[nm][ethtypemod]
851 self.eth_hf[nm]['create_field'] = self.eth_hf[nm]['create_field'] or self.field[f]['create_field']
852 self.eth_hf[nm]['ref'].append(f)
853 self.field[f]['ethname'] = nm
854 self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
857 nmx = nm + str(len(self.eth_hf_dupl[nm]))
858 self.eth_hf_dupl[nm][ethtype] = nmx
861 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
862 self.eth_hf[nm]['create_field'] = self.eth_hf[nm]['create_field'] or self.field[f]['create_field']
863 self.eth_hf[nm]['ref'].append(f)
864 self.field[f]['ethname'] = nm
865 self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
868 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
871 if (self.field[f]['pdu']):
872 self.eth_hfpdu_ord.append(nm)
874 self.eth_hf_ord.append(nm)
875 fullname = "hf_%s_%s" % (self.eproto, nm)
876 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
877 attr.update(self.field[f]['attr'])
878 if (self.NAPI() and attr.has_key('NAME')):
879 attr['NAME'] += self.field[f]['idx']
880 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
881 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
882 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
883 'attr' : attr.copy(),
884 'create_field' : self.field[f]['create_field'],
886 self.field[f]['ethname'] = nm
887 self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
888 #--- type dependencies -------------------
889 x = {} # already emitted
890 #print '# Dependency computation'
891 for t in self.type_ord:
892 if x.has_key(self.type[t]['ethname']):
893 #print 'Continue: %s : %s' % (t, self.type[t]['ethname'])
896 stackx = {t : self.type_dep.get(t, [])[:]}
897 #print 'Push: %s : %s' % (t, str(stackx[t]))
899 if stackx[stack[-1]]: # has dependencies
900 d = stackx[stack[-1]].pop(0)
901 if x.has_key(self.type[d]['ethname']) or self.type[d]['import']:
903 if stackx.has_key(d): # cyclic dependency
906 c = [d] + c[0:c.index(d)+1]
908 self.eth_dep_cycle.append(c)
909 #print 'Cyclic: %s ' % (' -> '.join(c))
912 stackx[d] = self.type_dep.get(d, [])[:]
913 #print 'Push: %s : %s' % (d, str(stackx[d]))
915 #print 'Pop: %s' % (stack[-1])
916 del stackx[stack[-1]]
917 e = self.type[stack.pop()]['ethname']
920 #print 'Add: %s' % (e)
921 self.eth_type_ord1.append(e)
924 while i < len(self.eth_dep_cycle):
925 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
926 self.dep_cycle_eth_type.setdefault(t, []).append(i)
929 #--- value dependencies and export -------------------
930 for v in self.eth_value_ord:
931 if self.eth_value[v]['export']:
932 self.eth_vexport_ord.append(v)
934 self.eth_value_ord1.append(v)
936 #--- eth_vals_nm ------------------------------------------------------------
937 def eth_vals_nm(self, tname):
939 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
940 out += "%s_" % (self.eproto)
941 out += "%s_vals" % (tname)
944 #--- eth_vals ---------------------------------------------------------------
945 def eth_vals(self, tname, vals):
947 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
948 if (not self.eth_type[tname]['export'] & EF_VALS):
950 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
952 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
953 for (val, id) in vals:
955 vval = self.eth_enum_item(tname, id)
958 out += ' { %3s, "%s" },\n' % (vval, id)
959 out += " { 0, NULL }\n};\n"
962 #--- eth_enum_prefix ------------------------------------------------------------
963 def eth_enum_prefix(self, tname):
965 if (self.eth_type[tname]['export'] & EF_ENUM):
966 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
968 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
971 if (not self.eth_type[tname]['enum'] & EF_NO_TYPE):
974 if (self.eth_type[tname]['enum'] & EF_UCASE):
978 #--- eth_enum_nm ------------------------------------------------------------
979 def eth_enum_nm(self, tname):
980 out = self.eth_enum_prefix(tname)
984 #--- eth_enum_item ---------------------------------------------------------------
985 def eth_enum_item(self, tname, ident):
986 out = self.eth_enum_prefix(tname)
987 out += '_' + asn2c(ident)
988 if (self.eth_type[tname]['enum'] & EF_UCASE):
992 #--- eth_enum ---------------------------------------------------------------
993 def eth_enum(self, tname, vals):
995 if (self.eth_type[tname]['enum'] & EF_DEFINE):
996 out += "/* enumerated values for %s */\n" % (tname)
997 for (val, id) in vals:
998 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1000 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1001 for (val, id) in vals:
1002 out += ' %-12s %3s,\n' % (self.eth_enum_item(tname, id), val)
1003 out += "} %s;\n" % (self.eth_enum_nm(tname))
1006 #--- eth_bits ---------------------------------------------------------------
1007 def eth_bits(self, tname, bits):
1009 out += "static const "
1010 out += "asn_namedbit %(TABLE)s[] = {\n"
1011 for (val, id) in bits:
1012 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1013 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1016 #--- eth_type_fn_h ----------------------------------------------------------
1017 def eth_type_fn_h(self, tname):
1019 if (not self.eth_type[tname]['export'] & EF_TYPE):
1023 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname)
1025 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)
1029 #--- eth_fn_call ------------------------------------------------------------
1030 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1033 if (ret == 'return'):
1039 for i in range(len(par)):
1040 if (i>0): out += ind * ' '
1041 out += ', '.join(par[i])
1042 if (i<(len(par)-1)): out += ',\n'
1046 #--- eth_type_fn_hdr --------------------------------------------------------
1047 def eth_type_fn_hdr(self, tname):
1049 if (not self.eth_type[tname]['export'] & EF_TYPE):
1053 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname)
1055 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)
1056 if self.conform.get_fn_presence(tname):
1057 out += self.conform.get_fn_text(tname, 'FN_HDR')
1058 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1059 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1062 #--- eth_type_fn_ftr --------------------------------------------------------
1063 def eth_type_fn_ftr(self, tname):
1065 if self.conform.get_fn_presence(tname):
1066 out += self.conform.get_fn_text(tname, 'FN_FTR')
1067 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1068 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1069 out += " return offset;\n"
1073 #--- eth_type_fn_body -------------------------------------------------------
1074 def eth_type_fn_body(self, tname, body, pars=None):
1076 if self.conform.get_fn_body_presence(tname):
1077 out = self.conform.get_fn_text(tname, 'FN_BODY')
1078 elif self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1079 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1087 #--- eth_output_hf ----------------------------------------------------------
1088 def eth_output_hf (self):
1089 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1090 fx = self.output.file_open('hf')
1091 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1092 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1093 if (self.named_bit):
1094 fx.write('/* named bits */\n')
1095 for nb in self.named_bit:
1096 fx.write("static int %s = -1;\n" % (nb['ethname']))
1097 self.output.file_close(fx)
1099 #--- eth_output_hf_arr ------------------------------------------------------
1100 def eth_output_hf_arr (self):
1101 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1102 fx = self.output.file_open('hfarr')
1103 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1104 t = self.eth_hf[f]['ethtype']
1105 blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
1106 attr = self.eth_hf[f]['attr'].copy()
1107 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1108 if not attr.has_key('BLURB'):
1109 attr['BLURB'] = blurb
1110 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1111 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1112 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1113 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1114 for nb in self.named_bit:
1116 fx.write(' { &%s,\n' % (nb['ethname']))
1117 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1118 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1119 fx.write(' "%s", HFILL }},\n' % (blurb))
1120 self.output.file_close(fx)
1122 #--- eth_output_ett ---------------------------------------------------------
1123 def eth_output_ett (self):
1124 fx = self.output.file_open('ett')
1126 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1127 for t in self.eth_type_ord:
1128 if self.eth_type[t]['tree']:
1129 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1131 self.output.file_close(fx, discard=fempty)
1133 #--- eth_output_ett_arr -----------------------------------------------------
1134 def eth_output_ett_arr(self):
1135 fx = self.output.file_open('ettarr')
1137 #fx.write(" &ett_%s,\n" % (self.eproto))
1138 for t in self.eth_type_ord:
1139 if self.eth_type[t]['tree']:
1140 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1142 self.output.file_close(fx, discard=fempty)
1144 #--- eth_output_export ------------------------------------------------------
1145 def eth_output_export(self):
1146 if (not len(self.eth_export_ord)): return
1147 fx = self.output.file_open('exp', ext='h')
1148 for t in self.eth_export_ord: # vals
1149 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1150 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1151 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1152 if not self.eth_type[t]['export'] & EF_TABLE:
1153 if self.eth_type[t]['export'] & EF_WS_VAR:
1154 fx.write("WS_VAR_IMPORT ")
1157 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1159 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1160 for t in self.eth_export_ord: # functions
1161 if (self.eth_type[t]['export'] & EF_TYPE):
1162 if self.eth_type[t]['export'] & EF_EXTERN:
1164 fx.write(self.eth_type_fn_h(t))
1165 self.output.file_close(fx)
1167 #--- eth_output_expcnf ------------------------------------------------------
1168 def eth_output_expcnf(self):
1169 fx = self.output.file_open('exp', ext='cnf')
1170 fx.write('#.MODULE\n')
1172 for (m, p) in self.modules:
1173 if (len(m) > maxw): maxw = len(m)
1174 for (m, p) in self.modules:
1175 fx.write("%-*s %s\n" % (maxw, m, p))
1176 fx.write('#.END\n\n')
1178 fx.write('#.IMPORT_TAG\n')
1179 for t in self.eth_export_ord: # tags
1180 if (self.eth_type[t]['export'] & EF_TYPE):
1181 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1182 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1183 fx.write('#.END\n\n')
1184 fx.write('#.TYPE_ATTR\n')
1185 for t in self.eth_export_ord: # attributes
1186 if (self.eth_type[t]['export'] & EF_TYPE):
1187 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1188 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1189 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1190 fx.write('#.END\n\n')
1191 self.output.file_close(fx, keep_anyway=True)
1193 #--- eth_output_val ------------------------------------------------------
1194 def eth_output_val(self):
1195 if (not len(self.eth_value_ord1)): return
1196 fx = self.output.file_open('val', ext='h')
1197 for v in self.eth_value_ord1:
1198 fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
1199 self.output.file_close(fx)
1201 #--- eth_output_valexp ------------------------------------------------------
1202 def eth_output_valexp(self):
1203 if (not len(self.eth_vexport_ord)): return
1204 fx = self.output.file_open('valexp', ext='h')
1205 for v in self.eth_vexport_ord:
1206 fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
1207 self.output.file_close(fx)
1209 #--- eth_output_types -------------------------------------------------------
1210 def eth_output_types(self):
1212 t = self.eth_hf[f]['ethtype']
1215 for r in self.eth_hf[f]['ref']:
1216 x[self.field[r]['impl']] = self.field[r]['impl']
1230 if (i): postfix = '_impl'; impl = 'TRUE'
1231 else: postfix = ''; impl = 'FALSE'
1232 out += 'static int dissect_'+f+postfix+'(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_) {\n'
1233 par=((impl, 'tvb', 'offset', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
1235 out += 'static int dissect_'+f+'(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_) {\n'
1236 par=(('tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
1237 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret='return',
1243 t = self.eth_hf[f]['ethtype']
1244 is_new = self.eth_hf[f]['pdu']['new']
1251 out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1253 out += ' int offset = 0;\n'
1260 if (self.Aligned()):
1264 out += " asn1_ctx_t asn1_ctx;\n"
1265 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1267 par=((impl, 'tvb', off_par, 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
1269 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1272 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1273 if (self.Per() and is_new):
1274 out += ' offset += 7; offset >>= 3;\n'
1276 out += ' return offset;\n'
1280 fx = self.output.file_open('fn')
1282 if self.eth_dep_cycle:
1283 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1285 while i < len(self.eth_dep_cycle):
1286 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1287 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1288 fx.write(''.join(map(lambda i: '/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]), self.dep_cycle_eth_type[t])))
1289 fx.write(self.eth_type_fn_h(t))
1290 if (self.Fld() or self.eth_type[t]['create_field']):
1292 for f in self.eth_hf_ord:
1293 if ((self.eth_hf[f]['ethtype'] == t) and (self.Fld() or self.eth_hf[f]['create_field'])):
1294 fx.write(out_field(f))
1298 if (self.Fld()): # fields for imported types
1299 fx.write('/*--- Fields for imported types ---*/\n\n')
1300 for f in self.eth_hf_ord:
1301 if (self.eth_type[self.eth_hf[f]['ethtype']]['import']):
1302 fx.write(out_field(f))
1304 for t in self.eth_type_ord1:
1305 if self.eth_type[t]['import']:
1307 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1308 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1309 if self.eth_type[t]['val'].eth_has_vals():
1310 if self.eth_type[t]['no_emit'] & EF_VALS:
1312 elif self.eth_type[t]['user_def'] & EF_VALS:
1313 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1314 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1317 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1318 if self.eth_type[t]['no_emit'] & EF_TYPE:
1320 elif self.eth_type[t]['user_def'] & EF_TYPE:
1321 fx.write(self.eth_type_fn_h(t))
1323 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1324 if ((self.Fld() or self.eth_type[t]['create_field']) and not self.dep_cycle_eth_type.has_key(t)):
1325 for f in self.eth_hf_ord:
1326 if ((self.eth_hf[f]['ethtype'] == t) and (self.Fld() or self.eth_hf[f]['create_field'])):
1327 fx.write(out_field(f))
1329 if (len(self.eth_hfpdu_ord)):
1330 fx.write('/*--- PDUs ---*/\n\n')
1331 for f in self.eth_hfpdu_ord:
1332 if (self.eth_hf[f]['pdu']):
1333 fx.write(out_pdu(f))
1335 fempty = pos == fx.tell()
1336 self.output.file_close(fx, discard=fempty)
1338 #--- eth_output_dis_hnd -----------------------------------------------------
1339 def eth_output_dis_hnd(self):
1340 fx = self.output.file_open('dis-hnd')
1342 for f in self.eth_hfpdu_ord:
1343 pdu = self.eth_hf[f]['pdu']
1344 if (pdu and pdu['reg'] and not pdu['hidden']):
1346 if (pdu['reg'] != '.'):
1347 dis += '.' + pdu['reg']
1348 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1351 self.output.file_close(fx, discard=fempty)
1353 #--- eth_output_dis_reg -----------------------------------------------------
1354 def eth_output_dis_reg(self):
1355 fx = self.output.file_open('dis-reg')
1357 for f in self.eth_hfpdu_ord:
1358 pdu = self.eth_hf[f]['pdu']
1359 if (pdu and pdu['reg']):
1361 if (pdu['new']): new_prefix = 'new_'
1363 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1364 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1365 if (not pdu['hidden']):
1366 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1369 self.output.file_close(fx, discard=fempty)
1371 #--- eth_output_dis_tab -----------------------------------------------------
1372 def eth_output_dis_tab(self):
1373 fx = self.output.file_open('dis-tab')
1375 for k in self.conform.get_order('REGISTER'):
1376 reg = self.conform.use_item('REGISTER', k)
1377 if not self.field.has_key(reg['pdu']): continue
1378 f = self.field[reg['pdu']]['ethname']
1379 pdu = self.eth_hf[f]['pdu']
1381 if (pdu['new']): new_prefix = 'new_'
1382 if (reg['rtype'] in ('NUM', 'STR')):
1384 if (reg['rtype'] == 'STR'): rstr = '_string'
1387 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1388 if (not pdu['hidden']):
1389 hnd = '%s_handle' % (asn2c(dis))
1391 hnd = 'find_dissector("%s")' % (dis)
1393 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1394 fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], reg['rport'], hnd))
1395 elif (reg['rtype'] in ('BER', 'PER')):
1396 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), reg['roid'], f, self.eproto, reg['roidname']))
1399 self.output.file_close(fx, discard=fempty)
1401 #--- dupl_report -----------------------------------------------------
1402 def dupl_report(self):
1404 tmplist = self.eth_type_dupl.keys()
1407 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1410 for tt in self.eth_type_dupl[t]:
1411 msg += " %-20s %s\n" % (t+str(x), tt)
1414 warnings.warn_explicit(msg, UserWarning, '', '')
1416 tmplist = self.eth_hf_dupl.keys()
1419 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
1421 for tt in self.eth_hf_dupl[f].keys():
1422 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
1423 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
1425 warnings.warn_explicit(msg, UserWarning, '', '')
1427 #--- eth_do_output ------------------------------------------------------------
1428 def eth_do_output(self):
1430 print "\n# Assignments"
1431 for a in self.assign_ord:
1433 if (self.assign[a]['virt']): v = '*'
1435 print "\n# Value assignments"
1436 print "\n".join(self.vassign_ord)
1438 print "\n# Imported Types"
1439 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1441 for t in self.type_imp:
1442 print "%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])
1443 print "\n# Imported Values"
1444 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1446 for t in self.value_imp:
1447 print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
1448 print "\n# Imported Object Classes"
1449 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1451 for t in self.objectclass_imp:
1452 print "%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])
1453 print "\n# Exported Types"
1454 print "%-31s %s" % ("Wireshark type", "Export Flag")
1456 for t in self.eth_export_ord:
1457 print "%-31s 0x%02X" % (t, self.eth_type[t]['export'])
1458 print "\n# Exported Values"
1459 print "%-40s %s" % ("Wireshark name", "Value")
1461 for v in self.eth_vexport_ord:
1462 print "%-40s %s" % (v, self.eth_value[v]['value'])
1463 print "\n# ASN.1 Types"
1464 print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
1466 for t in self.type_ord:
1467 print "%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])
1468 print "\n# Wireshark Types"
1469 print "Wireshark type References (ASN.1 types)"
1471 for t in self.eth_type_ord:
1472 print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
1473 print ', '.join(self.eth_type[t]['ref'])
1474 print "\n# ASN.1 Values"
1475 print "%-40s %-18s %s" % ("ASN.1 unique name", "Type", "Value")
1477 for v in self.value_ord:
1478 if isinstance (self.value[v]['value'], Value):
1479 print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'].to_str())
1481 print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'])
1482 print "\n# Wireshark Values"
1483 print "%-40s %s" % ("Wireshark name", "Value")
1485 for v in self.eth_value_ord:
1486 print "%-40s %s" % (v, self.eth_value[v]['value'])
1487 print "\n# ASN.1 Fields"
1488 print "ASN.1 unique name Wireshark name ASN.1 type"
1490 for f in (self.pdu_ord + self.field_ord):
1491 print "%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])
1492 print "\n# Wireshark Fields"
1493 print "Wireshark name Wireshark type References (ASN.1 fields)"
1495 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1496 print "%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])),
1497 print ', '.join(self.eth_hf[f]['ref'])
1498 #print "\n# Order after dependencies"
1499 #print '\n'.join(self.eth_type_ord1)
1500 print "\n# Cyclic dependencies"
1501 for c in self.eth_dep_cycle:
1502 print ' -> '.join(c)
1504 self.output.outnm = self.outnm_opt
1505 if (not self.output.outnm):
1506 self.output.outnm = self.proto
1507 self.eth_output_hf()
1508 self.eth_output_ett()
1509 self.eth_output_types()
1510 self.eth_output_hf_arr()
1511 self.eth_output_ett_arr()
1512 self.eth_output_export()
1514 self.eth_output_expcnf()
1515 self.eth_output_val()
1516 self.eth_output_valexp()
1517 self.eth_output_dis_hnd()
1518 self.eth_output_dis_reg()
1519 self.eth_output_dis_tab()
1521 #--- EthCnf -------------------------------------------------------------------
1529 self.suppress_line = False
1530 self.include_path = []
1531 # Value name Default value Duplicity check Usage check
1532 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1533 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1534 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1535 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1536 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1537 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1538 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
1539 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
1540 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1541 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1542 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1543 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1544 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
1545 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1546 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1547 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1548 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1549 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1552 for k in self.tblcfg.keys() :
1556 def add_item(self, table, key, fn, lineno, **kw):
1557 if self.tblcfg[table]['chk_dup'] and self.table[table].has_key(key):
1558 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
1559 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
1560 UserWarning, fn, lineno)
1562 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
1563 self.table[table][key].update(kw)
1564 self.order[table].append(key)
1566 def update_item(self, table, key, fn, lineno, **kw):
1567 if not self.table[table].has_key(key):
1568 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
1569 self.order[table].append(key)
1570 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
1572 def get_order(self, table):
1573 return self.order[table]
1575 def check_item(self, table, key):
1576 return self.table[table].has_key(key)
1578 def check_item_value(self, table, key, **kw):
1579 return self.table[table].has_key(key) and self.table[table][key].has_key(kw.get('val_nm', self.tblcfg[table]['val_nm']))
1581 def use_item(self, table, key, **kw):
1582 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
1583 if not self.table[table].has_key(key): return vdflt
1584 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
1585 #print "use_item() - set used for %s %s" % (table, key)
1586 self.table[table][key]['used'] = True
1587 return self.table[table][key].get(vname, vdflt)
1589 def add_fn_line(self, name, ctx, line, fn, lineno):
1590 if not self.fn.has_key(name):
1591 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
1592 if (self.fn[name][ctx]):
1593 self.fn[name][ctx]['text'] += line
1595 self.fn[name][ctx] = {'text' : line, 'used' : False,
1596 'fn' : fn, 'lineno' : lineno}
1597 def get_fn_presence(self, name):
1598 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
1599 #if self.fn.has_key(name): print self.fn[name]
1600 return self.fn.has_key(name)
1601 def get_fn_body_presence(self, name):
1602 return self.fn.has_key(name) and self.fn[name]['FN_BODY']
1603 def get_fn_text(self, name, ctx):
1604 if (not self.fn.has_key(name)):
1606 if (not self.fn[name][ctx]):
1608 self.fn[name][ctx]['used'] = True
1609 out = self.fn[name][ctx]['text']
1610 if (not self.suppress_line):
1611 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], self.fn[name][ctx]['fn'], out);
1614 def add_pdu(self, par, is_new, fn, lineno):
1615 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
1616 (reg, hidden) = (None, False)
1617 if (len(par) > 1): reg = par[1]
1618 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
1619 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden}
1620 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
1623 def add_register(self, pdu, par, fn, lineno):
1624 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
1625 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
1626 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
1627 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
1628 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
1629 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
1630 if ((len(par)-1) < pmin):
1631 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
1633 if ((len(par)-1) > pmax):
1634 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
1635 attr = {'pdu' : pdu, 'rtype' : rtype}
1636 if (rtype in ('NUM', 'STR')):
1637 attr['rtable'] = par[1]
1638 attr['rport'] = par[2]
1639 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
1640 elif (rtype in ('BER', 'PER')):
1641 attr['roid'] = par[1]
1642 attr['roidname'] = '""'
1643 if (len(par)>=3): attr['roidname'] = par[2]
1644 rkey = '/'.join([rtype, attr['roid']])
1645 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
1647 def check_par(self, par, pmin, pmax, fn, lineno):
1648 for i in range(len(par)):
1652 if par[i][0] == '#':
1656 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1658 if (pmax >= 0) and (len(par) > pmax):
1659 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
1664 def get_par(line, pmin, pmax, fn, lineno):
1665 par = line.split(None, pmax)
1666 par = self.check_par(par, pmin, pmax, fn, lineno)
1669 def get_par_nm(line, pmin, pmax, fn, lineno):
1671 par = line.split(None, pmax)
1674 for i in range(len(par)):
1675 if par[i][0] == '#':
1679 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1686 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
1687 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
1688 nmpar_end = re.compile(r'\s*$')
1689 result = nmpar_first.search(nmpar)
1692 k = result.group('attr')
1694 result = nmpar_next.search(nmpar, pos)
1699 p2 = nmpar_end.search(nmpar, pos).start()
1707 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_]+)\s+')
1708 comment = re.compile(r'^\s*#[^.]')
1709 empty = re.compile(r'^\s*$')
1713 default_flags = 0x00
1722 fn, f, lineno = frec['fn'], frec['f'], frec['lineno']
1726 if comment.search(line): continue
1727 result = directive.search(line)
1728 if result: # directive
1729 if result.group('name') == 'OPT':
1730 ctx = result.group('name')
1731 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
1732 if not par: continue
1733 self.set_opt(par[0], par[1:], fn, lineno)
1735 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
1736 'MODULE', 'MODULE_IMPORT',
1737 'OMIT_ASSIGNMENT', 'VIRTUAL_ASSGN', 'SET_TYPE',
1738 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
1739 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
1740 ctx = result.group('name')
1741 elif result.group('name') in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
1742 ctx = result.group('name')
1743 default_flags = EF_TYPE|EF_VALS
1744 if ctx == 'EXPORTS':
1745 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
1747 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
1748 if not par: continue
1750 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
1751 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
1752 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
1753 elif (ctx == 'EXPORTS'): p = 0
1754 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
1755 for i in range(p, len(par)):
1756 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
1757 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
1758 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
1759 elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
1760 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
1761 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
1762 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1763 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
1764 ctx = result.group('name')
1765 default_flags = EF_ENUM
1766 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT
1767 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE
1768 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
1769 for i in range(0, len(par)):
1770 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
1771 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
1772 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
1773 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
1774 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1775 elif result.group('name') in ('FN_HDR', 'FN_FTR'):
1776 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1777 if not par: continue
1778 ctx = result.group('name')
1780 elif result.group('name') == 'FN_BODY':
1781 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1782 if not par: continue
1783 ctx = result.group('name')
1786 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
1787 elif result.group('name') == 'FN_PARS':
1788 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
1789 ctx = result.group('name')
1794 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
1796 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
1798 elif result.group('name') == 'CLASS':
1799 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1800 if not par: continue
1801 ctx = result.group('name')
1803 add_class_ident(name)
1804 if not name.isupper():
1805 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
1806 UserWarning, fn, lineno)
1807 elif result.group('name') == 'INCLUDE':
1808 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1810 warnings.warn_explicit("INCLUDE requires parameter", UserWarning, fn, lineno)
1813 #print "Try include: %s" % (fname)
1814 if (not os.path.exists(fname)):
1815 fname = os.path.join(os.path.split(fn)[0], par[0])
1816 #print "Try include: %s" % (fname)
1818 while not os.path.exists(fname) and (i < len(self.include_path)):
1819 fname = os.path.join(self.include_path[i], par[0])
1820 #print "Try include: %s" % (fname)
1822 if (not os.path.exists(fname)):
1824 fnew = open(fname, "r")
1825 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno})
1826 fn, f, lineno = par[0], fnew, 0
1827 elif result.group('name') == 'END':
1830 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
1833 if not empty.match(line):
1834 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
1836 if empty.match(line): continue
1837 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
1838 if not par: continue
1839 self.set_opt(par[0], par[1:], fn, lineno)
1840 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
1841 if empty.match(line): continue
1842 if ctx == 'EXPORTS':
1843 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
1845 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
1846 if not par: continue
1847 flags = default_flags
1850 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
1851 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
1852 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
1853 elif (ctx == 'EXPORTS'): p = 1
1854 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
1855 for i in range(p, len(par)):
1856 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
1857 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
1858 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
1859 elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
1860 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
1861 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
1862 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1863 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
1864 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
1865 if empty.match(line): continue
1866 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
1867 if not par: continue
1868 flags = default_flags
1869 for i in range(1, len(par)):
1870 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
1871 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
1872 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
1873 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
1874 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1875 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
1876 elif ctx in ('PDU', 'PDU_NEW'):
1877 if empty.match(line): continue
1878 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
1879 if not par: continue
1881 if (ctx == 'PDU_NEW'): is_new = True
1882 self.add_pdu(par[0:2], is_new, fn, lineno)
1884 self.add_register(par[0], par[2:5], fn, lineno)
1885 elif ctx in ('REGISTER', 'REGISTER_NEW'):
1886 if empty.match(line): continue
1887 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
1888 if not par: continue
1889 if not self.check_item('PDU', par[0]):
1891 if (ctx == 'REGISTER_NEW'): is_new = True
1892 self.add_pdu(par[0:1], is_new, fn, lineno)
1893 self.add_register(par[0], par[1:4], fn, lineno)
1894 elif ctx in ('MODULE', 'MODULE_IMPORT'):
1895 if empty.match(line): continue
1896 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1897 if not par: continue
1898 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
1899 elif ctx == 'IMPORT_TAG':
1900 if empty.match(line): continue
1901 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
1902 if not par: continue
1903 self.add_item('IMPORT_TAG', par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
1904 elif ctx == 'OMIT_ASSIGNMENT':
1905 if empty.match(line): continue
1906 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
1907 if not par: continue
1908 self.add_item('OMIT_ASSIGNMENT', par[0], omit=True, fn=fn, lineno=lineno)
1909 elif ctx == 'VIRTUAL_ASSGN':
1910 if empty.match(line): continue
1911 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
1912 if not par: continue
1913 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
1914 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
1915 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
1917 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
1918 if not par[0][0].isupper():
1919 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
1920 UserWarning, fn, lineno)
1921 elif ctx == 'SET_TYPE':
1922 if empty.match(line): continue
1923 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1924 if not par: continue
1925 if not self.check_item('VIRTUAL_ASSGN', par[0]):
1926 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
1927 if not par[1][0].isupper():
1928 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
1929 UserWarning, fn, lineno)
1930 elif ctx == 'TYPE_RENAME':
1931 if empty.match(line): continue
1932 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1933 if not par: continue
1934 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
1935 if not par[1][0].isupper():
1936 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
1937 UserWarning, fn, lineno)
1938 elif ctx == 'FIELD_RENAME':
1939 if empty.match(line): continue
1940 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1941 if not par: continue
1942 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
1943 if not par[1][0].islower():
1944 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
1945 UserWarning, fn, lineno)
1946 elif ctx == 'TF_RENAME':
1947 if empty.match(line): continue
1948 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1949 if not par: continue
1950 tmpu = par[1][0].upper() + par[1][1:]
1951 tmpl = par[1][0].lower() + par[1][1:]
1952 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
1953 if not tmpu[0].isupper():
1954 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
1955 UserWarning, fn, lineno)
1956 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
1957 if not tmpl[0].islower():
1958 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
1959 UserWarning, fn, lineno)
1960 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
1961 if empty.match(line): continue
1962 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
1963 if not par: continue
1964 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
1965 elif ctx == 'FN_PARS':
1966 if empty.match(line): continue
1968 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
1970 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
1971 if not par: continue
1973 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
1975 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
1976 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
1977 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
1978 elif ctx == 'CLASS':
1979 if empty.match(line): continue
1980 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
1981 if not par: continue
1982 if (len(par) < 2): par.append('OpenType')
1983 if (len(par) < 3): par.append(None)
1984 if not set_type_to_class(name, par[0], par[1], par[2]):
1985 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
1986 UserWarning, fn, lineno)
1988 def set_opt(self, opt, par, fn, lineno):
1989 #print "set_opt: %s, %s" % (opt, par)
1991 par = self.check_par(par, 1, 1, fn, lineno)
1993 self.include_path.append(par[0])
1994 elif opt in ("-b", "BER", "CER", "DER"):
1995 par = self.check_par(par, 0, 0, fn, lineno)
1996 self.ectx.encoding = 'ber'
1997 elif opt in ("PER",):
1998 par = self.check_par(par, 0, 0, fn, lineno)
1999 self.ectx.encoding = 'per'
2000 elif opt in ("-p", "PROTO"):
2001 par = self.check_par(par, 1, 1, fn, lineno)
2003 self.ectx.proto_opt = par[0]
2004 self.ectx.merge_modules = True
2005 elif opt in ("-F", "CREATE_FIELDS"):
2006 par = self.check_par(par, 0, 1, fn, lineno)
2008 if (len(par) > 0): tnm = par[0]
2009 self.ectx.fld_opt[tnm] = True
2010 elif opt in ("-T",):
2011 par = self.check_par(par, 0, 0, fn, lineno)
2012 self.ectx.tag_opt = True
2013 elif opt in ("ALIGNED",):
2014 par = self.check_par(par, 0, 0, fn, lineno)
2015 self.ectx.aligned = True
2016 elif opt in ("-u", "UNALIGNED"):
2017 par = self.check_par(par, 0, 0, fn, lineno)
2018 self.ectx.aligned = False
2019 elif opt in ("-d",):
2020 par = self.check_par(par, 1, 1, fn, lineno)
2022 self.ectx.dbgopt = par[0]
2023 elif opt in ("-e",):
2024 par = self.check_par(par, 0, 0, fn, lineno)
2025 self.ectx.expcnf = True
2026 elif opt in ("-S",):
2027 par = self.check_par(par, 0, 0, fn, lineno)
2028 self.ectx.merge_modules = True
2029 elif opt in ("-o",):
2030 par = self.check_par(par, 1, 1, fn, lineno)
2032 self.ectx.outnm_opt = par[0]
2033 elif opt in ("-O",):
2034 par = self.check_par(par, 1, 1, fn, lineno)
2036 self.ectx.output.outdir = par[0]
2037 elif opt in ("-s",):
2038 par = self.check_par(par, 1, 1, fn, lineno)
2040 self.ectx.output.single_file = par[0]
2041 elif opt in ("-k",):
2042 par = self.check_par(par, 0, 0, fn, lineno)
2043 self.ectx.output.keep = True
2044 elif opt in ("-L",):
2045 par = self.check_par(par, 0, 0, fn, lineno)
2046 self.suppress_line = True
2048 warnings.warn_explicit("Unknown option %s" % (opt),
2049 UserWarning, fn, lineno)
2051 def dbg_print(self):
2052 print "\n# Conformance values"
2053 print "%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")
2055 tbls = self.table.keys()
2058 keys = self.table[t].keys()
2061 print "%-15s %4s %-15s %-20s %s" % (
2062 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))
2064 def unused_report(self):
2065 tbls = self.table.keys()
2068 if not self.tblcfg[t]['chk_use']: continue
2069 keys = self.table[t].keys()
2072 if not self.table[t][k]['used']:
2073 warnings.warn_explicit("Unused %s for %s" % (t, k),
2074 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2075 fnms = self.fn.keys()
2078 keys = self.fn[f].keys()
2081 if not self.fn[f][k]: continue
2082 if not self.fn[f][k]['used']:
2083 warnings.warn_explicit("Unused %s for %s" % (k, f),
2084 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2086 #--- EthOut -------------------------------------------------------------------
2092 self.single_file = None
2093 self.created_files = []
2094 self.unique_created_files = []
2096 #--- output_fname -------------------------------------------------------
2097 def output_fname(self, ftype, ext='c'):
2099 if not ext in ('cnf',):
2106 #--- output_fullname -------------------------------------------------------
2107 def output_fullname(self, ftype, ext='c'):
2108 return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
2109 #--- file_open -------------------------------------------------------
2110 def file_open(self, ftype, ext='c'):
2111 fn = self.output_fullname(ftype, ext=ext)
2114 fx.write(self.fhdr(fn, comment = '#'))
2116 if (not self.single_file):
2117 fx.write(self.fhdr(fn))
2119 #--- file_close -------------------------------------------------------
2120 def file_close(self, fx, discard=False, keep_anyway=False):
2124 elif (not keep_anyway):
2125 self.created_files.append(os.path.normcase(os.path.abspath(fx.name)))
2126 #--- fhdr -------------------------------------------------------
2127 def fhdr(self, fn, comment=None):
2130 return '# %s\n' % (ln)
2132 return '/* %-74s */\n' % (ln)
2134 out += outln('Do not modify this file.')
2135 out += outln('It is created automatically by the ASN.1 to Wireshark dissector compiler')
2137 out += outln(' '.join(sys.argv))
2141 #--- dbg_print -------------------------------------------------------
2142 def dbg_print(self):
2143 print "\n# Output files"
2144 print "\n".join(self.created_files)
2147 #--- make_single_file -------------------------------------------------------
2148 def make_single_file(self):
2149 if (not self.single_file): return
2150 in_nm = self.single_file + '.c'
2151 out_nm = self.output_fullname('')
2152 self.do_include(out_nm, in_nm)
2153 in_nm = self.single_file + '.h'
2154 if (os.path.exists(in_nm)):
2155 out_nm = self.output_fullname('', ext='h')
2156 self.do_include(out_nm, in_nm)
2158 self.unique_created_files = []
2159 [self.unique_created_files.append(wrd) for wrd in self.created_files if not self.unique_created_files.count(wrd)]
2160 for fn in self.unique_created_files:
2163 #--- do_include -------------------------------------------------------
2164 def do_include(self, out_nm, in_nm):
2165 def check_file(fn, fnlist):
2166 fnfull = os.path.normcase(os.path.abspath(fn))
2167 if ((fnfull in fnlist) and os.path.exists(fnfull)):
2168 return os.path.normpath(fn)
2170 fin = file(in_nm, "r")
2171 fout = file(out_nm, "w")
2172 fout.write(self.fhdr(out_nm))
2173 fout.write('/* Input file: ' + in_nm +' */\n')
2175 fout.write('#line 1 "%s"\n' % (in_nm))
2177 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2182 cont_linenum = cont_linenum + 1;
2183 line = fin.readline()
2184 if (line == ''): break
2186 result = include.search(line)
2187 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2189 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2191 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2193 ifile = check_file(result.group('fname'), self.created_files)
2196 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
2197 fout.write('#line 1 "' + ifile + '"\n')
2198 finc = file(ifile, "r")
2199 fout.write(finc.read())
2201 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
2202 fout.write('#line %i "%s"\n' % (cont_linenum+1,in_nm) )
2211 #--- Node ---------------------------------------------------------------------
2213 def __init__(self,*args, **kw):
2215 self.type = self.__class__.__name__
2217 assert (len(args) == 1)
2219 self.__dict__.update (kw)
2220 def str_child (self, key, child, depth):
2221 indent = " " * (2 * depth)
2222 keystr = indent + key + ": "
2223 if key == 'type': # already processed in str_depth
2225 if isinstance (child, Node): # ugh
2226 return keystr + "\n" + child.str_depth (depth+1)
2227 if type (child) == type ([]):
2230 if isinstance (x, Node):
2231 l.append (x.str_depth (depth+1))
2233 l.append (indent + " " + str(x) + "\n")
2234 return keystr + "[\n" + ''.join(l) + indent + "]\n"
2236 return keystr + str (child) + "\n"
2237 def str_depth (self, depth): # ugh
2238 indent = " " * (2 * depth)
2239 l = ["%s%s" % (indent, self.type)]
2240 l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
2241 self.__dict__.items ())))
2242 return "\n".join (l)
2244 return "\n" + self.str_depth (0)
2245 def to_python (self, ctx):
2246 return self.str_depth (ctx.indent_lev)
2248 def eth_reg(self, ident, ectx):
2251 #--- value_assign -------------------------------------------------------------
2252 class value_assign (Node):
2253 def __init__(self,*args, **kw) :
2254 Node.__init__ (self,*args, **kw)
2256 def eth_reg(self, ident, ectx):
2257 if ectx.conform.use_item('OMIT_ASSIGNMENT', self.ident): return # Assignment to omit
2258 ectx.eth_reg_vassign(self)
2259 ectx.eth_reg_value(self.ident, self.typ, self.val)
2262 #--- Type ---------------------------------------------------------------------
2264 def __init__(self,*args, **kw) :
2268 Node.__init__ (self,*args, **kw)
2271 if self.name is None :
2276 def HasConstraint(self):
2277 if self.constr is None :
2282 def HasOwnTag(self):
2283 return len(self.tags) > 0
2285 def HasImplicitTag(self, ectx):
2286 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
2288 def IndetermTag(self, ectx):
2291 def AddTag(self, tag):
2292 self.tags[0:0] = [tag]
2294 def GetTag(self, ectx):
2295 #print "GetTag(%s)\n" % self.name;
2296 if (self.HasOwnTag()):
2297 return self.tags[0].GetTag(ectx)
2299 return self.GetTTag(ectx)
2301 def GetTTag(self, ectx):
2302 print "#Unhandled GetTTag() in %s" % (self.type)
2303 print self.str_depth(1)
2304 return ('BER_CLASS_unknown', 'TAG_unknown')
2306 def SetName(self, name):
2309 def AddConstraint(self, constr):
2310 if not self.HasConstraint():
2311 self.constr = constr
2313 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
2315 def eth_tname(self):
2316 return '#' + self.type + '_' + str(id(self))
2318 def eth_ftype(self, ectx):
2319 return ('FT_NONE', 'BASE_NONE')
2321 def eth_strings(self):
2324 def eth_need_tree(self):
2327 def eth_has_vals(self):
2330 def eth_has_enum(self, tname, ectx):
2331 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
2333 def eth_named_bits(self):
2336 def eth_reg_sub(self, ident, ectx):
2339 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, idx='', parent=None):
2340 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(parent))
2341 if (ectx.Tag() and (len(self.tags) > tstrip)):
2342 tagged_type = TaggedType(val=self, tstrip=tstrip)
2343 tagged_type.AddTag(self.tags[tstrip])
2344 if not tagflag: # 1st tagged level
2346 tagged_type.SetName(self.name)
2347 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
2350 if ident and self.IsNamed() and not tagflag:
2351 nm = ident + '/' + self.name
2354 elif self.IsNamed():
2356 if not ident and ectx.conform.use_item('OMIT_ASSIGNMENT', nm): return # Assignment to omit
2357 if not ident: # Assignment
2358 ectx.eth_reg_assign(nm, self)
2359 if self.type == 'Type_Ref':
2360 ectx.eth_reg_type(nm, self)
2361 if (ectx.conform.check_item('PDU', nm)):
2362 ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
2363 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
2364 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
2365 if ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm):
2366 if ectx.conform.check_item('SET_TYPE', nm):
2367 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
2369 ectx.eth_reg_type(nm, self) # new type
2371 elif ectx.conform.check_item('SET_TYPE', nm):
2372 trnm = ectx.conform.use_item('SET_TYPE', nm)
2376 ectx.eth_reg_type(nm, self)
2378 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
2379 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
2380 ectx.eth_reg_assign(vnm, self, virt=True)
2381 ectx.eth_reg_type(vnm, self)
2382 self.eth_reg_sub(vnm, ectx)
2383 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
2384 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
2385 if ident and not tagflag:
2386 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
2387 if ectx.conform.check_item('SET_TYPE', nm):
2388 virtual_tr.eth_reg_sub(nm, ectx)
2390 self.eth_reg_sub(nm, ectx)
2392 def eth_get_size_constr(self):
2393 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2394 if not self.HasConstraint():
2395 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2396 elif self.constr.IsSize():
2397 (minv, maxv, ext) = self.constr.GetSize()
2398 elif (self.constr.type == 'Intersection'):
2399 if self.constr.subtype[0].IsSize():
2400 (minv, maxv, ext) = self.constr.subtype[0].GetSize()
2401 elif self.constr.subtype[1].IsSize():
2402 (minv, maxv, ext) = self.constr.subtype[1].GetSize()
2403 return (minv, maxv, ext)
2405 def eth_get_value_constr(self):
2406 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2407 if not self.HasConstraint():
2408 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2409 elif self.constr.IsValue():
2410 (minv, maxv, ext) = self.constr.GetValue()
2411 return (minv, maxv, ext)
2413 def eth_type_vals(self, tname, ectx):
2414 if self.eth_has_vals():
2415 print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
2416 print self.str_depth(1)
2419 def eth_type_enum(self, tname, ectx):
2420 if self.eth_has_enum(tname, ectx):
2421 print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
2422 print self.str_depth(1)
2425 def eth_type_default_table(self, ectx, tname):
2428 def eth_type_default_body(self, ectx):
2429 print "#Unhandled eth_type_default_body() in %s" % (self.type)
2430 print self.str_depth(1)
2433 def eth_type_default_pars(self, ectx, tname):
2440 'OFFSET' : 'offset',
2442 'HF_INDEX' : 'hf_index',
2444 'IMPLICIT_TAG' : 'implicit_tag',
2446 if (ectx.eth_type[tname]['tree']):
2447 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
2448 if (not ectx.Per()):
2449 pars['PINFO'] = 'pinfo'
2452 def eth_type_fn(self, proto, tname, ectx):
2453 body = self.eth_type_default_body(ectx, tname)
2454 pars = self.eth_type_default_pars(ectx, tname)
2455 if ectx.conform.check_item('FN_PARS', tname):
2456 pars.update(ectx.conform.use_item('FN_PARS', tname))
2457 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
2458 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
2459 pars['DEFAULT_BODY'] = body
2461 for k in pars.keys(): pars[k] = pars[k] % pars
2463 out += self.eth_type_default_table(ectx, tname) % pars
2464 out += ectx.eth_type_fn_hdr(tname)
2465 out += ectx.eth_type_fn_body(tname, body, pars=pars)
2466 out += ectx.eth_type_fn_ftr(tname)
2469 #--- Value --------------------------------------------------------------------
2471 def __init__(self,*args, **kw) :
2473 Node.__init__ (self,*args, **kw)
2475 def SetName(self, name) :
2484 #--- ObjectClass ---------------------------------------------------------------------
2485 class ObjectClass (Node):
2486 def __init__(self,*args, **kw) :
2488 Node.__init__ (self,*args, **kw)
2490 def SetName(self, name):
2492 add_class_ident(self.name)
2494 #--- Tag ---------------------------------------------------------------
2496 def to_python (self, ctx):
2497 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
2500 self.typ.to_python (ctx))
2501 def IsImplicit(self, ectx):
2502 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
2504 def GetTag(self, ectx):
2506 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
2507 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
2508 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
2509 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
2510 return (tc, self.num)
2512 def eth_tname(self):
2514 if (self.cls == 'UNIVERSAL'): n = 'U'
2515 elif (self.cls == 'APPLICATION'): n = 'A'
2516 elif (self.cls == 'CONTEXT'): n = 'C'
2517 elif (self.cls == 'PRIVATE'): n = 'P'
2518 return n + str(self.num)
2520 #--- Constraint ---------------------------------------------------------------
2521 class Constraint (Node):
2522 def to_python (self, ctx):
2523 print "Ignoring constraint:", self.type
2524 return self.subtype.typ.to_python (ctx)
2526 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
2529 return self.type == 'Size' and (self.subtype.type == 'SingleValue' or self.subtype.type == 'ValueRange')
2536 if self.subtype.type == 'SingleValue':
2537 minv = self.subtype.subtype
2538 maxv = self.subtype.subtype
2540 minv = self.subtype.subtype[0]
2541 maxv = self.subtype.subtype[1]
2542 if hasattr(self.subtype, 'ext') and self.subtype.ext:
2546 return (minv, maxv, ext)
2549 return self.type == 'SingleValue' or self.type == 'ValueRange'
2556 if self.type == 'SingleValue':
2560 if self.subtype[0] == 'MIN':
2563 minv = self.subtype[0]
2564 if self.subtype[1] == 'MAX':
2567 maxv = self.subtype[1]
2568 if str(minv).isdigit(): minv += 'U'
2569 if str(maxv).isdigit(): maxv += 'U'
2570 if hasattr(self, 'ext') and self.ext:
2574 return (minv, maxv, ext)
2576 def IsNegativ(self):
2578 return sval[0] == '-'
2579 if self.type == 'SingleValue':
2580 return is_neg(self.subtype)
2581 elif self.type == 'ValueRange':
2582 if self.subtype[0] == 'MIN': return True
2583 return is_neg(self.subtype[0])
2586 def IsPermAlph(self):
2587 return self.type == 'From' and self.subtype.type == 'SingleValue'
2589 def eth_constrname(self):
2593 return 'M' + str(-int(val))
2596 except (ValueError, TypeError):
2600 if hasattr(self, 'ext') and self.ext:
2602 if self.type == 'SingleValue':
2603 return int2str(self.subtype) + ext
2604 elif self.type == 'ValueRange':
2605 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
2606 elif self.type == 'Size':
2607 return 'SIZE_' + self.subtype.eth_constrname() + ext
2609 return 'CONSTR' + str(id(self)) + ext
2612 class Module (Node):
2613 def to_python (self, ctx):
2614 ctx.tag_def = self.tag_def.dfl_tag
2616 %s""" % (self.ident, self.body.to_python (ctx))
2618 def to_eth (self, ectx):
2619 ectx.tags_def = 'EXPLICIT' # default = explicit
2620 if (not ectx.proto):
2621 ectx.proto = ectx.conform.use_item('MODULE', self.ident.val, val_dflt=self.ident.val)
2622 ectx.tag_def = self.tag_def.dfl_tag
2623 ectx.modules.append((self.ident.val, ectx.proto))
2624 self.body.to_eth(ectx)
2626 class Module_Body (Node):
2627 def to_python (self, ctx):
2628 # XXX handle exports, imports.
2629 l = map (lambda x: x.to_python (ctx), self.assign_list)
2630 l = [a for a in l if a <> '']
2631 return "\n".join (l)
2633 def to_eth(self, ectx):
2634 for i in self.imports:
2636 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
2637 for s in i.symbol_list:
2638 if isinstance(s, Type_Ref):
2639 ectx.eth_import_type(s.val, mod, proto)
2640 elif isinstance(s, Class_Ref):
2641 ectx.eth_import_class(s.val, mod, proto)
2643 ectx.eth_import_value(s, mod, proto)
2644 for a in self.assign_list:
2647 class Default_Tags (Node):
2648 def to_python (self, ctx): # not to be used directly
2651 # XXX should just calculate dependencies as we go along.
2652 def calc_dependencies (node, dict, trace = 0):
2653 if not hasattr (node, '__dict__'):
2654 if trace: print "#returning, node=", node
2656 if isinstance (node, Type_Ref):
2658 if trace: print "#Setting", node.val
2660 for (a, val) in node.__dict__.items ():
2661 if trace: print "# Testing node ", node, "attr", a, " val", val
2664 elif isinstance (val, Node):
2665 calc_dependencies (val, dict, trace)
2666 elif isinstance (val, type ([])):
2668 calc_dependencies (v, dict, trace)
2671 class Type_Assign (Node):
2672 def __init__ (self, *args, **kw):
2673 Node.__init__ (self, *args, **kw)
2674 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
2675 to_test = self.val.typ
2678 if isinstance (to_test, SequenceType):
2679 to_test.sequence_name = self.name.name
2681 def to_python (self, ctx):
2683 calc_dependencies (self.val, dep_dict, 0)
2684 depend_list = dep_dict.keys ()
2685 return ctx.register_assignment (self.name.name,
2686 self.val.to_python (ctx),
2689 class PyQuote (Node):
2690 def to_python (self, ctx):
2691 return ctx.register_pyquote (self.val)
2693 #--- Class_Ref -----------------------------------------------------------------
2694 class Class_Ref (Type):
2695 def to_python (self, ctx):
2698 def eth_tname(self):
2699 return asn2c(self.val)
2701 #--- Type_Ref -----------------------------------------------------------------
2702 class Type_Ref (Type):
2703 def to_python (self, ctx):
2706 def eth_reg_sub(self, ident, ectx):
2707 ectx.eth_dep_add(ident, self.val)
2709 def eth_tname(self):
2710 return asn2c(self.val)
2712 def GetTTag(self, ectx):
2713 #print "GetTTag(%s)\n" % self.val;
2714 if (ectx.type[self.val]['import']):
2715 if not ectx.type[self.val].has_key('ttag'):
2716 if not ectx.conform.check_item('IMPORT_TAG', self.val):
2717 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
2718 warnings.warn_explicit(msg, UserWarning, '', '')
2719 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
2720 return ectx.type[self.val]['ttag']
2722 return ectx.type[self.val]['val'].GetTag(ectx)
2724 def IndetermTag(self, ectx):
2725 if (ectx.type[self.val]['import']):
2728 return ectx.type[self.val]['val'].IndetermTag(ectx)
2730 def eth_type_default_pars(self, ectx, tname):
2731 pars = Type.eth_type_default_pars(self, ectx, tname)
2732 t = ectx.type[self.val]['ethname']
2733 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
2734 pars['TYPE_REF_TNAME'] = t
2735 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
2738 def eth_type_default_body(self, ectx, tname):
2740 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
2741 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
2743 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
2744 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
2746 body = '#error Can not decode %s' % (tname)
2749 #--- TaggedType -----------------------------------------------------------------
2750 class TaggedType (Type):
2751 def eth_tname(self):
2753 for i in range(self.tstrip, len(self.val.tags)):
2754 tn += self.val.tags[i].eth_tname()
2756 tn += self.val.eth_tname()
2759 def eth_set_val_name(self, ident, val_name, ectx):
2760 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
2761 self.val_name = val_name
2762 ectx.eth_dep_add(ident, self.val_name)
2764 def eth_reg_sub(self, ident, ectx):
2765 self.val_name = ident + '/' + '_untag'
2766 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
2768 def eth_ftype(self, ectx):
2769 return self.val.eth_ftype(ectx)
2771 def eth_type_default_pars(self, ectx, tname):
2772 pars = Type.eth_type_default_pars(self, ectx, tname)
2773 t = ectx.type[self.val_name]['ethname']
2774 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
2775 pars['TYPE_REF_TNAME'] = t
2776 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
2777 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
2778 if self.HasImplicitTag(ectx):
2779 pars['TAG_IMPL'] = 'TRUE'
2781 pars['TAG_IMPL'] = 'FALSE'
2784 def eth_type_default_body(self, ectx, tname):
2786 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
2787 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2788 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
2790 body = '#error Can not decode %s' % (tname)
2793 #--- SqType -----------------------------------------------------------
2794 class SqType (Type):
2795 def out_item(self, f, val, optional, ext, ectx):
2796 ef = ectx.field[f]['ethname']
2797 t = ectx.eth_hf[ef]['ethtype']
2799 if (ectx.Ber() and ectx.field[f]['impl']):
2802 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
2803 #print val.str_depth(1)
2806 opt = 'BER_FLAGS_OPTIONAL'
2807 if (not val.HasOwnTag()):
2808 if (opt): opt += '|'
2809 opt += 'BER_FLAGS_NOOWNTAG'
2810 elif (val.HasImplicitTag(ectx)):
2811 if (opt): opt += '|'
2812 opt += 'BER_FLAGS_IMPLTAG'
2813 if (val.IndetermTag(ectx)):
2814 if (opt): opt += '|'
2815 opt += 'BER_FLAGS_NOTCHKTAG'
2816 if (not opt): opt = '0'
2819 opt = 'ASN1_OPTIONAL'
2821 opt = 'ASN1_NOT_OPTIONAL'
2823 (tc, tn) = val.GetTag(ectx)
2824 out = ' { %-13s, %s, %s, dissect_%s },\n' \
2825 % (tc, tn, opt, efd)
2827 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
2828 % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
2833 #--- SeqType -----------------------------------------------------------
2834 class SeqType (SqType):
2835 def eth_type_default_table(self, ectx, tname):
2836 #print "eth_type_default_table(tname='%s')" % (tname)
2837 fname = ectx.eth_type[tname]['ref'][0]
2838 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
2839 if hasattr(self, 'ext_list'):
2840 ext = 'ASN1_EXTENSION_ROOT'
2842 ext = 'ASN1_NO_EXTENSIONS'
2843 for e in (self.elt_list):
2844 f = fname + '/' + e.val.name
2845 table += self.out_item(f, e.val, e.optional, ext, ectx)
2846 if hasattr(self, 'ext_list'):
2847 for e in (self.ext_list):
2848 f = fname + '/' + e.val.name
2849 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
2851 table += " { 0, 0, 0, NULL }\n};\n"
2853 table += " { NULL, 0, 0, NULL }\n};\n"
2856 #--- SeqOfType -----------------------------------------------------------
2857 class SeqOfType (SqType):
2858 def eth_type_default_table(self, ectx, tname):
2859 #print "eth_type_default_table(tname='%s')" % (tname)
2860 fname = ectx.eth_type[tname]['ref'][0]
2861 if self.val.IsNamed ():
2862 f = fname + '/' + self.val.name
2864 f = fname + '/' + '_item'
2865 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
2866 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
2870 #--- SequenceOfType -----------------------------------------------------------
2871 class SequenceOfType (SeqOfType):
2872 def to_python (self, ctx):
2873 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2874 # or '' + (1,) for optional
2876 if self.size_constr <> None:
2877 print "#Ignoring size constraint:", self.size_constr.subtype
2878 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
2879 self.val.to_python (ctx),
2882 def eth_reg_sub(self, ident, ectx):
2884 if not self.val.IsNamed ():
2885 itmnm += '/' + '_item'
2886 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
2888 def eth_tname(self):
2889 if self.val.type != 'Type_Ref':
2890 return '#' + self.type + '_' + str(id(self))
2891 if not self.HasConstraint():
2892 return "SEQUENCE_OF_" + self.val.eth_tname()
2893 elif self.constr.IsSize():
2894 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
2896 return '#' + self.type + '_' + str(id(self))
2898 def eth_ftype(self, ectx):
2899 return ('FT_UINT32', 'BASE_DEC')
2901 def eth_need_tree(self):
2904 def GetTTag(self, ectx):
2905 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
2907 def eth_type_default_pars(self, ectx, tname):
2908 pars = Type.eth_type_default_pars(self, ectx, tname)
2909 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
2910 pars['TABLE'] = '%(TNAME)s_sequence_of'
2913 def eth_type_default_body(self, ectx, tname):
2915 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
2916 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2917 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2918 elif (ectx.Per() and not self.HasConstraint()):
2919 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
2920 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2921 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2922 elif (ectx.Per() and self.constr.type == 'Size'):
2923 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
2924 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2925 ('%(ETT_INDEX)s', '%(TABLE)s',),
2926 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
2928 body = '#error Can not decode %s' % (tname)
2932 #--- SetOfType ----------------------------------------------------------------
2933 class SetOfType (SeqOfType):
2934 def eth_reg_sub(self, ident, ectx):
2936 if not self.val.IsNamed ():
2937 itmnm += '/' + '_item'
2938 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
2940 def eth_tname(self):
2941 if self.val.type != 'Type_Ref':
2942 return '#' + self.type + '_' + str(id(self))
2943 if not self.HasConstraint():
2944 return "SET_OF_" + self.val.eth_tname()
2945 elif self.constr.IsSize():
2946 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
2948 return '#' + self.type + '_' + str(id(self))
2950 def eth_ftype(self, ectx):
2951 return ('FT_UINT32', 'BASE_DEC')
2953 def eth_need_tree(self):
2956 def GetTTag(self, ectx):
2957 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
2959 def eth_type_default_pars(self, ectx, tname):
2960 pars = Type.eth_type_default_pars(self, ectx, tname)
2961 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
2962 pars['TABLE'] = '%(TNAME)s_set_of'
2965 def eth_type_default_body(self, ectx, tname):
2967 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
2968 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2969 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2970 elif (ectx.Per() and not self.HasConstraint()):
2971 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
2972 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2973 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2974 elif (ectx.Per() and self.constr.type == 'Size'):
2975 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
2976 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2977 ('%(ETT_INDEX)s', '%(TABLE)s',),
2978 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
2980 body = '#error Can not decode %s' % (tname)
2983 def mk_tag_str (ctx, cls, typ, num):
2985 # XXX should do conversion to int earlier!
2988 if typ == 'DEFAULT':
2990 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
2992 #--- SequenceType -------------------------------------------------------------
2993 class SequenceType (SeqType):
2994 def to_python (self, ctx):
2995 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2996 # or '' + (1,) for optional
2997 # XXX should also collect names for SEQUENCE inside SEQUENCE or
2998 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
2999 # from? for others, element or arm name would be fine)
3000 seq_name = getattr (self, 'sequence_name', None)
3001 if seq_name == None:
3004 seq_name = "'" + seq_name + "'"
3005 if self.__dict__.has_key('ext_list'):
3006 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
3007 self.elts_to_py (self.elt_list, ctx),
3008 self.elts_to_py (self.ext_list, ctx), seq_name)
3010 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
3011 self.elts_to_py (self.elt_list, ctx), seq_name)
3012 def elts_to_py (self, list, ctx):
3013 # we have elt_type, val= named_type, maybe default=, optional=
3014 # named_type node: either ident = or typ =
3015 # need to dismember these in order to generate Python output syntax.
3018 assert (e.type == 'elt_type')
3020 optflag = e.optional
3021 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
3022 assert (nt.type == 'named_type')
3025 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
3026 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
3027 nt.typ.tag.tag_typ,nt.typ.tag.num)
3031 return "('%s',%s,%s,%d)" % (identstr, tagstr,
3032 nt.typ.to_python (ctx), optflag)
3033 indentstr = ",\n" + ctx.spaces ()
3034 rv = indentstr.join ([elt_to_py (e) for e in list])
3038 def eth_reg_sub(self, ident, ectx):
3039 for e in (self.elt_list):
3040 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3041 if hasattr(self, 'ext_list'):
3042 for e in (self.ext_list):
3043 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3045 def eth_need_tree(self):
3048 def GetTTag(self, ectx):
3049 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
3051 def eth_type_default_pars(self, ectx, tname):
3052 pars = Type.eth_type_default_pars(self, ectx, tname)
3053 pars['TABLE'] = '%(TNAME)s_sequence'
3056 def eth_type_default_body(self, ectx, tname):
3058 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
3059 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3060 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3062 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
3063 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3064 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3066 body = '#error Can not decode %s' % (tname)
3069 #--- SetType ------------------------------------------------------------------
3070 class SetType(SeqType):
3071 def eth_reg_sub(self, ident, ectx):
3072 for e in (self.elt_list):
3073 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3074 if hasattr(self, 'ext_list'):
3075 for e in (self.ext_list):
3076 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3078 def eth_need_tree(self):
3081 def GetTTag(self, ectx):
3082 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
3084 def eth_type_default_pars(self, ectx, tname):
3085 pars = Type.eth_type_default_pars(self, ectx, tname)
3086 pars['TABLE'] = '%(TNAME)s_set'
3089 def eth_type_default_body(self, ectx, tname):
3091 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
3092 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3093 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3095 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
3096 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3097 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3099 body = '#error Can not decode %s' % (tname)
3102 #--- ChoiceType ---------------------------------------------------------------
3103 class ChoiceType (Type):
3104 def to_python (self, ctx):
3105 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3106 # or '' + (1,) for optional
3107 if self.__dict__.has_key('ext_list'):
3108 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
3109 self.elts_to_py (self.elt_list, ctx),
3110 self.elts_to_py (self.ext_list, ctx))
3112 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
3113 def elts_to_py (self, list, ctx):
3116 assert (nt.type == 'named_type')
3118 if hasattr (nt, 'ident'):
3121 if hasattr (nt.typ, 'val'):
3122 identstr = nt.typ.val # XXX, making up name
3123 elif hasattr (nt.typ, 'name'):
3124 identstr = nt.typ.name
3126 identstr = ctx.make_new_name ()
3128 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
3129 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
3130 nt.typ.tag.tag_typ,nt.typ.tag.num)
3134 return "('%s',%s,%s)" % (identstr, tagstr,
3135 nt.typ.to_python (ctx))
3136 indentstr = ",\n" + ctx.spaces ()
3137 rv = indentstr.join ([elt_to_py (e) for e in list])
3141 def eth_reg_sub(self, ident, ectx):
3142 #print "eth_reg_sub(ident='%s')" % (ident)
3143 for e in (self.elt_list):
3144 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
3145 if hasattr(self, 'ext_list'):
3146 for e in (self.ext_list):
3147 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
3149 def eth_ftype(self, ectx):
3150 return ('FT_UINT32', 'BASE_DEC')
3152 def eth_strings(self):
3155 def eth_need_tree(self):
3158 def eth_has_vals(self):
3161 def GetTTag(self, ectx):
3163 cls = 'BER_CLASS_ANY/*choice*/'
3164 #if hasattr(self, 'ext_list'):
3165 # lst.extend(self.ext_list)
3167 # cls = lst[0].GetTag(ectx)[0]
3169 # if (e.GetTag(ectx)[0] != cls):
3170 # cls = '-1/*choice*/'
3171 return (cls, '-1/*choice*/')
3173 def IndetermTag(self, ectx):
3174 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
3175 return not self.HasOwnTag()
3177 def get_vals(self, ectx):
3181 if hasattr(self, 'ext_list'):
3182 lst.extend(self.ext_list)
3184 t = lst[0].GetTag(ectx)[0]
3186 if (t == 'BER_CLASS_UNI'):
3189 if (e.GetTag(ectx)[0] != t):
3193 for e in (self.elt_list):
3194 if (tagval): val = e.GetTag(ectx)[1]
3195 else: val = str(cnt)
3196 vals.append((val, e.name))
3198 if hasattr(self, 'ext_list'):
3199 for e in (self.ext_list):
3200 if (tagval): val = e.GetTag(ectx)[1]
3201 else: val = str(cnt)
3202 vals.append((val, e.name))
3206 def eth_type_vals(self, tname, ectx):
3208 vals = self.get_vals(ectx)
3209 out += ectx.eth_vals(tname, vals)
3212 def eth_type_enum(self, tname, ectx):
3214 vals = self.get_vals(ectx)
3215 out += ectx.eth_enum(tname, vals)
3218 def eth_type_default_pars(self, ectx, tname):
3219 pars = Type.eth_type_default_pars(self, ectx, tname)
3220 pars['TABLE'] = '%(TNAME)s_choice'
3223 def eth_type_default_table(self, ectx, tname):
3224 def out_item(val, e, ext, ectx):
3225 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
3227 vval = ectx.eth_enum_item(tname, e.name)
3230 f = fname + '/' + e.name
3231 ef = ectx.field[f]['ethname']
3232 t = ectx.eth_hf[ef]['ethtype']
3234 if (ectx.field[f]['impl']):
3238 if (not e.HasOwnTag()):
3239 opt = 'BER_FLAGS_NOOWNTAG'
3240 elif (e.HasImplicitTag(ectx)):
3241 if (opt): opt += '|'
3242 opt += 'BER_FLAGS_IMPLTAG'
3243 if (not opt): opt = '0'
3245 (tc, tn) = e.GetTag(ectx)
3246 out = ' { %3s, %-13s, %s, %s, dissect_%s },\n' \
3247 % (vval, tc, tn, opt, efd)
3249 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
3250 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
3255 #print "eth_type_default_table(tname='%s')" % (tname)
3256 fname = ectx.eth_type[tname]['ref'][0]
3260 if hasattr(self, 'ext_list'):
3261 lst.extend(self.ext_list)
3263 t = lst[0].GetTag(ectx)[0]
3265 if (t == 'BER_CLASS_UNI'):
3268 if (e.GetTag(ectx)[0] != t):
3270 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
3272 if hasattr(self, 'ext_list'):
3273 ext = 'ASN1_EXTENSION_ROOT'
3275 ext = 'ASN1_NO_EXTENSIONS'
3276 for e in (self.elt_list):
3277 if (tagval): val = e.GetTag(ectx)[1]
3278 else: val = str(cnt)
3279 table += out_item(val, e, ext, ectx)
3281 if hasattr(self, 'ext_list'):
3282 for e in (self.ext_list):
3283 if (tagval): val = e.GetTag(ectx)[1]
3284 else: val = str(cnt)
3285 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3288 table += " { 0, 0, 0, 0, NULL }\n};\n"
3290 table += " { 0, NULL, 0, NULL }\n};\n"
3293 def eth_type_default_body(self, ectx, tname):
3295 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3296 par=(('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3297 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
3300 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3301 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3302 ('%(ETT_INDEX)s', '%(TABLE)s',),
3305 body = '#error Can not decode %s' % (tname)
3308 #--- EnumeratedType -----------------------------------------------------------
3309 class EnumeratedType (Type):
3310 def to_python (self, ctx):
3311 def strify_one (named_num):
3312 return "%s=%s" % (named_num.ident, named_num.val)
3313 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
3315 def eth_ftype(self, ectx):
3316 return ('FT_UINT32', 'BASE_DEC')
3318 def eth_strings(self):
3321 def eth_has_vals(self):
3324 def GetTTag(self, ectx):
3325 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
3327 def get_vals_etc(self, ectx):
3335 for e in (self.val):
3336 if e.type == 'NamedNumber':
3337 used[int(e.val)] = True
3338 for e in (self.val):
3339 if e.type == 'NamedNumber':
3342 while used.has_key(lastv):
3346 vals.append((val, e.ident))
3347 map_table.append(val)
3351 if self.ext is not None:
3352 for e in (self.ext):
3353 if e.type == 'NamedNumber':
3354 used[int(e.val)] = True
3355 for e in (self.ext):
3356 if e.type == 'NamedNumber':
3359 while used.has_key(lastv):
3363 vals.append((val, e.ident))
3364 map_table.append(val)
3369 for i in range(len(map_table)):
3370 need_map = need_map or (map_table[i] != i)
3373 return (vals, root_num, ext_num, map_table)
3375 def eth_type_vals(self, tname, ectx):
3377 vals = self.get_vals_etc(ectx)[0]
3378 out += ectx.eth_vals(tname, vals)
3381 def eth_type_enum(self, tname, ectx):
3383 vals = self.get_vals_etc(ectx)[0]
3384 out += ectx.eth_enum(tname, vals)
3387 def eth_type_default_pars(self, ectx, tname):
3388 pars = Type.eth_type_default_pars(self, ectx, tname)
3389 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
3390 if (self.ext != None):
3394 pars['ROOT_NUM'] = str(root_num)
3396 pars['EXT_NUM'] = str(ext_num)
3398 pars['TABLE'] = '%(TNAME)s_value_map'
3400 pars['TABLE'] = 'NULL'
3403 def eth_type_default_table(self, ectx, tname):
3404 if (not ectx.Per()): return ''
3405 map_table = self.get_vals_etc(ectx)[3]
3406 if (map_table == None): return ''
3407 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
3408 table += ", ".join([str(v) for v in map_table])
3412 def eth_type_default_body(self, ectx, tname):
3414 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3415 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3418 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
3419 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3420 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
3422 body = '#error Can not decode %s' % (tname)
3425 #--- ExternalType -----------------------------------------------------------
3426 class ExternalType (Type):
3427 def eth_tname(self):
3430 def eth_ftype(self, ectx):
3431 return ('FT_NONE', 'BASE_NONE')
3433 def eth_type_default_pars(self, ectx, tname):
3434 pars = Type.eth_type_default_pars(self, ectx, tname)
3435 pars['TYPE_REF_FN'] = 'NULL'
3438 def eth_type_default_body(self, ectx, tname):
3440 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
3441 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
3443 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
3444 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
3446 body = '#error Can not decode %s' % (tname)
3449 #--- OpenType -----------------------------------------------------------
3450 class OpenType (Type):
3451 def to_python (self, ctx):
3454 def single_type(self):
3455 if (self.HasConstraint() and
3456 self.constr.type == 'Type' and
3457 self.constr.subtype.type == 'Type_Ref'):
3458 return self.constr.subtype.val
3461 def eth_reg_sub(self, ident, ectx):
3462 t = self.single_type()
3464 ectx.eth_dep_add(ident, t)
3466 def eth_tname(self):
3467 t = self.single_type()
3469 return 'OpenType_' + t
3471 return Type.eth_tname(self)
3473 def eth_ftype(self, ectx):
3474 return ('FT_NONE', 'BASE_NONE')
3476 def GetTTag(self, ectx):
3477 return ('BER_CLASS_ANY', '0')
3479 def eth_type_default_pars(self, ectx, tname):
3480 pars = Type.eth_type_default_pars(self, ectx, tname)
3481 t = self.single_type()
3483 t = ectx.type[t]['ethname']
3484 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3485 pars['TYPE_REF_TNAME'] = t
3486 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3488 pars['TYPE_REF_FN'] = 'NULL'
3491 def eth_type_default_body(self, ectx, tname):
3493 body = ectx.eth_fn_call('dissect_%(ER)s_open_type', ret='offset',
3494 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
3496 body = '#error Can not decode %s' % (tname)
3499 #--- AnyType -----------------------------------------------------------
3500 class AnyType (Type):
3501 def to_python (self, ctx):
3504 def eth_ftype(self, ectx):
3505 return ('FT_NONE', 'BASE_NONE')
3507 def GetTTag(self, ectx):
3508 return ('BER_CLASS_ANY', '0')
3510 def eth_type_default_body(self, ectx, tname):
3511 body = '#error Can not decode %s' % (tname)
3514 class Literal (Node):
3515 def to_python (self, ctx):
3518 #--- NullType -----------------------------------------------------------------
3519 class NullType (Type):
3520 def to_python (self, ctx):
3523 def eth_tname(self):
3526 def GetTTag(self, ectx):
3527 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
3529 def eth_type_default_body(self, ectx, tname):
3531 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
3532 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3534 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
3535 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3537 body = '#error Can not decode %s' % (tname)
3540 #--- RealType -----------------------------------------------------------------
3541 class RealType (Type):
3542 def to_python (self, ctx):
3545 def eth_tname(self):
3548 def GetTTag(self, ectx):
3549 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
3551 def eth_ftype(self, ectx):
3552 return ('FT_DOUBLE', 'BASE_NONE')
3554 def eth_type_default_body(self, ectx, tname):
3556 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
3557 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3560 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
3561 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3563 body = '#error Can not decode %s' % (tname)
3566 #--- BooleanType --------------------------------------------------------------
3567 class BooleanType (Type):
3568 def to_python (self, ctx):
3569 return 'asn1.BOOLEAN'
3571 def eth_tname(self):
3574 def GetTTag(self, ectx):
3575 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
3577 def eth_ftype(self, ectx):
3578 return ('FT_BOOLEAN', '8')
3580 def eth_type_default_body(self, ectx, tname):
3582 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
3583 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3585 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
3586 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3588 body = '#error Can not decode %s' % (tname)
3591 #--- OctetStringType ----------------------------------------------------------
3592 class OctetStringType (Type):
3593 def to_python (self, ctx):
3594 return 'asn1.OCTSTRING'
3596 def eth_tname(self):
3597 if not self.HasConstraint():
3598 return 'OCTET_STRING'
3599 elif self.constr.IsSize():
3600 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
3602 return '#' + self.type + '_' + str(id(self))
3604 def eth_ftype(self, ectx):
3605 return ('FT_BYTES', 'BASE_HEX')
3607 def GetTTag(self, ectx):
3608 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
3610 def eth_type_default_pars(self, ectx, tname):
3611 pars = Type.eth_type_default_pars(self, ectx, tname)
3612 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3615 def eth_type_default_body(self, ectx, tname):
3617 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
3618 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3621 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
3622 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3623 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s',),))
3625 body = '#error Can not decode %s' % (tname)
3628 #--- CharacterStringType ------------------------------------------------------
3629 class CharacterStringType (Type):
3630 def eth_tname(self):
3631 if not self.HasConstraint():
3632 return self.eth_tsname()
3633 elif self.constr.IsSize():
3634 return self.eth_tsname() + '_' + self.constr.eth_constrname()
3636 return '#' + self.type + '_' + str(id(self))
3638 def eth_ftype(self, ectx):
3639 return ('FT_STRING', 'BASE_NONE')
3641 class RestrictedCharacterStringType (CharacterStringType):
3642 def to_python (self, ctx):
3643 return 'asn1.' + self.eth_tsname()
3645 def GetTTag(self, ectx):
3646 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
3648 def HasPermAlph(self):
3649 return (self.HasConstraint() and
3650 (self.constr.IsPermAlph() or
3651 (self.constr.type == 'Intersection' and (self.constr.subtype[0].IsPermAlph() or self.constr.subtype[1].IsPermAlph()))
3655 def eth_type_default_pars(self, ectx, tname):
3656 pars = Type.eth_type_default_pars(self, ectx, tname)
3657 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3658 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
3659 (pars['ALPHABET'], pars['ALPHABET_LEN']) = ('NULL', '0')
3660 if self.HasPermAlph():
3661 if self.constr.IsPermAlph():
3662 pars['ALPHABET'] = self.constr.subtype.subtype
3663 elif self.constr.subtype[0].IsPermAlph():
3664 pars['ALPHABET'] = self.constr.subtype[0].subtype.subtype
3665 elif self.constr.subtype[1].IsPermAlph():
3666 pars['ALPHABET'] = self.constr.subtype[1].subtype.subtype
3667 pars['ALPHABET_LEN'] = 'strlen(%(ALPHABET)s)'
3670 def eth_type_default_body(self, ectx, tname):
3672 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
3673 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
3674 ('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3676 elif (ectx.Per() and self.HasPermAlph()):
3677 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
3678 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3679 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
3682 if (self.eth_tsname() == 'GeneralString'):
3683 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3684 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3685 elif (self.eth_tsname() == 'GeneralizedTime'):
3686 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
3687 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3688 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3689 elif (self.eth_tsname() == 'UTCTime'):
3690 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
3691 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3692 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3694 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3695 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3696 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3698 body = '#error Can not decode %s' % (tname)
3701 class BMPStringType (RestrictedCharacterStringType):
3702 def eth_tsname(self):
3705 class GeneralStringType (RestrictedCharacterStringType):
3706 def eth_tsname(self):
3707 return 'GeneralString'
3709 class GraphicStringType (RestrictedCharacterStringType):
3710 def eth_tsname(self):
3711 return 'GraphicString'
3713 class IA5StringType (RestrictedCharacterStringType):
3714 def eth_tsname(self):
3717 class NumericStringType (RestrictedCharacterStringType):
3718 def eth_tsname(self):
3719 return 'NumericString'
3721 class PrintableStringType (RestrictedCharacterStringType):
3722 def eth_tsname(self):
3723 return 'PrintableString'
3725 class TeletexStringType (RestrictedCharacterStringType):
3726 def eth_tsname(self):
3727 return 'TeletexString'
3729 class T61StringType (RestrictedCharacterStringType):
3730 def eth_tsname(self):
3732 def GetTTag(self, ectx):
3733 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
3735 class UniversalStringType (RestrictedCharacterStringType):
3736 def eth_tsname(self):
3737 return 'UniversalString'
3739 class UTF8StringType (RestrictedCharacterStringType):
3740 def eth_tsname(self):
3743 class VideotexStringType (RestrictedCharacterStringType):
3744 def eth_tsname(self):
3745 return 'VideotexString'
3747 class VisibleStringType (RestrictedCharacterStringType):
3748 def eth_tsname(self):
3749 return 'VisibleString'
3751 class ISO646StringType (RestrictedCharacterStringType):
3752 def eth_tsname(self):
3753 return 'ISO646String'
3754 def GetTTag(self, ectx):
3755 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
3757 class UnrestrictedCharacterStringType (CharacterStringType):
3758 def to_python (self, ctx):
3759 return 'asn1.UnrestrictedCharacterString'
3760 def eth_tsname(self):
3761 return 'CHARACTER_STRING'
3763 #--- UsefulType ---------------------------------------------------------------
3764 class GeneralizedTime (RestrictedCharacterStringType):
3765 def eth_tsname(self):
3766 return 'GeneralizedTime'
3768 def eth_type_default_body(self, ectx, tname):
3770 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3771 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3774 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
3776 class UTCTime (RestrictedCharacterStringType):
3777 def eth_tsname(self):
3780 class ObjectDescriptor (RestrictedCharacterStringType):
3781 def eth_tsname(self):
3782 return 'ObjectDescriptor'
3784 def eth_type_default_body(self, ectx, tname):
3786 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
3788 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
3789 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3791 body = '#error Can not decode %s' % (tname)
3794 #--- ObjectIdentifierType -----------------------------------------------------
3795 class ObjectIdentifierType (Type):
3796 def to_python (self, ctx):
3797 return 'asn1.OBJECT_IDENTIFIER'
3799 def eth_tname(self):
3800 return 'OBJECT_IDENTIFIER'
3802 def eth_ftype(self, ectx):
3803 return ('FT_OID', 'BASE_NONE')
3805 def GetTTag(self, ectx):
3806 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
3808 def eth_type_default_body(self, ectx, tname):
3810 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
3811 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3813 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
3814 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3816 body = '#error Can not decode %s' % (tname)
3819 #--- ObjectIdentifierValue ----------------------------------------------------
3820 class ObjectIdentifierValue (Value):
3821 def get_num(self, path, val):
3822 return str(oid_names.get(path + '/' + val, val))
3829 for v in self.comp_list:
3830 if isinstance(v, Node) and (v.type == 'name_and_number'):
3835 vstr = self.get_num(path, v)
3850 v = self.comp_list[0]
3851 if isinstance(v, Node) and (v.type == 'name_and_number'):
3856 vstr = self.get_num('', v)
3862 class NamedNumber(Node):
3863 def to_python (self, ctx):
3864 return "('%s',%s)" % (self.ident, self.val)
3866 class NamedNumListBase(Node):
3867 def to_python (self, ctx):
3868 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
3869 map (lambda x: x.to_python (ctx), self.named_list)))
3871 #--- IntegerType --------------------------------------------------------------
3872 class IntegerType (Type):
3873 def to_python (self, ctx):
3874 return "asn1.INTEGER_class ([%s])" % (",".join (
3875 map (lambda x: x.to_python (ctx), self.named_list)))
3877 def add_named_value(self, ident, val):
3878 e = NamedNumber(ident = ident, val = val)
3879 if not self.named_list:
3880 self.named_list = []
3881 self.named_list.append(e)
3883 def eth_tname(self):
3885 return Type.eth_tname(self)
3886 if not self.HasConstraint():
3888 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
3889 return 'INTEGER' + '_' + self.constr.eth_constrname()
3891 return 'INTEGER' + '_' + self.constr.eth_tname()
3893 def GetTTag(self, ectx):
3894 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
3897 def eth_ftype(self, ectx):
3898 if self.HasConstraint():
3899 if not self.constr.IsNegativ():
3900 return ('FT_UINT32', 'BASE_DEC')
3901 return ('FT_INT32', 'BASE_DEC')
3903 def eth_strings(self):
3904 if (self.named_list):
3909 def eth_has_vals(self):
3910 if (self.named_list):
3915 def get_vals(self, ectx):
3917 for e in (self.named_list):
3918 vals.append((int(e.val), e.ident))
3921 def eth_type_vals(self, tname, ectx):
3922 if not self.eth_has_vals(): return ''
3924 vals = self.get_vals(ectx)
3925 out += ectx.eth_vals(tname, vals)
3928 def eth_type_enum(self, tname, ectx):
3929 if not self.eth_has_enum(tname, ectx): return ''
3931 vals = self.get_vals(ectx)
3932 out += ectx.eth_enum(tname, vals)
3935 def eth_type_default_pars(self, ectx, tname):
3936 pars = Type.eth_type_default_pars(self, ectx, tname)
3937 if self.HasConstraint() and self.constr.IsValue():
3938 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr()
3941 def eth_type_default_body(self, ectx, tname):
3943 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3944 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3946 elif (ectx.Per() and not self.HasConstraint()):
3947 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3948 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
3949 elif (ectx.Per() and ((self.constr.type == 'SingleValue') or (self.constr.type == 'ValueRange'))):
3950 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
3951 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3952 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
3954 body = '#error Can not decode %s' % (tname)
3957 #--- BitStringType ------------------------------------------------------------
3958 class BitStringType (Type):
3959 def to_python (self, ctx):
3960 return "asn1.BITSTRING_class ([%s])" % (",".join (
3961 map (lambda x: x.to_python (ctx), self.named_list)))
3963 def eth_tname(self):
3965 return Type.eth_tname(self)
3966 elif not self.HasConstraint():
3968 elif self.constr.IsSize():
3969 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
3971 return '#' + self.type + '_' + str(id(self))
3973 def GetTTag(self, ectx):
3974 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
3976 def eth_ftype(self, ectx):
3977 return ('FT_BYTES', 'BASE_HEX')
3979 def eth_need_tree(self):
3980 return self.named_list
3982 def eth_named_bits(self):
3984 if (self.named_list):
3985 for e in (self.named_list):
3986 bits.append((int(e.val), e.ident))
3989 def eth_type_default_pars(self, ectx, tname):
3990 pars = Type.eth_type_default_pars(self, ectx, tname)
3991 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3992 if not pars.has_key('ETT_INDEX'):
3993 pars['ETT_INDEX'] = '-1'
3994 pars['TABLE'] = 'NULL'
3995 if self.eth_named_bits():
3996 pars['TABLE'] = '%(TNAME)s_bits'
3999 def eth_type_default_table(self, ectx, tname):
4000 #print "eth_type_default_table(tname='%s')" % (tname)
4002 bits = self.eth_named_bits()
4004 table = ectx.eth_bits(tname, bits)
4007 def eth_type_default_body(self, ectx, tname):
4009 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
4010 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4011 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
4014 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
4015 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4016 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s','%(VAL_PTR)s'),))
4018 body = '#error Can not decode %s' % (tname)
4022 #==============================================================================
4024 def p_module_list_1 (t):
4025 'module_list : module_list module_def'
4026 t[0] = t[1] + [t[2]]
4028 def p_module_list_2 (t):
4029 'module_list : module_def'
4033 #--- ITU-T Recommendation X.680 -----------------------------------------------
4036 # 11 ASN.1 lexical items --------------------------------------------------------
4038 # 11.2 Type references
4040 'type_ref : UCASE_IDENT'
4041 t[0] = Type_Ref(val=t[1])
4044 def p_identifier (t):
4045 'identifier : LCASE_IDENT'
4048 # 11.4 Value references
4049 def p_valuereference (t):
4050 'valuereference : LCASE_IDENT'
4053 # 11.5 Module references
4054 def p_modulereference (t):
4055 'modulereference : UCASE_IDENT'
4059 # 12 Module definition --------------------------------------------------------
4062 def p_module_def (t):
4063 'module_def : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT BEGIN module_body END'
4064 t[0] = Module (ident = t[1], tag_def = t[3], body = t[6])
4066 def p_TagDefault_1 (t):
4067 '''TagDefault : EXPLICIT TAGS
4070 t[0] = Default_Tags (dfl_tag = t[1])
4072 def p_TagDefault_2 (t):
4074 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
4075 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
4077 def p_ModuleIdentifier_1 (t):
4078 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
4079 t [0] = Node('module_ident', val = t[1], ident = t[2])
4081 def p_ModuleIdentifier_2 (t):
4082 'ModuleIdentifier : modulereference' # name, oid
4083 t [0] = Node('module_ident', val = t[1], ident = None)
4085 def p_DefinitiveIdentifier (t):
4086 'DefinitiveIdentifier : ObjectIdentifierValue'
4089 # XXX originally we had both type_ref and module_ref, but that caused
4090 # a reduce/reduce conflict (because both were UCASE_IDENT). Presumably
4091 # this didn't cause a problem in the original ESNACC grammar because it
4092 # was LALR(1) and PLY is (as of 1.1) only SLR.
4094 #def p_module_ref (t):
4095 # 'module_ref : UCASE_IDENT'
4098 def p_assigned_ident_1 (t):
4099 'assigned_ident : ObjectIdentifierValue'
4102 def p_assigned_ident_2 (t):
4103 'assigned_ident : LCASE_IDENT'
4106 def p_assigned_ident_3 (t):
4110 def p_module_body_1 (t):
4111 'module_body : exports Imports AssignmentList'
4112 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
4114 def p_module_body_2 (t):
4116 t[0] = Node ('module_body', exports = [], imports = [],
4119 def p_exports_1 (t):
4120 'exports : EXPORTS syms_exported SEMICOLON'
4123 def p_exports_2 (t):
4127 def p_syms_exported_1 (t):
4128 'syms_exported : exp_sym_list'
4131 def p_syms_exported_2 (t):
4135 def p_exp_sym_list_1 (t):
4136 'exp_sym_list : Symbol'
4139 def p_exp_sym_list_2 (t):
4140 'exp_sym_list : exp_sym_list COMMA Symbol'
4141 t[0] = t[1] + [t[3]]
4145 'Imports : IMPORTS SymbolsImported SEMICOLON'
4148 def p_Imports_2 (t):
4152 def p_SymbolsImported_1(t):
4153 'SymbolsImported : '
4156 def p_SymbolsImported_2 (t):
4157 'SymbolsImported : SymbolsFromModuleList'
4160 def p_SymbolsFromModuleList_1 (t):
4161 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
4162 t[0] = t[1] + [t[2]]
4164 def p_SymbolsFromModuleList_2 (t):
4165 'SymbolsFromModuleList : SymbolsFromModule'
4168 def p_SymbolsFromModule (t):
4169 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
4170 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
4172 def p_GlobalModuleReference (t):
4173 'GlobalModuleReference : modulereference assigned_ident'
4174 t [0] = Node('module_ident', val = t[1], ident = t[2])
4176 def p_SymbolList_1 (t):
4177 'SymbolList : Symbol'
4180 def p_SymbolList_2 (t):
4181 'SymbolList : SymbolList COMMA Symbol'
4182 t[0] = t[1] + [t[3]]
4185 '''Symbol : Reference
4186 | ParameterizedReference'''
4189 def p_Reference (t):
4190 '''Reference : type_ref
4192 | objectclassreference'''
4195 def p_AssignmentList_1 (t):
4196 'AssignmentList : AssignmentList Assignment'
4197 t[0] = t[1] + [t[2]]
4199 def p_AssignmentList_2 (t):
4200 'AssignmentList : Assignment SEMICOLON'
4203 def p_AssignmentList_3 (t):
4204 'AssignmentList : Assignment'
4207 def p_Assignment (t):
4208 '''Assignment : TypeAssignment
4210 | ObjectClassAssignment
4212 | ObjectSetAssignment
4213 | ParameterizedTypeAssignment
4218 # 13 Referencing type and value definitions -----------------------------------
4221 def p_DefinedType (t):
4222 '''DefinedType : ext_type_ref
4224 | ParameterizedType'''
4227 def p_DefinedValue(t):
4228 '''DefinedValue : ext_val_ref
4233 # 15 Assigning types and values -----------------------------------------------
4236 def p_TypeAssignment (t):
4237 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
4242 def p_ValueAssignment (t):
4243 'ValueAssignment : valuereference Type ASSIGNMENT Value'
4244 t[0] = value_assign (ident = t[1], typ = t[2], val = t[4])
4247 # 16 Definition of types and values -------------------------------------------
4251 '''Type : BuiltinType
4253 | ConstrainedType'''
4257 def p_BuiltinType (t):
4258 '''BuiltinType : AnyType
4261 | CharacterStringType
4267 | ObjectClassFieldType
4268 | ObjectIdentifierType
4280 def p_ReferencedType (t):
4281 '''ReferencedType : DefinedType
4285 def p_ext_type_ref (t):
4286 'ext_type_ref : type_ref DOT type_ref'
4287 # XXX coerce 1st type_ref to module_ref
4288 t[0] = Node ('ext_type_ref', module = t[1], typ = t[3])
4291 def p_NamedType (t):
4292 'NamedType : identifier Type'
4298 '''Value : BuiltinValue
4299 | ReferencedValue'''
4303 def p_BuiltinValue (t):
4304 '''BuiltinValue : BooleanValue
4306 | ObjectIdentifierValue
4311 | char_string''' # XXX we don't support {data} here
4315 def p_ReferencedValue (t):
4316 '''ReferencedValue : DefinedValue'''
4320 #def p_NamedValue (t):
4321 # 'NamedValue : identifier Value'
4322 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
4325 # 17 Notation for the boolean type --------------------------------------------
4328 def p_BooleanType (t):
4329 'BooleanType : BOOLEAN'
4330 t[0] = BooleanType ()
4333 def p_BooleanValue (t):
4334 '''BooleanValue : TRUE
4339 # 18 Notation for the integer type --------------------------------------------
4342 def p_IntegerType_1 (t):
4343 'IntegerType : INTEGER'
4344 t[0] = IntegerType (named_list = None)
4346 def p_IntegerType_2 (t):
4347 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
4348 t[0] = IntegerType(named_list = t[3])
4350 def p_NamedNumberList_1 (t):
4351 'NamedNumberList : NamedNumber'
4354 def p_NamedNumberList_2 (t):
4355 'NamedNumberList : NamedNumberList COMMA NamedNumber'
4356 t[0] = t[1] + [t[3]]
4358 def p_NamedNumber (t):
4359 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
4360 | identifier LPAREN DefinedValue RPAREN'''
4361 t[0] = NamedNumber(ident = t[1], val = t[3])
4363 def p_SignedNumber_1 (t):
4364 'SignedNumber : NUMBER'
4367 def p_SignedNumber_2 (t):
4368 'SignedNumber : MINUS NUMBER'
4372 def p_IntegerValue (t):
4373 'IntegerValue : SignedNumber'
4376 # 19 Notation for the enumerated type -----------------------------------------
4379 def p_EnumeratedType (t):
4380 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
4381 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
4383 def p_Enumerations_1 (t):
4384 'Enumerations : Enumeration'
4385 t[0] = { 'val' : t[1], 'ext' : None }
4387 def p_Enumerations_2 (t):
4388 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
4389 t[0] = { 'val' : t[1], 'ext' : [] }
4391 def p_Enumerations_3 (t):
4392 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
4393 t[0] = { 'val' : t[1], 'ext' : t[6] }
4395 def p_Enumeration_1 (t):
4396 'Enumeration : EnumerationItem'
4399 def p_Enumeration_2 (t):
4400 'Enumeration : Enumeration COMMA EnumerationItem'
4401 t[0] = t[1] + [t[3]]
4403 def p_EnumerationItem (t):
4404 '''EnumerationItem : Identifier
4408 def p_Identifier (t):
4409 'Identifier : identifier'
4410 t[0] = Node ('Identifier', ident = t[1])
4413 # 20 Notation for the real type -----------------------------------------------
4421 def p_RealValue (t):
4422 '''RealValue : REAL_NUMBER
4423 | SpecialRealValue'''
4426 def p_SpecialRealValue (t):
4427 '''SpecialRealValue : PLUS_INFINITY
4432 # 21 Notation for the bitstring type ------------------------------------------
4435 def p_BitStringType_1 (t):
4436 'BitStringType : BIT STRING'
4437 t[0] = BitStringType (named_list = None)
4439 def p_BitStringType_2 (t):
4440 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
4441 t[0] = BitStringType (named_list = t[4])
4443 def p_NamedBitList_1 (t):
4444 'NamedBitList : NamedBit'
4447 def p_NamedBitList_2 (t):
4448 'NamedBitList : NamedBitList COMMA NamedBit'
4449 t[0] = t[1] + [t[3]]
4452 '''NamedBit : identifier LPAREN NUMBER RPAREN
4453 | identifier LPAREN DefinedValue RPAREN'''
4454 t[0] = NamedNumber (ident = t[1], val = t[3])
4457 # 22 Notation for the octetstring type ----------------------------------------
4460 def p_OctetStringType (t):
4461 'OctetStringType : OCTET STRING'
4462 t[0] = OctetStringType ()
4465 # 23 Notation for the null type -----------------------------------------------
4473 #def p_NullValue (t):
4474 # 'NullValue : NULL'
4478 # 24 Notation for sequence types ----------------------------------------------
4481 def p_SequenceType_1 (t):
4482 'SequenceType : SEQUENCE LBRACE RBRACE'
4483 t[0] = SequenceType (elt_list = [])
4485 def p_SequenceType_2 (t):
4486 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
4487 if t[3].has_key('ext_list'):
4488 t[0] = SequenceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4490 t[0] = SequenceType (elt_list = t[3]['elt_list'])
4492 def p_ExtensionAndException_1 (t):
4493 'ExtensionAndException : ELLIPSIS'
4496 def p_OptionalExtensionMarker_1 (t):
4497 'OptionalExtensionMarker : COMMA ELLIPSIS'
4500 def p_OptionalExtensionMarker_2 (t):
4501 'OptionalExtensionMarker : '
4504 def p_ComponentTypeLists_1 (t):
4505 'ComponentTypeLists : element_type_list'
4506 t[0] = {'elt_list' : t[1]}
4508 def p_ComponentTypeLists_2 (t):
4509 'ComponentTypeLists : element_type_list COMMA ExtensionAndException extension_additions OptionalExtensionMarker'
4510 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
4512 def p_ComponentTypeLists_3 (t):
4513 'ComponentTypeLists : ExtensionAndException extension_additions OptionalExtensionMarker'
4514 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
4516 def p_extension_additions_1 (t):
4517 'extension_additions : extension_addition_list'
4520 def p_extension_additions_2 (t):
4521 'extension_additions : '
4524 def p_extension_addition_list_1 (t):
4525 'extension_addition_list : COMMA extension_addition'
4528 def p_extension_addition_list_2 (t):
4529 'extension_addition_list : extension_addition_list COMMA extension_addition'
4530 t[0] = t[1] + [t[3]]
4532 def p_extension_addition_1 (t):
4533 'extension_addition : element_type'
4536 def p_element_type_list_1 (t):
4537 'element_type_list : element_type'
4540 def p_element_type_list_2 (t):
4541 'element_type_list : element_type_list COMMA element_type'
4542 t[0] = t[1] + [t[3]]
4544 def p_element_type_1 (t):
4545 'element_type : NamedType'
4546 t[0] = Node ('elt_type', val = t[1], optional = 0)
4548 def p_element_type_2 (t):
4549 'element_type : NamedType OPTIONAL'
4550 t[0] = Node ('elt_type', val = t[1], optional = 1)
4552 def p_element_type_3 (t):
4553 'element_type : NamedType DEFAULT Value'
4554 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
4556 # * this rules uses NamedValue instead of Value
4557 # * for the stupid choice value syntax (fieldname value)
4558 # * it should be like a set/seq value (ie with
4562 # XXX get to COMPONENTS later
4565 def p_SequenceValue_1 (t):
4566 'SequenceValue : LBRACE RBRACE'
4570 #def p_SequenceValue_2 (t):
4571 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
4574 #def p_ComponentValueList_1 (t):
4575 # 'ComponentValueList : NamedValue'
4578 #def p_ComponentValueList_2 (t):
4579 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
4580 # t[0] = t[1] + [t[3]]
4583 # 25 Notation for sequence-of types -------------------------------------------
4586 def p_SequenceOfType (t):
4587 '''SequenceOfType : SEQUENCE OF Type
4588 | SEQUENCE OF NamedType'''
4589 t[0] = SequenceOfType (val = t[3], size_constr = None)
4592 # 26 Notation for set types ---------------------------------------------------
4595 def p_SetType_1 (t):
4596 'SetType : SET LBRACE RBRACE'
4597 if t[3].has_key('ext_list'):
4598 t[0] = SetType (elt_list = [])
4600 def p_SetType_2 (t):
4601 'SetType : SET LBRACE ComponentTypeLists RBRACE'
4602 if t[3].has_key('ext_list'):
4603 t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4605 t[0] = SetType (elt_list = t[3]['elt_list'])
4608 # 27 Notation for set-of types ------------------------------------------------
4611 def p_SetOfType (t):
4612 '''SetOfType : SET OF Type
4613 | SET OF NamedType'''
4614 t[0] = SetOfType (val = t[3])
4616 # 28 Notation for choice types ------------------------------------------------
4619 def p_ChoiceType (t):
4620 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
4621 if t[3].has_key('ext_list'):
4622 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4624 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
4626 def p_alternative_type_lists_1 (t):
4627 'alternative_type_lists : alternative_type_list'
4628 t[0] = {'elt_list' : t[1]}
4630 def p_alternative_type_lists_2 (t):
4631 '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
4632 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
4634 def p_extension_addition_alternatives_1 (t):
4635 'extension_addition_alternatives : extension_addition_alternatives_list'
4638 def p_extension_addition_alternatives_2 (t):
4639 'extension_addition_alternatives : '
4642 def p_extension_addition_alternatives_list_1 (t):
4643 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
4646 def p_extension_addition_alternatives_list_2 (t):
4647 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
4648 t[0] = t[1] + [t[3]]
4650 def p_extension_addition_alternative_1 (t):
4651 'extension_addition_alternative : NamedType'
4654 def p_alternative_type_list_1 (t):
4655 'alternative_type_list : NamedType'
4658 def p_alternative_type_list_2 (t):
4659 'alternative_type_list : alternative_type_list COMMA NamedType'
4660 t[0] = t[1] + [t[3]]
4662 def p_selection_type (t): # XXX what is this?
4663 'selection_type : identifier LT Type'
4664 return Node ('seltype', ident = t[1], typ = t[3])
4666 # 30 Notation for tagged types ------------------------------------------------
4669 def p_TaggedType_1 (t):
4670 'TaggedType : Tag Type'
4671 t[1].mode = 'default'
4675 def p_TaggedType_2 (t):
4676 '''TaggedType : Tag IMPLICIT Type
4677 | Tag EXPLICIT Type'''
4683 'Tag : LBRACK Class ClassNumber RBRACK'
4684 t[0] = Tag(cls = t[2], num = t[3])
4686 def p_ClassNumber_1 (t):
4687 'ClassNumber : number'
4690 def p_ClassNumber_2 (t):
4691 'ClassNumber : DefinedValue'
4695 '''Class : UNIVERSAL
4710 # 31 Notation for the object identifier type ----------------------------------
4713 def p_ObjectIdentifierType (t):
4714 'ObjectIdentifierType : OBJECT IDENTIFIER'
4715 t[0] = ObjectIdentifierType()
4718 def p_ObjectIdentifierValue (t):
4719 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
4720 t[0] = ObjectIdentifierValue (comp_list=t[2])
4722 def p_oid_comp_list_1 (t):
4723 'oid_comp_list : oid_comp_list ObjIdComponents'
4724 t[0] = t[1] + [t[2]]
4726 def p_oid_comp_list_2 (t):
4727 'oid_comp_list : ObjIdComponents'
4730 def p_ObjIdComponents (t):
4731 '''ObjIdComponents : NameForm
4733 | NameAndNumberForm'''
4737 'NameForm : LCASE_IDENT'
4740 def p_NumberForm (t):
4741 '''NumberForm : NUMBER'''
4745 def p_NameAndNumberForm (t):
4746 'NameAndNumberForm : LCASE_IDENT LPAREN NumberForm RPAREN'
4747 t[0] = Node('name_and_number', ident = t[1], number = t[3])
4749 # 34 Notation for the external type -------------------------------------------
4752 def p_ExternalType (t):
4753 'ExternalType : EXTERNAL'
4754 t[0] = ExternalType()
4756 # 36 Notation for character string types --------------------------------------
4759 def p_CharacterStringType (t):
4760 '''CharacterStringType : RestrictedCharacterStringType
4761 | UnrestrictedCharacterStringType'''
4765 # 37 Definition of restricted character string types --------------------------
4767 def p_RestrictedCharacterStringType_1 (t):
4768 'RestrictedCharacterStringType : BMPString'
4769 t[0] = BMPStringType ()
4770 def p_RestrictedCharacterStringType_2 (t):
4771 'RestrictedCharacterStringType : GeneralString'
4772 t[0] = GeneralStringType ()
4773 def p_RestrictedCharacterStringType_3 (t):
4774 'RestrictedCharacterStringType : GraphicString'
4775 t[0] = GraphicStringType ()
4776 def p_RestrictedCharacterStringType_4 (t):
4777 'RestrictedCharacterStringType : IA5String'
4778 t[0] = IA5StringType ()
4779 def p_RestrictedCharacterStringType_5 (t):
4780 'RestrictedCharacterStringType : ISO646String'
4781 t[0] = ISO646StringType ()
4782 def p_RestrictedCharacterStringType_6 (t):
4783 'RestrictedCharacterStringType : NumericString'
4784 t[0] = NumericStringType ()
4785 def p_RestrictedCharacterStringType_7 (t):
4786 'RestrictedCharacterStringType : PrintableString'
4787 t[0] = PrintableStringType ()
4788 def p_RestrictedCharacterStringType_8 (t):
4789 'RestrictedCharacterStringType : TeletexString'
4790 t[0] = TeletexStringType ()
4791 def p_RestrictedCharacterStringType_9 (t):
4792 'RestrictedCharacterStringType : T61String'
4793 t[0] = T61StringType ()
4794 def p_RestrictedCharacterStringType_10 (t):
4795 'RestrictedCharacterStringType : UniversalString'
4796 t[0] = UniversalStringType ()
4797 def p_RestrictedCharacterStringType_11 (t):
4798 'RestrictedCharacterStringType : UTF8String'
4799 t[0] = UTF8StringType ()
4800 def p_RestrictedCharacterStringType_12 (t):
4801 'RestrictedCharacterStringType : VideotexString'
4802 t[0] = VideotexStringType ()
4803 def p_RestrictedCharacterStringType_13 (t):
4804 'RestrictedCharacterStringType : VisibleString'
4805 t[0] = VisibleStringType ()
4808 # 40 Definition of unrestricted character string types ------------------------
4811 def p_UnrestrictedCharacterStringType (t):
4812 'UnrestrictedCharacterStringType : CHARACTER STRING'
4813 t[0] = UnrestrictedCharacterStringType ()
4816 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
4818 # 42 Generalized time ---------------------------------------------------------
4820 def p_UsefulType_1 (t):
4821 'UsefulType : GeneralizedTime'
4822 t[0] = GeneralizedTime()
4824 # 43 Universal time -----------------------------------------------------------
4826 def p_UsefulType_2 (t):
4827 'UsefulType : UTCTime'
4830 # 44 The object descriptor type -----------------------------------------------
4832 def p_UsefulType_3 (t):
4833 'UsefulType : ObjectDescriptor'
4834 t[0] = ObjectDescriptor()
4837 # 45 Constrained types --------------------------------------------------------
4840 def p_ConstrainedType_1 (t):
4841 'ConstrainedType : Type Constraint'
4843 t[0].AddConstraint(t[2])
4845 def p_ConstrainedType_2 (t):
4846 'ConstrainedType : TypeWithConstraint'
4850 def p_TypeWithConstraint_1 (t):
4851 '''TypeWithConstraint : SET Constraint OF Type
4852 | SET SizeConstraint OF Type'''
4853 t[0] = SetOfType (val = t[4], constr = t[2])
4855 def p_TypeWithConstraint_2 (t):
4856 '''TypeWithConstraint : SEQUENCE Constraint OF Type
4857 | SEQUENCE SizeConstraint OF Type'''
4858 t[0] = SequenceOfType (val = t[4], constr = t[2])
4860 def p_TypeWithConstraint_3 (t):
4861 '''TypeWithConstraint : SET Constraint OF NamedType
4862 | SET SizeConstraint OF NamedType'''
4863 t[0] = SetOfType (val = t[4], constr = t[2])
4865 def p_TypeWithConstraint_4 (t):
4866 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
4867 | SEQUENCE SizeConstraint OF NamedType'''
4868 t[0] = SequenceOfType (val = t[4], constr = t[2])
4872 def p_Constraint (t):
4873 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
4876 def p_ConstraintSpec (t):
4877 '''ConstraintSpec : ElementSetSpecs
4878 | GeneralConstraint'''
4881 # 46 Element set specification ------------------------------------------------
4884 def p_ElementSetSpecs_1 (t):
4885 'ElementSetSpecs : RootElementSetSpec'
4888 def p_ElementSetSpecs_2 (t):
4889 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
4893 def p_ElementSetSpecs_3 (t):
4894 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA ElementSetSpecs'
4898 # skip compound constraints, only simple ones are supported
4900 def p_RootElementSetSpec_1 (t):
4901 'RootElementSetSpec : SubtypeElements'
4904 def p_RootElementSetSpec_2 (t):
4905 'RootElementSetSpec : SubtypeElements IntersectionMark SubtypeElements'
4906 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
4908 def p_IntersectionMark (t):
4909 '''IntersectionMark : CIRCUMFLEX
4912 # 47 Subtype elements ---------------------------------------------------------
4915 def p_SubtypeElements (t):
4916 '''SubtypeElements : SingleValue
4922 | InnerTypeConstraints
4923 | PatternConstraint'''
4928 def p_SingleValue (t):
4929 'SingleValue : Value'
4930 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
4932 # 47.3 Contained subtype
4934 def p_ContainedSubtype (t):
4935 'ContainedSubtype : Includes Type'
4936 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
4939 '''Includes : INCLUDES
4944 def p_ValueRange (t):
4945 'ValueRange : lower_end_point RANGE upper_end_point'
4946 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
4949 def p_lower_end_point_1 (t):
4950 'lower_end_point : lower_end_value '
4953 def p_lower_end_point_2 (t):
4954 'lower_end_point : lower_end_value LT' # XXX LT first?
4955 t[0] = t[1] # but not inclusive range
4957 def p_upper_end_point_1 (t):
4958 'upper_end_point : upper_end_value'
4961 def p_upper_end_point_2 (t):
4962 'upper_end_point : LT upper_end_value'
4963 t[0] = t[1] # but not inclusive range
4965 def p_lower_end_value (t):
4966 '''lower_end_value : Value
4970 def p_upper_end_value (t):
4971 '''upper_end_value : Value
4975 # 47.5 Size constraint
4977 def p_SizeConstraint (t):
4978 'SizeConstraint : SIZE Constraint'
4979 t[0] = Constraint (type = 'Size', subtype = t[2])
4981 # 47.6 Type constraint
4983 def p_TypeConstraint (t):
4984 'TypeConstraint : Type'
4985 t[0] = Constraint (type = 'Type', subtype = t[1])
4987 # 47.7 Permitted alphabet
4989 def p_PermittedAlphabet (t):
4990 'PermittedAlphabet : FROM Constraint'
4991 t[0] = Constraint (type = 'From', subtype = t[2])
4993 # 47.8 Inner subtyping
4995 def p_InnerTypeConstraints (t):
4996 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
4997 | WITH COMPONENTS MultipleTypeConstraints'''
4998 pass # ignore PER invisible constraint
5001 def p_SingleTypeConstraint (t):
5002 'SingleTypeConstraint : Constraint'
5006 def p_MultipleTypeConstraints (t):
5007 '''MultipleTypeConstraints : FullSpecification
5008 | PartialSpecification'''
5011 def p_FullSpecification (t):
5012 'FullSpecification : LBRACE TypeConstraints RBRACE'
5015 def p_PartialSpecification (t):
5016 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
5019 def p_TypeConstraints_1 (t):
5020 'TypeConstraints : named_constraint'
5023 def p_TypeConstraints_2 (t):
5024 'TypeConstraints : TypeConstraints COMMA named_constraint'
5025 t[0] = t[1] + [t[3]]
5027 def p_named_constraint_1 (t):
5028 'named_constraint : identifier constraint'
5029 return Node ('named_constraint', ident = t[1], constr = t[2])
5031 def p_named_constraint_2 (t):
5032 'named_constraint : constraint'
5033 return Node ('named_constraint', constr = t[1])
5035 def p_constraint (t):
5036 'constraint : value_constraint presence_constraint'
5037 t[0] = Node ('constraint', value = t[1], presence = t[2])
5039 def p_value_constraint_1 (t):
5040 'value_constraint : Constraint'
5043 def p_value_constraint_2 (t):
5044 'value_constraint : '
5047 def p_presence_constraint_1 (t):
5048 '''presence_constraint : PRESENT
5053 def p_presence_constraint_2 (t):
5054 '''presence_constraint : '''
5057 # 47.9 Pattern constraint
5059 def p_PatternConstraint (t):
5060 'PatternConstraint : PATTERN Value'
5061 t[0] = Constraint (type = 'Pattern', subtype = t[2])
5063 # 49 The exception identifier
5066 def p_ExceptionSpec (t):
5070 # /*-----------------------------------------------------------------------*/
5071 # /* Value Notation Productions */
5072 # /*-----------------------------------------------------------------------*/
5077 def p_ext_val_ref (t):
5078 'ext_val_ref : type_ref DOT identifier'
5079 # XXX coerce type_ref to module_ref
5080 return Node ('ext_val_ref', module = t[1], ident = t[3])
5083 # see X.208 if you are dubious about lcase only for identifier
5085 def p_binary_string (t):
5086 'binary_string : BSTRING'
5089 def p_hex_string (t):
5090 'hex_string : HSTRING'
5093 def p_char_string (t):
5094 'char_string : QSTRING'
5102 #--- ITU-T Recommendation X.681 -----------------------------------------------
5104 # 7 ASN.1 lexical items -------------------------------------------------------
5106 # 7.1 Information object class references
5108 def p_objectclassreference (t):
5109 'objectclassreference : CLASS_IDENT'
5110 t[0] = Class_Ref(val=t[1])
5112 # 7.2 Information object references
5114 #def p_objectreference (t):
5115 # 'objectreference : LCASE_IDENT'
5118 # 7.3 Information object set references
5120 def p_objectsetreference (t):
5121 'objectsetreference : UCASE_IDENT'
5124 # 7.4 Type field references
5126 def p_typefieldreference (t):
5127 'typefieldreference : AMPERSAND UCASE_IDENT'
5130 # 7.5 Value field references
5132 def p_valuefieldreference (t):
5133 'valuefieldreference : AMPERSAND LCASE_IDENT'
5136 # 8 Referencing definitions
5139 def p_DefinedObjectClass (t):
5140 '''DefinedObjectClass : objectclassreference
5141 | UsefulObjectClassReference'''
5145 def p_UsefulObjectClassReference (t):
5146 '''UsefulObjectClassReference : TYPE_IDENTIFIER
5147 | ABSTRACT_SYNTAX'''
5150 # 9 Information object class definition and assignment
5153 def p_ObjectClassAssignment (t):
5154 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
5155 | UCASE_IDENT ASSIGNMENT ObjectClass'''
5160 def p_ObjectClass (t):
5161 '''ObjectClass : ObjectClassDefn'''
5165 def p_ObjectClassDefn (t):
5166 '''ObjectClassDefn : CLASS lbraceignore rbraceignore
5167 | CLASS lbraceignore rbraceignore WithSyntaxSpec'''
5168 t[0] = ObjectClass()
5170 def p_WithSyntaxSpec (t):
5171 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
5175 def p_FieldName (t):
5176 '''FieldName : typefieldreference
5177 | valuefieldreference'''
5180 # 11 Information object definition and assignment
5183 def p_ObjectAssignment (t):
5184 'ObjectAssignment : valuereference CLASS_IDENT ASSIGNMENT Object'
5185 t[0] = Node('ObjectAssignment', name=t[1], cls=t[2], val=t[4])
5189 'Object : lbraceignore rbraceignore'
5192 # 12 Information object set definition and assignment
5195 def p_ObjectSetAssignment (t):
5196 'ObjectSetAssignment : objectsetreference CLASS_IDENT ASSIGNMENT ObjectSet'
5197 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
5200 def p_ObjectSet (t):
5201 'ObjectSet : lbraceignore rbraceignore'
5204 # 14 Notation for the object class field type ---------------------------------
5207 def p_ObjectClassFieldType (t):
5208 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
5209 t[0] = get_type_from_class(t[1], t[3])
5214 useful_object_class_types = {
5216 'TYPE-IDENTIFIER/id' : lambda : ObjectIdentifierType(),
5217 'TYPE-IDENTIFIER/Type' : lambda : OpenType(),
5219 'ABSTRACT-SYNTAX/id' : lambda : ObjectIdentifierType(),
5220 'ABSTRACT-SYNTAX/Type' : lambda : OpenType(),
5221 'ABSTRACT-SYNTAX/property' : lambda : BitStringType(),
5224 object_class_types = {
5227 object_class_typerefs = {
5230 class_types_creator = {
5231 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
5232 'OpenType' : lambda : OpenType(),
5235 def is_class_ident(name):
5236 return class_names.has_key(name)
5238 def add_class_ident(name):
5239 class_names[name] = name
5241 def get_type_from_class(cls, fld):
5242 if (isinstance(cls, Class_Ref)):
5243 key = cls.val + '/' + fld
5245 key = cls + '/' + fld
5247 if object_class_typerefs.has_key(key):
5248 return Type_Ref(val=object_class_typerefs[key])
5250 creator = lambda : AnyType()
5251 creator = useful_object_class_types.get(key, creator)
5252 creator = object_class_types.get(key, creator)
5255 def set_type_to_class(cls, fld, typename, typeref = None):
5256 key = cls + '/' + fld
5257 if object_class_types.has_key(key): return False
5258 if object_class_typerefs.has_key(key): return False
5260 if (typename == 'TypeReference'):
5261 if not typeref: return False
5262 object_class_typerefs[key] = typeref
5265 creator = class_types_creator.get(typename)
5267 object_class_types[key] = creator
5272 #--- ITU-T Recommendation X.682 -----------------------------------------------
5274 # 8 General constraint specification ------------------------------------------
5277 def p_GeneralConstraint (t):
5278 '''GeneralConstraint : UserDefinedConstraint
5279 | TableConstraint'''
5280 # | ContentsConstraint''
5283 # 9 User-defined constraints --------------------------------------------------
5286 def p_UserDefinedConstraint (t):
5287 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
5288 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
5290 def p_UserDefinedConstraintParameterList_1 (t):
5291 'UserDefinedConstraintParameterList : '
5294 def p_UserDefinedConstraintParameterList_2 (t):
5295 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
5298 def p_UserDefinedConstraintParameterList_3 (t):
5299 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
5300 t[0] = t[1] + [t[3]]
5303 def p_UserDefinedConstraintParameter (t):
5304 'UserDefinedConstraintParameter : type_ref'
5307 # 10 Table constraints, including component relation constraints
5310 def p_TableConstraint (t):
5311 '''TableConstraint : SimpleTableConstraint
5312 | ComponentRelationConstraint'''
5313 t[0] = Constraint(type = 'Table', subtype = t[1])
5315 def p_SimpleTableConstraint (t):
5316 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
5320 def p_ComponentRelationConstraint (t):
5321 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AT LCASE_IDENT RBRACE'
5322 t[0] = t[2] + '@' + t[6]
5324 #--- ITU-T Recommendation X.683 -----------------------------------------------
5326 # 8 Parameterized assignments -------------------------------------------------
5331 def p_ParameterizedTypeAssignment (t):
5332 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
5334 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
5337 def p_ParameterList (t):
5338 'ParameterList : lbraceignore rbraceignore'
5340 #def p_ParameterList (t):
5341 # 'ParameterList : LBRACE Parameters RBRACE'
5344 #def p_Parameters_1 (t):
5345 # 'Parameters : Parameter'
5348 #def p_Parameters_2 (t):
5349 # 'Parameters : Parameters COMMA Parameter'
5350 # t[0] = t[1] + [t[3]]
5352 #def p_Parameter_1 (t):
5353 # 'Parameter : Type COLON Reference'
5354 # t[0] = [t[1], t[3]]
5356 #def p_Parameter_2 (t):
5357 # 'Parameter : Reference'
5361 # 9 Referencing parameterized definitions -------------------------------------
5364 def p_ParameterizedReference (t):
5365 'ParameterizedReference : type_ref LBRACE RBRACE'
5370 def p_ParameterizedType (t):
5371 'ParameterizedType : type_ref ActualParameterList'
5376 def p_ActualParameterList (t):
5377 'ActualParameterList : lbraceignore rbraceignore'
5379 #def p_ActualParameterList (t):
5380 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
5383 #def p_ActualParameters_1 (t):
5384 # 'ActualParameters : ActualParameter'
5387 #def p_ActualParameters_2 (t):
5388 # 'ActualParameters : ActualParameters COMMA ActualParameter'
5389 # t[0] = t[1] + [t[3]]
5391 #def p_ActualParameter (t):
5392 # '''ActualParameter : Type
5397 # {...} block to be ignored
5398 def p_lbraceignore(t):
5399 'lbraceignore : braceignorebegin LBRACE'
5402 def p_braceignorebegin(t):
5403 'braceignorebegin : '
5406 lexer.begin('braceignore')
5408 def p_rbraceignore(t):
5409 'rbraceignore : braceignoreend RBRACE'
5412 def p_braceignoreend(t):
5415 lexer.begin('INITIAL')
5419 raise ParseError(t, input_file)
5422 '''pyquote : PYQUOTE'''
5423 t[0] = PyQuote (val = t[1])
5429 token = lexer.token ()
5435 def do_module (ast, defined_dict):
5436 assert (ast.type == 'Module')
5437 ctx = Ctx (defined_dict)
5438 print ast.to_python (ctx)
5439 print ctx.output_assignments ()
5440 print ctx.output_pyquotes ()
5442 def eth_do_module (ast, ectx):
5443 assert (ast.type == 'Module')
5444 if ectx.dbg('s'): print ast.str_depth(0)
5447 def testyacc(s, fn, defined_dict):
5448 ast = yacc.parse(s, debug=0)
5449 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
5450 print """#!/usr/bin/env python
5451 # Auto-generated from %s at %s
5452 from PyZ3950 import asn1""" % (fn, time_str)
5454 eth_do_module (module, defined_dict)
5457 # Wireshark compiler
5460 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c conform_file] [-e] input_file(s) ...
5462 -b : BER (default is PER)
5463 -u : unaligned (default is aligned)
5464 -p proto : protocol name (implies -S)
5465 default is module-name from input_file (renamed by #.MODULE if present)
5466 -F : create 'field functions'
5467 -T : tagged type support (experimental)
5468 -o name : output files name core (default is <proto>)
5469 -O dir : output directory
5470 -c conform_file : conformation file
5471 -I path : path for conformance file includes
5472 -e : create conformation file for exported types
5473 -S : single output for multiple modules
5474 -s template : single file output (template is input file without .c/.h extension)
5475 -k : keep intermediate files though single file output is used
5476 -L : suppress #line directive from .cnf file
5477 input_file(s) : input ASN.1 file(s)
5479 -d dbg : debug output, dbg = [l][y][p][s][a][t][c][o]
5483 s - internal ASN.1 structure
5484 a - list of assignments
5486 c - conformance values
5487 o - list of output files
5493 print "ASN.1 to Wireshark dissector compiler";
5495 opts, args = getopt.getopt(sys.argv[1:], "h?d:buXp:FTo:O:c:I:eSs:kL");
5496 except getopt.GetoptError:
5497 eth_usage(); sys.exit(2)
5499 eth_usage(); sys.exit(2)
5504 ectx = EthCtx(conform, output)
5505 ectx.encoding = 'per'
5506 ectx.proto_opt = None
5508 ectx.tag_opt = False
5509 ectx.outnm_opt = None
5514 ectx.merge_modules = False
5515 ectx.conform.suppress_line = False;
5516 ectx.output.outnm = None
5517 ectx.output.single_file = None
5519 if o in ("-h", "-?"):
5520 eth_usage(); sys.exit(2)
5524 ectx.conform.include_path.append(a)
5526 warnings.warn("Command line option -X is obsolete and can be removed")
5529 ectx.conform.read(conf_to_read)
5532 if o in ("-h", "-?", "-c", "-I", "-X"):
5533 pass # already processed
5537 ectx.conform.set_opt(o, par, "commandline", 0)
5539 (ld, yd, pd) = (0, 0, 0);
5540 if ectx.dbg('l'): ld = 1
5541 if ectx.dbg('y'): yd = 1
5542 if ectx.dbg('p'): pd = 2
5543 lexer = lex.lex(debug=ld)
5544 yacc.yacc(method='LALR', debug=yd)
5549 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
5553 eth_do_module(module, ectx)
5554 if (not ectx.merge_modules): # output for each module
5556 ectx.eth_do_output()
5558 if (ectx.merge_modules): # common output for all module
5560 ectx.eth_do_output()
5563 ectx.conform.dbg_print()
5564 ectx.conform.unused_report()
5567 ectx.output.dbg_print()
5568 ectx.output.make_single_file()
5574 if len (sys.argv) == 1:
5576 s = raw_input ('Query: ')
5579 testfn (s, 'console', {})
5582 for fn in sys.argv [1:]:
5584 testfn (f.read (), fn, defined_dict)
5589 #--- BODY ---------------------------------------------------------------------
5591 if __name__ == '__main__':
5592 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
5597 #------------------------------------------------------------------------------