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('.', '_')
145 class LexError(Exception): pass
146 class ParseError(Exception): pass
148 # 11 ASN.1 lexical items
151 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
152 r'\.\.' : 'RANGE', # 11.17 Range separator
153 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
154 #r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
155 #r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
156 # 11.26 Single character lexical items
171 #r"'" : 'APOSTROPHE',
174 #r'\!' : 'EXCLAMATION',
175 r'\^' : 'CIRCUMFLEX',
179 # 11.27 Reserved words
181 # all keys in reserved_words must start w/ upper case
184 'BOOLEAN' : 'BOOLEAN',
185 'INTEGER' : 'INTEGER',
187 'CHARACTER' : 'CHARACTER',
191 'SEQUENCE': 'SEQUENCE',
194 'IMPLICIT': 'IMPLICIT',
197 # 'EXTERNAL' : 'EXTERNAL', # XXX added over base
198 'OPTIONAL':'OPTIONAL',
199 'DEFAULT' : 'DEFAULT',
200 'COMPONENTS': 'COMPONENTS',
201 'UNIVERSAL' : 'UNIVERSAL',
202 'APPLICATION' : 'APPLICATION',
203 'PRIVATE' : 'PRIVATE',
208 'DEFINITIONS' : 'DEFINITIONS',
209 'EXPLICIT' : 'EXPLICIT',
210 'ENUMERATED' : 'ENUMERATED',
211 'EXPORTS' : 'EXPORTS',
212 'IMPORTS' : 'IMPORTS',
214 'INCLUDES': 'INCLUDES',
219 'INTERSECTION' : 'INTERSECTION',
221 'PATTERN' : 'PATTERN',
223 'COMPONENT': 'COMPONENT',
224 'PRESENT' : 'PRESENT',
226 # 'DEFINED' : 'DEFINED',
227 'CONSTRAINED' : 'CONSTRAINED',
229 'PLUS-INFINITY' : 'PLUS_INFINITY',
230 'MINUS-INFINITY' : 'MINUS_INFINITY',
231 'GeneralizedTime' : 'GeneralizedTime',
232 'UTCTime' : 'UTCTime',
233 'ObjectDescriptor': 'ObjectDescriptor',
234 'AUTOMATIC': 'AUTOMATIC',
236 'IDENTIFIER': 'IDENTIFIER',
237 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
238 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
239 # 'OPERATION' : 'OPERATION',
240 # 'ARGUMENT' : 'ARGUMENT',
241 # 'RESULT' : 'RESULT',
242 # 'ERRORS' : 'ERRORS',
243 # 'LINKED' : 'LINKED',
245 # 'PARAMETER' : 'PARAMETER',
247 # 'BIND-ERROR' : 'BIND_ERROR',
248 # 'UNBIND' : 'UNBIND',
249 # 'APPLICATION-CONTEXT' : 'AC',
250 # 'APPLICATON-SERVICE-ELEMENTS' : 'ASES',
251 # 'REMOTE' : 'REMOTE',
252 # 'INITIATOR' : 'INITIATOR',
253 # 'RESPONDER' : 'RESPONDER',
254 # 'APPLICATION-SERVICE-ELEMENT' : 'ASE',
255 # 'OPERATIONS' : None,
256 # 'EXTENSION-ATTRIBUTE' : 'EXTENSION_ATTRIBUTE',
257 # 'EXTENSIONS' : None,
259 # 'EXTENSION' : None,
262 # 'SUBMISSION' : None,
268 # r'ABSTRACT\s*OPERATIONS' : 'ABSTR_OPS',
274 for k in static_tokens.keys ():
275 if static_tokens [k] == None:
276 static_tokens [k] = k
278 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
279 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
282 for s in StringTypes:
283 reserved_words[s + 'String'] = s + 'String'
285 tokens = static_tokens.values() \
286 + reserved_words.values() \
287 + ['BSTRING', 'HSTRING', 'QSTRING',
288 'UCASE_IDENT', 'LCASE_IDENT',
292 for (k, v) in static_tokens.items ():
293 __main__.__dict__['t_' + v] = k
295 # 11.10 Binary strings
300 # 11.12 Hexadecimal strings
307 return t # XXX might want to un-""
309 def t_UCASE_IDENT (t):
310 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
311 t.type = reserved_words.get(t.value, "UCASE_IDENT")
314 def t_LCASE_IDENT (t):
315 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
327 pyquote_str = 'PYQUOTE'
329 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
330 if (t.value.find("\n") >= 0) : t.lineno += 1
331 if t.value[2:2+len (pyquote_str)] == pyquote_str:
332 t.value = t.value[2+len(pyquote_str):]
333 t.value = t.value.lstrip ()
342 t.lineno += t.value.count("\n")
345 print "Error", t.value[:100], t.lineno
351 def __init__ (self, defined_dict, indent = 0):
352 self.tags_def = 'EXPLICIT' # default = explicit
354 self.assignments = {}
355 self.dependencies = {}
357 self.defined_dict = defined_dict
360 return " " * (4 * self.indent_lev)
365 assert (self.indent_lev >= 0)
366 def register_assignment (self, ident, val, dependencies):
367 if self.assignments.has_key (ident):
368 raise "Duplicate assignment for " + ident
369 if self.defined_dict.has_key (ident):
370 raise "cross-module duplicates for " + ident
371 self.defined_dict [ident] = 1
372 self.assignments[ident] = val
373 self.dependencies [ident] = dependencies
375 # return "#%s depends on %s" % (ident, str (dependencies))
376 def register_pyquote (self, val):
377 self.pyquotes.append (val)
379 def output_assignments (self):
382 assign_keys = self.assignments.keys()
383 to_output_count = len (assign_keys)
386 for (ident, val) in self.assignments.iteritems ():
387 if already_output.has_key (ident):
390 for d in self.dependencies [ident]:
391 if (not already_output.has_key (d) and
395 text_list.append ("%s=%s" % (ident,
396 self.assignments [ident]))
397 already_output [ident] = 1
400 assert (to_output_count >= 0)
402 if to_output_count == 0:
404 # OK, we detected a cycle
406 for ident in self.assignments.iterkeys ():
407 if not already_output.has_key (ident):
408 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
409 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
411 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
412 for (ident, val) in self.assignments.iteritems ():
413 if not already_output.has_key (ident):
414 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
417 return "\n".join (text_list)
418 def output_pyquotes (self):
419 return "\n".join (self.pyquotes)
420 def make_new_name (self):
422 return "_compiler_generated_name_%d" % (self.name_ctr,)
424 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
434 #--- EthCtx -------------------------------------------------------------------
436 def __init__(self, conform, output, indent = 0):
437 self.conform = conform
440 def encp(self): # encoding protocol
445 def Per(self): return self.encoding == 'per'
446 def Ber(self): return self.encoding == 'ber'
447 def Aligned(self): return self.aligned
448 def Unaligned(self): return not self.aligned
449 def Fld(self): return self.fld_opt or self.Ber()
450 def Tag(self): return self.tag_opt # or self.Ber() - temporary comment out (experimental feature)
451 def NAPI(self): return False # disable planned features
454 if (self.dbgopt.find(d) >= 0):
459 def eth_get_type_attr(self, type):
461 while (not self.type[type]['import']
462 and self.type[type]['val'].type == 'Type_Ref'):
463 type = self.type[type]['val'].val
468 attr.update(self.type[t]['attr'])
469 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
472 #--- eth_reg_assign ---------------------------------------------------------
473 def eth_reg_assign(self, ident, val, virt=False):
474 #print "eth_reg_assign(ident='%s')" % (ident)
475 if self.assign.has_key(ident):
476 raise "Duplicate assignment for " + ident
477 self.assign[ident] = { 'val' : val , 'virt' : virt }
478 self.assign_ord.append(ident)
480 #--- eth_reg_vassign --------------------------------------------------------
481 def eth_reg_vassign(self, vassign):
482 ident = vassign.ident
483 #print "eth_reg_vassign(ident='%s')" % (ident)
484 if self.vassign.has_key(ident):
485 raise "Duplicate value assignment for " + ident
486 self.vassign[ident] = vassign
487 self.vassign_ord.append(ident)
489 #--- eth_import_type --------------------------------------------------------
490 def eth_import_type(self, ident, mod, proto):
491 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
492 if self.type.has_key(ident):
493 raise "Duplicate type for " + ident
494 self.type[ident] = {'import' : mod, 'proto' : proto,
496 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
497 'STRINGS' : 'NULL', 'BITMASK' : '0' }
498 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
499 self.type_imp.append(ident)
501 #--- eth_import_value -------------------------------------------------------
502 def eth_import_value(self, ident, mod, proto):
503 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
504 if self.type.has_key(ident):
505 raise "Duplicate value for " + ident
506 self.value[ident] = {'import' : mod, 'proto' : proto,
508 self.value_imp.append(ident)
510 #--- eth_dep_add ------------------------------------------------------------
511 def eth_dep_add(self, type, dep):
512 if self.type_dep.has_key(type):
513 self.type_dep[type].append(dep)
515 self.type_dep[type] = [dep]
517 #--- eth_reg_type -----------------------------------------------------------
518 def eth_reg_type(self, ident, val):
519 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
520 if self.type.has_key(ident):
521 raise "Duplicate type for " + ident
522 self.type[ident] = { 'val' : val, 'import' : None }
523 if len(ident.split('/')) > 1:
524 self.type[ident]['tname'] = val.eth_tname()
526 self.type[ident]['tname'] = asn2c(ident)
527 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
528 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
529 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
530 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
531 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
532 self.type[ident]['ethname'] = ''
533 if val.type == 'Type_Ref':
534 self.type[ident]['attr'] = {}
536 (ftype, display) = val.eth_ftype(self)
537 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
538 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
539 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
540 self.type_ord.append(ident)
542 #--- eth_reg_value ----------------------------------------------------------
543 def eth_reg_value(self, ident, type, value):
544 #print "eth_reg_value(ident='%s')" % (ident)
545 if self.value.has_key(ident):
546 raise "Duplicate value for " + ident
547 self.value[ident] = { 'import' : None, 'proto' : self.proto,
548 'type' : type, 'value' : value }
549 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
550 self.value[ident]['ethname'] = ''
551 self.value_ord.append(ident)
553 #--- eth_reg_field ----------------------------------------------------------
554 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
555 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
556 if self.field.has_key(ident):
557 raise "Duplicate field for " + ident
558 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
559 'modified' : '', 'attr' : {} }
560 name = ident.split('/')[-1]
561 if len(ident.split('/')) > 1 and name == '_item': # Sequnce/Set of type
562 self.field[ident]['attr']['NAME'] = '"Item"'
563 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
565 self.field[ident]['attr']['NAME'] = '"%s"' % name
566 self.field[ident]['attr']['ABBREV'] = asn2c(name)
567 if self.conform.check_item('FIELD_ATTR', ident):
568 self.field[ident]['modified'] = '#' + str(id(self))
569 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
571 self.pdu_ord.append(ident)
573 self.field_ord.append(ident)
574 if parent: self.eth_dep_add(parent, type)
576 #--- eth_clean --------------------------------------------------------------
578 self.proto = self.proto_opt;
579 #--- ASN.1 tables ----------------
590 self.vassign_ord = []
594 #--- Modules ------------
596 #--- types -------------------
598 self.eth_type_ord = []
599 self.eth_export_ord = []
600 self.eth_type_dupl = {}
602 #--- value dependencies -------------------
604 #--- values -------------------
606 self.eth_value_ord = []
607 #--- fields -------------------------
610 self.eth_hfpdu_ord = []
611 self.eth_hf_dupl = {}
612 #--- type dependencies -------------------
613 self.eth_type_ord1 = []
614 self.eth_dep_cycle = []
615 self.dep_cycle_eth_type = {}
616 #--- value dependencies and export -------------------
617 self.eth_value_ord1 = []
618 self.eth_vexport_ord = []
620 #--- eth_prepare ------------------------------------------------------------
621 def eth_prepare(self):
622 self.eproto = asn2c(self.proto)
624 #--- dummy types/fields for PDU registration ---
626 if (self.conform.check_item('PDU', nm)):
627 self.eth_reg_type('_dummy/'+nm, NullType())
628 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
630 #--- types -------------------
631 for t in self.type_imp:
633 self.eth_type[nm] = { 'import' : self.type[t]['import'],
634 'proto' : asn2c(self.type[t]['proto']),
635 'attr' : {}, 'ref' : []}
636 self.type[t]['ethname'] = nm
637 for t in self.type_ord:
638 nm = self.type[t]['tname']
639 if ((nm.find('#') >= 0) or
640 ((len(t.split('/'))>1) and
641 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t)) and
642 not self.conform.check_item('TYPE_RENAME', t))):
643 if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequnce of type at the 1st level
644 nm = t.split('/')[0] + t.split('/')[1]
645 elif t.split('/')[-1] == '_item': # Sequnce/Set of type at next levels
646 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
647 elif t.split('/')[-1] == '_untag': # Untagged type
648 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
650 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
652 if self.eth_type.has_key(nm):
653 if self.eth_type_dupl.has_key(nm):
654 self.eth_type_dupl[nm].append(t)
656 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
657 nm += str(len(self.eth_type_dupl[nm])-1)
658 if self.eth_type.has_key(nm):
659 self.eth_type[nm]['ref'].append(t)
661 self.eth_type_ord.append(nm)
662 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
663 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
664 'val' : self.type[t]['val'],
667 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
668 self.type[t]['ethname'] = nm
669 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
670 self.eth_export_ord.append(nm)
671 self.eth_type[nm]['export'] |= self.type[t]['export']
672 self.eth_type[nm]['enum'] |= self.type[t]['enum']
673 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
674 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
675 if self.type[t]['attr'].get('STRINGS') == '$$':
676 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
677 for t in self.eth_type_ord:
678 bits = self.eth_type[t]['val'].eth_named_bits()
680 for (val, id) in bits:
681 self.named_bit.append({'name' : id, 'val' : val,
682 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
683 'ftype' : 'FT_BOOLEAN', 'display' : '8',
685 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
686 if self.eth_type[t]['val'].eth_need_tree():
687 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
689 self.eth_type[t]['tree'] = None
691 #--- value dependencies -------------------
692 for v in self.value_ord:
693 if isinstance (self.value[v]['value'], Value):
694 dep = self.value[v]['value'].get_dep()
696 dep = self.value[v]['value']
697 if dep and self.value.has_key(dep):
698 self.value_dep.setdefault(v, []).append(dep)
700 #--- exports all necessary values
701 for v in self.value_ord:
702 if not self.value[v]['export']: continue
703 deparr = self.value_dep.get(v, [])
706 if not self.value[d]['import']:
707 if not self.value[d]['export']:
708 self.value[d]['export'] = EF_TYPE
709 deparr.extend(self.value_dep.get(d, []))
711 #--- values -------------------
712 for v in self.value_imp:
714 self.eth_value[nm] = { 'import' : self.value[v]['import'],
715 'proto' : asn2c(self.value[v]['proto']),
717 self.value[v]['ethname'] = nm
718 for v in self.value_ord:
720 self.eth_value[nm] = { 'import' : None,
721 'proto' : asn2c(self.value[v]['proto']),
722 'export' : self.value[v]['export'], 'ref' : [v] }
723 if isinstance (self.value[v]['value'], Value):
724 self.eth_value[nm]['value'] = self.value[v]['value'].to_str()
726 self.eth_value[nm]['value'] = self.value[v]['value']
727 self.eth_value_ord.append(nm)
728 self.value[v]['ethname'] = nm
730 #--- fields -------------------------
731 for f in (self.pdu_ord + self.field_ord):
732 if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequnce/Set of type
733 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
735 nm = f.split('/')[-1]
736 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
738 if (self.field[f]['pdu']):
740 t = self.field[f]['type']
741 if self.type.has_key(t):
742 ethtype = self.type[t]['ethname']
743 else: # undefined type
745 print "Dummy imported: ", t
746 self.type[t] = {'import' : 'xxx', 'proto' : 'xxx',
748 self.type[t]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
749 'STRINGS' : 'NULL', 'BITMASK' : '0' }
750 self.eth_type[t] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
752 ethtypemod = ethtype + self.field[f]['modified']
753 if self.eth_hf.has_key(nm):
754 if self.eth_hf_dupl.has_key(nm):
755 if self.eth_hf_dupl[nm].has_key(ethtypemod):
756 nm = self.eth_hf_dupl[nm][ethtypemod]
757 self.eth_hf[nm]['ref'].append(f)
758 self.field[f]['ethname'] = nm
761 nmx = nm + str(len(self.eth_hf_dupl[nm]))
762 self.eth_hf_dupl[nm][ethtype] = nmx
765 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
766 self.eth_hf[nm]['ref'].append(f)
767 self.field[f]['ethname'] = nm
770 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
773 if (self.field[f]['pdu']):
774 self.eth_hfpdu_ord.append(nm)
776 self.eth_hf_ord.append(nm)
777 fullname = "hf_%s_%s" % (self.eproto, nm)
778 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
779 attr.update(self.field[f]['attr'])
780 if (self.NAPI() and attr.has_key('NAME')):
781 attr['NAME'] += self.field[f]['idx']
782 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
783 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
784 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
785 'attr' : attr.copy(), 'ref' : [f]}
786 self.field[f]['ethname'] = nm
787 #--- type dependencies -------------------
788 x = {} # already emitted
789 #print '# Dependency computation'
790 for t in self.type_ord:
791 if x.has_key(self.type[t]['ethname']):
792 #print 'Continue: %s : %s' % (t, self.type[t]['ethname'])
795 stackx = {t : self.type_dep.get(t, [])[:]}
796 #print 'Push: %s : %s' % (t, str(stackx[t]))
798 if stackx[stack[-1]]: # has dependencies
799 d = stackx[stack[-1]].pop(0)
800 if x.has_key(self.type[d]['ethname']) or self.type[d]['import']:
802 if stackx.has_key(d): # cyclic dependency
805 c = [d] + c[0:c.index(d)+1]
807 self.eth_dep_cycle.append(c)
808 #print 'Cyclic: %s ' % (' -> '.join(c))
811 stackx[d] = self.type_dep.get(d, [])[:]
812 #print 'Push: %s : %s' % (d, str(stackx[d]))
814 #print 'Pop: %s' % (stack[-1])
815 del stackx[stack[-1]]
816 e = self.type[stack.pop()]['ethname']
819 #print 'Add: %s' % (e)
820 self.eth_type_ord1.append(e)
823 while i < len(self.eth_dep_cycle):
824 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
825 self.dep_cycle_eth_type.setdefault(t, []).append(i)
828 #--- value dependencies and export -------------------
829 for v in self.eth_value_ord:
830 if self.eth_value[v]['export']:
831 self.eth_vexport_ord.append(v)
833 self.eth_value_ord1.append(v)
835 #--- eth_vals_nm ------------------------------------------------------------
836 def eth_vals_nm(self, tname):
838 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
839 out += "%s_" % (self.eproto)
840 out += "%s_vals" % (tname)
843 #--- eth_vals ---------------------------------------------------------------
844 def eth_vals(self, tname, vals):
846 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
847 if (not self.eth_type[tname]['export'] & EF_VALS):
849 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
850 for (val, id) in vals:
852 vval = self.eth_enum_item(tname, id)
855 out += ' { %3s, "%s" },\n' % (vval, id)
856 out += " { 0, NULL }\n};\n"
859 #--- eth_enum_prefix ------------------------------------------------------------
860 def eth_enum_prefix(self, tname):
862 if (self.eth_type[tname]['export'] & EF_ENUM):
863 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
865 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
868 if (not self.eth_type[tname]['enum'] & EF_NO_TYPE):
871 if (self.eth_type[tname]['enum'] & EF_UCASE):
875 #--- eth_enum_nm ------------------------------------------------------------
876 def eth_enum_nm(self, tname):
877 out = self.eth_enum_prefix(tname)
881 #--- eth_enum_item ---------------------------------------------------------------
882 def eth_enum_item(self, tname, ident):
883 out = self.eth_enum_prefix(tname)
884 out += '_' + asn2c(ident)
885 if (self.eth_type[tname]['enum'] & EF_UCASE):
889 #--- eth_enum ---------------------------------------------------------------
890 def eth_enum(self, tname, vals):
892 if (self.eth_type[tname]['enum'] & EF_DEFINE):
893 out += "/* enumerated values for %s */\n" % (tname)
894 for (val, id) in vals:
895 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
897 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
898 for (val, id) in vals:
899 out += ' %-12s %3s,\n' % (self.eth_enum_item(tname, id), val)
900 out += "} %s;\n" % (self.eth_enum_nm(tname))
903 #--- eth_bits ---------------------------------------------------------------
904 def eth_bits(self, tname, bits):
906 out += "static const "
907 out += "asn_namedbit %(TABLE)s[] = {\n"
908 for (val, id) in bits:
909 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
910 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
913 #--- eth_type_fn_h ----------------------------------------------------------
914 def eth_type_fn_h(self, tname):
916 if (not self.eth_type[tname]['export'] & EF_TYPE):
920 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)
922 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)
926 #--- eth_fn_call ------------------------------------------------------------
927 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
930 if (ret == 'return'):
936 for i in range(len(par)):
937 if (i>0): out += ind * ' '
938 out += ', '.join(par[i])
939 if (i<(len(par)-1)): out += ',\n'
943 #--- eth_type_fn_hdr --------------------------------------------------------
944 def eth_type_fn_hdr(self, tname):
946 if (not self.eth_type[tname]['export'] & EF_TYPE):
950 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)
952 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)
953 if self.conform.get_fn_presence(tname):
954 out += self.conform.get_fn_text(tname, 'FN_HDR')
955 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
956 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
959 #--- eth_type_fn_ftr --------------------------------------------------------
960 def eth_type_fn_ftr(self, tname):
962 if self.conform.get_fn_presence(tname):
963 out += self.conform.get_fn_text(tname, 'FN_FTR')
964 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
965 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
966 out += " return offset;\n"
970 #--- eth_type_fn_body -------------------------------------------------------
971 def eth_type_fn_body(self, tname, body, pars=None):
973 if self.conform.get_fn_body_presence(tname):
974 out = self.conform.get_fn_text(tname, 'FN_BODY')
975 elif self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
976 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
984 #--- eth_output_hf ----------------------------------------------------------
985 def eth_output_hf (self):
986 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
987 fx = self.output.file_open('hf')
988 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
989 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
991 fx.write('/* named bits */\n')
992 for nb in self.named_bit:
993 fx.write("static int %s = -1;\n" % (nb['ethname']))
994 self.output.file_close(fx)
996 #--- eth_output_hf_arr ------------------------------------------------------
997 def eth_output_hf_arr (self):
998 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
999 fx = self.output.file_open('hfarr')
1000 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1001 t = self.eth_hf[f]['ethtype']
1002 blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
1003 attr = self.eth_hf[f]['attr'].copy()
1004 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1005 if not attr.has_key('BLURB'):
1006 attr['BLURB'] = blurb
1007 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1008 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1009 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1010 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1011 for nb in self.named_bit:
1013 fx.write(' { &%s,\n' % (nb['ethname']))
1014 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1015 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1016 fx.write(' "%s", HFILL }},\n' % (blurb))
1017 self.output.file_close(fx)
1019 #--- eth_output_ett ---------------------------------------------------------
1020 def eth_output_ett (self):
1021 fx = self.output.file_open('ett')
1023 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1024 for t in self.eth_type_ord:
1025 if self.eth_type[t]['tree']:
1026 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1028 self.output.file_close(fx, discard=fempty)
1030 #--- eth_output_ett_arr -----------------------------------------------------
1031 def eth_output_ett_arr(self):
1032 fx = self.output.file_open('ettarr')
1034 #fx.write(" &ett_%s,\n" % (self.eproto))
1035 for t in self.eth_type_ord:
1036 if self.eth_type[t]['tree']:
1037 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1039 self.output.file_close(fx, discard=fempty)
1041 #--- eth_output_export ------------------------------------------------------
1042 def eth_output_export(self):
1043 if (not len(self.eth_export_ord)): return
1044 fx = self.output.file_open('exp', ext='h')
1045 for t in self.eth_export_ord: # vals
1046 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1047 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1048 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1049 if self.eth_type[t]['export'] & EF_WS_VAR:
1050 fx.write("WS_VAR_IMPORT ")
1053 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1054 for t in self.eth_export_ord: # functions
1055 if (self.eth_type[t]['export'] & EF_TYPE):
1056 fx.write(self.eth_type_fn_h(t))
1057 self.output.file_close(fx)
1059 #--- eth_output_expcnf ------------------------------------------------------
1060 def eth_output_expcnf(self):
1061 fx = self.output.file_open('exp', ext='cnf')
1062 fx.write('#.MODULE\n')
1064 for (m, p) in self.modules:
1065 if (len(m) > maxw): maxw = len(m)
1066 for (m, p) in self.modules:
1067 fx.write("%-*s %s\n" % (maxw, m, p))
1068 fx.write('#.END\n\n')
1070 fx.write('#.IMPORT_TAG\n')
1071 for t in self.eth_export_ord: # tags
1072 if (self.eth_type[t]['export'] & EF_TYPE):
1073 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1074 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1075 fx.write('#.END\n\n')
1076 fx.write('#.TYPE_ATTR\n')
1077 for t in self.eth_export_ord: # attributes
1078 if (self.eth_type[t]['export'] & EF_TYPE):
1079 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1080 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1081 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1082 fx.write('#.END\n\n')
1083 self.output.file_close(fx, keep_anyway=True)
1085 #--- eth_output_val ------------------------------------------------------
1086 def eth_output_val(self):
1087 if (not len(self.eth_value_ord1)): return
1088 fx = self.output.file_open('val', ext='h')
1089 for v in self.eth_value_ord1:
1090 fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
1091 self.output.file_close(fx)
1093 #--- eth_output_valexp ------------------------------------------------------
1094 def eth_output_valexp(self):
1095 if (not len(self.eth_vexport_ord)): return
1096 fx = self.output.file_open('valexp', ext='h')
1097 for v in self.eth_vexport_ord:
1098 fx.write("#define %-30s %s\n" % (v, self.eth_value[v]['value']))
1099 self.output.file_close(fx)
1101 #--- eth_output_types -------------------------------------------------------
1102 def eth_output_types(self):
1104 t = self.eth_hf[f]['ethtype']
1107 for r in self.eth_hf[f]['ref']:
1108 x[self.field[r]['impl']] = self.field[r]['impl']
1122 if (i): postfix = '_impl'; impl = 'TRUE'
1123 else: postfix = ''; impl = 'FALSE'
1124 out += 'static int dissect_'+f+postfix+'(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) {\n'
1125 par=((impl, 'tvb', 'offset', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
1127 out += 'static int dissect_'+f+'(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_) {\n'
1128 par=(('tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
1129 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret='return',
1135 t = self.eth_hf[f]['ethtype']
1136 is_new = self.eth_hf[f]['pdu']['new']
1137 if self.field[self.eth_hf[f]['ref'][0]]['impl']:
1146 out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1148 if (self.Aligned()):
1152 out += " asn1_ctx_t asn1_ctx;\n"
1153 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1155 par=((impl, 'tvb', '0', 'pinfo', 'tree', self.eth_hf[f]['fullname']),)
1157 par=(('tvb', '0', '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1161 if (is_new): ret = 'return'
1162 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret, par=par)
1166 fx = self.output.file_open('fn')
1168 if self.eth_dep_cycle:
1169 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1171 while i < len(self.eth_dep_cycle):
1172 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1173 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1174 fx.write(''.join(map(lambda i: '/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]), self.dep_cycle_eth_type[t])))
1175 fx.write(self.eth_type_fn_h(t))
1178 for f in self.eth_hf_ord:
1179 if (self.eth_hf[f]['ethtype'] == t):
1180 fx.write(out_field(f))
1184 if (self.Fld()): # fields for imported types
1185 fx.write('/*--- Fields for imported types ---*/\n\n')
1186 for f in self.eth_hf_ord:
1187 if (self.eth_type[self.eth_hf[f]['ethtype']]['import']):
1188 fx.write(out_field(f))
1190 for t in self.eth_type_ord1:
1191 if self.eth_type[t]['import']:
1193 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1194 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1195 if self.eth_type[t]['val'].eth_has_vals():
1196 if self.eth_type[t]['no_emit'] & EF_VALS:
1198 elif self.eth_type[t]['user_def'] & EF_VALS:
1199 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1201 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1202 if self.eth_type[t]['no_emit'] & EF_TYPE:
1204 elif self.eth_type[t]['user_def'] & EF_TYPE:
1205 fx.write(self.eth_type_fn_h(t))
1207 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1208 if (self.Fld() and not self.dep_cycle_eth_type.has_key(t)):
1209 for f in self.eth_hf_ord:
1210 if (self.eth_hf[f]['ethtype'] == t):
1211 fx.write(out_field(f))
1213 if (len(self.eth_hfpdu_ord)):
1214 fx.write('/*--- PDUs ---*/\n\n')
1215 for f in self.eth_hfpdu_ord:
1216 if (self.eth_hf[f]['pdu']):
1217 fx.write(out_pdu(f))
1219 fempty = pos == fx.tell()
1220 self.output.file_close(fx, discard=fempty)
1222 #--- eth_output_dis_hnd -----------------------------------------------------
1223 def eth_output_dis_hnd(self):
1224 fx = self.output.file_open('dis-hnd')
1226 for f in self.eth_hfpdu_ord:
1227 pdu = self.eth_hf[f]['pdu']
1228 if (pdu and pdu['reg'] and not pdu['hidden']):
1230 if (pdu['reg'] != '.'):
1231 dis += '.' + pdu['reg']
1232 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1235 self.output.file_close(fx, discard=fempty)
1237 #--- eth_output_dis_reg -----------------------------------------------------
1238 def eth_output_dis_reg(self):
1239 fx = self.output.file_open('dis-reg')
1241 for f in self.eth_hfpdu_ord:
1242 pdu = self.eth_hf[f]['pdu']
1243 if (pdu and pdu['reg']):
1245 if (pdu['new']): new_prefix = 'new_'
1247 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1248 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1249 if (not pdu['hidden']):
1250 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1253 self.output.file_close(fx, discard=fempty)
1255 #--- eth_output_dis_tab -----------------------------------------------------
1256 def eth_output_dis_tab(self):
1257 fx = self.output.file_open('dis-tab')
1259 for k in self.conform.get_order('REGISTER'):
1260 reg = self.conform.use_item('REGISTER', k)
1261 if not self.field.has_key(reg['pdu']): continue
1262 f = self.field[reg['pdu']]['ethname']
1263 pdu = self.eth_hf[f]['pdu']
1265 if (pdu['new']): new_prefix = 'new_'
1266 if (reg['rtype'] in ('NUM', 'STR')):
1268 if (reg['rtype'] == 'STR'): rstr = '_string'
1271 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1272 if (not pdu['hidden']):
1273 hnd = '%s_handle' % (asn2c(dis))
1275 hnd = 'find_dissector("%s")' % (dis)
1277 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1278 fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], reg['rport'], hnd))
1279 elif (reg['rtype'] in ('BER', 'PER')):
1280 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']))
1283 self.output.file_close(fx, discard=fempty)
1285 #--- dupl_report -----------------------------------------------------
1286 def dupl_report(self):
1288 tmplist = self.eth_type_dupl.keys()
1291 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1294 for tt in self.eth_type_dupl[t]:
1295 msg += " %-20s %s\n" % (t+str(x), tt)
1298 warnings.warn_explicit(msg, UserWarning, '', '')
1300 tmplist = self.eth_hf_dupl.keys()
1303 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
1305 for tt in self.eth_hf_dupl[f].keys():
1306 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
1307 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
1309 warnings.warn_explicit(msg, UserWarning, '', '')
1311 #--- eth_do_output ------------------------------------------------------------
1312 def eth_do_output(self):
1314 print "\n# Assignments"
1315 for a in self.assign_ord:
1317 if (self.assign[a]['virt']): v = '*'
1319 print "\n# Value assignments"
1320 print "\n".join(self.vassign_ord)
1322 print "\n# Imported Types"
1323 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1325 for t in self.type_imp:
1326 print "%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])
1327 print "\n# Imported Values"
1328 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1330 for t in self.value_imp:
1331 print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
1332 print "\n# Exported Types"
1333 print "%-31s %s" % ("Wireshark type", "Export Flag")
1335 for t in self.eth_export_ord:
1336 print "%-31s 0x%02X" % (t, self.eth_type[t]['export'])
1337 print "\n# Exported Values"
1338 print "%-40s %s" % ("Wireshark name", "Value")
1340 for v in self.eth_vexport_ord:
1341 print "%-40s %s" % (v, self.eth_value[v]['value'])
1342 print "\n# ASN.1 Types"
1343 print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
1345 for t in self.type_ord:
1346 print "%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])
1347 print "\n# Wireshark Types"
1348 print "Wireshark type References (ASN.1 types)"
1350 for t in self.eth_type_ord:
1351 print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
1352 print ', '.join(self.eth_type[t]['ref'])
1353 print "\n# ASN.1 Values"
1354 print "%-40s %-18s %s" % ("ASN.1 unique name", "Type", "Value")
1356 for v in self.value_ord:
1357 if isinstance (self.value[v]['value'], Value):
1358 print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'].to_str())
1360 print "%-40s %-18s %s" % (v, self.value[v]['type'].eth_tname(), self.value[v]['value'])
1361 print "\n# Wireshark Values"
1362 print "%-40s %s" % ("Wireshark name", "Value")
1364 for v in self.eth_value_ord:
1365 print "%-40s %s" % (v, self.eth_value[v]['value'])
1366 print "\n# ASN.1 Fields"
1367 print "ASN.1 unique name Wireshark name ASN.1 type"
1369 for f in (self.pdu_ord + self.field_ord):
1370 print "%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])
1371 print "\n# Wireshark Fields"
1372 print "Wireshark name Wireshark type References (ASN.1 fields)"
1374 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1375 print "%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])),
1376 print ', '.join(self.eth_hf[f]['ref'])
1377 #print "\n# Order after dependencies"
1378 #print '\n'.join(self.eth_type_ord1)
1379 print "\n# Cyclic dependencies"
1380 for c in self.eth_dep_cycle:
1381 print ' -> '.join(c)
1383 self.output.outnm = self.outnm_opt
1384 if (not self.output.outnm):
1385 self.output.outnm = self.proto
1386 self.eth_output_hf()
1387 self.eth_output_ett()
1388 self.eth_output_types()
1389 self.eth_output_hf_arr()
1390 self.eth_output_ett_arr()
1391 self.eth_output_export()
1393 self.eth_output_expcnf()
1394 self.eth_output_val()
1395 self.eth_output_valexp()
1396 self.eth_output_dis_hnd()
1397 self.eth_output_dis_reg()
1398 self.eth_output_dis_tab()
1400 #--- EthCnf -------------------------------------------------------------------
1407 self.suppress_line = False
1408 # Value name Default value Duplicity check Usage check
1409 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1410 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1411 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1412 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1413 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1414 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1415 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
1416 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
1417 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1418 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1419 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1420 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1421 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
1422 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1423 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1424 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1425 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1426 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1429 for k in self.tblcfg.keys() :
1433 def add_item(self, table, key, fn, lineno, **kw):
1434 if self.tblcfg[table]['chk_dup'] and self.table[table].has_key(key):
1435 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
1436 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
1437 UserWarning, fn, lineno)
1439 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
1440 self.table[table][key].update(kw)
1441 self.order[table].append(key)
1443 def get_order(self, table):
1444 return self.order[table]
1446 def check_item(self, table, key):
1447 return self.table[table].has_key(key)
1449 def check_item_value(self, table, key, **kw):
1450 return self.table[table].has_key(key) and self.table[table][key].has_key(kw.get('val_nm', self.tblcfg[table]['val_nm']))
1452 def use_item(self, table, key, **kw):
1453 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
1454 if not self.table[table].has_key(key): return vdflt
1455 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
1456 #print "use_item() - set used for %s %s" % (table, key)
1457 self.table[table][key]['used'] = True
1458 return self.table[table][key].get(vname, vdflt)
1460 def add_fn_line(self, name, ctx, line, fn, lineno):
1461 if not self.fn.has_key(name):
1462 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
1463 if (self.fn[name][ctx]):
1464 self.fn[name][ctx]['text'] += line
1466 self.fn[name][ctx] = {'text' : line, 'used' : False,
1467 'fn' : fn, 'lineno' : lineno}
1468 def get_fn_presence(self, name):
1469 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
1470 #if self.fn.has_key(name): print self.fn[name]
1471 return self.fn.has_key(name)
1472 def get_fn_body_presence(self, name):
1473 return self.fn.has_key(name) and self.fn[name]['FN_BODY']
1474 def get_fn_text(self, name, ctx):
1475 if (not self.fn.has_key(name)):
1477 if (not self.fn[name][ctx]):
1479 self.fn[name][ctx]['used'] = True
1480 out = self.fn[name][ctx]['text']
1481 if (not self.suppress_line):
1482 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], self.fn[name][ctx]['fn'], out);
1485 def add_pdu(self, par, is_new, fn, lineno):
1486 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
1487 (reg, hidden) = (None, False)
1488 if (len(par) > 1): reg = par[1]
1489 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
1490 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden}
1491 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
1494 def add_register(self, pdu, par, fn, lineno):
1495 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
1496 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
1497 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
1498 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
1499 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
1500 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
1501 if ((len(par)-1) < pmin):
1502 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
1504 if ((len(par)-1) > pmax):
1505 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
1506 attr = {'pdu' : pdu, 'rtype' : rtype}
1507 if (rtype in ('NUM', 'STR')):
1508 attr['rtable'] = par[1]
1509 attr['rport'] = par[2]
1510 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
1511 elif (rtype in ('BER', 'PER')):
1512 attr['roid'] = par[1]
1513 attr['roidname'] = '""'
1514 if (len(par)>=3): attr['roidname'] = par[2]
1515 rkey = '/'.join([rtype, attr['roid']])
1516 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
1519 def get_par(line, pmin, pmax, fn, lineno):
1520 par = line.split(None, pmax)
1521 for i in range(len(par)):
1525 if par[i][0] == '#':
1529 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1531 if (pmax >= 0) and (len(par) > pmax):
1532 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
1536 def get_par_nm(line, pmin, pmax, fn, lineno):
1538 par = line.split(None, pmax)
1541 for i in range(len(par)):
1542 if par[i][0] == '#':
1546 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1553 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
1554 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
1555 nmpar_end = re.compile(r'\s*$')
1556 result = nmpar_first.search(nmpar)
1559 k = result.group('attr')
1561 result = nmpar_next.search(nmpar, pos)
1566 p2 = nmpar_end.search(nmpar, pos).start()
1574 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_]+)\s+')
1575 comment = re.compile(r'^\s*#[^.]')
1576 empty = re.compile(r'^\s*$')
1580 default_flags = 0x00
1589 fn, f, lineno = frec['fn'], frec['f'], frec['lineno']
1593 if comment.search(line): continue
1594 result = directive.search(line)
1595 if result: # directive
1596 if result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
1597 'MODULE', 'MODULE_IMPORT',
1598 'OMIT_ASSIGNMENT', 'VIRTUAL_ASSGN', 'SET_TYPE',
1599 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
1600 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
1601 ctx = result.group('name')
1602 elif result.group('name') in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
1603 ctx = result.group('name')
1604 default_flags = EF_TYPE|EF_VALS
1605 if ctx == 'EXPORTS':
1606 par = get_par(line[result.end():], 0, 4, fn=fn, lineno=lineno)
1608 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
1609 if not par: continue
1611 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
1612 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
1613 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
1614 elif (ctx == 'EXPORTS'): p = 0
1615 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
1616 for i in range(p, len(par)):
1617 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
1618 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
1619 elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
1620 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
1621 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1622 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
1623 ctx = result.group('name')
1624 default_flags = EF_ENUM
1625 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT
1626 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE
1627 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
1628 for i in range(0, len(par)):
1629 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
1630 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
1631 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
1632 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
1633 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1634 elif result.group('name') in ('FN_HDR', 'FN_FTR'):
1635 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1636 if not par: continue
1637 ctx = result.group('name')
1639 elif result.group('name') == 'FN_BODY':
1640 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1641 if not par: continue
1642 ctx = result.group('name')
1645 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
1646 elif result.group('name') == 'FN_PARS':
1647 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
1648 ctx = result.group('name')
1654 self.add_item(ctx, name, pars=par[1], fn=fn, lineno=lineno)
1657 elif result.group('name') == 'INCLUDE':
1658 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
1660 warnings.warn_explicit("INCLUDE requires parameter", UserWarning, fn, lineno)
1662 fname = os.path.join(os.path.split(fn)[0], par[0])
1663 if (not os.path.exists(fname)):
1665 fnew = open(fname, "r")
1666 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno})
1667 fn, f, lineno = par[0], fnew, 0
1668 elif result.group('name') == 'END':
1671 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
1674 if not empty.match(line):
1675 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
1676 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
1677 if empty.match(line): continue
1678 if ctx == 'EXPORTS':
1679 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
1681 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
1682 if not par: continue
1683 flags = default_flags
1686 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
1687 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
1688 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
1689 elif (ctx == 'EXPORTS'): p = 1
1690 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
1691 for i in range(p, len(par)):
1692 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
1693 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
1694 elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
1695 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
1696 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1697 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
1698 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
1699 if empty.match(line): continue
1700 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
1701 if not par: continue
1702 flags = default_flags
1703 for i in range(1, len(par)):
1704 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
1705 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
1706 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
1707 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
1708 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
1709 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
1710 elif ctx in ('PDU', 'PDU_NEW'):
1711 if empty.match(line): continue
1712 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
1713 if not par: continue
1715 if (ctx == 'PDU_NEW'): is_new = True
1716 self.add_pdu(par[0:2], is_new, fn, lineno)
1718 self.add_register(par[0], par[2:5], fn, lineno)
1719 elif ctx in ('REGISTER', 'REGISTER_NEW'):
1720 if empty.match(line): continue
1721 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
1722 if not par: continue
1723 if not self.check_item('PDU', par[0]):
1725 if (ctx == 'REGISTER_NEW'): is_new = True
1726 self.add_pdu(par[0:1], is_new, fn, lineno)
1727 self.add_register(par[0], par[1:4], fn, lineno)
1728 elif ctx in ('MODULE', 'MODULE_IMPORT'):
1729 if empty.match(line): continue
1730 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1731 if not par: continue
1732 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
1733 elif ctx == 'IMPORT_TAG':
1734 if empty.match(line): continue
1735 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
1736 if not par: continue
1737 self.add_item('IMPORT_TAG', par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
1738 elif ctx == 'OMIT_ASSIGNMENT':
1739 if empty.match(line): continue
1740 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
1741 if not par: continue
1742 self.add_item('OMIT_ASSIGNMENT', par[0], omit=True, fn=fn, lineno=lineno)
1743 elif ctx == 'VIRTUAL_ASSGN':
1744 if empty.match(line): continue
1745 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
1746 if not par: continue
1747 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
1748 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
1749 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
1751 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
1752 if not par[0][0].isupper():
1753 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
1754 UserWarning, fn, lineno)
1755 elif ctx == 'SET_TYPE':
1756 if empty.match(line): continue
1757 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1758 if not par: continue
1759 if not self.check_item('VIRTUAL_ASSGN', par[0]):
1760 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
1761 if not par[1][0].isupper():
1762 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
1763 UserWarning, fn, lineno)
1764 elif ctx == 'TYPE_RENAME':
1765 if empty.match(line): continue
1766 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1767 if not par: continue
1768 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
1769 if not par[1][0].isupper():
1770 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
1771 UserWarning, fn, lineno)
1772 elif ctx == 'FIELD_RENAME':
1773 if empty.match(line): continue
1774 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1775 if not par: continue
1776 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
1777 if not par[1][0].islower():
1778 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
1779 UserWarning, fn, lineno)
1780 elif ctx == 'TF_RENAME':
1781 if empty.match(line): continue
1782 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
1783 if not par: continue
1784 tmpu = par[1][0].upper() + par[1][1:]
1785 tmpl = par[1][0].lower() + par[1][1:]
1786 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
1787 if not tmpu[0].isupper():
1788 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
1789 UserWarning, fn, lineno)
1790 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
1791 if not tmpl[0].islower():
1792 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
1793 UserWarning, fn, lineno)
1794 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
1795 if empty.match(line): continue
1796 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
1797 if not par: continue
1798 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
1799 elif ctx == 'FN_PARS':
1800 if empty.match(line): continue
1802 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
1804 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
1805 if not par: continue
1807 self.add_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
1809 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
1810 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
1811 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
1813 def dbg_print(self):
1814 print "\n# Conformance values"
1815 print "%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")
1817 tbls = self.table.keys()
1820 keys = self.table[t].keys()
1823 print "%-15s %4s %-15s %-20s %s" % (
1824 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))
1826 def unused_report(self):
1827 tbls = self.table.keys()
1830 if not self.tblcfg[t]['chk_use']: continue
1831 keys = self.table[t].keys()
1834 if not self.table[t][k]['used']:
1835 warnings.warn_explicit("Unused %s for %s" % (t, k),
1836 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
1837 fnms = self.fn.keys()
1840 keys = self.fn[f].keys()
1843 if not self.fn[f][k]: continue
1844 if not self.fn[f][k]['used']:
1845 warnings.warn_explicit("Unused %s for %s" % (k, f),
1846 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
1848 #--- EthOut -------------------------------------------------------------------
1853 self.single_file = None
1854 self.created_files = []
1855 self.unique_created_files = []
1857 #--- output_fname -------------------------------------------------------
1858 def output_fname(self, ftype, ext='c'):
1860 if not ext in ('cnf',):
1867 #--- output_fullname -------------------------------------------------------
1868 def output_fullname(self, ftype, ext='c'):
1869 return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
1870 #--- file_open -------------------------------------------------------
1871 def file_open(self, ftype, ext='c'):
1872 fn = self.output_fullname(ftype, ext=ext)
1875 fx.write(self.fhdr(fn, comment = '#'))
1877 if (not self.single_file):
1878 fx.write(self.fhdr(fn))
1880 #--- file_close -------------------------------------------------------
1881 def file_close(self, fx, discard=False, keep_anyway=False):
1885 elif (not keep_anyway):
1886 self.created_files.append(os.path.normcase(os.path.abspath(fx.name)))
1887 #--- fhdr -------------------------------------------------------
1888 def fhdr(self, fn, comment=None):
1891 return '# %s\n' % (ln)
1893 return '/* %-74s */\n' % (ln)
1895 out += outln('Do not modify this file.')
1896 out += outln('It is created automatically by the ASN.1 to Wireshark dissector compiler')
1898 out += outln(' '.join(sys.argv))
1902 #--- dbg_print -------------------------------------------------------
1903 def dbg_print(self):
1904 print "\n# Output files"
1905 print "\n".join(self.created_files)
1908 #--- make_single_file -------------------------------------------------------
1909 def make_single_file(self):
1910 if (not self.single_file): return
1911 in_nm = self.single_file + '.c'
1912 out_nm = self.output_fullname('')
1913 self.do_include(out_nm, in_nm)
1914 in_nm = self.single_file + '.h'
1915 if (os.path.exists(in_nm)):
1916 out_nm = self.output_fullname('', ext='h')
1917 self.do_include(out_nm, in_nm)
1919 self.unique_created_files = []
1920 [self.unique_created_files.append(wrd) for wrd in self.created_files if not self.unique_created_files.count(wrd)]
1921 for fn in self.unique_created_files:
1924 #--- do_include -------------------------------------------------------
1925 def do_include(self, out_nm, in_nm):
1926 def check_file(fn, fnlist):
1927 fnfull = os.path.normcase(os.path.abspath(fn))
1928 if ((fnfull in fnlist) and os.path.exists(fnfull)):
1929 return os.path.normpath(fn)
1931 fin = file(in_nm, "r")
1932 fout = file(out_nm, "w")
1933 fout.write(self.fhdr(out_nm))
1934 fout.write('/* Input file: ' + in_nm +' */\n')
1936 fout.write('#line 1 "%s"\n' % (in_nm))
1938 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
1943 cont_linenum = cont_linenum + 1;
1944 line = fin.readline()
1945 if (line == ''): break
1947 result = include.search(line)
1948 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
1950 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
1952 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
1954 ifile = check_file(result.group('fname'), self.created_files)
1957 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
1958 fout.write('#line 1 "' + ifile + '"\n')
1959 finc = file(ifile, "r")
1960 fout.write(finc.read())
1962 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
1963 fout.write('#line %i "%s"\n' % (cont_linenum+1,in_nm) )
1972 #--- Node ---------------------------------------------------------------------
1974 def __init__(self,*args, **kw):
1976 self.type = self.__class__.__name__
1978 assert (len(args) == 1)
1980 self.__dict__.update (kw)
1981 def str_child (self, key, child, depth):
1982 indent = " " * (2 * depth)
1983 keystr = indent + key + ": "
1984 if key == 'type': # already processed in str_depth
1986 if isinstance (child, Node): # ugh
1987 return keystr + "\n" + child.str_depth (depth+1)
1988 if type (child) == type ([]):
1991 if isinstance (x, Node):
1992 l.append (x.str_depth (depth+1))
1994 l.append (indent + " " + str(x) + "\n")
1995 return keystr + "[\n" + ''.join(l) + indent + "]\n"
1997 return keystr + str (child) + "\n"
1998 def str_depth (self, depth): # ugh
1999 indent = " " * (2 * depth)
2000 l = ["%s%s" % (indent, self.type)]
2001 l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
2002 self.__dict__.items ())))
2003 return "\n".join (l)
2005 return "\n" + self.str_depth (0)
2006 def to_python (self, ctx):
2007 return self.str_depth (ctx.indent_lev)
2009 def eth_reg(self, ident, ectx):
2012 #--- value_assign -------------------------------------------------------------
2013 class value_assign (Node):
2014 def __init__(self,*args, **kw) :
2015 Node.__init__ (self,*args, **kw)
2017 def eth_reg(self, ident, ectx):
2018 if ectx.conform.use_item('OMIT_ASSIGNMENT', self.ident): return # Assignment to omit
2019 ectx.eth_reg_vassign(self)
2020 ectx.eth_reg_value(self.ident, self.typ, self.val)
2023 #--- Type ---------------------------------------------------------------------
2025 def __init__(self,*args, **kw) :
2029 Node.__init__ (self,*args, **kw)
2032 if self.name is None :
2037 def HasConstraint(self):
2038 if self.constr is None :
2043 def HasOwnTag(self):
2044 return len(self.tags) > 0
2046 def HasImplicitTag(self, ectx):
2047 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
2049 def IndetermTag(self, ectx):
2052 def AddTag(self, tag):
2053 self.tags[0:0] = [tag]
2055 def GetTag(self, ectx):
2056 #print "GetTag(%s)\n" % self.name;
2057 if (self.HasOwnTag()):
2058 return self.tags[0].GetTag(ectx)
2060 return self.GetTTag(ectx)
2062 def GetTTag(self, ectx):
2063 print "#Unhandled GetTTag() in %s" % (self.type)
2064 print self.str_depth(1)
2065 return ('BER_CLASS_unknown', 'TAG_unknown')
2067 def SetName(self, name):
2070 def AddConstraint(self, constr):
2071 if not self.HasConstraint():
2072 self.constr = constr
2074 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
2076 def eth_tname(self):
2077 return '#' + self.type + '_' + str(id(self))
2079 def eth_ftype(self, ectx):
2080 return ('FT_NONE', 'BASE_NONE')
2082 def eth_strings(self):
2085 def eth_need_tree(self):
2088 def eth_has_vals(self):
2091 def eth_has_enum(self, tname, ectx):
2092 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
2094 def eth_named_bits(self):
2097 def eth_reg_sub(self, ident, ectx):
2100 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, idx='', parent=None):
2101 if (ectx.Tag() and (len(self.tags) > tstrip)):
2102 tagged_type = TaggedType(val=self, tstrip=tstrip)
2103 tagged_type.AddTag(self.tags[tstrip])
2104 if not tagflag: # 1st tagged level
2106 tagged_type.SetName(self.name)
2108 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
2111 if ident and self.IsNamed() and not tagflag:
2112 nm = ident + '/' + self.name
2115 elif self.IsNamed():
2117 if not ident and ectx.conform.use_item('OMIT_ASSIGNMENT', nm): return # Assignment to omit
2118 if not ident: # Assignment
2119 ectx.eth_reg_assign(nm, self)
2120 if self.type == 'Type_Ref':
2121 ectx.eth_reg_type(nm, self)
2122 if (ectx.conform.check_item('PDU', nm)):
2123 ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
2124 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
2125 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
2126 if ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm):
2127 if ectx.conform.check_item('SET_TYPE', nm):
2128 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
2130 ectx.eth_reg_type(nm, self) # new type
2132 elif ectx.conform.check_item('SET_TYPE', nm):
2133 trnm = ectx.conform.use_item('SET_TYPE', nm)
2137 ectx.eth_reg_type(nm, self)
2138 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
2139 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
2140 ectx.eth_reg_assign(vnm, self, virt=True)
2141 ectx.eth_reg_type(vnm, self)
2142 self.eth_reg_sub(vnm, ectx)
2143 if ident and not tagflag:
2144 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
2145 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
2147 ectx.eth_reg_field(nm, nm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
2148 if ectx.conform.check_item('SET_TYPE', nm):
2149 virtual_tr.eth_reg_sub(nm, ectx)
2151 self.eth_reg_sub(nm, ectx)
2153 def eth_get_size_constr(self):
2154 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2155 if not self.HasConstraint():
2156 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2157 elif self.constr.IsSize():
2158 (minv, maxv, ext) = self.constr.GetSize()
2159 elif (self.constr.type == 'Intersection'):
2160 if self.constr.subtype[0].IsSize():
2161 (minv, maxv, ext) = self.constr.subtype[0].GetSize()
2162 elif self.constr.subtype[1].IsSize():
2163 (minv, maxv, ext) = self.constr.subtype[1].GetSize()
2164 return (minv, maxv, ext)
2166 def eth_get_value_constr(self):
2167 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2168 if not self.HasConstraint():
2169 (minv, maxv, ext) = ('NO_BOUND', 'NO_BOUND', 'FALSE')
2170 elif self.constr.IsValue():
2171 (minv, maxv, ext) = self.constr.GetValue()
2172 return (minv, maxv, ext)
2174 def eth_type_vals(self, tname, ectx):
2175 if self.eth_has_vals():
2176 print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
2177 print self.str_depth(1)
2180 def eth_type_enum(self, tname, ectx):
2181 if self.eth_has_enum(tname, ectx):
2182 print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
2183 print self.str_depth(1)
2186 def eth_type_default_table(self, ectx, tname):
2189 def eth_type_default_body(self, ectx):
2190 print "#Unhandled eth_type_default_body() in %s" % (self.type)
2191 print self.str_depth(1)
2194 def eth_type_default_pars(self, ectx, tname):
2201 'OFFSET' : 'offset',
2203 'HF_INDEX' : 'hf_index',
2205 'IMPLICIT_TAG' : 'implicit_tag',
2207 if (ectx.eth_type[tname]['tree']):
2208 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
2209 if (not ectx.Per()):
2210 pars['PINFO'] = 'pinfo'
2213 def eth_type_fn(self, proto, tname, ectx):
2214 body = self.eth_type_default_body(ectx, tname)
2215 pars = self.eth_type_default_pars(ectx, tname)
2216 if ectx.conform.check_item('FN_PARS', tname):
2217 pars.update(ectx.conform.use_item('FN_PARS', tname))
2218 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
2219 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
2220 pars['DEFAULT_BODY'] = body
2222 for k in pars.keys(): pars[k] = pars[k] % pars
2224 out += self.eth_type_default_table(ectx, tname) % pars
2225 out += ectx.eth_type_fn_hdr(tname)
2226 out += ectx.eth_type_fn_body(tname, body, pars=pars)
2227 out += ectx.eth_type_fn_ftr(tname)
2230 #--- Value --------------------------------------------------------------------
2232 def __init__(self,*args, **kw) :
2234 Node.__init__ (self,*args, **kw)
2236 def SetName(self, name) :
2245 #--- Tag ---------------------------------------------------------------
2247 def to_python (self, ctx):
2248 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
2251 self.typ.to_python (ctx))
2252 def IsImplicit(self, ectx):
2253 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
2255 def GetTag(self, ectx):
2257 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
2258 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
2259 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
2260 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
2261 return (tc, self.num)
2263 def eth_tname(self):
2265 if (self.cls == 'UNIVERSAL'): n = 'U'
2266 elif (self.cls == 'APPLICATION'): n = 'A'
2267 elif (self.cls == 'CONTEXT'): n = 'C'
2268 elif (self.cls == 'PRIVATE'): n = 'P'
2269 return n + str(self.num)
2271 #--- Constraint ---------------------------------------------------------------
2272 class Constraint (Node):
2273 def to_python (self, ctx):
2274 print "Ignoring constraint:", self.type
2275 return self.subtype.typ.to_python (ctx)
2277 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
2280 return self.type == 'Size' and (self.subtype.type == 'SingleValue' or self.subtype.type == 'ValueRange')
2287 if self.subtype.type == 'SingleValue':
2288 minv = self.subtype.subtype
2289 maxv = self.subtype.subtype
2291 minv = self.subtype.subtype[0]
2292 maxv = self.subtype.subtype[1]
2293 if hasattr(self.subtype, 'ext') and self.subtype.ext:
2297 return (minv, maxv, ext)
2300 return self.type == 'SingleValue' or self.type == 'ValueRange'
2307 if self.type == 'SingleValue':
2311 if self.subtype[0] == 'MIN':
2314 minv = self.subtype[0]
2315 if self.subtype[1] == 'MAX':
2318 maxv = self.subtype[1]
2319 if str(minv).isdigit(): minv += 'U'
2320 if str(maxv).isdigit(): maxv += 'U'
2321 if hasattr(self, 'ext') and self.ext:
2325 return (minv, maxv, ext)
2327 def IsNegativ(self):
2329 return sval[0] == '-'
2330 if self.type == 'SingleValue':
2331 return is_neg(self.subtype)
2332 elif self.type == 'ValueRange':
2333 if self.subtype[0] == 'MIN': return True
2334 return is_neg(self.subtype[0])
2337 def IsPermAlph(self):
2338 return self.type == 'From' and self.subtype.type == 'SingleValue'
2340 def eth_constrname(self):
2344 return 'M' + str(-int(val))
2347 except (ValueError, TypeError):
2351 if hasattr(self, 'ext') and self.ext:
2353 if self.type == 'SingleValue':
2354 return int2str(self.subtype) + ext
2355 elif self.type == 'ValueRange':
2356 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
2357 elif self.type == 'Size':
2358 return 'SIZE_' + self.subtype.eth_constrname() + ext
2360 return 'CONSTR' + str(id(self)) + ext
2363 class Module (Node):
2364 def to_python (self, ctx):
2365 ctx.tag_def = self.tag_def.dfl_tag
2367 %s""" % (self.ident, self.body.to_python (ctx))
2369 def to_eth (self, ectx):
2370 ectx.tags_def = 'EXPLICIT' # default = explicit
2371 if (not ectx.proto):
2372 ectx.proto = ectx.conform.use_item('MODULE', self.ident.val, val_dflt=self.ident.val)
2373 ectx.tag_def = self.tag_def.dfl_tag
2374 ectx.modules.append((self.ident.val, ectx.proto))
2375 self.body.to_eth(ectx)
2377 class Module_Body (Node):
2378 def to_python (self, ctx):
2379 # XXX handle exports, imports.
2380 l = map (lambda x: x.to_python (ctx), self.assign_list)
2381 l = [a for a in l if a <> '']
2382 return "\n".join (l)
2384 def to_eth(self, ectx):
2385 for i in self.imports:
2387 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
2388 for s in i.symbol_list:
2389 if isinstance(s, Type_Ref):
2390 ectx.eth_import_type(s.val, mod, proto)
2392 ectx.eth_import_value(s, mod, proto)
2393 for a in self.assign_list:
2396 class Default_Tags (Node):
2397 def to_python (self, ctx): # not to be used directly
2400 # XXX should just calculate dependencies as we go along.
2401 def calc_dependencies (node, dict, trace = 0):
2402 if not hasattr (node, '__dict__'):
2403 if trace: print "#returning, node=", node
2405 if isinstance (node, Type_Ref):
2407 if trace: print "#Setting", node.val
2409 for (a, val) in node.__dict__.items ():
2410 if trace: print "# Testing node ", node, "attr", a, " val", val
2413 elif isinstance (val, Node):
2414 calc_dependencies (val, dict, trace)
2415 elif isinstance (val, type ([])):
2417 calc_dependencies (v, dict, trace)
2420 class Type_Assign (Node):
2421 def __init__ (self, *args, **kw):
2422 Node.__init__ (self, *args, **kw)
2423 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
2424 to_test = self.val.typ
2427 if isinstance (to_test, SequenceType):
2428 to_test.sequence_name = self.name.name
2430 def to_python (self, ctx):
2432 calc_dependencies (self.val, dep_dict, 0)
2433 depend_list = dep_dict.keys ()
2434 return ctx.register_assignment (self.name.name,
2435 self.val.to_python (ctx),
2438 class PyQuote (Node):
2439 def to_python (self, ctx):
2440 return ctx.register_pyquote (self.val)
2442 #--- Type_Ref -----------------------------------------------------------------
2443 class Type_Ref (Type):
2444 def to_python (self, ctx):
2447 def eth_reg_sub(self, ident, ectx):
2448 ectx.eth_dep_add(ident, self.val)
2450 def eth_tname(self):
2451 return asn2c(self.val)
2453 def GetTTag(self, ectx):
2454 #print "GetTTag(%s)\n" % self.val;
2455 if (ectx.type[self.val]['import']):
2456 if not ectx.type[self.val].has_key('ttag'):
2457 if not ectx.conform.check_item('IMPORT_TAG', self.val):
2458 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
2459 warnings.warn_explicit(msg, UserWarning, '', '')
2460 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
2461 return ectx.type[self.val]['ttag']
2463 return ectx.type[self.val]['val'].GetTag(ectx)
2465 def IndetermTag(self, ectx):
2466 if (ectx.type[self.val]['import']):
2469 return ectx.type[self.val]['val'].IndetermTag(ectx)
2471 def eth_type_default_pars(self, ectx, tname):
2472 pars = Type.eth_type_default_pars(self, ectx, tname)
2473 t = ectx.type[self.val]['ethname']
2474 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
2475 pars['TYPE_REF_TNAME'] = t
2476 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
2479 def eth_type_default_body(self, ectx, tname):
2481 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
2482 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(PINFO)s', '%(TREE)s', '%(HF_INDEX)s'),))
2484 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
2485 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
2487 body = '#error Can not decode %s' % (tname)
2490 #--- TaggedType -----------------------------------------------------------------
2491 class TaggedType (Type):
2492 def eth_tname(self):
2494 for i in range(self.tstrip, len(self.val.tags)):
2495 tn += self.val.tags[i].eth_tname()
2497 tn += self.val.eth_tname()
2500 def eth_reg_sub(self, ident, ectx):
2501 self.val_name = ident + '/' + '_untag'
2502 ectx.eth_dep_add(ident, self.val_name)
2503 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
2505 def eth_ftype(self, ectx):
2506 return self.val.eth_ftype(ectx)
2508 def eth_type_default_pars(self, ectx, tname):
2509 pars = Type.eth_type_default_pars(self, ectx, tname)
2510 t = ectx.type[self.val_name]['ethname']
2511 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
2512 pars['TYPE_REF_TNAME'] = t
2513 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
2514 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
2515 if self.HasImplicitTag(ectx):
2516 pars['TAG_IMPL'] = 'TRUE'
2518 pars['TAG_IMPL'] = 'FALSE'
2521 def eth_type_default_body(self, ectx, tname):
2523 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
2524 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2525 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
2527 body = '#error Can not decode %s' % (tname)
2530 #--- SqType -----------------------------------------------------------
2531 class SqType (Type):
2532 def out_item(self, f, val, optional, ext, ectx):
2533 ef = ectx.field[f]['ethname']
2534 t = ectx.eth_hf[ef]['ethtype']
2536 if (ectx.Ber() and ectx.field[f]['impl']):
2539 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
2540 #print val.str_depth(1)
2543 opt = 'BER_FLAGS_OPTIONAL'
2544 if (not val.HasOwnTag()):
2545 if (opt): opt += '|'
2546 opt += 'BER_FLAGS_NOOWNTAG'
2547 elif (val.HasImplicitTag(ectx)):
2548 if (opt): opt += '|'
2549 opt += 'BER_FLAGS_IMPLTAG'
2550 if (val.IndetermTag(ectx)):
2551 if (opt): opt += '|'
2552 opt += 'BER_FLAGS_NOTCHKTAG'
2553 if (not opt): opt = '0'
2556 opt = 'ASN1_OPTIONAL'
2558 opt = 'ASN1_NOT_OPTIONAL'
2560 (tc, tn) = val.GetTag(ectx)
2561 out = ' { %-13s, %s, %s, dissect_%s },\n' \
2562 % (tc, tn, opt, efd)
2564 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
2565 % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
2570 #--- SeqType -----------------------------------------------------------
2571 class SeqType (SqType):
2572 def eth_type_default_table(self, ectx, tname):
2573 #print "eth_type_default_table(tname='%s')" % (tname)
2574 fname = ectx.eth_type[tname]['ref'][0]
2575 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
2576 if hasattr(self, 'ext_list'):
2577 ext = 'ASN1_EXTENSION_ROOT'
2579 ext = 'ASN1_NO_EXTENSIONS'
2580 for e in (self.elt_list):
2581 f = fname + '/' + e.val.name
2582 table += self.out_item(f, e.val, e.optional, ext, ectx)
2583 if hasattr(self, 'ext_list'):
2584 for e in (self.ext_list):
2585 f = fname + '/' + e.val.name
2586 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
2588 table += " { 0, 0, 0, NULL }\n};\n"
2590 table += " { NULL, 0, 0, NULL }\n};\n"
2593 #--- SeqOfType -----------------------------------------------------------
2594 class SeqOfType (SqType):
2595 def eth_type_default_table(self, ectx, tname):
2596 #print "eth_type_default_table(tname='%s')" % (tname)
2597 fname = ectx.eth_type[tname]['ref'][0]
2598 if self.val.IsNamed ():
2599 f = fname + '/' + self.val.name
2601 f = fname + '/' + '_item'
2602 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
2603 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
2607 #--- SequenceOfType -----------------------------------------------------------
2608 class SequenceOfType (SeqOfType):
2609 def to_python (self, ctx):
2610 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2611 # or '' + (1,) for optional
2613 if self.size_constr <> None:
2614 print "#Ignoring size constraint:", self.size_constr.subtype
2615 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
2616 self.val.to_python (ctx),
2619 def eth_reg_sub(self, ident, ectx):
2621 if not self.val.IsNamed ():
2622 itmnm += '/' + '_item'
2623 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
2625 def eth_tname(self):
2626 if self.val.type != 'Type_Ref':
2627 return '#' + self.type + '_' + str(id(self))
2628 if not self.HasConstraint():
2629 return "SEQUENCE_OF_" + self.val.eth_tname()
2630 elif self.constr.IsSize():
2631 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
2633 return '#' + self.type + '_' + str(id(self))
2635 def eth_ftype(self, ectx):
2636 return ('FT_UINT32', 'BASE_DEC')
2638 def eth_need_tree(self):
2641 def GetTTag(self, ectx):
2642 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
2644 def eth_type_default_pars(self, ectx, tname):
2645 pars = Type.eth_type_default_pars(self, ectx, tname)
2646 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
2647 pars['TABLE'] = '%(TNAME)s_sequence_of'
2650 def eth_type_default_body(self, ectx, tname):
2652 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
2653 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2654 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2655 elif (ectx.Per() and not self.HasConstraint()):
2656 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
2657 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2658 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2659 elif (ectx.Per() and self.constr.type == 'Size'):
2660 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
2661 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2662 ('%(ETT_INDEX)s', '%(TABLE)s',),
2663 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
2665 body = '#error Can not decode %s' % (tname)
2669 #--- SetOfType ----------------------------------------------------------------
2670 class SetOfType (SeqOfType):
2671 def eth_reg_sub(self, ident, ectx):
2673 if not self.val.IsNamed ():
2674 itmnm += '/' + '_item'
2675 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
2677 def eth_tname(self):
2678 if self.val.type != 'Type_Ref':
2679 return '#' + self.type + '_' + str(id(self))
2680 if not self.HasConstraint():
2681 return "SET_OF_" + self.val.eth_tname()
2682 elif self.constr.IsSize():
2683 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
2685 return '#' + self.type + '_' + str(id(self))
2687 def eth_ftype(self, ectx):
2688 return ('FT_UINT32', 'BASE_DEC')
2690 def eth_need_tree(self):
2693 def GetTTag(self, ectx):
2694 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
2696 def eth_type_default_pars(self, ectx, tname):
2697 pars = Type.eth_type_default_pars(self, ectx, tname)
2698 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
2699 pars['TABLE'] = '%(TNAME)s_set_of'
2702 def eth_type_default_body(self, ectx, tname):
2704 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
2705 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2706 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2707 elif (ectx.Per() and not self.HasConstraint()):
2708 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
2709 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2710 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2711 elif (ectx.Per() and self.constr.type == 'Size'):
2712 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
2713 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2714 ('%(ETT_INDEX)s', '%(TABLE)s',),
2715 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
2717 body = '#error Can not decode %s' % (tname)
2720 def mk_tag_str (ctx, cls, typ, num):
2722 # XXX should do conversion to int earlier!
2725 if typ == 'DEFAULT':
2727 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
2729 #--- SequenceType -------------------------------------------------------------
2730 class SequenceType (SeqType):
2731 def to_python (self, ctx):
2732 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2733 # or '' + (1,) for optional
2734 # XXX should also collect names for SEQUENCE inside SEQUENCE or
2735 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
2736 # from? for others, element or arm name would be fine)
2737 seq_name = getattr (self, 'sequence_name', None)
2738 if seq_name == None:
2741 seq_name = "'" + seq_name + "'"
2742 if self.__dict__.has_key('ext_list'):
2743 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
2744 self.elts_to_py (self.elt_list, ctx),
2745 self.elts_to_py (self.ext_list, ctx), seq_name)
2747 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
2748 self.elts_to_py (self.elt_list, ctx), seq_name)
2749 def elts_to_py (self, list, ctx):
2750 # we have elt_type, val= named_type, maybe default=, optional=
2751 # named_type node: either ident = or typ =
2752 # need to dismember these in order to generate Python output syntax.
2755 assert (e.type == 'elt_type')
2757 optflag = e.optional
2758 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
2759 assert (nt.type == 'named_type')
2762 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
2763 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
2764 nt.typ.tag.tag_typ,nt.typ.tag.num)
2768 return "('%s',%s,%s,%d)" % (identstr, tagstr,
2769 nt.typ.to_python (ctx), optflag)
2770 indentstr = ",\n" + ctx.spaces ()
2771 rv = indentstr.join ([elt_to_py (e) for e in list])
2775 def eth_reg_sub(self, ident, ectx):
2776 for e in (self.elt_list):
2777 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2778 if hasattr(self, 'ext_list'):
2779 for e in (self.ext_list):
2780 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2782 def eth_need_tree(self):
2785 def GetTTag(self, ectx):
2786 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
2788 def eth_type_default_pars(self, ectx, tname):
2789 pars = Type.eth_type_default_pars(self, ectx, tname)
2790 pars['TABLE'] = '%(TNAME)s_sequence'
2793 def eth_type_default_body(self, ectx, tname):
2795 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
2796 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2797 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2799 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
2800 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2801 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2803 body = '#error Can not decode %s' % (tname)
2806 #--- SetType ------------------------------------------------------------------
2807 class SetType(SeqType):
2808 def eth_reg_sub(self, ident, ectx):
2809 for e in (self.elt_list):
2810 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2811 if hasattr(self, 'ext_list'):
2812 for e in (self.ext_list):
2813 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
2815 def eth_need_tree(self):
2818 def GetTTag(self, ectx):
2819 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
2821 def eth_type_default_pars(self, ectx, tname):
2822 pars = Type.eth_type_default_pars(self, ectx, tname)
2823 pars['TABLE'] = '%(TNAME)s_set'
2826 def eth_type_default_body(self, ectx, tname):
2828 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
2829 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
2830 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
2832 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
2833 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
2834 ('%(ETT_INDEX)s', '%(TABLE)s',),))
2836 body = '#error Can not decode %s' % (tname)
2839 #--- ChoiceType ---------------------------------------------------------------
2840 class ChoiceType (Type):
2841 def to_python (self, ctx):
2842 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
2843 # or '' + (1,) for optional
2844 if self.__dict__.has_key('ext_list'):
2845 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
2846 self.elts_to_py (self.elt_list, ctx),
2847 self.elts_to_py (self.ext_list, ctx))
2849 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
2850 def elts_to_py (self, list, ctx):
2853 assert (nt.type == 'named_type')
2855 if hasattr (nt, 'ident'):
2858 if hasattr (nt.typ, 'val'):
2859 identstr = nt.typ.val # XXX, making up name
2860 elif hasattr (nt.typ, 'name'):
2861 identstr = nt.typ.name
2863 identstr = ctx.make_new_name ()
2865 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
2866 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
2867 nt.typ.tag.tag_typ,nt.typ.tag.num)
2871 return "('%s',%s,%s)" % (identstr, tagstr,
2872 nt.typ.to_python (ctx))
2873 indentstr = ",\n" + ctx.spaces ()
2874 rv = indentstr.join ([elt_to_py (e) for e in list])
2878 def eth_reg_sub(self, ident, ectx):
2879 #print "eth_reg_sub(ident='%s')" % (ident)
2880 for e in (self.elt_list):
2881 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
2882 if hasattr(self, 'ext_list'):
2883 for e in (self.ext_list):
2884 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
2886 def eth_ftype(self, ectx):
2887 return ('FT_UINT32', 'BASE_DEC')
2889 def eth_strings(self):
2892 def eth_need_tree(self):
2895 def eth_has_vals(self):
2898 def GetTTag(self, ectx):
2900 cls = 'BER_CLASS_ANY/*choice*/'
2901 #if hasattr(self, 'ext_list'):
2902 # lst.extend(self.ext_list)
2904 # cls = lst[0].GetTag(ectx)[0]
2906 # if (e.GetTag(ectx)[0] != cls):
2907 # cls = '-1/*choice*/'
2908 return (cls, '-1/*choice*/')
2910 def IndetermTag(self, ectx):
2911 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
2912 return not self.HasOwnTag()
2914 def get_vals(self, ectx):
2918 if hasattr(self, 'ext_list'):
2919 lst.extend(self.ext_list)
2921 t = lst[0].GetTag(ectx)[0]
2923 if (t == 'BER_CLASS_UNI'):
2926 if (e.GetTag(ectx)[0] != t):
2930 for e in (self.elt_list):
2931 if (tagval): val = e.GetTag(ectx)[1]
2932 else: val = str(cnt)
2933 vals.append((val, e.name))
2935 if hasattr(self, 'ext_list'):
2936 for e in (self.ext_list):
2937 if (tagval): val = e.GetTag(ectx)[1]
2938 else: val = str(cnt)
2939 vals.append((val, e.name))
2943 def eth_type_vals(self, tname, ectx):
2945 vals = self.get_vals(ectx)
2946 out += ectx.eth_vals(tname, vals)
2949 def eth_type_enum(self, tname, ectx):
2951 vals = self.get_vals(ectx)
2952 out += ectx.eth_enum(tname, vals)
2955 def eth_type_default_pars(self, ectx, tname):
2956 pars = Type.eth_type_default_pars(self, ectx, tname)
2957 pars['TABLE'] = '%(TNAME)s_choice'
2960 def eth_type_default_table(self, ectx, tname):
2961 def out_item(val, e, ext, ectx):
2962 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
2964 vval = ectx.eth_enum_item(tname, e.name)
2967 f = fname + '/' + e.name
2968 ef = ectx.field[f]['ethname']
2969 t = ectx.eth_hf[ef]['ethtype']
2971 if (ectx.field[f]['impl']):
2975 if (not e.HasOwnTag()):
2976 opt = 'BER_FLAGS_NOOWNTAG'
2977 elif (e.HasImplicitTag(ectx)):
2978 if (opt): opt += '|'
2979 opt += 'BER_FLAGS_IMPLTAG'
2980 if (not opt): opt = '0'
2982 (tc, tn) = e.GetTag(ectx)
2983 out = ' { %3s, %-13s, %s, %s, dissect_%s },\n' \
2984 % (vval, tc, tn, opt, efd)
2986 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
2987 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
2992 #print "eth_type_default_table(tname='%s')" % (tname)
2993 fname = ectx.eth_type[tname]['ref'][0]
2997 if hasattr(self, 'ext_list'):
2998 lst.extend(self.ext_list)
3000 t = lst[0].GetTag(ectx)[0]
3002 if (t == 'BER_CLASS_UNI'):
3005 if (e.GetTag(ectx)[0] != t):
3007 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
3009 if hasattr(self, 'ext_list'):
3010 ext = 'ASN1_EXTENSION_ROOT'
3012 ext = 'ASN1_NO_EXTENSIONS'
3013 for e in (self.elt_list):
3014 if (tagval): val = e.GetTag(ectx)[1]
3015 else: val = str(cnt)
3016 table += out_item(val, e, ext, ectx)
3018 if hasattr(self, 'ext_list'):
3019 for e in (self.ext_list):
3020 if (tagval): val = e.GetTag(ectx)[1]
3021 else: val = str(cnt)
3022 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3025 table += " { 0, 0, 0, 0, NULL }\n};\n"
3027 table += " { 0, NULL, 0, NULL }\n};\n"
3030 def eth_type_default_body(self, ectx, tname):
3032 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3033 par=(('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3034 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
3037 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3038 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3039 ('%(ETT_INDEX)s', '%(TABLE)s',),
3042 body = '#error Can not decode %s' % (tname)
3045 #--- EnumeratedType -----------------------------------------------------------
3046 class EnumeratedType (Type):
3047 def to_python (self, ctx):
3048 def strify_one (named_num):
3049 return "%s=%s" % (named_num.ident, named_num.val)
3050 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
3052 def eth_ftype(self, ectx):
3053 return ('FT_UINT32', 'BASE_DEC')
3055 def eth_strings(self):
3058 def eth_has_vals(self):
3061 def GetTTag(self, ectx):
3062 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
3064 def get_vals_etc(self, ectx):
3072 for e in (self.val):
3073 if e.type == 'NamedNumber':
3074 used[int(e.val)] = True
3075 for e in (self.val):
3076 if e.type == 'NamedNumber':
3079 while used.has_key(lastv):
3083 vals.append((val, e.ident))
3084 map_table.append(val)
3088 if self.ext is not None:
3089 for e in (self.ext):
3090 if e.type == 'NamedNumber':
3091 used[int(e.val)] = True
3092 for e in (self.ext):
3093 if e.type == 'NamedNumber':
3096 while used.has_key(lastv):
3100 vals.append((val, e.ident))
3101 map_table.append(val)
3106 for i in range(len(map_table)):
3107 need_map = need_map or (map_table[i] != i)
3110 return (vals, root_num, ext_num, map_table)
3112 def eth_type_vals(self, tname, ectx):
3114 vals = self.get_vals_etc(ectx)[0]
3115 out += ectx.eth_vals(tname, vals)
3118 def eth_type_enum(self, tname, ectx):
3120 vals = self.get_vals_etc(ectx)[0]
3121 out += ectx.eth_enum(tname, vals)
3124 def eth_type_default_pars(self, ectx, tname):
3125 pars = Type.eth_type_default_pars(self, ectx, tname)
3126 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
3127 if (self.ext != None):
3131 pars['ROOT_NUM'] = str(root_num)
3133 pars['EXT_NUM'] = str(ext_num)
3135 pars['TABLE'] = '%(TNAME)s_value_map'
3137 pars['TABLE'] = 'NULL'
3140 def eth_type_default_table(self, ectx, tname):
3141 if (not ectx.Per()): return ''
3142 map_table = self.get_vals_etc(ectx)[3]
3143 if (map_table == None): return ''
3144 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
3145 table += ", ".join([str(v) for v in map_table])
3149 def eth_type_default_body(self, ectx, tname):
3151 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3152 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3155 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
3156 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3157 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
3159 body = '#error Can not decode %s' % (tname)
3162 #--- OpenType -----------------------------------------------------------
3163 class OpenType (Type):
3164 def to_python (self, ctx):
3167 def single_type(self):
3168 if (self.HasConstraint() and
3169 self.constr.type == 'Type' and
3170 self.constr.subtype.type == 'Type_Ref'):
3171 return self.constr.subtype.val
3174 def eth_reg_sub(self, ident, ectx):
3175 t = self.single_type()
3177 ectx.eth_dep_add(ident, t)
3179 def eth_tname(self):
3180 t = self.single_type()
3182 return 'OpenType_' + t
3184 return Type.eth_tname(self)
3186 def eth_ftype(self, ectx):
3187 return ('FT_NONE', 'BASE_NONE')
3189 def GetTTag(self, ectx):
3190 return ('BER_CLASS_ANY', '0')
3192 def eth_type_default_pars(self, ectx, tname):
3193 pars = Type.eth_type_default_pars(self, ectx, tname)
3194 t = self.single_type()
3196 t = ectx.type[t]['ethname']
3197 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3198 pars['TYPE_REF_TNAME'] = t
3199 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3201 pars['TYPE_REF_FN'] = 'NULL'
3204 def eth_type_default_body(self, ectx, tname):
3206 body = ectx.eth_fn_call('dissect_%(ER)s_open_type', ret='offset',
3207 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
3209 body = '#error Can not decode %s' % (tname)
3212 #--- AnyType -----------------------------------------------------------
3213 class AnyType (Type):
3214 def to_python (self, ctx):
3217 def eth_ftype(self, ectx):
3218 return ('FT_NONE', 'BASE_NONE')
3220 def GetTTag(self, ectx):
3221 return ('BER_CLASS_ANY', '0')
3223 def eth_type_default_body(self, ectx, tname):
3224 body = '#error Can not decode %s' % (tname)
3227 class Literal (Node):
3228 def to_python (self, ctx):
3231 #--- NullType -----------------------------------------------------------------
3232 class NullType (Type):
3233 def to_python (self, ctx):
3236 def eth_tname(self):
3239 def GetTTag(self, ectx):
3240 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
3242 def eth_type_default_body(self, ectx, tname):
3244 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
3245 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3247 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
3248 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3250 body = '#error Can not decode %s' % (tname)
3253 #--- RealType -----------------------------------------------------------------
3254 class RealType (Type):
3255 def to_python (self, ctx):
3258 def eth_tname(self):
3261 def eth_type_default_body(self, ectx, tname):
3262 body = '#error Can not decode %s' % (tname)
3265 #--- BooleanType --------------------------------------------------------------
3266 class BooleanType (Type):
3267 def to_python (self, ctx):
3268 return 'asn1.BOOLEAN'
3270 def eth_tname(self):
3273 def GetTTag(self, ectx):
3274 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
3276 def eth_ftype(self, ectx):
3277 return ('FT_BOOLEAN', '8')
3279 def eth_type_default_body(self, ectx, tname):
3281 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
3282 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3284 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
3285 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3287 body = '#error Can not decode %s' % (tname)
3290 #--- OctetStringType ----------------------------------------------------------
3291 class OctetStringType (Type):
3292 def to_python (self, ctx):
3293 return 'asn1.OCTSTRING'
3295 def eth_tname(self):
3296 if not self.HasConstraint():
3297 return 'OCTET_STRING'
3298 elif self.constr.IsSize():
3299 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
3301 return '#' + self.type + '_' + str(id(self))
3303 def eth_ftype(self, ectx):
3304 return ('FT_BYTES', 'BASE_HEX')
3306 def GetTTag(self, ectx):
3307 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
3309 def eth_type_default_pars(self, ectx, tname):
3310 pars = Type.eth_type_default_pars(self, ectx, tname)
3311 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3314 def eth_type_default_body(self, ectx, tname):
3316 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
3317 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3320 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
3321 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3322 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s',),))
3324 body = '#error Can not decode %s' % (tname)
3327 #--- CharacterStringType ------------------------------------------------------
3328 class CharacterStringType (Type):
3329 def eth_tname(self):
3330 if not self.HasConstraint():
3331 return self.eth_tsname()
3332 elif self.constr.IsSize():
3333 return self.eth_tsname() + '_' + self.constr.eth_constrname()
3335 return '#' + self.type + '_' + str(id(self))
3337 def eth_ftype(self, ectx):
3338 return ('FT_STRING', 'BASE_NONE')
3340 class RestrictedCharacterStringType (CharacterStringType):
3341 def to_python (self, ctx):
3342 return 'asn1.' + self.eth_tsname()
3344 def GetTTag(self, ectx):
3345 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
3347 def HasPermAlph(self):
3348 return (self.HasConstraint() and
3349 (self.constr.IsPermAlph() or
3350 (self.constr.type == 'Intersection' and (self.constr.subtype[0].IsPermAlph() or self.constr.subtype[1].IsPermAlph()))
3354 def eth_type_default_pars(self, ectx, tname):
3355 pars = Type.eth_type_default_pars(self, ectx, tname)
3356 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3357 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
3358 (pars['ALPHABET'], pars['ALPHABET_LEN']) = ('NULL', '0')
3359 if self.HasPermAlph():
3360 if self.constr.IsPermAlph():
3361 pars['ALPHABET'] = self.constr.subtype.subtype
3362 elif self.constr.subtype[0].IsPermAlph():
3363 pars['ALPHABET'] = self.constr.subtype[0].subtype.subtype
3364 elif self.constr.subtype[1].IsPermAlph():
3365 pars['ALPHABET'] = self.constr.subtype[1].subtype.subtype
3366 pars['ALPHABET_LEN'] = 'strlen(%(ALPHABET)s)'
3369 def eth_type_default_body(self, ectx, tname):
3371 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
3372 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
3373 ('%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3375 elif (ectx.Per() and self.HasPermAlph()):
3376 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
3377 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3378 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
3381 if (self.eth_tsname() == 'GeneralString'):
3382 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3383 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3384 elif (self.eth_tsname() == 'GeneralizedTime'):
3385 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
3386 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3387 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3388 elif (self.eth_tsname() == 'UTCTime'):
3389 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
3390 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3391 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3393 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3394 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3395 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3397 body = '#error Can not decode %s' % (tname)
3400 class BMPStringType (RestrictedCharacterStringType):
3401 def eth_tsname(self):
3404 class GeneralStringType (RestrictedCharacterStringType):
3405 def eth_tsname(self):
3406 return 'GeneralString'
3408 class GraphicStringType (RestrictedCharacterStringType):
3409 def eth_tsname(self):
3410 return 'GraphicString'
3412 class IA5StringType (RestrictedCharacterStringType):
3413 def eth_tsname(self):
3416 class NumericStringType (RestrictedCharacterStringType):
3417 def eth_tsname(self):
3418 return 'NumericString'
3420 class PrintableStringType (RestrictedCharacterStringType):
3421 def eth_tsname(self):
3422 return 'PrintableString'
3424 class TeletexStringType (RestrictedCharacterStringType):
3425 def eth_tsname(self):
3426 return 'TeletexString'
3428 class T61StringType (RestrictedCharacterStringType):
3429 def eth_tsname(self):
3431 def GetTTag(self, ectx):
3432 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
3434 class UniversalStringType (RestrictedCharacterStringType):
3435 def eth_tsname(self):
3436 return 'UniversalString'
3438 class UTF8StringType (RestrictedCharacterStringType):
3439 def eth_tsname(self):
3442 class VideotexStringType (RestrictedCharacterStringType):
3443 def eth_tsname(self):
3444 return 'VideotexString'
3446 class VisibleStringType (RestrictedCharacterStringType):
3447 def eth_tsname(self):
3448 return 'VisibleString'
3450 class ISO646StringType (RestrictedCharacterStringType):
3451 def eth_tsname(self):
3452 return 'ISO646String'
3453 def GetTTag(self, ectx):
3454 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
3456 class UnrestrictedCharacterStringType (CharacterStringType):
3457 def to_python (self, ctx):
3458 return 'asn1.UnrestrictedCharacterString'
3459 def eth_tsname(self):
3460 return 'CHARACTER_STRING'
3462 #--- UsefulType ---------------------------------------------------------------
3463 class GeneralizedTime (RestrictedCharacterStringType):
3464 def eth_tsname(self):
3465 return 'GeneralizedTime'
3467 def eth_type_default_body(self, ectx, tname):
3469 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
3470 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
3473 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
3475 class UTCTime (RestrictedCharacterStringType):
3476 def eth_tsname(self):
3479 class ObjectDescriptor (RestrictedCharacterStringType):
3480 def eth_tsname(self):
3481 return 'ObjectDescriptor'
3484 #--- ObjectIdentifierType -----------------------------------------------------
3485 class ObjectIdentifierType (Type):
3486 def to_python (self, ctx):
3487 return 'asn1.OBJECT_IDENTIFIER'
3489 def eth_tname(self):
3490 return 'OBJECT_IDENTIFIER'
3492 def eth_ftype(self, ectx):
3493 return ('FT_OID', 'BASE_NONE')
3495 def GetTTag(self, ectx):
3496 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
3498 def eth_type_default_body(self, ectx, tname):
3500 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
3501 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3503 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
3504 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
3506 body = '#error Can not decode %s' % (tname)
3509 #--- ObjectIdentifierValue ----------------------------------------------------
3510 class ObjectIdentifierValue (Value):
3511 def get_num(self, path, val):
3512 return str(oid_names.get(path + '/' + val, val))
3519 for v in self.comp_list:
3520 if isinstance(v, Node) and (v.type == 'name_and_number'):
3525 vstr = self.get_num(path, v)
3540 v = self.comp_list[0]
3541 if isinstance(v, Node) and (v.type == 'name_and_number'):
3546 vstr = self.get_num('', v)
3552 class NamedNumber (Node):
3553 def to_python (self, ctx):
3554 return "('%s',%s)" % (self.ident, self.val)
3556 class NamedNumListBase(Node):
3557 def to_python (self, ctx):
3558 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
3559 map (lambda x: x.to_python (ctx), self.named_list)))
3561 #--- IntegerType --------------------------------------------------------------
3562 class IntegerType (Type):
3563 def to_python (self, ctx):
3564 return "asn1.INTEGER_class ([%s])" % (",".join (
3565 map (lambda x: x.to_python (ctx), self.named_list)))
3567 def eth_tname(self):
3569 return Type.eth_tname(self)
3570 if not self.HasConstraint():
3572 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
3573 return 'INTEGER' + '_' + self.constr.eth_constrname()
3575 return 'INTEGER' + '_' + self.constr.eth_tname()
3577 def GetTTag(self, ectx):
3578 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
3581 def eth_ftype(self, ectx):
3582 if self.HasConstraint():
3583 if not self.constr.IsNegativ():
3584 return ('FT_UINT32', 'BASE_DEC')
3585 return ('FT_INT32', 'BASE_DEC')
3587 def eth_strings(self):
3588 if (self.named_list):
3593 def eth_has_vals(self):
3594 if (self.named_list):
3599 def get_vals(self, ectx):
3601 for e in (self.named_list):
3602 vals.append((int(e.val), e.ident))
3605 def eth_type_vals(self, tname, ectx):
3606 if not self.eth_has_vals(): return ''
3608 vals = self.get_vals(ectx)
3609 out += ectx.eth_vals(tname, vals)
3612 def eth_type_enum(self, tname, ectx):
3613 if not self.eth_has_enum(tname, ectx): return ''
3615 vals = self.get_vals(ectx)
3616 out += ectx.eth_enum(tname, vals)
3619 def eth_type_default_pars(self, ectx, tname):
3620 pars = Type.eth_type_default_pars(self, ectx, tname)
3621 if self.HasConstraint() and self.constr.IsValue():
3622 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr()
3625 def eth_type_default_body(self, ectx, tname):
3627 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3628 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
3630 elif (ectx.Per() and not self.HasConstraint()):
3631 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
3632 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
3633 elif (ectx.Per() and ((self.constr.type == 'SingleValue') or (self.constr.type == 'ValueRange'))):
3634 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
3635 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3636 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
3638 body = '#error Can not decode %s' % (tname)
3641 #--- BitStringType ------------------------------------------------------------
3642 class BitStringType (Type):
3643 def to_python (self, ctx):
3644 return "asn1.BITSTRING_class ([%s])" % (",".join (
3645 map (lambda x: x.to_python (ctx), self.named_list)))
3647 def eth_tname(self):
3649 return Type.eth_tname(self)
3650 elif not self.HasConstraint():
3652 elif self.constr.IsSize():
3653 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
3655 return '#' + self.type + '_' + str(id(self))
3657 def GetTTag(self, ectx):
3658 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
3660 def eth_ftype(self, ectx):
3661 return ('FT_BYTES', 'BASE_HEX')
3663 def eth_need_tree(self):
3664 return self.named_list
3666 def eth_named_bits(self):
3668 if (self.named_list):
3669 for e in (self.named_list):
3670 bits.append((int(e.val), e.ident))
3673 def eth_type_default_pars(self, ectx, tname):
3674 pars = Type.eth_type_default_pars(self, ectx, tname)
3675 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr()
3676 if not pars.has_key('ETT_INDEX'):
3677 pars['ETT_INDEX'] = '-1'
3678 pars['TABLE'] = 'NULL'
3679 if self.eth_named_bits():
3680 pars['TABLE'] = '%(TNAME)s_bits'
3683 def eth_type_default_table(self, ectx, tname):
3684 #print "eth_type_default_table(tname='%s')" % (tname)
3686 bits = self.eth_named_bits()
3688 table = ectx.eth_bits(tname, bits)
3691 def eth_type_default_body(self, ectx, tname):
3693 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
3694 par=(('%(IMPLICIT_TAG)s', '%(PINFO)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3695 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
3698 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
3699 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3700 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s','%(VAL_PTR)s'),))
3702 body = '#error Can not decode %s' % (tname)
3706 #==============================================================================
3708 def p_module_list_1 (t):
3709 'module_list : module_list module_def'
3710 t[0] = t[1] + [t[2]]
3712 def p_module_list_2 (t):
3713 'module_list : module_def'
3717 #--- ITU-T Recommendation X.680 -----------------------------------------------
3720 # 11 ASN.1 lexical items --------------------------------------------------------
3722 # 11.2 Type references
3724 'type_ref : UCASE_IDENT'
3725 t[0] = Type_Ref(val=t[1])
3727 # 11.4 Value references
3728 def p_valuereference (t):
3729 'valuereference : LCASE_IDENT'
3732 # 11.5 Module references
3733 def p_modulereference (t):
3734 'modulereference : UCASE_IDENT'
3738 # 12 Module definition --------------------------------------------------------
3741 def p_module_def (t):
3742 'module_def : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT BEGIN module_body END'
3743 t[0] = Module (ident = t[1], tag_def = t[3], body = t[6])
3745 def p_TagDefault_1 (t):
3746 '''TagDefault : EXPLICIT TAGS
3749 t[0] = Default_Tags (dfl_tag = t[1])
3751 def p_TagDefault_2 (t):
3753 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
3754 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
3756 def p_ModuleIdentifier_1 (t):
3757 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
3758 t [0] = Node('module_ident', val = t[1], ident = t[2])
3760 def p_ModuleIdentifier_2 (t):
3761 'ModuleIdentifier : modulereference' # name, oid
3762 t [0] = Node('module_ident', val = t[1], ident = None)
3764 def p_DefinitiveIdentifier (t):
3765 'DefinitiveIdentifier : ObjectIdentifierValue'
3768 # XXX originally we had both type_ref and module_ref, but that caused
3769 # a reduce/reduce conflict (because both were UCASE_IDENT). Presumably
3770 # this didn't cause a problem in the original ESNACC grammar because it
3771 # was LALR(1) and PLY is (as of 1.1) only SLR.
3773 #def p_module_ref (t):
3774 # 'module_ref : UCASE_IDENT'
3777 def p_assigned_ident_1 (t):
3778 'assigned_ident : ObjectIdentifierValue'
3781 def p_assigned_ident_2 (t):
3782 'assigned_ident : LCASE_IDENT'
3785 def p_assigned_ident_3 (t):
3789 def p_module_body_1 (t):
3790 'module_body : exports Imports AssignmentList'
3791 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
3793 def p_module_body_2 (t):
3795 t[0] = Node ('module_body', exports = [], imports = [],
3798 def p_exports_1 (t):
3799 'exports : EXPORTS syms_exported SEMICOLON'
3802 def p_exports_2 (t):
3806 def p_syms_exported_1 (t):
3807 'syms_exported : exp_sym_list'
3810 def p_syms_exported_2 (t):
3814 def p_exp_sym_list_1 (t):
3815 'exp_sym_list : Symbol'
3818 def p_exp_sym_list_2 (t):
3819 'exp_sym_list : exp_sym_list COMMA Symbol'
3820 t[0] = t[1] + [t[3]]
3824 'Imports : IMPORTS SymbolsImported SEMICOLON'
3827 def p_Imports_2 (t):
3831 def p_SymbolsImported_1(t):
3832 'SymbolsImported : '
3835 def p_SymbolsImported_2 (t):
3836 'SymbolsImported : SymbolsFromModuleList'
3839 def p_SymbolsFromModuleList_1 (t):
3840 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
3841 t[0] = t[1] + [t[2]]
3843 def p_SymbolsFromModuleList_2 (t):
3844 'SymbolsFromModuleList : SymbolsFromModule'
3847 def p_SymbolsFromModule (t):
3848 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
3849 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
3851 def p_GlobalModuleReference (t):
3852 'GlobalModuleReference : modulereference assigned_ident'
3853 t [0] = Node('module_ident', val = t[1], ident = t[2])
3855 def p_SymbolList_1 (t):
3856 'SymbolList : Symbol'
3859 def p_SymbolList_2 (t):
3860 'SymbolList : SymbolList COMMA Symbol'
3861 t[0] = t[1] + [t[3]]
3864 '''Symbol : type_ref
3865 | ParameterizedReference
3866 | identifier''' # XXX omit DefinedMacroName
3869 def p_Reference (t):
3870 '''Reference : type_ref
3874 def p_AssignmentList_1 (t):
3875 'AssignmentList : AssignmentList Assignment'
3876 t[0] = t[1] + [t[2]]
3878 def p_AssignmentList_2 (t):
3879 'AssignmentList : Assignment SEMICOLON'
3882 def p_AssignmentList_3 (t):
3883 'AssignmentList : Assignment'
3886 def p_Assignment (t):
3887 '''Assignment : TypeAssignment
3890 | ParameterizedTypeAssignment'''
3894 '''pyquote : PYQUOTE'''
3895 t[0] = PyQuote (val = t[1])
3898 # 13 Referencing type and value definitions -----------------------------------
3901 def p_DefinedType (t):
3902 '''DefinedType : ext_type_ref
3904 | ParameterizedType'''
3907 def p_DefinedValue(t):
3908 '''DefinedValue : ext_val_ref
3913 # 15 Assigning types and values -----------------------------------------------
3916 def p_TypeAssignment (t):
3917 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
3922 def p_ValueAssignment (t):
3923 'ValueAssignment : identifier Type ASSIGNMENT Value'
3924 t[0] = value_assign (ident = t[1], typ = t[2], val = t[4])
3927 # 16 Definition of types and values -------------------------------------------
3931 '''Type : BuiltinType
3933 | ConstrainedType'''
3937 def p_BuiltinType (t):
3938 '''BuiltinType : AnyType
3941 | CharacterStringType
3946 | ObjectClassFieldType
3947 | ObjectIdentifierType
3959 def p_ReferencedType (t):
3960 '''ReferencedType : DefinedType
3964 def p_ext_type_ref (t):
3965 'ext_type_ref : type_ref DOT type_ref'
3966 # XXX coerce 1st type_ref to module_ref
3967 t[0] = Node ('ext_type_ref', module = t[1], typ = t[3])
3970 def p_NamedType (t):
3971 'NamedType : identifier Type'
3977 '''Value : BuiltinValue
3978 | ReferencedValue'''
3982 def p_BuiltinValue (t):
3983 '''BuiltinValue : BooleanValue
3984 | ObjectIdentifierValue
3990 | char_string''' # XXX we don't support {data} here
3994 def p_ReferencedValue (t):
3995 '''ReferencedValue : DefinedValue'''
3999 #def p_NamedValue (t):
4000 # 'NamedValue : identifier Value'
4001 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
4004 # 17 Notation for the boolean type --------------------------------------------
4007 def p_BooleanType (t):
4008 'BooleanType : BOOLEAN'
4009 t[0] = BooleanType ()
4012 def p_BooleanValue (t):
4013 '''BooleanValue : TRUE
4018 # 18 Notation for the integer type --------------------------------------------
4021 def p_IntegerType_1 (t):
4022 'IntegerType : INTEGER'
4023 t[0] = IntegerType (named_list = None)
4025 def p_IntegerType_2 (t):
4026 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
4027 t[0] = IntegerType (named_list = t[3])
4029 def p_NamedNumberList_1 (t):
4030 'NamedNumberList : NamedNumber'
4033 def p_NamedNumberList_2 (t):
4034 'NamedNumberList : NamedNumberList COMMA NamedNumber'
4035 t[0] = t[1] + [t[3]]
4037 def p_NamedNumber (t):
4038 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
4039 | identifier LPAREN DefinedValue RPAREN'''
4040 t[0] = NamedNumber (ident = t[1], val = t[3])
4042 def p_SignedNumber_1 (t):
4043 'SignedNumber : NUMBER'
4046 def p_SignedNumber_2 (t):
4047 'SignedNumber : MINUS NUMBER'
4051 # 19 Notation for the enumerated type -----------------------------------------
4054 def p_EnumeratedType (t):
4055 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
4056 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
4058 def p_Enumerations_1 (t):
4059 'Enumerations : Enumeration'
4060 t[0] = { 'val' : t[1], 'ext' : None }
4062 def p_Enumerations_2 (t):
4063 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
4064 t[0] = { 'val' : t[1], 'ext' : [] }
4066 def p_Enumerations_3 (t):
4067 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
4068 t[0] = { 'val' : t[1], 'ext' : t[6] }
4070 def p_Enumeration_1 (t):
4071 'Enumeration : EnumerationItem'
4074 def p_Enumeration_2 (t):
4075 'Enumeration : Enumeration COMMA EnumerationItem'
4076 t[0] = t[1] + [t[3]]
4078 def p_EnumerationItem (t):
4079 '''EnumerationItem : Identifier
4083 def p_Identifier (t):
4084 'Identifier : identifier'
4085 t[0] = Node ('Identifier', ident = t[1])
4088 # 20 Notation for the real type -----------------------------------------------
4095 # 21 Notation for the bitstring type ------------------------------------------
4098 def p_BitStringType_1 (t):
4099 'BitStringType : BIT STRING'
4100 t[0] = BitStringType (named_list = None)
4102 def p_BitStringType_2 (t):
4103 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
4104 t[0] = BitStringType (named_list = t[4])
4106 def p_NamedBitList_1 (t):
4107 'NamedBitList : NamedBit'
4110 def p_NamedBitList_2 (t):
4111 'NamedBitList : NamedBitList COMMA NamedBit'
4112 t[0] = t[1] + [t[3]]
4115 '''NamedBit : identifier LPAREN NUMBER RPAREN
4116 | identifier LPAREN DefinedValue RPAREN'''
4117 t[0] = NamedNumber (ident = t[1], val = t[3])
4120 # 22 Notation for the octetstring type ----------------------------------------
4123 def p_OctetStringType (t):
4124 'OctetStringType : OCTET STRING'
4125 t[0] = OctetStringType ()
4128 # 23 Notation for the null type -----------------------------------------------
4136 #def p_NullValue (t):
4137 # 'NullValue : NULL'
4141 # 24 Notation for sequence types ----------------------------------------------
4144 def p_SequenceType_1 (t):
4145 'SequenceType : SEQUENCE LBRACE RBRACE'
4146 t[0] = SequenceType (elt_list = [])
4148 def p_SequenceType_2 (t):
4149 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
4150 if t[3].has_key('ext_list'):
4151 t[0] = SequenceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4153 t[0] = SequenceType (elt_list = t[3]['elt_list'])
4155 def p_ExtensionAndException_1 (t):
4156 'ExtensionAndException : ELLIPSIS'
4159 def p_OptionalExtensionMarker_1 (t):
4160 'OptionalExtensionMarker : COMMA ELLIPSIS'
4163 def p_OptionalExtensionMarker_2 (t):
4164 'OptionalExtensionMarker : '
4167 def p_ComponentTypeLists_1 (t):
4168 'ComponentTypeLists : element_type_list'
4169 t[0] = {'elt_list' : t[1]}
4171 def p_ComponentTypeLists_2 (t):
4172 'ComponentTypeLists : element_type_list COMMA ExtensionAndException extension_additions OptionalExtensionMarker'
4173 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
4175 def p_ComponentTypeLists_3 (t):
4176 'ComponentTypeLists : ExtensionAndException extension_additions OptionalExtensionMarker'
4177 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
4179 def p_extension_additions_1 (t):
4180 'extension_additions : extension_addition_list'
4183 def p_extension_additions_2 (t):
4184 'extension_additions : '
4187 def p_extension_addition_list_1 (t):
4188 'extension_addition_list : COMMA extension_addition'
4191 def p_extension_addition_list_2 (t):
4192 'extension_addition_list : extension_addition_list COMMA extension_addition'
4193 t[0] = t[1] + [t[3]]
4195 def p_extension_addition_1 (t):
4196 'extension_addition : element_type'
4199 def p_element_type_list_1 (t):
4200 'element_type_list : element_type'
4203 def p_element_type_list_2 (t):
4204 'element_type_list : element_type_list COMMA element_type'
4205 t[0] = t[1] + [t[3]]
4207 def p_element_type_1 (t):
4208 'element_type : NamedType'
4209 t[0] = Node ('elt_type', val = t[1], optional = 0)
4211 def p_element_type_2 (t):
4212 'element_type : NamedType OPTIONAL'
4213 t[0] = Node ('elt_type', val = t[1], optional = 1)
4215 def p_element_type_3 (t):
4216 'element_type : NamedType DEFAULT Value'
4217 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
4219 # * this rules uses NamedValue instead of Value
4220 # * for the stupid choice value syntax (fieldname value)
4221 # * it should be like a set/seq value (ie with
4225 # XXX get to COMPONENTS later
4228 def p_SequenceValue_1 (t):
4229 'SequenceValue : LBRACE RBRACE'
4233 #def p_SequenceValue_2 (t):
4234 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
4237 #def p_ComponentValueList_1 (t):
4238 # 'ComponentValueList : NamedValue'
4241 #def p_ComponentValueList_2 (t):
4242 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
4243 # t[0] = t[1] + [t[3]]
4246 # 25 Notation for sequence-of types -------------------------------------------
4249 def p_SequenceOfType (t):
4250 '''SequenceOfType : SEQUENCE OF Type
4251 | SEQUENCE OF NamedType'''
4252 t[0] = SequenceOfType (val = t[3], size_constr = None)
4255 # 26 Notation for set types ---------------------------------------------------
4258 def p_SetType_1 (t):
4259 'SetType : SET LBRACE RBRACE'
4260 if t[3].has_key('ext_list'):
4261 t[0] = SetType (elt_list = [])
4263 def p_SetType_2 (t):
4264 'SetType : SET LBRACE ComponentTypeLists RBRACE'
4265 if t[3].has_key('ext_list'):
4266 t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4268 t[0] = SetType (elt_list = t[3]['elt_list'])
4271 # 27 Notation for set-of types ------------------------------------------------
4274 def p_SetOfType (t):
4275 '''SetOfType : SET OF Type
4276 | SET OF NamedType'''
4277 t[0] = SetOfType (val = t[3])
4279 # 28 Notation for choice types ------------------------------------------------
4282 def p_ChoiceType (t):
4283 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
4284 if t[3].has_key('ext_list'):
4285 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
4287 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
4289 def p_alternative_type_lists_1 (t):
4290 'alternative_type_lists : alternative_type_list'
4291 t[0] = {'elt_list' : t[1]}
4293 def p_alternative_type_lists_2 (t):
4294 '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
4295 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
4297 def p_extension_addition_alternatives_1 (t):
4298 'extension_addition_alternatives : extension_addition_alternatives_list'
4301 def p_extension_addition_alternatives_2 (t):
4302 'extension_addition_alternatives : '
4305 def p_extension_addition_alternatives_list_1 (t):
4306 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
4309 def p_extension_addition_alternatives_list_2 (t):
4310 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
4311 t[0] = t[1] + [t[3]]
4313 def p_extension_addition_alternative_1 (t):
4314 'extension_addition_alternative : NamedType'
4317 def p_alternative_type_list_1 (t):
4318 'alternative_type_list : NamedType'
4321 def p_alternative_type_list_2 (t):
4322 'alternative_type_list : alternative_type_list COMMA NamedType'
4323 t[0] = t[1] + [t[3]]
4325 def p_selection_type (t): # XXX what is this?
4326 'selection_type : identifier LT Type'
4327 return Node ('seltype', ident = t[1], typ = t[3])
4329 # 30 Notation for tagged types ------------------------------------------------
4332 def p_TaggedType_1 (t):
4333 'TaggedType : Tag Type'
4334 t[1].mode = 'default'
4338 def p_TaggedType_2 (t):
4339 '''TaggedType : Tag IMPLICIT Type
4340 | Tag EXPLICIT Type'''
4346 'Tag : LBRACK Class ClassNumber RBRACK'
4347 t[0] = Tag(cls = t[2], num = t[3])
4349 def p_ClassNumber_1 (t):
4350 'ClassNumber : number'
4353 def p_ClassNumber_2 (t):
4354 'ClassNumber : DefinedValue'
4358 '''Class : UNIVERSAL
4372 #def p_any_type_2 (t):
4373 # 'any_type : ANY DEFINED BY identifier'
4374 # t[0] = Literal (val='asn1.ANY_constr(def_by="%s")' % t[4]) # XXX
4377 # 31 Notation for the object identifier type ----------------------------------
4380 def p_ObjectIdentifierType (t):
4381 'ObjectIdentifierType : OBJECT IDENTIFIER'
4382 t[0] = ObjectIdentifierType()
4385 def p_ObjectIdentifierValue (t):
4386 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
4387 t[0] = ObjectIdentifierValue (comp_list=t[2])
4389 def p_oid_comp_list_1 (t):
4390 'oid_comp_list : oid_comp_list oid_component'
4391 t[0] = t[1] + [t[2]]
4393 def p_oid_comp_list_2 (t):
4394 'oid_comp_list : oid_component'
4397 def p_oid_component (t):
4398 '''oid_component : number_form
4400 | name_and_number_form'''
4403 def p_number_form (t):
4404 'number_form : NUMBER'
4407 # 36 Notation for character string types --------------------------------------
4410 def p_CharacterStringType (t):
4411 '''CharacterStringType : RestrictedCharacterStringType
4412 | UnrestrictedCharacterStringType'''
4416 # 37 Definition of restricted character string types --------------------------
4418 def p_RestrictedCharacterStringType_1 (t):
4419 'RestrictedCharacterStringType : BMPString'
4420 t[0] = BMPStringType ()
4421 def p_RestrictedCharacterStringType_2 (t):
4422 'RestrictedCharacterStringType : GeneralString'
4423 t[0] = GeneralStringType ()
4424 def p_RestrictedCharacterStringType_3 (t):
4425 'RestrictedCharacterStringType : GraphicString'
4426 t[0] = GraphicStringType ()
4427 def p_RestrictedCharacterStringType_4 (t):
4428 'RestrictedCharacterStringType : IA5String'
4429 t[0] = IA5StringType ()
4430 def p_RestrictedCharacterStringType_5 (t):
4431 'RestrictedCharacterStringType : ISO646String'
4432 t[0] = ISO646StringType ()
4433 def p_RestrictedCharacterStringType_6 (t):
4434 'RestrictedCharacterStringType : NumericString'
4435 t[0] = NumericStringType ()
4436 def p_RestrictedCharacterStringType_7 (t):
4437 'RestrictedCharacterStringType : PrintableString'
4438 t[0] = PrintableStringType ()
4439 def p_RestrictedCharacterStringType_8 (t):
4440 'RestrictedCharacterStringType : TeletexString'
4441 t[0] = TeletexStringType ()
4442 def p_RestrictedCharacterStringType_9 (t):
4443 'RestrictedCharacterStringType : T61String'
4444 t[0] = T61StringType ()
4445 def p_RestrictedCharacterStringType_10 (t):
4446 'RestrictedCharacterStringType : UniversalString'
4447 t[0] = UniversalStringType ()
4448 def p_RestrictedCharacterStringType_11 (t):
4449 'RestrictedCharacterStringType : UTF8String'
4450 t[0] = UTF8StringType ()
4451 def p_RestrictedCharacterStringType_12 (t):
4452 'RestrictedCharacterStringType : VideotexString'
4453 t[0] = VideotexStringType ()
4454 def p_RestrictedCharacterStringType_13 (t):
4455 'RestrictedCharacterStringType : VisibleString'
4456 t[0] = VisibleStringType ()
4459 # 40 Definition of unrestricted character string types ------------------------
4462 def p_UnrestrictedCharacterStringType (t):
4463 'UnrestrictedCharacterStringType : CHARACTER STRING'
4464 t[0] = UnrestrictedCharacterStringType ()
4467 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
4469 # 42 Generalized time ---------------------------------------------------------
4471 def p_UsefulType_1 (t):
4472 'UsefulType : GeneralizedTime'
4473 t[0] = GeneralizedTime()
4475 # 43 Universal time -----------------------------------------------------------
4477 def p_UsefulType_2 (t):
4478 'UsefulType : UTCTime'
4481 # 44 The object descriptor type -----------------------------------------------
4483 def p_UsefulType_3 (t):
4484 'UsefulType : ObjectDescriptor'
4485 t[0] = ObjectDescriptor()
4488 # 45 Constrained types --------------------------------------------------------
4491 def p_ConstrainedType_1 (t):
4492 'ConstrainedType : Type Constraint'
4494 t[0].AddConstraint(t[2])
4496 def p_ConstrainedType_2 (t):
4497 'ConstrainedType : TypeWithConstraint'
4501 def p_TypeWithConstraint_1 (t):
4502 '''TypeWithConstraint : SET Constraint OF Type
4503 | SET SizeConstraint OF Type'''
4504 t[0] = SetOfType (val = t[4], constr = t[2])
4506 def p_TypeWithConstraint_2 (t):
4507 '''TypeWithConstraint : SEQUENCE Constraint OF Type
4508 | SEQUENCE SizeConstraint OF Type'''
4509 t[0] = SequenceOfType (val = t[4], constr = t[2])
4511 def p_TypeWithConstraint_3 (t):
4512 '''TypeWithConstraint : SET Constraint OF NamedType
4513 | SET SizeConstraint OF NamedType'''
4514 t[0] = SetOfType (val = t[4], constr = t[2])
4516 def p_TypeWithConstraint_4 (t):
4517 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
4518 | SEQUENCE SizeConstraint OF NamedType'''
4519 t[0] = SequenceOfType (val = t[4], constr = t[2])
4523 def p_Constraint (t):
4524 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
4527 def p_ConstraintSpec (t):
4528 '''ConstraintSpec : ElementSetSpecs
4529 | GeneralConstraint'''
4532 # 46 Element set specification ------------------------------------------------
4535 def p_ElementSetSpecs_1 (t):
4536 'ElementSetSpecs : RootElementSetSpec'
4539 def p_ElementSetSpecs_2 (t):
4540 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
4544 def p_ElementSetSpecs_3 (t):
4545 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA ElementSetSpecs'
4549 # skip compound constraints, only simple ones are supported
4551 def p_RootElementSetSpec_1 (t):
4552 'RootElementSetSpec : SubtypeElements'
4555 def p_RootElementSetSpec_2 (t):
4556 'RootElementSetSpec : SubtypeElements IntersectionMark SubtypeElements'
4557 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
4559 def p_IntersectionMark (t):
4560 '''IntersectionMark : CIRCUMFLEX
4563 # 47 Subtype elements ---------------------------------------------------------
4566 def p_SubtypeElements (t):
4567 '''SubtypeElements : SingleValue
4573 | InnerTypeConstraints
4574 | PatternConstraint'''
4579 def p_SingleValue (t):
4580 'SingleValue : Value'
4581 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
4583 # 47.3 Contained subtype
4585 def p_ContainedSubtype (t):
4586 'ContainedSubtype : Includes Type'
4587 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
4590 '''Includes : INCLUDES
4595 def p_ValueRange (t):
4596 'ValueRange : lower_end_point RANGE upper_end_point'
4597 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
4600 def p_lower_end_point_1 (t):
4601 'lower_end_point : lower_end_value '
4604 def p_lower_end_point_2 (t):
4605 'lower_end_point : lower_end_value LT' # XXX LT first?
4606 t[0] = t[1] # but not inclusive range
4608 def p_upper_end_point_1 (t):
4609 'upper_end_point : upper_end_value'
4612 def p_upper_end_point_2 (t):
4613 'upper_end_point : LT upper_end_value'
4614 t[0] = t[1] # but not inclusive range
4616 def p_lower_end_value (t):
4617 '''lower_end_value : Value
4621 def p_upper_end_value (t):
4622 '''upper_end_value : Value
4626 # 47.5 Size constraint
4628 def p_SizeConstraint (t):
4629 'SizeConstraint : SIZE Constraint'
4630 t[0] = Constraint (type = 'Size', subtype = t[2])
4632 # 47.6 Type constraint
4634 def p_TypeConstraint (t):
4635 'TypeConstraint : Type'
4636 t[0] = Constraint (type = 'Type', subtype = t[1])
4638 # 47.7 Permitted alphabet
4640 def p_PermittedAlphabet (t):
4641 'PermittedAlphabet : FROM Constraint'
4642 t[0] = Constraint (type = 'From', subtype = t[2])
4644 # 47.8 Inner subtyping
4646 def p_InnerTypeConstraints (t):
4647 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
4648 | WITH COMPONENTS MultipleTypeConstraints'''
4649 pass # ignore PER invisible constraint
4652 def p_SingleTypeConstraint (t):
4653 'SingleTypeConstraint : Constraint'
4657 def p_MultipleTypeConstraints (t):
4658 '''MultipleTypeConstraints : FullSpecification
4659 | PartialSpecification'''
4662 def p_FullSpecification (t):
4663 'FullSpecification : LBRACE TypeConstraints RBRACE'
4666 def p_PartialSpecification (t):
4667 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
4670 def p_TypeConstraints_1 (t):
4671 'TypeConstraints : named_constraint'
4674 def p_TypeConstraints_2 (t):
4675 'TypeConstraints : TypeConstraints COMMA named_constraint'
4676 t[0] = t[1] + [t[3]]
4678 def p_named_constraint_1 (t):
4679 'named_constraint : identifier constraint'
4680 return Node ('named_constraint', ident = t[1], constr = t[2])
4682 def p_named_constraint_2 (t):
4683 'named_constraint : constraint'
4684 return Node ('named_constraint', constr = t[1])
4686 def p_constraint (t):
4687 'constraint : value_constraint presence_constraint'
4688 t[0] = Node ('constraint', value = t[1], presence = t[2])
4690 def p_value_constraint_1 (t):
4691 'value_constraint : Constraint'
4694 def p_value_constraint_2 (t):
4695 'value_constraint : '
4698 def p_presence_constraint_1 (t):
4699 '''presence_constraint : PRESENT
4704 def p_presence_constraint_2 (t):
4705 '''presence_constraint : '''
4708 # 47.9 Pattern constraint
4710 def p_PatternConstraint (t):
4711 'PatternConstraint : PATTERN Value'
4712 t[0] = Constraint (type = 'Pattern', subtype = t[2])
4714 # 49 The exception identifier
4717 def p_ExceptionSpec (t):
4721 # /*-----------------------------------------------------------------------*/
4722 # /* Value Notation Productions */
4723 # /*-----------------------------------------------------------------------*/
4728 def p_ext_val_ref (t):
4729 'ext_val_ref : type_ref DOT identifier'
4730 # XXX coerce type_ref to module_ref
4731 return Node ('ext_val_ref', module = t[1], ident = t[3])
4733 def p_special_real_val (t):
4734 '''special_real_val : PLUS_INFINITY
4739 # Note that Z39.50 v3 spec has upper-case here for, e.g., SUTRS.
4740 # I've hacked the grammar to be liberal about what it accepts.
4741 # XXX should have -strict command-line flag to only accept lowercase
4742 # here, since that's what X.208 says.
4743 def p_name_form (t):
4744 '''name_form : type_ref
4748 def p_name_and_number_form_1 (t):
4749 '''name_and_number_form : identifier LPAREN number_form RPAREN
4750 | type_ref LPAREN number_form RPAREN'''
4751 t[0] = Node ('name_and_number', ident = t[1], number = t[3])
4753 def p_name_and_number_form_2 (t):
4754 'name_and_number_form : identifier LPAREN DefinedValue RPAREN'
4755 t[0] = Node ('name_and_number', ident = t[1], val = t[3])
4757 # see X.208 if you are dubious about lcase only for identifier
4758 def p_identifier (t):
4759 'identifier : LCASE_IDENT'
4763 def p_binary_string (t):
4764 'binary_string : BSTRING'
4767 def p_hex_string (t):
4768 'hex_string : HSTRING'
4771 def p_char_string (t):
4772 'char_string : QSTRING'
4780 #--- ITU-T Recommendation X.681 -----------------------------------------------
4782 # 7 ASN.1 lexical items -------------------------------------------------------
4784 # 7.4 Type field references
4786 def p_typefieldreference (t):
4787 'typefieldreference : AMPERSAND UCASE_IDENT'
4790 # 7.5 Value field references
4792 def p_valuefieldreference (t):
4793 'valuefieldreference : AMPERSAND LCASE_IDENT'
4796 # 8 Referencing definitions
4799 def p_DefinedObjectClass (t):
4800 'DefinedObjectClass : UsefulObjectClassReference'
4804 def p_UsefulObjectClassReference (t):
4805 '''UsefulObjectClassReference : TYPE_IDENTIFIER
4806 | ABSTRACT_SYNTAX'''
4809 # 9 Information object class definition and assignment
4812 def p_FieldName (t):
4813 '''FieldName : typefieldreference
4814 | valuefieldreference'''
4817 # 14 Notation for the object class field type ---------------------------------
4820 def p_ObjectClassFieldType (t):
4821 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'''
4822 t[0] = get_type_from_class(t[1], t[3])
4824 object_class_types = {
4825 'TYPE-IDENTIFIER/id' : lambda : ObjectIdentifierType(),
4826 'TYPE-IDENTIFIER/Type' : lambda : OpenType(),
4827 'ABSTRACT-SYNTAX/id' : lambda : ObjectIdentifierType(),
4828 'ABSTRACT-SYNTAX/Type' : lambda : OpenType(),
4829 'ABSTRACT-SYNTAX/property' : lambda : BitStringType(),
4832 def get_type_from_class(cls, fld):
4833 return object_class_types.get(cls + '/' + fld, lambda : AnyType())()
4835 #--- ITU-T Recommendation X.682 -----------------------------------------------
4837 # 8 General constraint specification ------------------------------------------
4840 def p_GeneralConstraint (t):
4841 '''GeneralConstraint : UserDefinedConstraint'''
4843 # | ContentsConstraint''
4846 # 9 User-defined constraints --------------------------------------------------
4849 def p_UserDefinedConstraint (t):
4850 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
4851 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
4853 def p_UserDefinedConstraintParameterList_1 (t):
4854 'UserDefinedConstraintParameterList : '
4857 def p_UserDefinedConstraintParameterList_2 (t):
4858 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
4861 def p_UserDefinedConstraintParameterList_3 (t):
4862 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
4863 t[0] = t[1] + [t[3]]
4866 def p_UserDefinedConstraintParameter (t):
4867 'UserDefinedConstraintParameter : type_ref'
4871 #--- ITU-T Recommendation X.683 -----------------------------------------------
4873 # 8 Parameterized assignments -------------------------------------------------
4878 def p_ParameterizedTypeAssignment (t):
4879 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
4881 t[0].SetName(t[1] + 'xxx')
4884 def p_ParameterList (t):
4885 'ParameterList : LBRACE Parameters RBRACE'
4888 def p_Parameters_1 (t):
4889 'Parameters : Parameter'
4892 def p_Parameters_2 (t):
4893 'Parameters : Parameters COMMA Parameter'
4894 t[0] = t[1] + [t[3]]
4896 def p_Parameter_1 (t):
4897 'Parameter : Type COLON Reference'
4900 def p_Parameter_2 (t):
4901 'Parameter : Reference'
4905 # 9 Referencing parameterized definitions -------------------------------------
4908 def p_ParameterizedReference (t):
4909 'ParameterizedReference : type_ref LBRACE RBRACE'
4914 def p_ParameterizedType (t):
4915 'ParameterizedType : type_ref ActualParameterList'
4920 def p_ActualParameterList (t):
4921 'ActualParameterList : LBRACE ActualParameters RBRACE'
4924 def p_ActualParameters_1 (t):
4925 'ActualParameters : ActualParameter'
4928 def p_ActualParameters_2 (t):
4929 'ActualParameters : ActualParameters COMMA ActualParameter'
4930 t[0] = t[1] + [t[3]]
4932 def p_ActualParameter (t):
4933 '''ActualParameter : Type
4939 raise ParseError(str(t))
4944 token = lexer.token ()
4950 def do_module (ast, defined_dict):
4951 assert (ast.type == 'Module')
4952 ctx = Ctx (defined_dict)
4953 print ast.to_python (ctx)
4954 print ctx.output_assignments ()
4955 print ctx.output_pyquotes ()
4957 def eth_do_module (ast, ectx):
4958 assert (ast.type == 'Module')
4959 if ectx.dbg('s'): print ast.str_depth(0)
4962 def testyacc(s, fn, defined_dict):
4963 ast = yacc.parse(s, debug=0)
4964 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
4965 print """#!/usr/bin/env python
4966 # Auto-generated from %s at %s
4967 from PyZ3950 import asn1""" % (fn, time_str)
4969 eth_do_module (module, defined_dict)
4972 # Wireshark compiler
4975 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c conform_file] [-e] input_file(s) ...
4977 -b : BER (default is PER)
4978 -u : unaligned (default is aligned)
4979 -p proto : protocol name (implies -S)
4980 default is module-name from input_file (renamed by #.MODULE if present)
4981 -F : create 'field functions'
4982 -T : tagged type support (experimental)
4983 -o name : output files name core (default is <proto>)
4984 -O dir : output directory
4985 -c conform_file : conformation file
4986 -e : create conformation file for exported types
4987 -S : single output for multiple modules
4988 -s template : single file output (template is input file without .c/.h extension)
4989 -k : keep intermediate files though single file output is used
4990 -L : suppress #line directive from .cnf file
4991 input_file(s) : input ASN.1 file(s)
4993 -d dbg : debug output, dbg = [l][y][p][s][a][t][c][o]
4997 s - internal ASN.1 structure
4998 a - list of assignments
5000 c - conformance values
5001 o - list of output files
5005 print "ASN.1 to Wireshark dissector compiler";
5007 opts, args = getopt.getopt(sys.argv[1:], "h?d:buXp:FTo:O:c:eSs:kL");
5008 except getopt.GetoptError:
5009 eth_usage(); sys.exit(2)
5011 eth_usage(); sys.exit(2)
5015 ectx = EthCtx(conform, output)
5016 ectx.encoding = 'per'
5017 ectx.proto_opt = None
5018 ectx.fld_opt = False
5019 ectx.tag_opt = False
5020 ectx.outnm_opt = None
5025 ectx.merge_modules = False
5026 ectx.output.suppress_line = False;
5027 ectx.output.outnm = None
5028 ectx.output.single_file = None
5030 if o in ("-h", "-?"):
5031 eth_usage(); sys.exit(2)
5033 ectx.encoding = 'ber'
5036 ectx.merge_modules = True
5042 ectx.conform.read(a)
5044 ectx.aligned = False
5050 ectx.merge_modules = True
5054 ectx.output.outdir = a
5056 ectx.output.single_file = a
5058 ectx.output.keep = True
5060 ectx.output.suppress_line = True
5062 warnings.warn("Command line option -X is obsolete and can be removed")
5064 (ld, yd, pd) = (0, 0, 0);
5065 if ectx.dbg('l'): ld = 1
5066 if ectx.dbg('y'): yd = 1
5067 if ectx.dbg('p'): pd = 2
5068 lexer = lex.lex(debug=ld)
5069 yacc.yacc(method='LALR', debug=yd)
5073 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
5077 eth_do_module(module, ectx)
5078 if (not ectx.merge_modules): # output for each module
5080 ectx.eth_do_output()
5082 if (ectx.merge_modules): # common output for all module
5084 ectx.eth_do_output()
5087 ectx.conform.dbg_print()
5088 ectx.conform.unused_report()
5091 ectx.output.dbg_print()
5092 ectx.output.make_single_file()
5098 if len (sys.argv) == 1:
5100 s = raw_input ('Query: ')
5103 testfn (s, 'console', {})
5106 for fn in sys.argv [1:]:
5108 testfn (f.read (), fn, defined_dict)
5113 #--- BODY ---------------------------------------------------------------------
5115 if __name__ == '__main__':
5116 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
5121 #------------------------------------------------------------------------------