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('.', '_')
147 class LexError(Exception):
148 def __init__(self, tok, filename=None):
150 self.filename = filename
151 self.msg = "Unexpected character %r" % (self.tok.value[0])
152 Exception.__init__(self, self.msg)
154 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
158 class ParseError(Exception):
159 def __init__(self, tok, filename=None):
161 self.filename = filename
162 self.msg = "Unexpected token %r" % (self.tok.value)
163 Exception.__init__(self, self.msg)
165 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
168 # 11 ASN.1 lexical items
171 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
172 r'\.\.' : 'RANGE', # 11.17 Range separator
173 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
174 #r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
175 #r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
176 # 11.26 Single character lexical items
191 #r"'" : 'APOSTROPHE',
194 #r'\!' : 'EXCLAMATION',
195 r'\^' : 'CIRCUMFLEX',
199 # 11.27 Reserved words
201 # all keys in reserved_words must start w/ upper case
204 'BOOLEAN' : 'BOOLEAN',
205 'INTEGER' : 'INTEGER',
207 'CHARACTER' : 'CHARACTER',
211 'SEQUENCE': 'SEQUENCE',
214 'IMPLICIT': 'IMPLICIT',
217 'EXTERNAL' : 'EXTERNAL',
218 'OPTIONAL':'OPTIONAL',
219 'DEFAULT' : 'DEFAULT',
220 'COMPONENTS': 'COMPONENTS',
221 'UNIVERSAL' : 'UNIVERSAL',
222 'APPLICATION' : 'APPLICATION',
223 'PRIVATE' : 'PRIVATE',
228 'DEFINITIONS' : 'DEFINITIONS',
229 'EXPLICIT' : 'EXPLICIT',
230 'ENUMERATED' : 'ENUMERATED',
231 'EXPORTS' : 'EXPORTS',
232 'IMPORTS' : 'IMPORTS',
234 'INCLUDES': 'INCLUDES',
239 'INTERSECTION' : 'INTERSECTION',
241 'PATTERN' : 'PATTERN',
243 'COMPONENT': 'COMPONENT',
244 'PRESENT' : 'PRESENT',
246 # 'DEFINED' : 'DEFINED',
247 'CONSTRAINED' : 'CONSTRAINED',
249 'PLUS-INFINITY' : 'PLUS_INFINITY',
250 'MINUS-INFINITY' : 'MINUS_INFINITY',
251 'GeneralizedTime' : 'GeneralizedTime',
252 'UTCTime' : 'UTCTime',
253 'ObjectDescriptor': 'ObjectDescriptor',
254 'AUTOMATIC': 'AUTOMATIC',
256 'IDENTIFIER': 'IDENTIFIER',
257 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
258 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
259 # 'OPERATION' : 'OPERATION',
260 # 'ARGUMENT' : 'ARGUMENT',
261 # 'RESULT' : 'RESULT',
262 # 'ERRORS' : 'ERRORS',
263 # 'LINKED' : 'LINKED',
265 # 'PARAMETER' : 'PARAMETER',
267 # 'BIND-ERROR' : 'BIND_ERROR',
268 # 'UNBIND' : 'UNBIND',
269 # 'APPLICATION-CONTEXT' : 'AC',
270 # 'APPLICATON-SERVICE-ELEMENTS' : 'ASES',
271 # 'REMOTE' : 'REMOTE',
272 # 'INITIATOR' : 'INITIATOR',
273 # 'RESPONDER' : 'RESPONDER',
274 # 'APPLICATION-SERVICE-ELEMENT' : 'ASE',
275 # 'OPERATIONS' : None,
276 # 'EXTENSION-ATTRIBUTE' : 'EXTENSION_ATTRIBUTE',
277 # 'EXTENSIONS' : None,
279 # 'EXTENSION' : None,
282 # 'SUBMISSION' : None,
288 # r'ABSTRACT\s*OPERATIONS' : 'ABSTR_OPS',
294 for k in static_tokens.keys ():
295 if static_tokens [k] == None:
296 static_tokens [k] = k
298 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
299 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
302 for s in StringTypes:
303 reserved_words[s + 'String'] = s + 'String'
305 tokens = static_tokens.values() \
306 + reserved_words.values() \
307 + ['BSTRING', 'HSTRING', 'QSTRING',
308 'UCASE_IDENT', 'LCASE_IDENT', 'CLASS_IDENT',
312 for (k, v) in static_tokens.items ():
313 __main__.__dict__['t_' + v] = k
315 # 11.10 Binary strings
320 # 11.12 Hexadecimal strings
327 return t # XXX might want to un-""
329 def t_UCASE_IDENT (t):
330 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
331 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
332 t.type = reserved_words.get(t.value, t.type)
335 def t_LCASE_IDENT (t):
336 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
348 pyquote_str = 'PYQUOTE'
350 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
351 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
352 if t.value[2:2+len (pyquote_str)] == pyquote_str:
353 t.value = t.value[2+len(pyquote_str):]
354 t.value = t.value.lstrip ()
363 t.lexer.lineno += t.value.count("\n")
367 raise LexError(t, input_file)
371 def __init__ (self, defined_dict, indent = 0):
372 self.tags_def = 'EXPLICIT' # default = explicit
374 self.assignments = {}
375 self.dependencies = {}
377 self.defined_dict = defined_dict
380 return " " * (4 * self.indent_lev)
385 assert (self.indent_lev >= 0)
386 def register_assignment (self, ident, val, dependencies):
387 if self.assignments.has_key (ident):
388 raise "Duplicate assignment for " + ident
389 if self.defined_dict.has_key (ident):
390 raise "cross-module duplicates for " + ident
391 self.defined_dict [ident] = 1
392 self.assignments[ident] = val
393 self.dependencies [ident] = dependencies
395 # return "#%s depends on %s" % (ident, str (dependencies))
396 def register_pyquote (self, val):
397 self.pyquotes.append (val)
399 def output_assignments (self):
402 assign_keys = self.assignments.keys()
403 to_output_count = len (assign_keys)
406 for (ident, val) in self.assignments.iteritems ():
407 if already_output.has_key (ident):
410 for d in self.dependencies [ident]:
411 if (not already_output.has_key (d) and
415 text_list.append ("%s=%s" % (ident,
416 self.assignments [ident]))
417 already_output [ident] = 1
420 assert (to_output_count >= 0)
422 if to_output_count == 0:
424 # OK, we detected a cycle
426 for ident in self.assignments.iterkeys ():
427 if not already_output.has_key (ident):
428 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
429 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
431 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
432 for (ident, val) in self.assignments.iteritems ():
433 if not already_output.has_key (ident):
434 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
437 return "\n".join (text_list)
438 def output_pyquotes (self):
439 return "\n".join (self.pyquotes)
440 def make_new_name (self):
442 return "_compiler_generated_name_%d" % (self.name_ctr,)
444 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
456 #--- EthCtx -------------------------------------------------------------------
458 def __init__(self, conform, output, indent = 0):
459 self.conform = conform
462 def encp(self): # encoding protocol
467 def Per(self): return self.encoding == 'per'
468 def Ber(self): return self.encoding == 'ber'
469 def Aligned(self): return self.aligned
470 def Unaligned(self): return not self.aligned
471 def Fld(self): return self.fld_opt or self.Ber()
472 def Tag(self): return self.tag_opt # or self.Ber() - temporary comment out (experimental feature)
473 def NAPI(self): return False # disable planned features
475 def module(self): # current module name
476 return self.modules[-1][0]
479 if (self.dbgopt.find(d) >= 0):
484 def eth_get_type_attr(self, type):
486 while (not self.type[type]['import']
487 and self.type[type]['val'].type == 'Type_Ref'):
488 type = self.type[type]['val'].val
493 attr.update(self.type[t]['attr'])
494 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
497 #--- eth_reg_assign ---------------------------------------------------------
498 def eth_reg_assign(self, ident, val, virt=False):
499 #print "eth_reg_assign(ident='%s')" % (ident)
500 if self.assign.has_key(ident):
501 raise "Duplicate assignment for " + ident
502 self.assign[ident] = { 'val' : val , 'virt' : virt }
503 self.assign_ord.append(ident)
505 #--- eth_reg_vassign --------------------------------------------------------
506 def eth_reg_vassign(self, vassign):
507 ident = vassign.ident
508 #print "eth_reg_vassign(ident='%s')" % (ident)
509 if self.vassign.has_key(ident):
510 raise "Duplicate value assignment for " + ident
511 self.vassign[ident] = vassign
512 self.vassign_ord.append(ident)
514 #--- eth_import_type --------------------------------------------------------
515 def eth_import_type(self, ident, mod, proto):
516 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
517 if self.type.has_key(ident):
518 #print "already defined import=%s, module=%s" % (str(self.type[ident]['import']), self.type[ident]['module'])
519 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
520 return # OK - already defined
521 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
522 return # OK - already imported
524 raise "Duplicate type for " + ident
525 self.type[ident] = {'import' : mod, 'proto' : proto,
527 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
528 'STRINGS' : 'NULL', 'BITMASK' : '0' }
529 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
530 self.type_imp.append(ident)
532 #--- eth_import_value -------------------------------------------------------
533 def eth_import_value(self, ident, mod, proto):
534 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
535 if self.type.has_key(ident):
536 raise "Duplicate value for " + ident
537 self.value[ident] = {'import' : mod, 'proto' : proto,
539 self.value_imp.append(ident)
541 #--- eth_dep_add ------------------------------------------------------------
542 def eth_dep_add(self, type, dep):
543 if self.type_dep.has_key(type):
544 self.type_dep[type].append(dep)
546 self.type_dep[type] = [dep]
548 #--- eth_reg_type -----------------------------------------------------------
549 def eth_reg_type(self, ident, val):
550 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
551 if self.type.has_key(ident):
552 if self.type[ident]['import'] and (self.type[ident]['import'] == self.module()) :
553 # replace imported type
555 self.type_imp.remove(ident)
557 raise "Duplicate type for " + ident
558 self.type[ident] = { 'val' : val, 'import' : None }
559 self.type[ident]['module'] = self.module()
560 self.type[ident]['proto'] = self.proto
561 if len(ident.split('/')) > 1:
562 self.type[ident]['tname'] = val.eth_tname()
564 self.type[ident]['tname'] = asn2c(ident)
565 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
566 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
567 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
568 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
569 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
570 self.type[ident]['ethname'] = ''
571 if val.type == 'Type_Ref':
572 self.type[ident]['attr'] = {}
574 (ftype, display) = val.eth_ftype(self)
575 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
576 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
577 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
578 self.type_ord.append(ident)
580 #--- eth_reg_value ----------------------------------------------------------
581 def eth_reg_value(self, ident, type, value):
582 #print "eth_reg_value(ident='%s')" % (ident)
583 if self.value.has_key(ident):
584 raise "Duplicate value for " + ident
585 self.value[ident] = { 'import' : None, 'proto' : self.proto,
586 'type' : type, 'value' : value }
587 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
588 self.value[ident]['ethname'] = ''
589 self.value_ord.append(ident)
591 #--- eth_reg_field ----------------------------------------------------------
592 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
593 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
594 if self.field.has_key(ident):
595 raise "Duplicate field for " + ident
596 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
597 'modified' : '', 'attr' : {} }
598 name = ident.split('/')[-1]
599 if len(ident.split('/')) > 1 and name == '_item': # Sequnce/Set of type
600 self.field[ident]['attr']['NAME'] = '"Item"'
601 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
603 self.field[ident]['attr']['NAME'] = '"%s"' % name
604 self.field[ident]['attr']['ABBREV'] = asn2c(name)
605 if self.conform.check_item('FIELD_ATTR', ident):
606 self.field[ident]['modified'] = '#' + str(id(self))
607 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
609 self.pdu_ord.append(ident)
611 self.field_ord.append(ident)
612 if parent: self.eth_dep_add(parent, type)
614 #--- eth_clean --------------------------------------------------------------
616 self.proto = self.proto_opt;
617 #--- ASN.1 tables ----------------
628 self.vassign_ord = []
632 #--- Modules ------------
634 #--- types -------------------
636 self.eth_type_ord = []
637 self.eth_export_ord = []
638 self.eth_type_dupl = {}
640 #--- value dependencies -------------------
642 #--- values -------------------
644 self.eth_value_ord = []
645 #--- fields -------------------------
648 self.eth_hfpdu_ord = []
649 self.eth_hf_dupl = {}
650 #--- type dependencies -------------------
651 self.eth_type_ord1 = []
652 self.eth_dep_cycle = []
653 self.dep_cycle_eth_type = {}
654 #--- value dependencies and export -------------------
655 self.eth_value_ord1 = []
656 self.eth_vexport_ord = []
658 #--- eth_prepare ------------------------------------------------------------
659 def eth_prepare(self):
660 self.eproto = asn2c(self.proto)
662 #--- dummy types/fields for PDU registration ---
664 if (self.conform.check_item('PDU', nm)):
665 self.eth_reg_type('_dummy/'+nm, NullType())
666 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
668 #--- types -------------------
669 for t in self.type_imp:
671 self.eth_type[nm] = { 'import' : self.type[t]['import'],
672 'proto' : asn2c(self.type[t]['proto']),
673 'attr' : {}, 'ref' : []}
674 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
675 self.type[t]['ethname'] = nm
676 for t in self.type_ord:
677 nm = self.type[t]['tname']
678 if ((nm.find('#') >= 0) or
679 ((len(t.split('/'))>1) and
680 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t)) and
681 not self.conform.check_item('TYPE_RENAME', t))):
682 if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequnce of type at the 1st level
683 nm = t.split('/')[0] + t.split('/')[1]
684 elif t.split('/')[-1] == '_item': # Sequnce/Set of type at next levels
685 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
686 elif t.split('/')[-1] == '_untag': # Untagged type
687 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
689 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
691 if self.eth_type.has_key(nm):
692 if self.eth_type_dupl.has_key(nm):
693 self.eth_type_dupl[nm].append(t)
695 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
696 nm += str(len(self.eth_type_dupl[nm])-1)
697 if self.eth_type.has_key(nm):
698 self.eth_type[nm]['ref'].append(t)
700 self.eth_type_ord.append(nm)
701 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
702 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
703 'val' : self.type[t]['val'],
706 self.type[t]['ethname'] = nm
707 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
708 self.eth_export_ord.append(nm)
709 self.eth_type[nm]['export'] |= self.type[t]['export']
710 self.eth_type[nm]['enum'] |= self.type[t]['enum']
711 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
712 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
713 if self.type[t]['attr'].get('STRINGS') == '$$':
714 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
715 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
716 for t in self.eth_type_ord:
717 bits = self.eth_type[t]['val'].eth_named_bits()
719 for (val, id) in bits:
720 self.named_bit.append({'name' : id, 'val' : val,
721 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
722 'ftype' : 'FT_BOOLEAN', 'display' : '8',
724 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
725 if self.eth_type[t]['val'].eth_need_tree():
726 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
728 self.eth_type[t]['tree'] = None
730 #--- value dependencies -------------------
731 for v in self.value_ord:
732 if isinstance (self.value[v]['value'], Value):
733 dep = self.value[v]['value'].get_dep()
735 dep = self.value[v]['value']
736 if dep and self.value.has_key(dep):
737 self.value_dep.setdefault(v, []).append(dep)
739 #--- exports all necessary values
740 for v in self.value_ord:
741 if not self.value[v]['export']: continue
742 deparr = self.value_dep.get(v, [])
745 if not self.value[d]['import']:
746 if not self.value[d]['export']:
747 self.value[d]['export'] = EF_TYPE
748 deparr.extend(self.value_dep.get(d, []))
750 #--- values -------------------
751 for v in self.value_imp:
753 self.eth_value[nm] = { 'import' : self.value[v]['import'],
754 'proto' : asn2c(self.value[v]['proto']),
756 self.value[v]['ethname'] = nm
757 for v in self.value_ord:
759 self.eth_value[nm] = { 'import' : None,
760 'proto' : asn2c(self.value[v]['proto']),
761 'export' : self.value[v]['export'], 'ref' : [v] }
762 if isinstance (self.value[v]['value'], Value):
763 self.eth_value[nm]['value'] = self.value[v]['value'].to_str()
765 self.eth_value[nm]['value'] = self.value[v]['value']
766 self.eth_value_ord.append(nm)
767 self.value[v]['ethname'] = nm
769 #--- fields -------------------------
770 for f in (self.pdu_ord + self.field_ord):
771 if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequnce/Set of type
772 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
774 nm = f.split('/')[-1]
775 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
777 if (self.field[f]['pdu']):
779 t = self.field[f]['type']
780 if self.type.has_key(t):
781 ethtype = self.type[t]['ethname']
782 else: # undefined type
784 print "Dummy imported: ", t
785 self.type[t] = {'import' : 'xxx', 'proto' : 'xxx',
787 self.type[t]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
788 'STRINGS' : 'NULL', 'BITMASK' : '0' }
789 self.eth_type[t] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
791 ethtypemod = ethtype + self.field[f]['modified']
792 if self.eth_hf.has_key(nm):
793 if self.eth_hf_dupl.has_key(nm):
794 if self.eth_hf_dupl[nm].has_key(ethtypemod):
795 nm = self.eth_hf_dupl[nm][ethtypemod]
796 self.eth_hf[nm]['ref'].append(f)
797 self.field[f]['ethname'] = nm
800 nmx = nm + str(len(self.eth_hf_dupl[nm]))
801 self.eth_hf_dupl[nm][ethtype] = nmx
804 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
805 self.eth_hf[nm]['ref'].append(f)
806 self.field[f]['ethname'] = nm
809 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
812 if (self.field[f]['pdu']):
813 self.eth_hfpdu_ord.append(nm)
815 self.eth_hf_ord.append(nm)
816 fullname = "hf_%s_%s" % (self.eproto, nm)
817 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
818 attr.update(self.field[f]['attr'])
819 if (self.NAPI() and attr.has_key('NAME')):
820 attr['NAME'] += self.field[f]['idx']
821 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
822 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
823 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
824 'attr' : attr.copy(), 'ref' : [f]}
825 self.field[f]['ethname'] = nm
826 #--- type dependencies -------------------
827 x = {} # already emitted
828 #print '# Dependency computation'
829 for t in self.type_ord:
830 if x.has_key(self.type[t]['ethname']):
831 #print 'Continue: %s : %s' % (t, self.type[t]['ethname'])
834 stackx = {t : self.type_dep.get(t, [])[:]}
835 #print 'Push: %s : %s' % (t, str(stackx[t]))
837 if stackx[stack[-1]]: # has dependencies
838 d = stackx[stack[-1]].pop(0)
839 if x.has_key(self.type[d]['ethname']) or self.type[d]['import']:
841 if stackx.has_key(d): # cyclic dependency
844 c = [d] + c[0:c.index(d)+1]
846 self.eth_dep_cycle.append(c)
847 #print 'Cyclic: %s ' % (' -> '.join(c))
850 stackx[d] = self.type_dep.get(d, [])[:]
851 #print 'Push: %s : %s' % (d, str(stackx[d]))
853 #print 'Pop: %s' % (stack[-1])
854 del stackx[stack[-1]]
855 e = self.type[stack.pop()]['ethname']
858 #print 'Add: %s' % (e)
859 self.eth_type_ord1.append(e)
862 while i < len(self.eth_dep_cycle):
863 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
864 self.dep_cycle_eth_type.setdefault(t, []).append(i)
867 #--- value dependencies and export -------------------
868 for v in self.eth_value_ord:
869 if self.eth_value[v]['export']:
870 self.eth_vexport_ord.append(v)
872 self.eth_value_ord1.append(v)
874 #--- eth_vals_nm ------------------------------------------------------------
875 def eth_vals_nm(self, tname):
877 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
878 out += "%s_" % (self.eproto)
879 out += "%s_vals" % (tname)
882 #--- eth_vals ---------------------------------------------------------------
883 def eth_vals(self, tname, vals):
885 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
886 if (not self.eth_type[tname]['export'] & EF_VALS):
888 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
890 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
891 for (val, id) in vals:
893 vval = self.eth_enum_item(tname, id)
896 out += ' { %3s, "%s" },\n' % (vval, id)
897 out += " { 0, NULL }\n};\n"
900 #--- eth_enum_prefix ------------------------------------------------------------
901 def eth_enum_prefix(self, tname):
903 if (self.eth_type[tname]['export'] & EF_ENUM):
904 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
906 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
909 if (not self.eth_type[tname]['enum'] & EF_NO_TYPE):
912 if (self.eth_type[tname]['enum'] & EF_UCASE):
916 #--- eth_enum_nm ------------------------------------------------------------
917 def eth_enum_nm(self, tname):
918 out = self.eth_enum_prefix(tname)
922 #--- eth_enum_item ---------------------------------------------------------------
923 def eth_enum_item(self, tname, ident):
924 out = self.eth_enum_prefix(tname)
925 out += '_' + asn2c(ident)
926 if (self.eth_type[tname]['enum'] & EF_UCASE):
930 #--- eth_enum ---------------------------------------------------------------
931 def eth_enum(self, tname, vals):
933 if (self.eth_type[tname]['enum'] & EF_DEFINE):
934 out += "/* enumerated values for %s */\n" % (tname)
935 for (val, id) in vals:
936 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
938 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
939 for (val, id) in vals:
940 out += ' %-12s %3s,\n' % (self.eth_enum_item(tname, id), val)
941 out += "} %s;\n" % (self.eth_enum_nm(tname))
944 #--- eth_bits ---------------------------------------------------------------
945 def eth_bits(self, tname, bits):
947 out += "static const "
948 out += "asn_namedbit %(TABLE)s[] = {\n"
949 for (val, id) in bits:
950 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
951 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
954 #--- eth_type_fn_h ----------------------------------------------------------
955 def eth_type_fn_h(self, tname):
957 if (not self.eth_type[tname]['export'] & EF_TYPE):
961 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)
963 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)
967 #--- eth_fn_call ------------------------------------------------------------
968 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
971 if (ret == 'return'):
977 for i in range(len(par)):
978 if (i>0): out += ind * ' '
979 out += ', '.join(par[i])
980 if (i<(len(par)-1)): out += ',\n'
984 #--- eth_type_fn_hdr --------------------------------------------------------
985 def eth_type_fn_hdr(self, tname):
987 if (not self.eth_type[tname]['export'] & EF_TYPE):
991 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)
993 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)
994 if self.conform.get_fn_presence(tname):
995 out += self.conform.get_fn_text(tname, 'FN_HDR')
996 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
997 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1000 #--- eth_type_fn_ftr --------------------------------------------------------
1001 def eth_type_fn_ftr(self, tname):
1003 if self.conform.get_fn_presence(tname):
1004 out += self.conform.get_fn_text(tname, 'FN_FTR')
1005 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1006 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1007 out += " return offset;\n"
1011 #--- eth_type_fn_body -------------------------------------------------------
1012 def eth_type_fn_body(self, tname, body, pars=None):
1014 if self.conform.get_fn_body_presence(tname):
1015 out = self.conform.get_fn_text(tname, 'FN_BODY')
1016 elif self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1017 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1025 #--- eth_output_hf ----------------------------------------------------------
1026 def eth_output_hf (self):
1027 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1028 fx = self.output.file_open('hf')
1029 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1030 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1031 if (self.named_bit):
1032 fx.write('/* named bits */\n')
1033 for nb in self.named_bit:
1034 fx.write("static int %s = -1;\n" % (nb['ethname']))
1035 self.output.file_close(fx)
1037 #--- eth_output_hf_arr ------------------------------------------------------
1038 def eth_output_hf_arr (self):
1039 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1040 fx = self.output.file_open('hfarr')
1041 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1042 t = self.eth_hf[f]['ethtype']
1043 blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
1044 attr = self.eth_hf[f]['attr'].copy()
1045 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1046 if not attr.has_key('BLURB'):
1047 attr['BLURB'] = blurb
1048 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1049 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1050 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1051 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1052 for nb in self.named_bit:
1054 fx.write(' { &%s,\n' % (nb['ethname']))
1055 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1056 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1057 fx.write(' "%s", HFILL }},\n' % (blurb))
1058 self.output.file_close(fx)
1060 #--- eth_output_ett ---------------------------------------------------------
1061 def eth_output_ett (self):
1062 fx = self.output.file_open('ett')
1064 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1065 for t in self.eth_type_ord:
1066 if self.eth_type[t]['tree']:
1067 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1069 self.output.file_close(fx, discard=fempty)
1071 #--- eth_output_ett_arr -----------------------------------------------------
1072 def eth_output_ett_arr(self):
1073 fx = self.output.file_open('ettarr')
1075 #fx.write(" &ett_%s,\n" % (self.eproto))
1076 for t in self.eth_type_ord:
1077 if self.eth_type[t]['tree']:
1078 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1080 self.output.file_close(fx, discard=fempty)
1082 #--- eth_output_export ------------------------------------------------------
1083 def eth_output_export(self):
1084 if (not len(self.eth_export_ord)): return
1085 fx = self.output.file_open('exp', ext='h')
1086 for t in self.eth_export_ord: # vals
1087 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1088 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1089 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1090 if not self.eth_type[t]['export'] & EF_TABLE:
1091 if self.eth_type[t]['export'] & EF_WS_VAR:
1092 fx.write("WS_VAR_IMPORT ")
1095 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1097 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1098 for t in self.eth_export_ord: # functions
1099 if (self.eth_type[t]['export'] & EF_TYPE):
1100 if self.eth_type[t]['export'] & EF_EXTERN:
1102 fx.write(self.eth_type_fn_h(t))
1103 self.output.file_close(fx)
1105 #--- eth_output_expcnf ------------------------------------------------------
1106 def eth_output_expcnf(self):
1107 fx = self.output.file_open('exp', ext='cnf')
1108 fx.write('#.MODULE\n')
1110 for (m, p) in self.modules:
1111 if (len(m) > maxw): maxw = len(m)
1112 for (m, p) in self.modules:
1113 fx.write("%-*s %s\n" % (maxw, m, p))
1114 fx.write('#.END\n\n')
1116 fx.write('#.IMPORT_TAG\n')
1117 for t in self.eth_export_ord: # tags
1118 if (self.eth_type[t]['export'] & EF_TYPE):
1119 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1120 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1121 fx.write('#.END\n\n')
1122 fx.write('#.TYPE_ATTR\n')
1123 for t in self.eth_export_ord: # attributes
1124 if (self.eth_type[t]['export'] & EF_TYPE):
1125 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1126 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1127 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1128 fx.write('#.END\n\n')
1129 self.output.file_close(fx, keep_anyway=True)
1131 #--- eth_output_val ------------------------------------------------------
1132 def eth_output_val(self):
1133 if (not len(self.eth_value_ord1)): return
1134 fx = self.output.file_open('val', ext='h')
1135 for v in self.eth_value_ord1:
1136 fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
1137 self.output.file_close(fx)
1139 #--- eth_output_valexp ------------------------------------------------------
1140 def eth_output_valexp(self):
1141 if (not len(self.eth_vexport_ord)): return
1142 fx = self.output.file_open('valexp', ext='h')
1143 for v in self.eth_vexport_ord:
1144 fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
1145 self.output.file_close(fx)
1147 #--- eth_output_types -------------------------------------------------------
1148 def eth_output_types(self):
1150 t = self.eth_hf[f]['ethtype']
1153 for r in self.eth_hf[f]['ref']:
1154 x[self.field[r]['impl']] = self.field[r]['impl']
1168 if (i): postfix = '_impl'; impl = 'TRUE'
1169 else: postfix = ''; impl = 'FALSE'
1170 out += 'static int dissect_'+f+postfix+'(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) {\n'
1171 par=((impl, 'tvb', 'offset', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
1173 out += 'static int dissect_'+f+'(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_) {\n'
1174 par=(('tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
1175 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret='return',
1181 t = self.eth_hf[f]['ethtype']
1182 is_new = self.eth_hf[f]['pdu']['new']
1189 out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1191 if (self.Aligned()):
1195 out += " asn1_ctx_t asn1_ctx;\n"
1196 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1198 par=((impl, 'tvb', '0', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
1200 par=(('tvb', '0', '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1204 if (is_new): ret = 'return'
1205 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret, par=par)
1209 fx = self.output.file_open('fn')
1211 if self.eth_dep_cycle:
1212 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1214 while i < len(self.eth_dep_cycle):
1215 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1216 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1217 fx.write(''.join(map(lambda i: '/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]), self.dep_cycle_eth_type[t])))
1218 fx.write(self.eth_type_fn_h(t))
1221 for f in self.eth_hf_ord:
1222 if (self.eth_hf[f]['ethtype'] == t):
1223 fx.write(out_field(f))
1227 if (self.Fld()): # fields for imported types
1228 fx.write('/*--- Fields for imported types ---*/\n\n')
1229 for f in self.eth_hf_ord:
1230 if (self.eth_type[self.eth_hf[f]['ethtype']]['import']):
1231 fx.write(out_field(f))
1233 for t in self.eth_type_ord1:
1234 if self.eth_type[t]['import']:
1236 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1237 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1238 if self.eth_type[t]['val'].eth_has_vals():
1239 if self.eth_type[t]['no_emit'] & EF_VALS:
1241 elif self.eth_type[t]['user_def'] & EF_VALS:
1242 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1243 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1246 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1247 if self.eth_type[t]['no_emit'] & EF_TYPE:
1249 elif self.eth_type[t]['user_def'] & EF_TYPE:
1250 fx.write(self.eth_type_fn_h(t))
1252 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1253 if (self.Fld() and not self.dep_cycle_eth_type.has_key(t)):
1254 for f in self.eth_hf_ord:
1255 if (self.eth_hf[f]['ethtype'] == t):
1256 fx.write(out_field(f))
1258 if (len(self.eth_hfpdu_ord)):
1259 fx.write('/*--- PDUs ---*/\n\n')
1260 for f in self.eth_hfpdu_ord:
1261 if (self.eth_hf[f]['pdu']):
1262 fx.write(out_pdu(f))
1264 fempty = pos == fx.tell()
1265 self.output.file_close(fx, discard=fempty)
1267 #--- eth_output_dis_hnd -----------------------------------------------------
1268 def eth_output_dis_hnd(self):
1269 fx = self.output.file_open('dis-hnd')
1271 for f in self.eth_hfpdu_ord:
1272 pdu = self.eth_hf[f]['pdu']
1273 if (pdu and pdu['reg'] and not pdu['hidden']):
1275 if (pdu['reg'] != '.'):
1276 dis += '.' + pdu['reg']
1277 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1280 self.output.file_close(fx, discard=fempty)
1282 #--- eth_output_dis_reg -----------------------------------------------------
1283 def eth_output_dis_reg(self):
1284 fx = self.output.file_open('dis-reg')
1286 for f in self.eth_hfpdu_ord:
1287 pdu = self.eth_hf[f]['pdu']
1288 if (pdu and pdu['reg']):
1290 if (pdu['new']): new_prefix = 'new_'
1292 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1293 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1294 if (not pdu['hidden']):
1295 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1298 self.output.file_close(fx, discard=fempty)
1300 #--- eth_output_dis_tab -----------------------------------------------------
1301 def eth_output_dis_tab(self):
1302 fx = self.output.file_open('dis-tab')
1304 for k in self.conform.get_order('REGISTER'):
1305 reg = self.conform.use_item('REGISTER', k)
1306 if not self.field.has_key(reg['pdu']): continue
1307 f = self.field[reg['pdu']]['ethname']
1308 pdu = self.eth_hf[f]['pdu']
1310 if (pdu['new']): new_prefix = 'new_'
1311 if (reg['rtype'] in ('NUM', 'STR')):
1313 if (reg['rtype'] == 'STR'): rstr = '_string'
1316 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1317 if (not pdu['hidden']):
1318 hnd = '%s_handle' % (asn2c(dis))
1320 hnd = 'find_dissector("%s")' % (dis)
1322 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1323 fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], reg['rport'], hnd))
1324 elif (reg['rtype'] in ('BER', 'PER')):
1325 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']))
1328 self.output.file_close(fx, discard=fempty)
1330 #--- dupl_report -----------------------------------------------------
1331 def dupl_report(self):
1333 tmplist = self.eth_type_dupl.keys()
1336 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1339 for tt in self.eth_type_dupl[t]:
1340 msg += " %-20s %s\n" % (t+str(x), tt)
1343 warnings.warn_explicit(msg, UserWarning, '', '')
1345 tmplist = self.eth_hf_dupl.keys()
1348 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
1350 for tt in self.eth_hf_dupl[f].keys():
1351 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
1352 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
1354 warnings.warn_explicit(msg, UserWarning, '', '')
1356 #--- eth_do_output ------------------------------------------------------------
1357 def eth_do_output(self):
1359 print "\n# Assignments"
1360 for a in self.assign_ord:
1362 if (self.assign[a]['virt']): v = '*'
1364 print "\n# Value assignments"
1365 print "\n".join(self.vassign_ord)
1367 print "\n# Imported Types"
1368 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1370 for t in self.type_imp:
1371 print "%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])
1372 print "\n# Imported Values"
1373 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1375 for t in self.value_imp:
1376 print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
1377 print "\n# Exported Types"
1378 print "%-31s %s" % ("Wireshark type", "Export Flag")
1380 for t in self.eth_export_ord:
1381 print "%-31s 0x%02X" % (t, self.eth_type[t]['export'])
1382 print "\n# Exported Values"
1383 print "%-40s %s" % ("Wireshark name", "Value")
1385 for v in self.eth_vexport_ord:
1386 print "%-40s %s" % (v, self.eth_value[v]['value'])
1387 print "\n# ASN.1 Types"
1388 print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
1390 for t in self.type_ord:
1391 print "%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])
1392 print "\n# Wireshark Types"
1393 print "Wireshark type References (ASN.1 types)"
1395 for t in self.eth_type_ord:
1396 print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
1397 print ', '.join(self.eth_type[t]['ref'])
1398 print "\n# ASN.1 Values"
1399 print "%-40s %-18s %s" % ("ASN.1 unique name", "Type", "Value")
1401 for v in self.value_ord:
1402 if isinstance (self.value[v]['value'], Value):
1403 print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'].to_str())
1405 print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'])
1406 print "\n# Wireshark Values"
1407 print "%-40s %s" % ("Wireshark name", "Value")
1409 for v in self.eth_value_ord:
1410 print "%-40s %s" % (v, self.eth_value[v]['value'])
1411 print "\n# ASN.1 Fields"
1412 print "ASN.1 unique name Wireshark name ASN.1 type"
1414 for f in (self.pdu_ord + self.field_ord):
1415 print "%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])
1416 print "\n# Wireshark Fields"
1417 print "Wireshark name Wireshark type References (ASN.1 fields)"
1419 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1420 print "%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])),
1421 print ', '.join(self.eth_hf[f]['ref'])
1422 #print "\n# Order after dependencies"
1423 #print '\n'.join(self.eth_type_ord1)
1424 print "\n# Cyclic dependencies"
1425 for c in self.eth_dep_cycle:
1426 print ' -> '.join(c)
1428 self.output.outnm = self.outnm_opt
1429 if (not self.output.outnm):
1430 self.output.outnm = self.proto
1431 self.eth_output_hf()
1432 self.eth_output_ett()
1433 self.eth_output_types()
1434 self.eth_output_hf_arr()
1435 self.eth_output_ett_arr()
1436 self.eth_output_export()
1438 self.eth_output_expcnf()
1439 self.eth_output_val()
1440 self.eth_output_valexp()
1441 self.eth_output_dis_hnd()
1442 self.eth_output_dis_reg()
1443 self.eth_output_dis_tab()
1445 #--- EthCnf -------------------------------------------------------------------
1452 self.suppress_line = False
1453 self.include_path = []
1454 # Value name Default value Duplicity check Usage check
1455 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1456 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1457 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1458 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1459 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1460 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1461 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
1462 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
1463 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1464 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1465 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1466 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1467 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
1468 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1469 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1470 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1471 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1472 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1475 for k in self.tblcfg.keys() :
1479 def add_item(self, table, key, fn, lineno, **kw):
1480 if self.tblcfg[table]['chk_dup'] and self.table[table].has_key(key):
1481 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
1482 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
1483 UserWarning, fn, lineno)
1485 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
1486 self.table[table][key].update(kw)
1487 self.order[table].append(key)
1489 def get_order(self, table):
1490 return self.order[table]
1492 def check_item(self, table, key):
1493 return self.table[table].has_key(key)
1495 def check_item_value(self, table, key, **kw):
1496 return self.table[table].has_key(key) and self.table[table][key].has_key(kw.get('val_nm', self.tblcfg[table]['val_nm']))
1498 def use_item(self, table, key, **kw):
1499 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
1500 if not self.table[table].has_key(key): return vdflt
1501 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
1502 #print "use_item() - set used for %s %s" % (table, key)
1503 self.table[table][key]['used'] = True
1504 return self.table[table][key].get(vname, vdflt)
1506 def add_fn_line(self, name, ctx, line, fn, lineno):
1507 if not self.fn.has_key(name):
1508 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
1509 if (self.fn[name][ctx]):
1510 self.fn[name][ctx]['text'] += line
1512 self.fn[name][ctx] = {'text' : line, 'used' : False,
1513 'fn' : fn, 'lineno' : lineno}
1514 def get_fn_presence(self, name):
1515 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
1516 #if self.fn.has_key(name): print self.fn[name]
1517 return self.fn.has_key(name)
1518 def get_fn_body_presence(self, name):
1519 return self.fn.has_key(name) and self.fn[name]['FN_BODY']
1520 def get_fn_text(self, name, ctx):
1521 if (not self.fn.has_key(name)):
1523 if (not self.fn[name][ctx]):
1525 self.fn[name][ctx]['used'] = True
1526 out = self.fn[name][ctx]['text']
1527 if (not self.suppress_line):
1528 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], self.fn[name][ctx]['fn'], out);
1531 def add_pdu(self, par, is_new, fn, lineno):
1532 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
1533 (reg, hidden) = (None, False)
1534 if (len(par) > 1): reg = par[1]
1535 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
1536 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden}
1537 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
1540 def add_register(self, pdu, par, fn, lineno):
1541 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
1542 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
1543 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
1544 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
1545 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
1546 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
1547 if ((len(par)-1) < pmin):
1548 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
1550 if ((len(par)-1) > pmax):
1551 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
1552 attr = {'pdu' : pdu, 'rtype' : rtype}
1553 if (rtype in ('NUM', 'STR')):
1554 attr['rtable'] = par[1]
1555 attr['rport'] = par[2]
1556 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
1557 elif (rtype in ('BER', 'PER')):
1558 attr['roid'] = par[1]
1559 attr['roidname'] = '""'
1560 if (len(par)>=3): attr['roidname'] = par[2]
1561 rkey = '/'.join([rtype, attr['roid']])
1562 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
1565 def get_par(line, pmin, pmax, fn, lineno):
1566 par = line.split(None, pmax)
1567 for i in range(len(par)):
1571 if par[i][0] == '#':
1575 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1577 if (pmax >= 0) and (len(par) > pmax):
1578 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
1582 def get_par_nm(line, pmin, pmax, fn, lineno):
1584 par = line.split(None, pmax)
1587 for i in range(len(par)):
1588 if par[i][0] == '#':
1592 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1599 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
1600 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
1601 nmpar_end = re.compile(r'\s*$')
1602 result = nmpar_first.search(nmpar)
1605 k = result.group('attr')
1607 result = nmpar_next.search(nmpar, pos)
1612 p2 = nmpar_end.search(nmpar, pos).start()
1620 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_]+)\s+')
1621 comment = re.compile(r'^\s*#[^.]')
1622 empty = re.compile(r'^\s*$')
1626 default_flags = 0x00
1635 fn, f, lineno = frec['fn'], frec['f'], frec['lineno']
1639 if comment.search(line): continue
1640 result = directive.search(line)
1641 if result: # directive
1642 if result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
1643 'MODULE', 'MODULE_IMPORT',
1644 'OMIT_ASSIGNMENT', 'VIRTUAL_ASSGN', 'SET_TYPE',
1645 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
1646 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
1647 ctx = result.group('name')
1648 elif result.group('name') in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
1649 ctx = result.group('name')
1650 default_flags = EF_TYPE|EF_VALS
1651 if ctx == 'EXPORTS':
1652 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
1654 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
1655 if not par: continue
1657 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
1658 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
1659 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
1660 elif (ctx == 'EXPORTS'): p = 0
1661 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
1662 for i in range(p, len(par)):
1663 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
1664 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
1665 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
1666 elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
1667 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
1668 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
1669 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1670 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
1671 ctx = result.group('name')
1672 default_flags = EF_ENUM
1673 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT
1674 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE
1675 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
1676 for i in range(0, len(par)):
1677 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
1678 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
1679 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
1680 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
1681 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1682 elif result.group('name') in ('FN_HDR', 'FN_FTR'):
1683 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1684 if not par: continue
1685 ctx = result.group('name')
1687 elif result.group('name') == 'FN_BODY':
1688 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1689 if not par: continue
1690 ctx = result.group('name')
1693 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
1694 elif result.group('name') == 'FN_PARS':
1695 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
1696 ctx = result.group('name')
1702 self.add_item(ctx, name, pars=par[1], fn=fn, lineno=lineno)
1705 elif result.group('name') == 'CLASS':
1706 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1707 if not par: continue
1708 ctx = result.group('name')
1710 add_class_ident(name)
1711 if not name.isupper():
1712 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
1713 UserWarning, fn, lineno)
1714 elif result.group('name') == 'INCLUDE':
1715 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1717 warnings.warn_explicit("INCLUDE requires parameter", UserWarning, fn, lineno)
1720 #print "Try include: %s" % (fname)
1721 if (not os.path.exists(fname)):
1722 fname = os.path.join(os.path.split(fn)[0], par[0])
1723 #print "Try include: %s" % (fname)
1725 while not os.path.exists(fname) and (i < len(self.include_path)):
1726 fname = os.path.join(self.include_path[i], par[0])
1727 #print "Try include: %s" % (fname)
1729 if (not os.path.exists(fname)):
1731 fnew = open(fname, "r")
1732 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno})
1733 fn, f, lineno = par[0], fnew, 0
1734 elif result.group('name') == 'END':
1737 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
1740 if not empty.match(line):
1741 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
1742 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
1743 if empty.match(line): continue
1744 if ctx == 'EXPORTS':
1745 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
1747 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
1748 if not par: continue
1749 flags = default_flags
1752 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
1753 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
1754 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
1755 elif (ctx == 'EXPORTS'): p = 1
1756 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
1757 for i in range(p, len(par)):
1758 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
1759 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
1760 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
1761 elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
1762 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
1763 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
1764 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1765 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
1766 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
1767 if empty.match(line): continue
1768 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
1769 if not par: continue
1770 flags = default_flags
1771 for i in range(1, len(par)):
1772 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
1773 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
1774 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
1775 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
1776 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1777 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
1778 elif ctx in ('PDU', 'PDU_NEW'):
1779 if empty.match(line): continue
1780 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
1781 if not par: continue
1783 if (ctx == 'PDU_NEW'): is_new = True
1784 self.add_pdu(par[0:2], is_new, fn, lineno)
1786 self.add_register(par[0], par[2:5], fn, lineno)
1787 elif ctx in ('REGISTER', 'REGISTER_NEW'):
1788 if empty.match(line): continue
1789 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
1790 if not par: continue
1791 if not self.check_item('PDU', par[0]):
1793 if (ctx == 'REGISTER_NEW'): is_new = True
1794 self.add_pdu(par[0:1], is_new, fn, lineno)
1795 self.add_register(par[0], par[1:4], fn, lineno)
1796 elif ctx in ('MODULE', 'MODULE_IMPORT'):
1797 if empty.match(line): continue
1798 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1799 if not par: continue
1800 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
1801 elif ctx == 'IMPORT_TAG':
1802 if empty.match(line): continue
1803 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
1804 if not par: continue
1805 self.add_item('IMPORT_TAG', par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
1806 elif ctx == 'OMIT_ASSIGNMENT':
1807 if empty.match(line): continue
1808 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
1809 if not par: continue
1810 self.add_item('OMIT_ASSIGNMENT', par[0], omit=True, fn=fn, lineno=lineno)
1811 elif ctx == 'VIRTUAL_ASSGN':
1812 if empty.match(line): continue
1813 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1814 if not par: continue
1815 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
1816 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
1817 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
1819 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
1820 if not par[0][0].isupper():
1821 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
1822 UserWarning, fn, lineno)
1823 elif ctx == 'SET_TYPE':
1824 if empty.match(line): continue
1825 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1826 if not par: continue
1827 if not self.check_item('VIRTUAL_ASSGN', par[0]):
1828 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
1829 if not par[1][0].isupper():
1830 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
1831 UserWarning, fn, lineno)
1832 elif ctx == 'TYPE_RENAME':
1833 if empty.match(line): continue
1834 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1835 if not par: continue
1836 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
1837 if not par[1][0].isupper():
1838 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
1839 UserWarning, fn, lineno)
1840 elif ctx == 'FIELD_RENAME':
1841 if empty.match(line): continue
1842 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1843 if not par: continue
1844 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
1845 if not par[1][0].islower():
1846 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
1847 UserWarning, fn, lineno)
1848 elif ctx == 'TF_RENAME':
1849 if empty.match(line): continue
1850 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1851 if not par: continue
1852 tmpu = par[1][0].upper() + par[1][1:]
1853 tmpl = par[1][0].lower() + par[1][1:]
1854 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
1855 if not tmpu[0].isupper():
1856 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
1857 UserWarning, fn, lineno)
1858 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
1859 if not tmpl[0].islower():
1860 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
1861 UserWarning, fn, lineno)
1862 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
1863 if empty.match(line): continue
1864 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
1865 if not par: continue
1866 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
1867 elif ctx == 'FN_PARS':
1868 if empty.match(line): continue
1870 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
1872 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
1873 if not par: continue
1875 self.add_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
1877 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
1878 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
1879 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
1880 elif ctx == 'CLASS':
1881 if empty.match(line): continue
1882 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
1883 if not par: continue
1884 if (len(par) < 2): par.append('OpenType')
1885 if (len(par) < 3): par.append(None)
1886 if not set_type_to_class(name, par[0], par[1], par[2]):
1887 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
1888 UserWarning, fn, lineno)
1890 def dbg_print(self):
1891 print "\n# Conformance values"
1892 print "%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")
1894 tbls = self.table.keys()
1897 keys = self.table[t].keys()
1900 print "%-15s %4s %-15s %-20s %s" % (
1901 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))
1903 def unused_report(self):
1904 tbls = self.table.keys()
1907 if not self.tblcfg[t]['chk_use']: continue
1908 keys = self.table[t].keys()
1911 if not self.table[t][k]['used']:
1912 warnings.warn_explicit("Unused %s for %s" % (t, k),
1913 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
1914 fnms = self.fn.keys()
1917 keys = self.fn[f].keys()
1920 if not self.fn[f][k]: continue
1921 if not self.fn[f][k]['used']:
1922 warnings.warn_explicit("Unused %s for %s" % (k, f),
1923 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
1925 #--- EthOut -------------------------------------------------------------------
1930 self.single_file = None
1931 self.created_files = []
1932 self.unique_created_files = []
1934 #--- output_fname -------------------------------------------------------
1935 def output_fname(self, ftype, ext='c'):
1937 if not ext in ('cnf',):
1944 #--- output_fullname -------------------------------------------------------
1945 def output_fullname(self, ftype, ext='c'):
1946 return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
1947 #--- file_open -------------------------------------------------------
1948 def file_open(self, ftype, ext='c'):
1949 fn = self.output_fullname(ftype, ext=ext)
1952 fx.write(self.fhdr(fn, comment = '#'))
1954 if (not self.single_file):
1955 fx.write(self.fhdr(fn))
1957 #--- file_close -------------------------------------------------------
1958 def file_close(self, fx, discard=False, keep_anyway=False):
1962 elif (not keep_anyway):
1963 self.created_files.append(os.path.normcase(os.path.abspath(fx.name)))
1964 #--- fhdr -------------------------------------------------------
1965 def fhdr(self, fn, comment=None):
1968 return '# %s\n' % (ln)
1970 return '/* %-74s */\n' % (ln)
1972 out += outln('Do not modify this file.')
1973 out += outln('It is created automatically by the ASN.1 to Wireshark dissector compiler')
1975 out += outln(' '.join(sys.argv))
1979 #--- dbg_print -------------------------------------------------------
1980 def dbg_print(self):
1981 print "\n# Output files"
1982 print "\n".join(self.created_files)
1985 #--- make_single_file -------------------------------------------------------
1986 def make_single_file(self):
1987 if (not self.single_file): return
1988 in_nm = self.single_file + '.c'
1989 out_nm = self.output_fullname('')
1990 self.do_include(out_nm, in_nm)
1991 in_nm = self.single_file + '.h'
1992 if (os.path.exists(in_nm)):
1993 out_nm = self.output_fullname('', ext='h')
1994 self.do_include(out_nm, in_nm)
1996 self.unique_created_files = []
1997 [self.unique_created_files.append(wrd) for wrd in self.created_files if not self.unique_created_files.count(wrd)]
1998 for fn in self.unique_created_files:
2001 #--- do_include -------------------------------------------------------
2002 def do_include(self, out_nm, in_nm):
2003 def check_file(fn, fnlist):
2004 fnfull = os.path.normcase(os.path.abspath(fn))
2005 if ((fnfull in fnlist) and os.path.exists(fnfull)):
2006 return os.path.normpath(fn)
2008 fin = file(in_nm, "r")
2009 fout = file(out_nm, "w")
2010 fout.write(self.fhdr(out_nm))
2011 fout.write('/* Input file: ' + in_nm +' */\n')
2013 fout.write('#line 1 "%s"\n' % (in_nm))
2015 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2020 cont_linenum = cont_linenum + 1;
2021 line = fin.readline()
2022 if (line == ''): break
2024 result = include.search(line)
2025 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2027 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2029 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2031 ifile = check_file(result.group('fname'), self.created_files)
2034 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
2035 fout.write('#line 1 "' + ifile + '"\n')
2036 finc = file(ifile, "r")
2037 fout.write(finc.read())
2039 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
2040 fout.write('#line %i "%s"\n' % (cont_linenum+1,in_nm) )
2049 #--- Node ---------------------------------------------------------------------
2051 def __init__(self,*args, **kw):
2053 self.type = self.__class__.__name__
2055 assert (len(args) == 1)
2057 self.__dict__.update (kw)
2058 def str_child (self, key, child, depth):
2059 indent = " " * (2 * depth)
2060 keystr = indent + key + ": "
2061 if key == 'type': # already processed in str_depth
2063 if isinstance (child, Node): # ugh
2064 return keystr + "\n" + child.str_depth (depth+1)
2065 if type (child) == type ([]):
2068 if isinstance (x, Node):
2069 l.append (x.str_depth (depth+1))
2071 l.append (indent + " " + str(x) + "\n")
2072 return keystr + "[\n" + ''.join(l) + indent + "]\n"
2074 return keystr + str (child) + "\n"
2075 def str_depth (self, depth): # ugh
2076 indent = " " * (2 * depth)
2077 l = ["%s%s" % (indent, self.type)]
2078 l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
2079 self.__dict__.items ())))
2080 return "\n".join (l)
2082 return "\n" + self.str_depth (0)
2083 def to_python (self, ctx):
2084 return self.str_depth (ctx.indent_lev)
2086 def eth_reg(self, ident, ectx):
2089 #--- value_assign -------------------------------------------------------------
2090 class value_assign (Node):
2091 def __init__(self,*args, **kw) :
2092 Node.__init__ (self,*args, **kw)
2094 def eth_reg(self, ident, ectx):
2095 if ectx.conform.use_item('OMIT_ASSIGNMENT', self.ident): return # Assignment to omit
2096 ectx.eth_reg_vassign(self)
2097 ectx.eth_reg_value(self.ident, self.typ, self.val)
2100 #--- Type ---------------------------------------------------------------------
2102 def __init__(self,*args, **kw) :
2106 Node.__init__ (self,*args, **kw)
2109 if self.name is None :
2114 def HasConstraint(self):
2115 if self.constr is None :
2120 def HasOwnTag(self):
2121 return len(self.tags) > 0
2123 def HasImplicitTag(self, ectx):
2124 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
2126 def IndetermTag(self, ectx):
2129 def AddTag(self, tag):
2130 self.tags[0:0] = [tag]
2132 def GetTag(self, ectx):
2133 #print "GetTag(%s)\n" % self.name;
2134 if (self.HasOwnTag()):
2135 return self.tags[0].GetTag(ectx)
2137 return self.GetTTag(ectx)
2139 def GetTTag(self, ectx):
2140 print "#Unhandled GetTTag() in %s" % (self.type)
2141 print self.str_depth(1)
2142 return ('BER_CLASS_unknown', 'TAG_unknown')
2144 def SetName(self, name):
2147 def AddConstraint(self, constr):
2148 if not self.HasConstraint():
2149 self.constr = constr
2151 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
2153 def eth_tname(self):
2154 return '#' + self.type + '_' + str(id(self))
2156 def eth_ftype(self, ectx):
2157 return ('FT_NONE', 'BASE_NONE')
2159 def eth_strings(self):
2162 def eth_need_tree(self):
2165 def eth_has_vals(self):
2168 def eth_has_enum(self, tname, ectx):
2169 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
2171 def eth_named_bits(self):
2174 def eth_reg_sub(self, ident, ectx):
2177 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, idx='', parent=None):
2178 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(parent))
2179 if (ectx.Tag() and (len(self.tags) > tstrip)):
2180 tagged_type = TaggedType(val=self, tstrip=tstrip)
2181 tagged_type.AddTag(self.tags[tstrip])
2182 if not tagflag: # 1st tagged level
2184 tagged_type.SetName(self.name)
2185 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
2188 if ident and self.IsNamed() and not tagflag:
2189 nm = ident + '/' + self.name
2192 elif self.IsNamed():
2194 if not ident and ectx.conform.use_item('OMIT_ASSIGNMENT', nm): return # Assignment to omit
2195 if not ident: # Assignment
2196 ectx.eth_reg_assign(nm, self)
2197 if self.type == 'Type_Ref':
2198 ectx.eth_reg_type(nm, self)
2199 if (ectx.conform.check_item('PDU', nm)):
2200 ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
2201 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
2202 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
2203 if ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm):
2204 if ectx.conform.check_item('SET_TYPE', nm):
2205 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
2207 ectx.eth_reg_type(nm, self) # new type
2209 elif ectx.conform.check_item('SET_TYPE', nm):
2210 trnm = ectx.conform.use_item('SET_TYPE', nm)
2214 ectx.eth_reg_type(nm, self)
2216 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
2217 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
2218 ectx.eth_reg_assign(vnm, self, virt=True)
2219 ectx.eth_reg_type(vnm, self)
2220 self.eth_reg_sub(vnm, ectx)
2221 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
2222 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
2223 if ident and not tagflag:
2224 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
2225 if ectx.conform.check_item('SET_TYPE', nm):
2226 virtual_tr.eth_reg_sub(nm, ectx)
2228 self.eth_reg_sub(nm, ectx)
2230 def eth_get_size_constr(self):
2231 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2232 if not self.HasConstraint():
2233 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2234 elif self.constr.IsSize():
2235 (minv, maxv, ext) = self.constr.GetSize()
2236 elif (self.constr.type == 'Intersection'):
2237 if self.constr.subtype[0].IsSize():
2238 (minv, maxv, ext) = self.constr.subtype[0].GetSize()
2239 elif self.constr.subtype[1].IsSize():
2240 (minv, maxv, ext) = self.constr.subtype[1].GetSize()
2241 return (minv, maxv, ext)
2243 def eth_get_value_constr(self):
2244 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2245 if not self.HasConstraint():
2246 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2247 elif self.constr.IsValue():
2248 (minv, maxv, ext) = self.constr.GetValue()
2249 return (minv, maxv, ext)
2251 def eth_type_vals(self, tname, ectx):
2252 if self.eth_has_vals():
2253 print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
2254 print self.str_depth(1)
2257 def eth_type_enum(self, tname, ectx):
2258 if self.eth_has_enum(tname, ectx):
2259 print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
2260 print self.str_depth(1)
2263 def eth_type_default_table(self, ectx, tname):
2266 def eth_type_default_body(self, ectx):
2267 print "#Unhandled eth_type_default_body() in %s" % (self.type)
2268 print self.str_depth(1)
2271 def eth_type_default_pars(self, ectx, tname):
2278 'OFFSET' : 'offset',
2280 'HF_INDEX' : 'hf_index',
2282 'IMPLICIT_TAG' : 'implicit_tag',
2284 if (ectx.eth_type[tname]['tree']):
2285 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
2286 if (not ectx.Per()):
2287 pars['PINFO'] = 'pinfo'
2290 def eth_type_fn(self, proto, tname, ectx):
2291 body = self.eth_type_default_body(ectx, tname)
2292 pars = self.eth_type_default_pars(ectx, tname)
2293 if ectx.conform.check_item('FN_PARS', tname):
2294 pars.update(ectx.conform.use_item('FN_PARS', tname))
2295 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
2296 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
2297 pars['DEFAULT_BODY'] = body
2299 for k in pars.keys(): pars[k] = pars[k] % pars
2301 out += self.eth_type_default_table(ectx, tname) % pars
2302 out += ectx.eth_type_fn_hdr(tname)
2303 out += ectx.eth_type_fn_body(tname, body, pars=pars)
2304 out += ectx.eth_type_fn_ftr(tname)
2307 #--- Value --------------------------------------------------------------------
2309 def __init__(self,*args, **kw) :
2311 Node.__init__ (self,*args, **kw)
2313 def SetName(self, name) :
2322 #--- Tag ---------------------------------------------------------------
2324 def to_python (self, ctx):
2325 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
2328 self.typ.to_python (ctx))
2329 def IsImplicit(self, ectx):
2330 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
2332 def GetTag(self, ectx):
2334 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
2335 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
2336 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
2337 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
2338 return (tc, self.num)
2340 def eth_tname(self):
2342 if (self.cls == 'UNIVERSAL'): n = 'U'
2343 elif (self.cls == 'APPLICATION'): n = 'A'
2344 elif (self.cls == 'CONTEXT'): n = 'C'
2345 elif (self.cls == 'PRIVATE'): n = 'P'
2346 return n + str(self.num)
2348 #--- Constraint ---------------------------------------------------------------
2349 class Constraint (Node):
2350 def to_python (self, ctx):
2351 print "Ignoring constraint:", self.type
2352 return self.subtype.typ.to_python (ctx)
2354 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
2357 return self.type == 'Size' and (self.subtype.type == 'SingleValue' or self.subtype.type == 'ValueRange')
2364 if self.subtype.type == 'SingleValue':
2365 minv = self.subtype.subtype
2366 maxv = self.subtype.subtype
2368 minv = self.subtype.subtype[0]
2369 maxv = self.subtype.subtype[1]
2370 if hasattr(self.subtype, 'ext') and self.subtype.ext:
2374 return (minv, maxv, ext)
2377 return self.type == 'SingleValue' or self.type == 'ValueRange'
2384 if self.type == 'SingleValue':
2388 if self.subtype[0] == 'MIN':
2391 minv = self.subtype[0]
2392 if self.subtype[1] == 'MAX':
2395 maxv = self.subtype[1]
2396 if str(minv).isdigit(): minv += 'U'
2397 if str(maxv).isdigit(): maxv += 'U'
2398 if hasattr(self, 'ext') and self.ext:
2402 return (minv, maxv, ext)
2404 def IsNegativ(self):
2406 return sval[0] == '-'
2407 if self.type == 'SingleValue':
2408 return is_neg(self.subtype)
2409 elif self.type == 'ValueRange':
2410 if self.subtype[0] == 'MIN': return True
2411 return is_neg(self.subtype[0])
2414 def IsPermAlph(self):
2415 return self.type == 'From' and self.subtype.type == 'SingleValue'
2417 def eth_constrname(self):
2421 return 'M' + str(-int(val))
2424 except (ValueError, TypeError):
2428 if hasattr(self, 'ext') and self.ext:
2430 if self.type == 'SingleValue':
2431 return int2str(self.subtype) + ext
2432 elif self.type == 'ValueRange':
2433 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
2434 elif self.type == 'Size':
2435 return 'SIZE_' + self.subtype.eth_constrname() + ext
2437 return 'CONSTR' + str(id(self)) + ext
2440 class Module (Node):
2441 def to_python (self, ctx):
2442 ctx.tag_def = self.tag_def.dfl_tag
2444 %s""" % (self.ident, self.body.to_python (ctx))
2446 def to_eth (self, ectx):
2447 ectx.tags_def = 'EXPLICIT' # default = explicit
2448 if (not ectx.proto):
2449 ectx.proto = ectx.conform.use_item('MODULE', self.ident.val, val_dflt=self.ident.val)
2450 ectx.tag_def = self.tag_def.dfl_tag
2451 ectx.modules.append((self.ident.val, ectx.proto))
2452 self.body.to_eth(ectx)
2454 class Module_Body (Node):
2455 def to_python (self, ctx):
2456 # XXX handle exports, imports.
2457 l = map (lambda x: x.to_python (ctx), self.assign_list)
2458 l = [a for a in l if a <> '']
2459 return "\n".join (l)
2461 def to_eth(self, ectx):
2462 for i in self.imports:
2464 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
2465 for s in i.symbol_list:
2466 if isinstance(s, Type_Ref):
2467 ectx.eth_import_type(s.val, mod, proto)
2469 ectx.eth_import_value(s, mod, proto)
2470 for a in self.assign_list:
2473 class Default_Tags (Node):
2474 def to_python (self, ctx): # not to be used directly
2477 # XXX should just calculate dependencies as we go along.
2478 def calc_dependencies (node, dict, trace = 0):
2479 if not hasattr (node, '__dict__'):
2480 if trace: print "#returning, node=", node
2482 if isinstance (node, Type_Ref):
2484 if trace: print "#Setting", node.val
2486 for (a, val) in node.__dict__.items ():
2487 if trace: print "# Testing node ", node, "attr", a, " val", val
2490 elif isinstance (val, Node):
2491 calc_dependencies (val, dict, trace)
2492 elif isinstance (val, type ([])):
2494 calc_dependencies (v, dict, trace)
2497 class Type_Assign (Node):
2498 def __init__ (self, *args, **kw):
2499 Node.__init__ (self, *args, **kw)
2500 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
2501 to_test = self.val.typ
2504 if isinstance (to_test, SequenceType):
2505 to_test.sequence_name = self.name.name
2507 def to_python (self, ctx):
2509 calc_dependencies (self.val, dep_dict, 0)
2510 depend_list = dep_dict.keys ()
2511 return ctx.register_assignment (self.name.name,
2512 self.val.to_python (ctx),
2515 class PyQuote (Node):
2516 def to_python (self, ctx):
2517 return ctx.register_pyquote (self.val)
2519 #--- Type_Ref -----------------------------------------------------------------
2520 class Type_Ref (Type):
2521 def to_python (self, ctx):
2524 def eth_reg_sub(self, ident, ectx):
2525 ectx.eth_dep_add(ident, self.val)
2527 def eth_tname(self):
2528 return asn2c(self.val)
2530 def GetTTag(self, ectx):
2531 #print "GetTTag(%s)\n" % self.val;
2532 if (ectx.type[self.val]['import']):
2533 if not ectx.type[self.val].has_key('ttag'):
2534 if not ectx.conform.check_item('IMPORT_TAG', self.val):
2535 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
2536 warnings.warn_explicit(msg, UserWarning, '', '')
2537 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
2538 return ectx.type[self.val]['ttag']
2540 return ectx.type[self.val]['val'].GetTag(ectx)
2542 def IndetermTag(self, ectx):
2543 if (ectx.type[self.val]['import']):
2546 return ectx.type[self.val]['val'].IndetermTag(ectx)
2548 def eth_type_default_pars(self, ectx, tname):
2549 pars = Type.eth_type_default_pars(self, ectx, tname)
2550 t = ectx.type[self.val]['ethname']
2551 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
2552 pars['TYPE_REF_TNAME'] = t
2553 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
2556 def eth_type_default_body(self, ectx, tname):
2558 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
2559 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
2561 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
2562 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
2564 body = '#error Can not decode %s' % (tname)
2567 #--- TaggedType -----------------------------------------------------------------
2568 class TaggedType (Type):
2569 def eth_tname(self):
2571 for i in range(self.tstrip, len(self.val.tags)):
2572 tn += self.val.tags[i].eth_tname()
2574 tn += self.val.eth_tname()
2577 def eth_set_val_name(self, ident, val_name, ectx):
2578 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
2579 self.val_name = val_name
2580 ectx.eth_dep_add(ident, self.val_name)
2582 def eth_reg_sub(self, ident, ectx):
2583 self.val_name = ident + '/' + '_untag'
2584 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
2586 def eth_ftype(self, ectx):
2587 return self.val.eth_ftype(ectx)
2589 def eth_type_default_pars(self, ectx, tname):
2590 pars = Type.eth_type_default_pars(self, ectx, tname)
2591 t = ectx.type[self.val_name]['ethname']
2592 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
2593 pars['TYPE_REF_TNAME'] = t
2594 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
2595 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
2596 if self.HasImplicitTag(ectx):
2597 pars['TAG_IMPL'] = 'TRUE'
2599 pars['TAG_IMPL'] = 'FALSE'
2602 def eth_type_default_body(self, ectx, tname):
2604 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
2605 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2606 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
2608 body = '#error Can not decode %s' % (tname)
2611 #--- SqType -----------------------------------------------------------
2612 class SqType (Type):
2613 def out_item(self, f, val, optional, ext, ectx):
2614 ef = ectx.field[f]['ethname']
2615 t = ectx.eth_hf[ef]['ethtype']
2617 if (ectx.Ber() and ectx.field[f]['impl']):
2620 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
2621 #print val.str_depth(1)
2624 opt = 'BER_FLAGS_OPTIONAL'
2625 if (not val.HasOwnTag()):
2626 if (opt): opt += '|'
2627 opt += 'BER_FLAGS_NOOWNTAG'
2628 elif (val.HasImplicitTag(ectx)):
2629 if (opt): opt += '|'
2630 opt += 'BER_FLAGS_IMPLTAG'
2631 if (val.IndetermTag(ectx)):
2632 if (opt): opt += '|'
2633 opt += 'BER_FLAGS_NOTCHKTAG'
2634 if (not opt): opt = '0'
2637 opt = 'ASN1_OPTIONAL'
2639 opt = 'ASN1_NOT_OPTIONAL'
2641 (tc, tn) = val.GetTag(ectx)
2642 out = ' { %-13s, %s, %s, dissect_%s },\n' \
2643 % (tc, tn, opt, efd)
2645 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
2646 % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
2651 #--- SeqType -----------------------------------------------------------
2652 class SeqType (SqType):
2653 def eth_type_default_table(self, ectx, tname):
2654 #print "eth_type_default_table(tname='%s')" % (tname)
2655 fname = ectx.eth_type[tname]['ref'][0]
2656 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
2657 if hasattr(self, 'ext_list'):
2658 ext = 'ASN1_EXTENSION_ROOT'
2660 ext = 'ASN1_NO_EXTENSIONS'
2661 for e in (self.elt_list):
2662 f = fname + '/' + e.val.name
2663 table += self.out_item(f, e.val, e.optional, ext, ectx)
2664 if hasattr(self, 'ext_list'):
2665 for e in (self.ext_list):
2666 f = fname + '/' + e.val.name
2667 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
2669 table += " { 0, 0, 0, NULL }\n};\n"
2671 table += " { NULL, 0, 0, NULL }\n};\n"
2674 #--- SeqOfType -----------------------------------------------------------
2675 class SeqOfType (SqType):
2676 def eth_type_default_table(self, ectx, tname):
2677 #print "eth_type_default_table(tname='%s')" % (tname)
2678 fname = ectx.eth_type[tname]['ref'][0]
2679 if self.val.IsNamed ():
2680 f = fname + '/' + self.val.name
2682 f = fname + '/' + '_item'
2683 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
2684 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
2688 #--- SequenceOfType -----------------------------------------------------------
2689 class SequenceOfType (SeqOfType):
2690 def to_python (self, ctx):
2691 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2692 # or '' + (1,) for optional
2694 if self.size_constr <> None:
2695 print "#Ignoring size constraint:", self.size_constr.subtype
2696 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
2697 self.val.to_python (ctx),
2700 def eth_reg_sub(self, ident, ectx):
2702 if not self.val.IsNamed ():
2703 itmnm += '/' + '_item'
2704 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
2706 def eth_tname(self):
2707 if self.val.type != 'Type_Ref':
2708 return '#' + self.type + '_' + str(id(self))
2709 if not self.HasConstraint():
2710 return "SEQUENCE_OF_" + self.val.eth_tname()
2711 elif self.constr.IsSize():
2712 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
2714 return '#' + self.type + '_' + str(id(self))
2716 def eth_ftype(self, ectx):
2717 return ('FT_UINT32', 'BASE_DEC')
2719 def eth_need_tree(self):
2722 def GetTTag(self, ectx):
2723 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
2725 def eth_type_default_pars(self, ectx, tname):
2726 pars = Type.eth_type_default_pars(self, ectx, tname)
2727 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
2728 pars['TABLE'] = '%(TNAME)s_sequence_of'
2731 def eth_type_default_body(self, ectx, tname):
2733 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
2734 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2735 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2736 elif (ectx.Per() and not self.HasConstraint()):
2737 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
2738 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2739 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2740 elif (ectx.Per() and self.constr.type == 'Size'):
2741 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
2742 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2743 ('%(ETT_INDEX)s', '%(TABLE)s',),
2744 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
2746 body = '#error Can not decode %s' % (tname)
2750 #--- SetOfType ----------------------------------------------------------------
2751 class SetOfType (SeqOfType):
2752 def eth_reg_sub(self, ident, ectx):
2754 if not self.val.IsNamed ():
2755 itmnm += '/' + '_item'
2756 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
2758 def eth_tname(self):
2759 if self.val.type != 'Type_Ref':
2760 return '#' + self.type + '_' + str(id(self))
2761 if not self.HasConstraint():
2762 return "SET_OF_" + self.val.eth_tname()
2763 elif self.constr.IsSize():
2764 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
2766 return '#' + self.type + '_' + str(id(self))
2768 def eth_ftype(self, ectx):
2769 return ('FT_UINT32', 'BASE_DEC')
2771 def eth_need_tree(self):
2774 def GetTTag(self, ectx):
2775 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
2777 def eth_type_default_pars(self, ectx, tname):
2778 pars = Type.eth_type_default_pars(self, ectx, tname)
2779 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
2780 pars['TABLE'] = '%(TNAME)s_set_of'
2783 def eth_type_default_body(self, ectx, tname):
2785 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
2786 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2787 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2788 elif (ectx.Per() and not self.HasConstraint()):
2789 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
2790 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2791 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2792 elif (ectx.Per() and self.constr.type == 'Size'):
2793 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
2794 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2795 ('%(ETT_INDEX)s', '%(TABLE)s',),
2796 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
2798 body = '#error Can not decode %s' % (tname)
2801 def mk_tag_str (ctx, cls, typ, num):
2803 # XXX should do conversion to int earlier!
2806 if typ == 'DEFAULT':
2808 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
2810 #--- SequenceType -------------------------------------------------------------
2811 class SequenceType (SeqType):
2812 def to_python (self, ctx):
2813 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2814 # or '' + (1,) for optional
2815 # XXX should also collect names for SEQUENCE inside SEQUENCE or
2816 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
2817 # from? for others, element or arm name would be fine)
2818 seq_name = getattr (self, 'sequence_name', None)
2819 if seq_name == None:
2822 seq_name = "'" + seq_name + "'"
2823 if self.__dict__.has_key('ext_list'):
2824 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
2825 self.elts_to_py (self.elt_list, ctx),
2826 self.elts_to_py (self.ext_list, ctx), seq_name)
2828 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
2829 self.elts_to_py (self.elt_list, ctx), seq_name)
2830 def elts_to_py (self, list, ctx):
2831 # we have elt_type, val= named_type, maybe default=, optional=
2832 # named_type node: either ident = or typ =
2833 # need to dismember these in order to generate Python output syntax.
2836 assert (e.type == 'elt_type')
2838 optflag = e.optional
2839 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
2840 assert (nt.type == 'named_type')
2843 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
2844 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
2845 nt.typ.tag.tag_typ,nt.typ.tag.num)
2849 return "('%s',%s,%s,%d)" % (identstr, tagstr,
2850 nt.typ.to_python (ctx), optflag)
2851 indentstr = ",\n" + ctx.spaces ()
2852 rv = indentstr.join ([elt_to_py (e) for e in list])
2856 def eth_reg_sub(self, ident, ectx):
2857 for e in (self.elt_list):
2858 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2859 if hasattr(self, 'ext_list'):
2860 for e in (self.ext_list):
2861 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2863 def eth_need_tree(self):
2866 def GetTTag(self, ectx):
2867 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
2869 def eth_type_default_pars(self, ectx, tname):
2870 pars = Type.eth_type_default_pars(self, ectx, tname)
2871 pars['TABLE'] = '%(TNAME)s_sequence'
2874 def eth_type_default_body(self, ectx, tname):
2876 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
2877 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2878 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2880 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
2881 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2882 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2884 body = '#error Can not decode %s' % (tname)
2887 #--- SetType ------------------------------------------------------------------
2888 class SetType(SeqType):
2889 def eth_reg_sub(self, ident, ectx):
2890 for e in (self.elt_list):
2891 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2892 if hasattr(self, 'ext_list'):
2893 for e in (self.ext_list):
2894 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2896 def eth_need_tree(self):
2899 def GetTTag(self, ectx):
2900 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
2902 def eth_type_default_pars(self, ectx, tname):
2903 pars = Type.eth_type_default_pars(self, ectx, tname)
2904 pars['TABLE'] = '%(TNAME)s_set'
2907 def eth_type_default_body(self, ectx, tname):
2909 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
2910 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2911 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2913 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
2914 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2915 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2917 body = '#error Can not decode %s' % (tname)
2920 #--- ChoiceType ---------------------------------------------------------------
2921 class ChoiceType (Type):
2922 def to_python (self, ctx):
2923 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2924 # or '' + (1,) for optional
2925 if self.__dict__.has_key('ext_list'):
2926 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
2927 self.elts_to_py (self.elt_list, ctx),
2928 self.elts_to_py (self.ext_list, ctx))
2930 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
2931 def elts_to_py (self, list, ctx):
2934 assert (nt.type == 'named_type')
2936 if hasattr (nt, 'ident'):
2939 if hasattr (nt.typ, 'val'):
2940 identstr = nt.typ.val # XXX, making up name
2941 elif hasattr (nt.typ, 'name'):
2942 identstr = nt.typ.name
2944 identstr = ctx.make_new_name ()
2946 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
2947 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
2948 nt.typ.tag.tag_typ,nt.typ.tag.num)
2952 return "('%s',%s,%s)" % (identstr, tagstr,
2953 nt.typ.to_python (ctx))
2954 indentstr = ",\n" + ctx.spaces ()
2955 rv = indentstr.join ([elt_to_py (e) for e in list])
2959 def eth_reg_sub(self, ident, ectx):
2960 #print "eth_reg_sub(ident='%s')" % (ident)
2961 for e in (self.elt_list):
2962 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
2963 if hasattr(self, 'ext_list'):
2964 for e in (self.ext_list):
2965 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
2967 def eth_ftype(self, ectx):
2968 return ('FT_UINT32', 'BASE_DEC')
2970 def eth_strings(self):
2973 def eth_need_tree(self):
2976 def eth_has_vals(self):
2979 def GetTTag(self, ectx):
2981 cls = 'BER_CLASS_ANY/*choice*/'
2982 #if hasattr(self, 'ext_list'):
2983 # lst.extend(self.ext_list)
2985 # cls = lst[0].GetTag(ectx)[0]
2987 # if (e.GetTag(ectx)[0] != cls):
2988 # cls = '-1/*choice*/'
2989 return (cls, '-1/*choice*/')
2991 def IndetermTag(self, ectx):
2992 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
2993 return not self.HasOwnTag()
2995 def get_vals(self, ectx):
2999 if hasattr(self, 'ext_list'):
3000 lst.extend(self.ext_list)
3002 t = lst[0].GetTag(ectx)[0]
3004 if (t == 'BER_CLASS_UNI'):
3007 if (e.GetTag(ectx)[0] != t):
3011 for e in (self.elt_list):
3012 if (tagval): val = e.GetTag(ectx)[1]
3013 else: val = str(cnt)
3014 vals.append((val, e.name))
3016 if hasattr(self, 'ext_list'):
3017 for e in (self.ext_list):
3018 if (tagval): val = e.GetTag(ectx)[1]
3019 else: val = str(cnt)
3020 vals.append((val, e.name))
3024 def eth_type_vals(self, tname, ectx):
3026 vals = self.get_vals(ectx)
3027 out += ectx.eth_vals(tname, vals)
3030 def eth_type_enum(self, tname, ectx):
3032 vals = self.get_vals(ectx)
3033 out += ectx.eth_enum(tname, vals)
3036 def eth_type_default_pars(self, ectx, tname):
3037 pars = Type.eth_type_default_pars(self, ectx, tname)
3038 pars['TABLE'] = '%(TNAME)s_choice'
3041 def eth_type_default_table(self, ectx, tname):
3042 def out_item(val, e, ext, ectx):
3043 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
3045 vval = ectx.eth_enum_item(tname, e.name)
3048 f = fname + '/' + e.name
3049 ef = ectx.field[f]['ethname']
3050 t = ectx.eth_hf[ef]['ethtype']
3052 if (ectx.field[f]['impl']):
3056 if (not e.HasOwnTag()):
3057 opt = 'BER_FLAGS_NOOWNTAG'
3058 elif (e.HasImplicitTag(ectx)):
3059 if (opt): opt += '|'
3060 opt += 'BER_FLAGS_IMPLTAG'
3061 if (not opt): opt = '0'
3063 (tc, tn) = e.GetTag(ectx)
3064 out = ' { %3s, %-13s, %s, %s, dissect_%s },\n' \
3065 % (vval, tc, tn, opt, efd)
3067 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
3068 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
3073 #print "eth_type_default_table(tname='%s')" % (tname)
3074 fname = ectx.eth_type[tname]['ref'][0]
3078 if hasattr(self, 'ext_list'):
3079 lst.extend(self.ext_list)
3081 t = lst[0].GetTag(ectx)[0]
3083 if (t == 'BER_CLASS_UNI'):
3086 if (e.GetTag(ectx)[0] != t):
3088 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
3090 if hasattr(self, 'ext_list'):
3091 ext = 'ASN1_EXTENSION_ROOT'
3093 ext = 'ASN1_NO_EXTENSIONS'
3094 for e in (self.elt_list):
3095 if (tagval): val = e.GetTag(ectx)[1]
3096 else: val = str(cnt)
3097 table += out_item(val, e, ext, ectx)
3099 if hasattr(self, 'ext_list'):
3100 for e in (self.ext_list):
3101 if (tagval): val = e.GetTag(ectx)[1]
3102 else: val = str(cnt)
3103 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3106 table += " { 0, 0, 0, 0, NULL }\n};\n"
3108 table += " { 0, NULL, 0, NULL }\n};\n"
3111 def eth_type_default_body(self, ectx, tname):
3113 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3114 par=(('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3115 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
3118 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3119 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3120 ('%(ETT_INDEX)s', '%(TABLE)s',),
3123 body = '#error Can not decode %s' % (tname)
3126 #--- EnumeratedType -----------------------------------------------------------
3127 class EnumeratedType (Type):
3128 def to_python (self, ctx):
3129 def strify_one (named_num):
3130 return "%s=%s" % (named_num.ident, named_num.val)
3131 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
3133 def eth_ftype(self, ectx):
3134 return ('FT_UINT32', 'BASE_DEC')
3136 def eth_strings(self):
3139 def eth_has_vals(self):
3142 def GetTTag(self, ectx):
3143 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
3145 def get_vals_etc(self, ectx):
3153 for e in (self.val):
3154 if e.type == 'NamedNumber':
3155 used[int(e.val)] = True
3156 for e in (self.val):
3157 if e.type == 'NamedNumber':
3160 while used.has_key(lastv):
3164 vals.append((val, e.ident))
3165 map_table.append(val)
3169 if self.ext is not None:
3170 for e in (self.ext):
3171 if e.type == 'NamedNumber':
3172 used[int(e.val)] = True
3173 for e in (self.ext):
3174 if e.type == 'NamedNumber':
3177 while used.has_key(lastv):
3181 vals.append((val, e.ident))
3182 map_table.append(val)
3187 for i in range(len(map_table)):
3188 need_map = need_map or (map_table[i] != i)
3191 return (vals, root_num, ext_num, map_table)
3193 def eth_type_vals(self, tname, ectx):
3195 vals = self.get_vals_etc(ectx)[0]
3196 out += ectx.eth_vals(tname, vals)
3199 def eth_type_enum(self, tname, ectx):
3201 vals = self.get_vals_etc(ectx)[0]
3202 out += ectx.eth_enum(tname, vals)
3205 def eth_type_default_pars(self, ectx, tname):
3206 pars = Type.eth_type_default_pars(self, ectx, tname)
3207 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
3208 if (self.ext != None):
3212 pars['ROOT_NUM'] = str(root_num)
3214 pars['EXT_NUM'] = str(ext_num)
3216 pars['TABLE'] = '%(TNAME)s_value_map'
3218 pars['TABLE'] = 'NULL'
3221 def eth_type_default_table(self, ectx, tname):
3222 if (not ectx.Per()): return ''
3223 map_table = self.get_vals_etc(ectx)[3]
3224 if (map_table == None): return ''
3225 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
3226 table += ", ".join([str(v) for v in map_table])
3230 def eth_type_default_body(self, ectx, tname):
3232 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3233 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3236 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
3237 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3238 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
3240 body = '#error Can not decode %s' % (tname)
3243 #--- ExternalType -----------------------------------------------------------
3244 class ExternalType (Type):
3245 def eth_tname(self):
3248 def eth_ftype(self, ectx):
3249 return ('FT_NONE', 'BASE_NONE')
3251 def eth_type_default_pars(self, ectx, tname):
3252 pars = Type.eth_type_default_pars(self, ectx, tname)
3253 pars['TYPE_REF_FN'] = 'NULL'
3256 def eth_type_default_body(self, ectx, tname):
3258 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
3259 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
3261 body = '#error Can not decode %s' % (tname)
3264 #--- OpenType -----------------------------------------------------------
3265 class OpenType (Type):
3266 def to_python (self, ctx):
3269 def single_type(self):
3270 if (self.HasConstraint() and
3271 self.constr.type == 'Type' and
3272 self.constr.subtype.type == 'Type_Ref'):
3273 return self.constr.subtype.val
3276 def eth_reg_sub(self, ident, ectx):
3277 t = self.single_type()
3279 ectx.eth_dep_add(ident, t)
3281 def eth_tname(self):
3282 t = self.single_type()
3284 return 'OpenType_' + t
3286 return Type.eth_tname(self)
3288 def eth_ftype(self, ectx):
3289 return ('FT_NONE', 'BASE_NONE')
3291 def GetTTag(self, ectx):
3292 return ('BER_CLASS_ANY', '0')
3294 def eth_type_default_pars(self, ectx, tname):
3295 pars = Type.eth_type_default_pars(self, ectx, tname)
3296 t = self.single_type()
3298 t = ectx.type[t]['ethname']
3299 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3300 pars['TYPE_REF_TNAME'] = t
3301 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3303 pars['TYPE_REF_FN'] = 'NULL'
3306 def eth_type_default_body(self, ectx, tname):
3308 body = ectx.eth_fn_call('dissect_%(ER)s_open_type', ret='offset',
3309 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
3311 body = '#error Can not decode %s' % (tname)
3314 #--- AnyType -----------------------------------------------------------
3315 class AnyType (Type):
3316 def to_python (self, ctx):
3319 def eth_ftype(self, ectx):
3320 return ('FT_NONE', 'BASE_NONE')
3322 def GetTTag(self, ectx):
3323 return ('BER_CLASS_ANY', '0')
3325 def eth_type_default_body(self, ectx, tname):
3326 body = '#error Can not decode %s' % (tname)
3329 class Literal (Node):
3330 def to_python (self, ctx):
3333 #--- NullType -----------------------------------------------------------------
3334 class NullType (Type):
3335 def to_python (self, ctx):
3338 def eth_tname(self):
3341 def GetTTag(self, ectx):
3342 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
3344 def eth_type_default_body(self, ectx, tname):
3346 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
3347 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3349 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
3350 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3352 body = '#error Can not decode %s' % (tname)
3355 #--- RealType -----------------------------------------------------------------
3356 class RealType (Type):
3357 def to_python (self, ctx):
3360 def eth_tname(self):
3363 def eth_type_default_body(self, ectx, tname):
3364 body = '#error Can not decode %s' % (tname)
3367 #--- BooleanType --------------------------------------------------------------
3368 class BooleanType (Type):
3369 def to_python (self, ctx):
3370 return 'asn1.BOOLEAN'
3372 def eth_tname(self):
3375 def GetTTag(self, ectx):
3376 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
3378 def eth_ftype(self, ectx):
3379 return ('FT_BOOLEAN', '8')
3381 def eth_type_default_body(self, ectx, tname):
3383 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
3384 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3386 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
3387 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3389 body = '#error Can not decode %s' % (tname)
3392 #--- OctetStringType ----------------------------------------------------------
3393 class OctetStringType (Type):
3394 def to_python (self, ctx):
3395 return 'asn1.OCTSTRING'
3397 def eth_tname(self):
3398 if not self.HasConstraint():
3399 return 'OCTET_STRING'
3400 elif self.constr.IsSize():
3401 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
3403 return '#' + self.type + '_' + str(id(self))
3405 def eth_ftype(self, ectx):
3406 return ('FT_BYTES', 'BASE_HEX')
3408 def GetTTag(self, ectx):
3409 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
3411 def eth_type_default_pars(self, ectx, tname):
3412 pars = Type.eth_type_default_pars(self, ectx, tname)
3413 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3416 def eth_type_default_body(self, ectx, tname):
3418 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
3419 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3422 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
3423 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3424 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s',),))
3426 body = '#error Can not decode %s' % (tname)
3429 #--- CharacterStringType ------------------------------------------------------
3430 class CharacterStringType (Type):
3431 def eth_tname(self):
3432 if not self.HasConstraint():
3433 return self.eth_tsname()
3434 elif self.constr.IsSize():
3435 return self.eth_tsname() + '_' + self.constr.eth_constrname()
3437 return '#' + self.type + '_' + str(id(self))
3439 def eth_ftype(self, ectx):
3440 return ('FT_STRING', 'BASE_NONE')
3442 class RestrictedCharacterStringType (CharacterStringType):
3443 def to_python (self, ctx):
3444 return 'asn1.' + self.eth_tsname()
3446 def GetTTag(self, ectx):
3447 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
3449 def HasPermAlph(self):
3450 return (self.HasConstraint() and
3451 (self.constr.IsPermAlph() or
3452 (self.constr.type == 'Intersection' and (self.constr.subtype[0].IsPermAlph() or self.constr.subtype[1].IsPermAlph()))
3456 def eth_type_default_pars(self, ectx, tname):
3457 pars = Type.eth_type_default_pars(self, ectx, tname)
3458 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3459 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
3460 (pars['ALPHABET'], pars['ALPHABET_LEN']) = ('NULL', '0')
3461 if self.HasPermAlph():
3462 if self.constr.IsPermAlph():
3463 pars['ALPHABET'] = self.constr.subtype.subtype
3464 elif self.constr.subtype[0].IsPermAlph():
3465 pars['ALPHABET'] = self.constr.subtype[0].subtype.subtype
3466 elif self.constr.subtype[1].IsPermAlph():
3467 pars['ALPHABET'] = self.constr.subtype[1].subtype.subtype
3468 pars['ALPHABET_LEN'] = 'strlen(%(ALPHABET)s)'
3471 def eth_type_default_body(self, ectx, tname):
3473 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
3474 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
3475 ('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3477 elif (ectx.Per() and self.HasPermAlph()):
3478 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
3479 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3480 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
3483 if (self.eth_tsname() == 'GeneralString'):
3484 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3485 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3486 elif (self.eth_tsname() == 'GeneralizedTime'):
3487 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
3488 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3489 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3490 elif (self.eth_tsname() == 'UTCTime'):
3491 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
3492 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3493 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3495 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3496 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3497 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3499 body = '#error Can not decode %s' % (tname)
3502 class BMPStringType (RestrictedCharacterStringType):
3503 def eth_tsname(self):
3506 class GeneralStringType (RestrictedCharacterStringType):
3507 def eth_tsname(self):
3508 return 'GeneralString'
3510 class GraphicStringType (RestrictedCharacterStringType):
3511 def eth_tsname(self):
3512 return 'GraphicString'
3514 class IA5StringType (RestrictedCharacterStringType):
3515 def eth_tsname(self):
3518 class NumericStringType (RestrictedCharacterStringType):
3519 def eth_tsname(self):
3520 return 'NumericString'
3522 class PrintableStringType (RestrictedCharacterStringType):
3523 def eth_tsname(self):
3524 return 'PrintableString'
3526 class TeletexStringType (RestrictedCharacterStringType):
3527 def eth_tsname(self):
3528 return 'TeletexString'
3530 class T61StringType (RestrictedCharacterStringType):
3531 def eth_tsname(self):
3533 def GetTTag(self, ectx):
3534 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
3536 class UniversalStringType (RestrictedCharacterStringType):
3537 def eth_tsname(self):
3538 return 'UniversalString'
3540 class UTF8StringType (RestrictedCharacterStringType):
3541 def eth_tsname(self):
3544 class VideotexStringType (RestrictedCharacterStringType):
3545 def eth_tsname(self):
3546 return 'VideotexString'
3548 class VisibleStringType (RestrictedCharacterStringType):
3549 def eth_tsname(self):
3550 return 'VisibleString'
3552 class ISO646StringType (RestrictedCharacterStringType):
3553 def eth_tsname(self):
3554 return 'ISO646String'
3555 def GetTTag(self, ectx):
3556 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
3558 class UnrestrictedCharacterStringType (CharacterStringType):
3559 def to_python (self, ctx):
3560 return 'asn1.UnrestrictedCharacterString'
3561 def eth_tsname(self):
3562 return 'CHARACTER_STRING'
3564 #--- UsefulType ---------------------------------------------------------------
3565 class GeneralizedTime (RestrictedCharacterStringType):
3566 def eth_tsname(self):
3567 return 'GeneralizedTime'
3569 def eth_type_default_body(self, ectx, tname):
3571 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3572 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3575 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
3577 class UTCTime (RestrictedCharacterStringType):
3578 def eth_tsname(self):
3581 class ObjectDescriptor (RestrictedCharacterStringType):
3582 def eth_tsname(self):
3583 return 'ObjectDescriptor'
3585 def eth_type_default_body(self, ectx, tname):
3587 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
3589 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
3590 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3592 body = '#error Can not decode %s' % (tname)
3595 #--- ObjectIdentifierType -----------------------------------------------------
3596 class ObjectIdentifierType (Type):
3597 def to_python (self, ctx):
3598 return 'asn1.OBJECT_IDENTIFIER'
3600 def eth_tname(self):
3601 return 'OBJECT_IDENTIFIER'
3603 def eth_ftype(self, ectx):
3604 return ('FT_OID', 'BASE_NONE')
3606 def GetTTag(self, ectx):
3607 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
3609 def eth_type_default_body(self, ectx, tname):
3611 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
3612 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3614 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
3615 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3617 body = '#error Can not decode %s' % (tname)
3620 #--- ObjectIdentifierValue ----------------------------------------------------
3621 class ObjectIdentifierValue (Value):
3622 def get_num(self, path, val):
3623 return str(oid_names.get(path + '/' + val, val))
3630 for v in self.comp_list:
3631 if isinstance(v, Node) and (v.type == 'name_and_number'):
3636 vstr = self.get_num(path, v)
3651 v = self.comp_list[0]
3652 if isinstance(v, Node) and (v.type == 'name_and_number'):
3657 vstr = self.get_num('', v)
3663 class NamedNumber (Node):
3664 def to_python (self, ctx):
3665 return "('%s',%s)" % (self.ident, self.val)
3667 class NamedNumListBase(Node):
3668 def to_python (self, ctx):
3669 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
3670 map (lambda x: x.to_python (ctx), self.named_list)))
3672 #--- IntegerType --------------------------------------------------------------
3673 class IntegerType (Type):
3674 def to_python (self, ctx):
3675 return "asn1.INTEGER_class ([%s])" % (",".join (
3676 map (lambda x: x.to_python (ctx), self.named_list)))
3678 def eth_tname(self):
3680 return Type.eth_tname(self)
3681 if not self.HasConstraint():
3683 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
3684 return 'INTEGER' + '_' + self.constr.eth_constrname()
3686 return 'INTEGER' + '_' + self.constr.eth_tname()
3688 def GetTTag(self, ectx):
3689 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
3692 def eth_ftype(self, ectx):
3693 if self.HasConstraint():
3694 if not self.constr.IsNegativ():
3695 return ('FT_UINT32', 'BASE_DEC')
3696 return ('FT_INT32', 'BASE_DEC')
3698 def eth_strings(self):
3699 if (self.named_list):
3704 def eth_has_vals(self):
3705 if (self.named_list):
3710 def get_vals(self, ectx):
3712 for e in (self.named_list):
3713 vals.append((int(e.val), e.ident))
3716 def eth_type_vals(self, tname, ectx):
3717 if not self.eth_has_vals(): return ''
3719 vals = self.get_vals(ectx)
3720 out += ectx.eth_vals(tname, vals)
3723 def eth_type_enum(self, tname, ectx):
3724 if not self.eth_has_enum(tname, ectx): return ''
3726 vals = self.get_vals(ectx)
3727 out += ectx.eth_enum(tname, vals)
3730 def eth_type_default_pars(self, ectx, tname):
3731 pars = Type.eth_type_default_pars(self, ectx, tname)
3732 if self.HasConstraint() and self.constr.IsValue():
3733 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr()
3736 def eth_type_default_body(self, ectx, tname):
3738 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3739 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3741 elif (ectx.Per() and not self.HasConstraint()):
3742 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3743 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
3744 elif (ectx.Per() and ((self.constr.type == 'SingleValue') or (self.constr.type == 'ValueRange'))):
3745 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
3746 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3747 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
3749 body = '#error Can not decode %s' % (tname)
3752 #--- BitStringType ------------------------------------------------------------
3753 class BitStringType (Type):
3754 def to_python (self, ctx):
3755 return "asn1.BITSTRING_class ([%s])" % (",".join (
3756 map (lambda x: x.to_python (ctx), self.named_list)))
3758 def eth_tname(self):
3760 return Type.eth_tname(self)
3761 elif not self.HasConstraint():
3763 elif self.constr.IsSize():
3764 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
3766 return '#' + self.type + '_' + str(id(self))
3768 def GetTTag(self, ectx):
3769 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
3771 def eth_ftype(self, ectx):
3772 return ('FT_BYTES', 'BASE_HEX')
3774 def eth_need_tree(self):
3775 return self.named_list
3777 def eth_named_bits(self):
3779 if (self.named_list):
3780 for e in (self.named_list):
3781 bits.append((int(e.val), e.ident))
3784 def eth_type_default_pars(self, ectx, tname):
3785 pars = Type.eth_type_default_pars(self, ectx, tname)
3786 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3787 if not pars.has_key('ETT_INDEX'):
3788 pars['ETT_INDEX'] = '-1'
3789 pars['TABLE'] = 'NULL'
3790 if self.eth_named_bits():
3791 pars['TABLE'] = '%(TNAME)s_bits'
3794 def eth_type_default_table(self, ectx, tname):
3795 #print "eth_type_default_table(tname='%s')" % (tname)
3797 bits = self.eth_named_bits()
3799 table = ectx.eth_bits(tname, bits)
3802 def eth_type_default_body(self, ectx, tname):
3804 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
3805 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3806 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
3809 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
3810 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3811 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s','%(VAL_PTR)s'),))
3813 body = '#error Can not decode %s' % (tname)
3817 #==============================================================================
3819 def p_module_list_1 (t):
3820 'module_list : module_list module_def'
3821 t[0] = t[1] + [t[2]]
3823 def p_module_list_2 (t):
3824 'module_list : module_def'
3828 #--- ITU-T Recommendation X.680 -----------------------------------------------
3831 # 11 ASN.1 lexical items --------------------------------------------------------
3833 # 11.2 Type references
3835 'type_ref : UCASE_IDENT'
3836 t[0] = Type_Ref(val=t[1])
3838 # 11.4 Value references
3839 def p_valuereference (t):
3840 'valuereference : LCASE_IDENT'
3843 # 11.5 Module references
3844 def p_modulereference (t):
3845 'modulereference : UCASE_IDENT'
3849 # 12 Module definition --------------------------------------------------------
3852 def p_module_def (t):
3853 'module_def : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT BEGIN module_body END'
3854 t[0] = Module (ident = t[1], tag_def = t[3], body = t[6])
3856 def p_TagDefault_1 (t):
3857 '''TagDefault : EXPLICIT TAGS
3860 t[0] = Default_Tags (dfl_tag = t[1])
3862 def p_TagDefault_2 (t):
3864 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
3865 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
3867 def p_ModuleIdentifier_1 (t):
3868 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
3869 t [0] = Node('module_ident', val = t[1], ident = t[2])
3871 def p_ModuleIdentifier_2 (t):
3872 'ModuleIdentifier : modulereference' # name, oid
3873 t [0] = Node('module_ident', val = t[1], ident = None)
3875 def p_DefinitiveIdentifier (t):
3876 'DefinitiveIdentifier : ObjectIdentifierValue'
3879 # XXX originally we had both type_ref and module_ref, but that caused
3880 # a reduce/reduce conflict (because both were UCASE_IDENT). Presumably
3881 # this didn't cause a problem in the original ESNACC grammar because it
3882 # was LALR(1) and PLY is (as of 1.1) only SLR.
3884 #def p_module_ref (t):
3885 # 'module_ref : UCASE_IDENT'
3888 def p_assigned_ident_1 (t):
3889 'assigned_ident : ObjectIdentifierValue'
3892 def p_assigned_ident_2 (t):
3893 'assigned_ident : LCASE_IDENT'
3896 def p_assigned_ident_3 (t):
3900 def p_module_body_1 (t):
3901 'module_body : exports Imports AssignmentList'
3902 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
3904 def p_module_body_2 (t):
3906 t[0] = Node ('module_body', exports = [], imports = [],
3909 def p_exports_1 (t):
3910 'exports : EXPORTS syms_exported SEMICOLON'
3913 def p_exports_2 (t):
3917 def p_syms_exported_1 (t):
3918 'syms_exported : exp_sym_list'
3921 def p_syms_exported_2 (t):
3925 def p_exp_sym_list_1 (t):
3926 'exp_sym_list : Symbol'
3929 def p_exp_sym_list_2 (t):
3930 'exp_sym_list : exp_sym_list COMMA Symbol'
3931 t[0] = t[1] + [t[3]]
3935 'Imports : IMPORTS SymbolsImported SEMICOLON'
3938 def p_Imports_2 (t):
3942 def p_SymbolsImported_1(t):
3943 'SymbolsImported : '
3946 def p_SymbolsImported_2 (t):
3947 'SymbolsImported : SymbolsFromModuleList'
3950 def p_SymbolsFromModuleList_1 (t):
3951 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
3952 t[0] = t[1] + [t[2]]
3954 def p_SymbolsFromModuleList_2 (t):
3955 'SymbolsFromModuleList : SymbolsFromModule'
3958 def p_SymbolsFromModule (t):
3959 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
3960 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
3962 def p_GlobalModuleReference (t):
3963 'GlobalModuleReference : modulereference assigned_ident'
3964 t [0] = Node('module_ident', val = t[1], ident = t[2])
3966 def p_SymbolList_1 (t):
3967 'SymbolList : Symbol'
3970 def p_SymbolList_2 (t):
3971 'SymbolList : SymbolList COMMA Symbol'
3972 t[0] = t[1] + [t[3]]
3975 '''Symbol : type_ref
3976 | ParameterizedReference
3977 | identifier''' # XXX omit DefinedMacroName
3980 def p_Reference (t):
3981 '''Reference : type_ref
3985 def p_AssignmentList_1 (t):
3986 'AssignmentList : AssignmentList Assignment'
3987 t[0] = t[1] + [t[2]]
3989 def p_AssignmentList_2 (t):
3990 'AssignmentList : Assignment SEMICOLON'
3993 def p_AssignmentList_3 (t):
3994 'AssignmentList : Assignment'
3997 def p_Assignment (t):
3998 '''Assignment : TypeAssignment
4001 | ParameterizedTypeAssignment'''
4005 '''pyquote : PYQUOTE'''
4006 t[0] = PyQuote (val = t[1])
4009 # 13 Referencing type and value definitions -----------------------------------
4012 def p_DefinedType (t):
4013 '''DefinedType : ext_type_ref
4015 | ParameterizedType'''
4018 def p_DefinedValue(t):
4019 '''DefinedValue : ext_val_ref
4024 # 15 Assigning types and values -----------------------------------------------
4027 def p_TypeAssignment (t):
4028 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
4033 def p_ValueAssignment (t):
4034 'ValueAssignment : identifier Type ASSIGNMENT Value'
4035 t[0] = value_assign (ident = t[1], typ = t[2], val = t[4])
4038 # 16 Definition of types and values -------------------------------------------
4042 '''Type : BuiltinType
4044 | ConstrainedType'''
4048 def p_BuiltinType (t):
4049 '''BuiltinType : AnyType
4052 | CharacterStringType
4058 | ObjectClassFieldType
4059 | ObjectIdentifierType
4071 def p_ReferencedType (t):
4072 '''ReferencedType : DefinedType
4076 def p_ext_type_ref (t):
4077 'ext_type_ref : type_ref DOT type_ref'
4078 # XXX coerce 1st type_ref to module_ref
4079 t[0] = Node ('ext_type_ref', module = t[1], typ = t[3])
4082 def p_NamedType (t):
4083 'NamedType : identifier Type'
4089 '''Value : BuiltinValue
4090 | ReferencedValue'''
4094 def p_BuiltinValue (t):
4095 '''BuiltinValue : BooleanValue
4096 | ObjectIdentifierValue
4102 | char_string''' # XXX we don't support {data} here
4106 def p_ReferencedValue (t):
4107 '''ReferencedValue : DefinedValue'''
4111 #def p_NamedValue (t):
4112 # 'NamedValue : identifier Value'
4113 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
4116 # 17 Notation for the boolean type --------------------------------------------
4119 def p_BooleanType (t):
4120 'BooleanType : BOOLEAN'
4121 t[0] = BooleanType ()
4124 def p_BooleanValue (t):
4125 '''BooleanValue : TRUE
4130 # 18 Notation for the integer type --------------------------------------------
4133 def p_IntegerType_1 (t):
4134 'IntegerType : INTEGER'
4135 t[0] = IntegerType (named_list = None)
4137 def p_IntegerType_2 (t):
4138 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
4139 t[0] = IntegerType (named_list = t[3])
4141 def p_NamedNumberList_1 (t):
4142 'NamedNumberList : NamedNumber'
4145 def p_NamedNumberList_2 (t):
4146 'NamedNumberList : NamedNumberList COMMA NamedNumber'
4147 t[0] = t[1] + [t[3]]
4149 def p_NamedNumber (t):
4150 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
4151 | identifier LPAREN DefinedValue RPAREN'''
4152 t[0] = NamedNumber (ident = t[1], val = t[3])
4154 def p_SignedNumber_1 (t):
4155 'SignedNumber : NUMBER'
4158 def p_SignedNumber_2 (t):
4159 'SignedNumber : MINUS NUMBER'
4163 # 19 Notation for the enumerated type -----------------------------------------
4166 def p_EnumeratedType (t):
4167 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
4168 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
4170 def p_Enumerations_1 (t):
4171 'Enumerations : Enumeration'
4172 t[0] = { 'val' : t[1], 'ext' : None }
4174 def p_Enumerations_2 (t):
4175 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
4176 t[0] = { 'val' : t[1], 'ext' : [] }
4178 def p_Enumerations_3 (t):
4179 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
4180 t[0] = { 'val' : t[1], 'ext' : t[6] }
4182 def p_Enumeration_1 (t):
4183 'Enumeration : EnumerationItem'
4186 def p_Enumeration_2 (t):
4187 'Enumeration : Enumeration COMMA EnumerationItem'
4188 t[0] = t[1] + [t[3]]
4190 def p_EnumerationItem (t):
4191 '''EnumerationItem : Identifier
4195 def p_Identifier (t):
4196 'Identifier : identifier'
4197 t[0] = Node ('Identifier', ident = t[1])
4200 # 20 Notation for the real type -----------------------------------------------
4207 # 21 Notation for the bitstring type ------------------------------------------
4210 def p_BitStringType_1 (t):
4211 'BitStringType : BIT STRING'
4212 t[0] = BitStringType (named_list = None)
4214 def p_BitStringType_2 (t):
4215 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
4216 t[0] = BitStringType (named_list = t[4])
4218 def p_NamedBitList_1 (t):
4219 'NamedBitList : NamedBit'
4222 def p_NamedBitList_2 (t):
4223 'NamedBitList : NamedBitList COMMA NamedBit'
4224 t[0] = t[1] + [t[3]]
4227 '''NamedBit : identifier LPAREN NUMBER RPAREN
4228 | identifier LPAREN DefinedValue RPAREN'''
4229 t[0] = NamedNumber (ident = t[1], val = t[3])
4232 # 22 Notation for the octetstring type ----------------------------------------
4235 def p_OctetStringType (t):
4236 'OctetStringType : OCTET STRING'
4237 t[0] = OctetStringType ()
4240 # 23 Notation for the null type -----------------------------------------------
4248 #def p_NullValue (t):
4249 # 'NullValue : NULL'
4253 # 24 Notation for sequence types ----------------------------------------------
4256 def p_SequenceType_1 (t):
4257 'SequenceType : SEQUENCE LBRACE RBRACE'
4258 t[0] = SequenceType (elt_list = [])
4260 def p_SequenceType_2 (t):
4261 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
4262 if t[3].has_key('ext_list'):
4263 t[0] = SequenceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4265 t[0] = SequenceType (elt_list = t[3]['elt_list'])
4267 def p_ExtensionAndException_1 (t):
4268 'ExtensionAndException : ELLIPSIS'
4271 def p_OptionalExtensionMarker_1 (t):
4272 'OptionalExtensionMarker : COMMA ELLIPSIS'
4275 def p_OptionalExtensionMarker_2 (t):
4276 'OptionalExtensionMarker : '
4279 def p_ComponentTypeLists_1 (t):
4280 'ComponentTypeLists : element_type_list'
4281 t[0] = {'elt_list' : t[1]}
4283 def p_ComponentTypeLists_2 (t):
4284 'ComponentTypeLists : element_type_list COMMA ExtensionAndException extension_additions OptionalExtensionMarker'
4285 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
4287 def p_ComponentTypeLists_3 (t):
4288 'ComponentTypeLists : ExtensionAndException extension_additions OptionalExtensionMarker'
4289 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
4291 def p_extension_additions_1 (t):
4292 'extension_additions : extension_addition_list'
4295 def p_extension_additions_2 (t):
4296 'extension_additions : '
4299 def p_extension_addition_list_1 (t):
4300 'extension_addition_list : COMMA extension_addition'
4303 def p_extension_addition_list_2 (t):
4304 'extension_addition_list : extension_addition_list COMMA extension_addition'
4305 t[0] = t[1] + [t[3]]
4307 def p_extension_addition_1 (t):
4308 'extension_addition : element_type'
4311 def p_element_type_list_1 (t):
4312 'element_type_list : element_type'
4315 def p_element_type_list_2 (t):
4316 'element_type_list : element_type_list COMMA element_type'
4317 t[0] = t[1] + [t[3]]
4319 def p_element_type_1 (t):
4320 'element_type : NamedType'
4321 t[0] = Node ('elt_type', val = t[1], optional = 0)
4323 def p_element_type_2 (t):
4324 'element_type : NamedType OPTIONAL'
4325 t[0] = Node ('elt_type', val = t[1], optional = 1)
4327 def p_element_type_3 (t):
4328 'element_type : NamedType DEFAULT Value'
4329 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
4331 # * this rules uses NamedValue instead of Value
4332 # * for the stupid choice value syntax (fieldname value)
4333 # * it should be like a set/seq value (ie with
4337 # XXX get to COMPONENTS later
4340 def p_SequenceValue_1 (t):
4341 'SequenceValue : LBRACE RBRACE'
4345 #def p_SequenceValue_2 (t):
4346 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
4349 #def p_ComponentValueList_1 (t):
4350 # 'ComponentValueList : NamedValue'
4353 #def p_ComponentValueList_2 (t):
4354 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
4355 # t[0] = t[1] + [t[3]]
4358 # 25 Notation for sequence-of types -------------------------------------------
4361 def p_SequenceOfType (t):
4362 '''SequenceOfType : SEQUENCE OF Type
4363 | SEQUENCE OF NamedType'''
4364 t[0] = SequenceOfType (val = t[3], size_constr = None)
4367 # 26 Notation for set types ---------------------------------------------------
4370 def p_SetType_1 (t):
4371 'SetType : SET LBRACE RBRACE'
4372 if t[3].has_key('ext_list'):
4373 t[0] = SetType (elt_list = [])
4375 def p_SetType_2 (t):
4376 'SetType : SET LBRACE ComponentTypeLists RBRACE'
4377 if t[3].has_key('ext_list'):
4378 t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4380 t[0] = SetType (elt_list = t[3]['elt_list'])
4383 # 27 Notation for set-of types ------------------------------------------------
4386 def p_SetOfType (t):
4387 '''SetOfType : SET OF Type
4388 | SET OF NamedType'''
4389 t[0] = SetOfType (val = t[3])
4391 # 28 Notation for choice types ------------------------------------------------
4394 def p_ChoiceType (t):
4395 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
4396 if t[3].has_key('ext_list'):
4397 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4399 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
4401 def p_alternative_type_lists_1 (t):
4402 'alternative_type_lists : alternative_type_list'
4403 t[0] = {'elt_list' : t[1]}
4405 def p_alternative_type_lists_2 (t):
4406 '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
4407 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
4409 def p_extension_addition_alternatives_1 (t):
4410 'extension_addition_alternatives : extension_addition_alternatives_list'
4413 def p_extension_addition_alternatives_2 (t):
4414 'extension_addition_alternatives : '
4417 def p_extension_addition_alternatives_list_1 (t):
4418 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
4421 def p_extension_addition_alternatives_list_2 (t):
4422 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
4423 t[0] = t[1] + [t[3]]
4425 def p_extension_addition_alternative_1 (t):
4426 'extension_addition_alternative : NamedType'
4429 def p_alternative_type_list_1 (t):
4430 'alternative_type_list : NamedType'
4433 def p_alternative_type_list_2 (t):
4434 'alternative_type_list : alternative_type_list COMMA NamedType'
4435 t[0] = t[1] + [t[3]]
4437 def p_selection_type (t): # XXX what is this?
4438 'selection_type : identifier LT Type'
4439 return Node ('seltype', ident = t[1], typ = t[3])
4441 # 30 Notation for tagged types ------------------------------------------------
4444 def p_TaggedType_1 (t):
4445 'TaggedType : Tag Type'
4446 t[1].mode = 'default'
4450 def p_TaggedType_2 (t):
4451 '''TaggedType : Tag IMPLICIT Type
4452 | Tag EXPLICIT Type'''
4458 'Tag : LBRACK Class ClassNumber RBRACK'
4459 t[0] = Tag(cls = t[2], num = t[3])
4461 def p_ClassNumber_1 (t):
4462 'ClassNumber : number'
4465 def p_ClassNumber_2 (t):
4466 'ClassNumber : DefinedValue'
4470 '''Class : UNIVERSAL
4484 #def p_any_type_2 (t):
4485 # 'any_type : ANY DEFINED BY identifier'
4486 # t[0] = Literal (val='asn1.ANY_constr(def_by="%s")' % t[4]) # XXX
4489 # 31 Notation for the object identifier type ----------------------------------
4492 def p_ObjectIdentifierType (t):
4493 'ObjectIdentifierType : OBJECT IDENTIFIER'
4494 t[0] = ObjectIdentifierType()
4497 def p_ObjectIdentifierValue (t):
4498 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
4499 t[0] = ObjectIdentifierValue (comp_list=t[2])
4501 def p_oid_comp_list_1 (t):
4502 'oid_comp_list : oid_comp_list oid_component'
4503 t[0] = t[1] + [t[2]]
4505 def p_oid_comp_list_2 (t):
4506 'oid_comp_list : oid_component'
4509 def p_oid_component (t):
4510 '''oid_component : number_form
4512 | name_and_number_form'''
4515 def p_number_form (t):
4516 'number_form : NUMBER'
4519 # 34 Notation for the external type -------------------------------------------
4522 def p_ExternalType (t):
4523 'ExternalType : EXTERNAL'
4524 t[0] = ExternalType()
4526 # 36 Notation for character string types --------------------------------------
4529 def p_CharacterStringType (t):
4530 '''CharacterStringType : RestrictedCharacterStringType
4531 | UnrestrictedCharacterStringType'''
4535 # 37 Definition of restricted character string types --------------------------
4537 def p_RestrictedCharacterStringType_1 (t):
4538 'RestrictedCharacterStringType : BMPString'
4539 t[0] = BMPStringType ()
4540 def p_RestrictedCharacterStringType_2 (t):
4541 'RestrictedCharacterStringType : GeneralString'
4542 t[0] = GeneralStringType ()
4543 def p_RestrictedCharacterStringType_3 (t):
4544 'RestrictedCharacterStringType : GraphicString'
4545 t[0] = GraphicStringType ()
4546 def p_RestrictedCharacterStringType_4 (t):
4547 'RestrictedCharacterStringType : IA5String'
4548 t[0] = IA5StringType ()
4549 def p_RestrictedCharacterStringType_5 (t):
4550 'RestrictedCharacterStringType : ISO646String'
4551 t[0] = ISO646StringType ()
4552 def p_RestrictedCharacterStringType_6 (t):
4553 'RestrictedCharacterStringType : NumericString'
4554 t[0] = NumericStringType ()
4555 def p_RestrictedCharacterStringType_7 (t):
4556 'RestrictedCharacterStringType : PrintableString'
4557 t[0] = PrintableStringType ()
4558 def p_RestrictedCharacterStringType_8 (t):
4559 'RestrictedCharacterStringType : TeletexString'
4560 t[0] = TeletexStringType ()
4561 def p_RestrictedCharacterStringType_9 (t):
4562 'RestrictedCharacterStringType : T61String'
4563 t[0] = T61StringType ()
4564 def p_RestrictedCharacterStringType_10 (t):
4565 'RestrictedCharacterStringType : UniversalString'
4566 t[0] = UniversalStringType ()
4567 def p_RestrictedCharacterStringType_11 (t):
4568 'RestrictedCharacterStringType : UTF8String'
4569 t[0] = UTF8StringType ()
4570 def p_RestrictedCharacterStringType_12 (t):
4571 'RestrictedCharacterStringType : VideotexString'
4572 t[0] = VideotexStringType ()
4573 def p_RestrictedCharacterStringType_13 (t):
4574 'RestrictedCharacterStringType : VisibleString'
4575 t[0] = VisibleStringType ()
4578 # 40 Definition of unrestricted character string types ------------------------
4581 def p_UnrestrictedCharacterStringType (t):
4582 'UnrestrictedCharacterStringType : CHARACTER STRING'
4583 t[0] = UnrestrictedCharacterStringType ()
4586 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
4588 # 42 Generalized time ---------------------------------------------------------
4590 def p_UsefulType_1 (t):
4591 'UsefulType : GeneralizedTime'
4592 t[0] = GeneralizedTime()
4594 # 43 Universal time -----------------------------------------------------------
4596 def p_UsefulType_2 (t):
4597 'UsefulType : UTCTime'
4600 # 44 The object descriptor type -----------------------------------------------
4602 def p_UsefulType_3 (t):
4603 'UsefulType : ObjectDescriptor'
4604 t[0] = ObjectDescriptor()
4607 # 45 Constrained types --------------------------------------------------------
4610 def p_ConstrainedType_1 (t):
4611 'ConstrainedType : Type Constraint'
4613 t[0].AddConstraint(t[2])
4615 def p_ConstrainedType_2 (t):
4616 'ConstrainedType : TypeWithConstraint'
4620 def p_TypeWithConstraint_1 (t):
4621 '''TypeWithConstraint : SET Constraint OF Type
4622 | SET SizeConstraint OF Type'''
4623 t[0] = SetOfType (val = t[4], constr = t[2])
4625 def p_TypeWithConstraint_2 (t):
4626 '''TypeWithConstraint : SEQUENCE Constraint OF Type
4627 | SEQUENCE SizeConstraint OF Type'''
4628 t[0] = SequenceOfType (val = t[4], constr = t[2])
4630 def p_TypeWithConstraint_3 (t):
4631 '''TypeWithConstraint : SET Constraint OF NamedType
4632 | SET SizeConstraint OF NamedType'''
4633 t[0] = SetOfType (val = t[4], constr = t[2])
4635 def p_TypeWithConstraint_4 (t):
4636 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
4637 | SEQUENCE SizeConstraint OF NamedType'''
4638 t[0] = SequenceOfType (val = t[4], constr = t[2])
4642 def p_Constraint (t):
4643 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
4646 def p_ConstraintSpec (t):
4647 '''ConstraintSpec : ElementSetSpecs
4648 | GeneralConstraint'''
4651 # 46 Element set specification ------------------------------------------------
4654 def p_ElementSetSpecs_1 (t):
4655 'ElementSetSpecs : RootElementSetSpec'
4658 def p_ElementSetSpecs_2 (t):
4659 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
4663 def p_ElementSetSpecs_3 (t):
4664 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA ElementSetSpecs'
4668 # skip compound constraints, only simple ones are supported
4670 def p_RootElementSetSpec_1 (t):
4671 'RootElementSetSpec : SubtypeElements'
4674 def p_RootElementSetSpec_2 (t):
4675 'RootElementSetSpec : SubtypeElements IntersectionMark SubtypeElements'
4676 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
4678 def p_IntersectionMark (t):
4679 '''IntersectionMark : CIRCUMFLEX
4682 # 47 Subtype elements ---------------------------------------------------------
4685 def p_SubtypeElements (t):
4686 '''SubtypeElements : SingleValue
4692 | InnerTypeConstraints
4693 | PatternConstraint'''
4698 def p_SingleValue (t):
4699 'SingleValue : Value'
4700 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
4702 # 47.3 Contained subtype
4704 def p_ContainedSubtype (t):
4705 'ContainedSubtype : Includes Type'
4706 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
4709 '''Includes : INCLUDES
4714 def p_ValueRange (t):
4715 'ValueRange : lower_end_point RANGE upper_end_point'
4716 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
4719 def p_lower_end_point_1 (t):
4720 'lower_end_point : lower_end_value '
4723 def p_lower_end_point_2 (t):
4724 'lower_end_point : lower_end_value LT' # XXX LT first?
4725 t[0] = t[1] # but not inclusive range
4727 def p_upper_end_point_1 (t):
4728 'upper_end_point : upper_end_value'
4731 def p_upper_end_point_2 (t):
4732 'upper_end_point : LT upper_end_value'
4733 t[0] = t[1] # but not inclusive range
4735 def p_lower_end_value (t):
4736 '''lower_end_value : Value
4740 def p_upper_end_value (t):
4741 '''upper_end_value : Value
4745 # 47.5 Size constraint
4747 def p_SizeConstraint (t):
4748 'SizeConstraint : SIZE Constraint'
4749 t[0] = Constraint (type = 'Size', subtype = t[2])
4751 # 47.6 Type constraint
4753 def p_TypeConstraint (t):
4754 'TypeConstraint : Type'
4755 t[0] = Constraint (type = 'Type', subtype = t[1])
4757 # 47.7 Permitted alphabet
4759 def p_PermittedAlphabet (t):
4760 'PermittedAlphabet : FROM Constraint'
4761 t[0] = Constraint (type = 'From', subtype = t[2])
4763 # 47.8 Inner subtyping
4765 def p_InnerTypeConstraints (t):
4766 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
4767 | WITH COMPONENTS MultipleTypeConstraints'''
4768 pass # ignore PER invisible constraint
4771 def p_SingleTypeConstraint (t):
4772 'SingleTypeConstraint : Constraint'
4776 def p_MultipleTypeConstraints (t):
4777 '''MultipleTypeConstraints : FullSpecification
4778 | PartialSpecification'''
4781 def p_FullSpecification (t):
4782 'FullSpecification : LBRACE TypeConstraints RBRACE'
4785 def p_PartialSpecification (t):
4786 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
4789 def p_TypeConstraints_1 (t):
4790 'TypeConstraints : named_constraint'
4793 def p_TypeConstraints_2 (t):
4794 'TypeConstraints : TypeConstraints COMMA named_constraint'
4795 t[0] = t[1] + [t[3]]
4797 def p_named_constraint_1 (t):
4798 'named_constraint : identifier constraint'
4799 return Node ('named_constraint', ident = t[1], constr = t[2])
4801 def p_named_constraint_2 (t):
4802 'named_constraint : constraint'
4803 return Node ('named_constraint', constr = t[1])
4805 def p_constraint (t):
4806 'constraint : value_constraint presence_constraint'
4807 t[0] = Node ('constraint', value = t[1], presence = t[2])
4809 def p_value_constraint_1 (t):
4810 'value_constraint : Constraint'
4813 def p_value_constraint_2 (t):
4814 'value_constraint : '
4817 def p_presence_constraint_1 (t):
4818 '''presence_constraint : PRESENT
4823 def p_presence_constraint_2 (t):
4824 '''presence_constraint : '''
4827 # 47.9 Pattern constraint
4829 def p_PatternConstraint (t):
4830 'PatternConstraint : PATTERN Value'
4831 t[0] = Constraint (type = 'Pattern', subtype = t[2])
4833 # 49 The exception identifier
4836 def p_ExceptionSpec (t):
4840 # /*-----------------------------------------------------------------------*/
4841 # /* Value Notation Productions */
4842 # /*-----------------------------------------------------------------------*/
4847 def p_ext_val_ref (t):
4848 'ext_val_ref : type_ref DOT identifier'
4849 # XXX coerce type_ref to module_ref
4850 return Node ('ext_val_ref', module = t[1], ident = t[3])
4852 def p_special_real_val (t):
4853 '''special_real_val : PLUS_INFINITY
4858 # Note that Z39.50 v3 spec has upper-case here for, e.g., SUTRS.
4859 # I've hacked the grammar to be liberal about what it accepts.
4860 # XXX should have -strict command-line flag to only accept lowercase
4861 # here, since that's what X.208 says.
4862 def p_name_form (t):
4863 '''name_form : type_ref
4867 def p_name_and_number_form_1 (t):
4868 '''name_and_number_form : identifier LPAREN number_form RPAREN
4869 | type_ref LPAREN number_form RPAREN'''
4870 t[0] = Node ('name_and_number', ident = t[1], number = t[3])
4872 def p_name_and_number_form_2 (t):
4873 'name_and_number_form : identifier LPAREN DefinedValue RPAREN'
4874 t[0] = Node ('name_and_number', ident = t[1], val = t[3])
4876 # see X.208 if you are dubious about lcase only for identifier
4877 def p_identifier (t):
4878 'identifier : LCASE_IDENT'
4882 def p_binary_string (t):
4883 'binary_string : BSTRING'
4886 def p_hex_string (t):
4887 'hex_string : HSTRING'
4890 def p_char_string (t):
4891 'char_string : QSTRING'
4899 #--- ITU-T Recommendation X.681 -----------------------------------------------
4901 # 7 ASN.1 lexical items -------------------------------------------------------
4903 # 7.1 Information object class references
4905 def p_objectclassreference (t):
4906 'objectclassreference : CLASS_IDENT'
4909 # 7.4 Type field references
4911 def p_typefieldreference (t):
4912 'typefieldreference : AMPERSAND UCASE_IDENT'
4915 # 7.5 Value field references
4917 def p_valuefieldreference (t):
4918 'valuefieldreference : AMPERSAND LCASE_IDENT'
4921 # 8 Referencing definitions
4924 def p_DefinedObjectClass (t):
4925 '''DefinedObjectClass : objectclassreference
4926 | UsefulObjectClassReference'''
4930 def p_UsefulObjectClassReference (t):
4931 '''UsefulObjectClassReference : TYPE_IDENTIFIER
4932 | ABSTRACT_SYNTAX'''
4935 # 9 Information object class definition and assignment
4938 def p_FieldName (t):
4939 '''FieldName : typefieldreference
4940 | valuefieldreference'''
4943 # 14 Notation for the object class field type ---------------------------------
4946 def p_ObjectClassFieldType (t):
4947 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
4948 t[0] = get_type_from_class(t[1], t[3])
4953 useful_object_class_types = {
4955 'TYPE-IDENTIFIER/id' : lambda : ObjectIdentifierType(),
4956 'TYPE-IDENTIFIER/Type' : lambda : OpenType(),
4958 'ABSTRACT-SYNTAX/id' : lambda : ObjectIdentifierType(),
4959 'ABSTRACT-SYNTAX/Type' : lambda : OpenType(),
4960 'ABSTRACT-SYNTAX/property' : lambda : BitStringType(),
4963 object_class_types = {
4966 object_class_typerefs = {
4969 class_types_creator = {
4970 'OpenType' : lambda : OpenType(),
4973 def is_class_ident(name):
4974 return class_names.has_key(name)
4976 def add_class_ident(name):
4977 class_names[name] = name
4979 def get_type_from_class(cls, fld):
4980 key = cls + '/' + fld
4982 if object_class_typerefs.has_key(key):
4983 return Type_Ref(val=object_class_typerefs[key])
4985 creator = lambda : AnyType()
4986 creator = useful_object_class_types.get(key, creator)
4987 creator = object_class_types.get(key, creator)
4990 def set_type_to_class(cls, fld, typename, typeref = None):
4991 key = cls + '/' + fld
4992 if object_class_types.has_key(key): return False
4993 if object_class_typerefs.has_key(key): return False
4995 if (typename == 'TypeReference'):
4996 if not typeref: return False
4997 object_class_typerefs[key] = typeref
5000 creator = class_types_creator.get(typename)
5002 object_class_types[key] = creator
5007 #--- ITU-T Recommendation X.682 -----------------------------------------------
5009 # 8 General constraint specification ------------------------------------------
5012 def p_GeneralConstraint (t):
5013 '''GeneralConstraint : UserDefinedConstraint'''
5015 # | ContentsConstraint''
5018 # 9 User-defined constraints --------------------------------------------------
5021 def p_UserDefinedConstraint (t):
5022 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
5023 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
5025 def p_UserDefinedConstraintParameterList_1 (t):
5026 'UserDefinedConstraintParameterList : '
5029 def p_UserDefinedConstraintParameterList_2 (t):
5030 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
5033 def p_UserDefinedConstraintParameterList_3 (t):
5034 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
5035 t[0] = t[1] + [t[3]]
5038 def p_UserDefinedConstraintParameter (t):
5039 'UserDefinedConstraintParameter : type_ref'
5043 #--- ITU-T Recommendation X.683 -----------------------------------------------
5045 # 8 Parameterized assignments -------------------------------------------------
5050 def p_ParameterizedTypeAssignment (t):
5051 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
5053 t[0].SetName(t[1] + 'xxx')
5056 def p_ParameterList (t):
5057 'ParameterList : LBRACE Parameters RBRACE'
5060 def p_Parameters_1 (t):
5061 'Parameters : Parameter'
5064 def p_Parameters_2 (t):
5065 'Parameters : Parameters COMMA Parameter'
5066 t[0] = t[1] + [t[3]]
5068 def p_Parameter_1 (t):
5069 'Parameter : Type COLON Reference'
5072 def p_Parameter_2 (t):
5073 'Parameter : Reference'
5077 # 9 Referencing parameterized definitions -------------------------------------
5080 def p_ParameterizedReference (t):
5081 'ParameterizedReference : type_ref LBRACE RBRACE'
5086 def p_ParameterizedType (t):
5087 'ParameterizedType : type_ref ActualParameterList'
5092 def p_ActualParameterList (t):
5093 'ActualParameterList : LBRACE ActualParameters RBRACE'
5096 def p_ActualParameters_1 (t):
5097 'ActualParameters : ActualParameter'
5100 def p_ActualParameters_2 (t):
5101 'ActualParameters : ActualParameters COMMA ActualParameter'
5102 t[0] = t[1] + [t[3]]
5104 def p_ActualParameter (t):
5105 '''ActualParameter : Type
5112 raise ParseError(t, input_file)
5117 token = lexer.token ()
5123 def do_module (ast, defined_dict):
5124 assert (ast.type == 'Module')
5125 ctx = Ctx (defined_dict)
5126 print ast.to_python (ctx)
5127 print ctx.output_assignments ()
5128 print ctx.output_pyquotes ()
5130 def eth_do_module (ast, ectx):
5131 assert (ast.type == 'Module')
5132 if ectx.dbg('s'): print ast.str_depth(0)
5135 def testyacc(s, fn, defined_dict):
5136 ast = yacc.parse(s, debug=0)
5137 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
5138 print """#!/usr/bin/env python
5139 # Auto-generated from %s at %s
5140 from PyZ3950 import asn1""" % (fn, time_str)
5142 eth_do_module (module, defined_dict)
5145 # Wireshark compiler
5148 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c conform_file] [-e] input_file(s) ...
5150 -b : BER (default is PER)
5151 -u : unaligned (default is aligned)
5152 -p proto : protocol name (implies -S)
5153 default is module-name from input_file (renamed by #.MODULE if present)
5154 -F : create 'field functions'
5155 -T : tagged type support (experimental)
5156 -o name : output files name core (default is <proto>)
5157 -O dir : output directory
5158 -c conform_file : conformation file
5159 -I path : path for conformance file includes
5160 -e : create conformation file for exported types
5161 -S : single output for multiple modules
5162 -s template : single file output (template is input file without .c/.h extension)
5163 -k : keep intermediate files though single file output is used
5164 -L : suppress #line directive from .cnf file
5165 input_file(s) : input ASN.1 file(s)
5167 -d dbg : debug output, dbg = [l][y][p][s][a][t][c][o]
5171 s - internal ASN.1 structure
5172 a - list of assignments
5174 c - conformance values
5175 o - list of output files
5180 print "ASN.1 to Wireshark dissector compiler";
5182 opts, args = getopt.getopt(sys.argv[1:], "h?d:buXp:FTo:O:c:I:eSs:kL");
5183 except getopt.GetoptError:
5184 eth_usage(); sys.exit(2)
5186 eth_usage(); sys.exit(2)
5191 ectx = EthCtx(conform, output)
5192 ectx.encoding = 'per'
5193 ectx.proto_opt = None
5194 ectx.fld_opt = False
5195 ectx.tag_opt = False
5196 ectx.outnm_opt = None
5201 ectx.merge_modules = False
5202 ectx.conform.suppress_line = False;
5203 ectx.output.outnm = None
5204 ectx.output.single_file = None
5206 if o in ("-h", "-?"):
5207 eth_usage(); sys.exit(2)
5209 ectx.encoding = 'ber'
5212 ectx.merge_modules = True
5220 ectx.conform.include_path.append(a)
5222 ectx.aligned = False
5228 ectx.merge_modules = True
5232 ectx.output.outdir = a
5234 ectx.output.single_file = a
5236 ectx.output.keep = True
5238 ectx.conform.suppress_line = True
5240 warnings.warn("Command line option -X is obsolete and can be removed")
5243 ectx.conform.read(conf_to_read)
5245 (ld, yd, pd) = (0, 0, 0);
5246 if ectx.dbg('l'): ld = 1
5247 if ectx.dbg('y'): yd = 1
5248 if ectx.dbg('p'): pd = 2
5249 lexer = lex.lex(debug=ld)
5250 yacc.yacc(method='LALR', debug=yd)
5255 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
5259 eth_do_module(module, ectx)
5260 if (not ectx.merge_modules): # output for each module
5262 ectx.eth_do_output()
5264 if (ectx.merge_modules): # common output for all module
5266 ectx.eth_do_output()
5269 ectx.conform.dbg_print()
5270 ectx.conform.unused_report()
5273 ectx.output.dbg_print()
5274 ectx.output.make_single_file()
5280 if len (sys.argv) == 1:
5282 s = raw_input ('Query: ')
5285 testfn (s, 'console', {})
5288 for fn in sys.argv [1:]:
5290 testfn (f.read (), fn, defined_dict)
5295 #--- BODY ---------------------------------------------------------------------
5297 if __name__ == '__main__':
5298 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
5303 #------------------------------------------------------------------------------