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
36 # ITU-T Recommendation X.880 (07/1994),
37 # Information technology - Remote Operations: Concepts, model and notation
40 from __future__ import nested_scopes
52 import __main__ # XXX blech!
56 # OID name -> number conversion table
62 '0/recommendation' : 0,
91 '0/administration' : 2,
92 '0/network-operator' : 3,
93 '0/identified-organization' : 4,
94 '0/r-recommendation' : 5,
98 '1/registration-authority' : 1,
100 '1/identified-organization' : 3,
101 '/joint-iso-itu-t' : 2,
102 '/joint-iso-ccitt' : 2,
103 '2/presentation' : 0,
105 '2/association-control' : 2,
106 '2/reliable-transfer' : 3,
107 '2/remote-operations' : 4,
115 '2/osi-management' : 9,
116 '2/transaction-processing' : 10,
118 '2/distinguished-object-reference' : 11,
119 '2/reference-data-transfe' : 12,
120 '2/network-layer' : 13,
121 '2/network-layer-management' : 13,
122 '2/transport-layer' : 14,
123 '2/transport-layer-management' : 14,
124 '2/datalink-layer' : 15,
125 '2/datalink-layer-managemen' : 15,
126 '2/datalink-layer-management-information' : 15,
128 '2/registration-procedures' : 17,
129 '2/registration-procedure' : 17,
130 '2/physical-layer' : 18,
131 '2/physical-layer-management' : 18,
134 '2/generic-upper-layers-security' : 20,
136 '2/transport-layer-security-protocol' : 21,
137 '2/network-layer-security-protocol' : 22,
138 '2/international-organizations' : 23,
139 '2/internationalRA' : 23,
147 return id.replace('-', '_').replace('.', '_')
153 class LexError(Exception):
154 def __init__(self, tok, filename=None):
156 self.filename = filename
157 self.msg = "Unexpected character %r" % (self.tok.value[0])
158 Exception.__init__(self, self.msg)
160 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
164 class ParseError(Exception):
165 def __init__(self, tok, filename=None):
167 self.filename = filename
168 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
169 Exception.__init__(self, self.msg)
171 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
176 ('braceignore','exclusive'),
180 ('left', 'UNION', 'BAR'),
181 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
183 # 11 ASN.1 lexical items
186 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
187 r'\.\.' : 'RANGE', # 11.17 Range separator
188 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
189 #r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
190 #r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
191 # 11.26 Single character lexical items
206 #r"'" : 'APOSTROPHE',
209 #r'\!' : 'EXCLAMATION',
210 r'\^' : 'CIRCUMFLEX',
215 # 11.27 Reserved words
217 # all keys in reserved_words must start w/ upper case
220 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
222 'APPLICATION' : 'APPLICATION',
223 'AUTOMATIC' : 'AUTOMATIC',
226 'BOOLEAN' : 'BOOLEAN',
228 'CHARACTER' : 'CHARACTER',
231 'COMPONENT' : 'COMPONENT',
232 'COMPONENTS' : 'COMPONENTS',
233 'CONSTRAINED' : 'CONSTRAINED',
234 'CONTAINING' : 'CONTAINING',
235 'DEFAULT' : 'DEFAULT',
236 'DEFINITIONS' : 'DEFINITIONS',
237 'EMBEDDED' : 'EMBEDDED',
238 # 'ENCODED' : 'ENCODED',
240 'ENUMERATED' : 'ENUMERATED',
241 # 'EXCEPT' : 'EXCEPT',
242 'EXPLICIT' : 'EXPLICIT',
243 'EXPORTS' : 'EXPORTS',
244 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
245 'EXTERNAL' : 'EXTERNAL',
248 'GeneralizedTime' : 'GeneralizedTime',
249 'IDENTIFIER' : 'IDENTIFIER',
250 'IMPLICIT' : 'IMPLICIT',
251 # 'IMPLIED' : 'IMPLIED',
252 'IMPORTS' : 'IMPORTS',
253 'INCLUDES' : 'INCLUDES',
254 # 'INSTANCE' : 'INSTANCE',
255 'INTEGER' : 'INTEGER',
256 'INTERSECTION' : 'INTERSECTION',
259 'MINUS-INFINITY' : 'MINUS_INFINITY',
262 'ObjectDescriptor' : 'ObjectDescriptor',
265 'OPTIONAL' : 'OPTIONAL',
266 'PATTERN' : 'PATTERN',
268 'PLUS-INFINITY' : 'PLUS_INFINITY',
269 'PRESENT' : 'PRESENT',
270 'PRIVATE' : 'PRIVATE',
272 # 'RELATIVE-OID' : 'RELATIVE-OID',
273 'SEQUENCE' : 'SEQUENCE',
280 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
282 # 'UNIQUE' : 'UNIQUE',
283 'UNIVERSAL' : 'UNIVERSAL',
284 'UTCTime' : 'UTCTime',
286 # obsolete but still used
290 for k in static_tokens.keys ():
291 if static_tokens [k] == None:
292 static_tokens [k] = k
294 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
295 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
298 for s in StringTypes:
299 reserved_words[s + 'String'] = s + 'String'
301 tokens = static_tokens.values() \
302 + reserved_words.values() \
303 + ['BSTRING', 'HSTRING', 'QSTRING',
304 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
305 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
308 for (k, v) in static_tokens.items ():
309 __main__.__dict__['t_' + v] = k
311 # 11.10 Binary strings
316 # 11.12 Hexadecimal strings
325 def t_UCASE_IDENT (t):
326 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
327 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
328 if (is_x880_syntax(t.value)): t.type = t.value
329 t.type = reserved_words.get(t.value, t.type)
332 lcase_ident_assigned = {}
333 def t_LCASE_IDENT (t):
334 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
335 if (not in_oid and lcase_ident_assigned.has_key(t.value)): t.type = 'LCASE_IDENT_ASSIGNED'
339 def t_REAL_NUMBER (t):
340 r"[0-9]+\.[0-9]*(?!\.)"
349 pyquote_str = 'PYQUOTE'
351 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
352 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
353 if t.value[2:2+len (pyquote_str)] == pyquote_str:
354 t.value = t.value[2+len(pyquote_str):]
355 t.value = t.value.lstrip ()
364 t.lexer.lineno += t.value.count("\n")
368 raise LexError(t, input_file)
370 # state 'braceignore'
372 def t_braceignore_lbrace(t):
376 def t_braceignore_rbrace(t):
379 # If closing brace, return token
380 if t.lexer.level == 0:
384 def t_braceignore_QSTRING (t):
387 def t_braceignore_COMMENT(t):
388 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
389 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
391 def t_braceignore_nonspace(t):
392 r'[^\s\{\}\"-]+|-(?!-)'
394 t_braceignore_ignore = " \t\r"
396 def t_braceignore_NEWLINE(t):
398 t.lexer.lineno += t.value.count("\n")
400 def t_braceignore_error(t):
404 def __init__ (self, defined_dict, indent = 0):
405 self.tags_def = 'EXPLICIT' # default = explicit
407 self.assignments = {}
408 self.dependencies = {}
410 self.defined_dict = defined_dict
413 return " " * (4 * self.indent_lev)
418 assert (self.indent_lev >= 0)
419 def register_assignment (self, ident, val, dependencies):
420 if self.assignments.has_key (ident):
421 raise "Duplicate assignment for " + ident
422 if self.defined_dict.has_key (ident):
423 raise "cross-module duplicates for " + ident
424 self.defined_dict [ident] = 1
425 self.assignments[ident] = val
426 self.dependencies [ident] = dependencies
428 # return "#%s depends on %s" % (ident, str (dependencies))
429 def register_pyquote (self, val):
430 self.pyquotes.append (val)
432 def output_assignments (self):
435 assign_keys = self.assignments.keys()
436 to_output_count = len (assign_keys)
439 for (ident, val) in self.assignments.iteritems ():
440 if already_output.has_key (ident):
443 for d in self.dependencies [ident]:
444 if (not already_output.has_key (d) and
448 text_list.append ("%s=%s" % (ident,
449 self.assignments [ident]))
450 already_output [ident] = 1
453 assert (to_output_count >= 0)
455 if to_output_count == 0:
457 # OK, we detected a cycle
459 for ident in self.assignments.iterkeys ():
460 if not already_output.has_key (ident):
461 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
462 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
464 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
465 for (ident, val) in self.assignments.iteritems ():
466 if not already_output.has_key (ident):
467 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
470 return "\n".join (text_list)
471 def output_pyquotes (self):
472 return "\n".join (self.pyquotes)
473 def make_new_name (self):
475 return "_compiler_generated_name_%d" % (self.name_ctr,)
477 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
489 #--- common dependency computation ---
490 # Input : list of items
491 # dictionary with lists of dependency
494 # Output : list of two outputs:
495 # [0] list of items in dependency
496 # [1] list of cycle dependency cycles
497 def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
500 x = {} # already emitted
501 #print '# Dependency computation'
503 if x.has_key(map_fn(t)):
504 #print 'Continue: %s : %s' % (t, (map_fn(t))
507 stackx = {t : dependency.get(t, [])[:]}
508 #print 'Push: %s : %s' % (t, str(stackx[t]))
510 if stackx[stack[-1]]: # has dependencies
511 d = stackx[stack[-1]].pop(0)
512 if x.has_key(map_fn(d)) or ignore_fn(d):
514 if stackx.has_key(d): # cyclic dependency
517 c = [d] + c[0:c.index(d)+1]
520 #print 'Cyclic: %s ' % (' -> '.join(c))
523 stackx[d] = dependency.get(d, [])[:]
524 #print 'Push: %s : %s' % (d, str(stackx[d]))
526 #print 'Pop: %s' % (stack[-1])
527 del stackx[stack[-1]]
528 e = map_fn(stack.pop())
531 #print 'Add: %s' % (e)
534 return (item_ord, item_cyc)
536 #--- EthCtx -------------------------------------------------------------------
538 def __init__(self, conform, output, indent = 0):
539 self.conform = conform
541 self.conform.ectx = self
542 self.output.ectx = self
543 self.encoding = 'per'
546 self.default_oid_variant = ''
547 self.default_opentype_variant = ''
548 self.default_containing_variant = '_pdu_new'
549 self.default_external_type_cb = None
555 def encp(self): # encoding protocol
560 def Per(self): return self.encoding == 'per'
561 def Ber(self): return self.encoding == 'ber'
562 def NewBer(self): return self.new_ber
563 def Aligned(self): return self.aligned
564 def Unaligned(self): return not self.aligned
565 def Fld(self, tnm='*'): return self.fld_opt.get('*', False) or self.fld_opt.get(tnm, False) or (self.Ber() and not self.NewBer())
566 def Tag(self): return self.tag_opt # or self.Ber() - temporary comment out (experimental feature)
567 def NAPI(self): return False # disable planned features
569 def Module(self): # current module name
570 return self.modules[-1][0]
573 if (self.dbgopt.find(d) >= 0):
578 def value_max(self, a, b):
579 if (a == 'MAX') or (b == 'MAX'): return 'MAX';
580 if a == 'MIN': return b;
581 if b == 'MIN': return a;
583 if (int(a) > int(b)):
587 except (ValueError, TypeError):
589 return "MAX((%s),(%s))" % (a, b)
591 def value_min(self, a, b):
592 if (a == 'MIN') or (b == 'MIN'): return 'MIN';
593 if a == 'MAX': return b;
594 if b == 'MAX': return a;
596 if (int(a) < int(b)):
600 except (ValueError, TypeError):
602 return "MIN((%s),(%s))" % (a, b)
604 def value_get_eth(self, nm):
606 if self.value.has_key(nm):
607 ethname = self.value[nm]['ethname']
610 def value_get_val(self, nm):
612 if self.value.has_key(nm):
613 if self.value[nm]['import']:
614 v = self.get_val_from_all(nm, self.value[nm]['import'])
616 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
617 warnings.warn_explicit(msg, UserWarning, '', '')
621 val = self.value[nm]['value']
622 if isinstance (val, Value):
623 val = val.to_str(self)
625 msg = 'Need value of unknown value identifier %s' % (nm)
626 warnings.warn_explicit(msg, UserWarning, '', '')
629 def eth_get_type_attr(self, type):
631 while (not self.type[type]['import']
632 and self.type[type]['val'].type == 'Type_Ref'):
633 type = self.type[type]['val'].val
638 attr.update(self.type[t]['attr'])
639 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
642 def get_ttag_from_all(self, type, module):
644 if self.all_tags.has_key(module) and self.all_tags[module].has_key(type):
645 ttag = self.all_tags[module][type]
648 def get_val_from_all(self, nm, module):
650 if self.all_vals.has_key(module) and self.all_vals[module].has_key(nm):
651 val = self.all_vals[module][nm]
654 #--- eth_reg_module -----------------------------------------------------------
655 def eth_reg_module(self, module):
656 #print "eth_reg_module(module='%s')" % (module)
657 self.modules.append((module, self.proto))
658 if self.module.has_key(module):
659 raise "Duplicate module for " + module
660 self.module[module] = []
661 self.module_ord.append(module)
663 #--- eth_module_dep_add ------------------------------------------------------------
664 def eth_module_dep_add(self, module, dep):
665 self.module[module].append(dep)
667 #--- eth_exports ------------------------------------------------------------
668 def eth_exports(self, exports):
669 self.exports_all = False
670 if ((len(exports) == 1) and (exports[0] == 'ALL')):
671 self.exports_all = True
674 if isinstance(e, Type_Ref):
675 self.exports.append(e.val)
676 elif isinstance(e, Class_Ref):
677 self.cexports.append(e.val)
679 self.vexports.append(e)
681 #--- eth_reg_assign ---------------------------------------------------------
682 def eth_reg_assign(self, ident, val, virt=False):
683 #print "eth_reg_assign(ident='%s')" % (ident)
684 if self.assign.has_key(ident):
685 raise "Duplicate assignment for " + ident
686 self.assign[ident] = { 'val' : val , 'virt' : virt }
687 self.assign_ord.append(ident)
688 if (self.exports_all):
689 self.exports.append(ident)
691 #--- eth_reg_vassign --------------------------------------------------------
692 def eth_reg_vassign(self, vassign):
693 ident = vassign.ident
694 #print "eth_reg_vassign(ident='%s')" % (ident)
695 if self.vassign.has_key(ident):
696 raise "Duplicate value assignment for " + ident
697 self.vassign[ident] = vassign
698 self.vassign_ord.append(ident)
699 if (self.exports_all):
700 self.vexports.append(ident)
702 #--- eth_import_type --------------------------------------------------------
703 def eth_import_type(self, ident, mod, proto):
704 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
705 if self.type.has_key(ident):
706 #print "already defined import=%s, module=%s" % (str(self.type[ident]['import']), self.type[ident]['module'])
707 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
708 return # OK - already defined
709 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
710 return # OK - already imported
712 raise "Duplicate type for " + ident
713 self.type[ident] = {'import' : mod, 'proto' : proto,
715 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
716 'STRINGS' : 'NULL', 'BITMASK' : '0' }
717 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
718 self.type_imp.append(ident)
720 #--- dummy_import_type --------------------------------------------------------
721 def dummy_import_type(self, ident):
723 if self.type.has_key(ident):
724 raise "Try to dummy import for existing type :" + ident
725 ethtype = asn2c(ident)
726 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
727 'ethname' : ethtype }
728 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
729 'STRINGS' : 'NULL', 'BITMASK' : '0' }
730 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'create_field' : False, 'ref' : []}
731 print "Dummy imported: %s (%s)" % (ident, ethtype)
734 #--- eth_import_class --------------------------------------------------------
735 def eth_import_class(self, ident, mod, proto):
736 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
737 if self.objectclass.has_key(ident):
738 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
739 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
740 return # OK - already defined
741 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
742 return # OK - already imported
744 raise "Duplicate object class for " + ident
745 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
747 self.objectclass_imp.append(ident)
749 #--- eth_import_value -------------------------------------------------------
750 def eth_import_value(self, ident, mod, proto):
751 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
752 if self.value.has_key(ident):
753 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
754 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
755 return # OK - already defined
756 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
757 return # OK - already imported
759 raise "Duplicate value for " + ident
760 self.value[ident] = {'import' : mod, 'proto' : proto,
762 self.value_imp.append(ident)
764 #--- eth_sel_req ------------------------------------------------------------
765 def eth_sel_req(self, typ, sel):
766 key = typ + '.' + sel
767 if not self.sel_req.has_key(key):
768 self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
769 self.sel_req_ord.append(key)
772 #--- eth_comp_req ------------------------------------------------------------
773 def eth_comp_req(self, type):
774 self.comp_req_ord.append(type)
776 #--- eth_dep_add ------------------------------------------------------------
777 def eth_dep_add(self, type, dep):
778 if not self.type_dep.has_key(type):
779 self.type_dep[type] = []
780 self.type_dep[type].append(dep)
782 #--- eth_reg_type -----------------------------------------------------------
783 def eth_reg_type(self, ident, val):
784 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
785 if self.type.has_key(ident):
786 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
787 # replace imported type
789 self.type_imp.remove(ident)
791 raise "Duplicate type for " + ident
792 self.type[ident] = { 'val' : val, 'import' : None }
793 self.type[ident]['module'] = self.Module()
794 self.type[ident]['proto'] = self.proto
795 if len(ident.split('/')) > 1:
796 self.type[ident]['tname'] = val.eth_tname()
798 self.type[ident]['tname'] = asn2c(ident)
799 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
800 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
801 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
802 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
803 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
804 self.type[ident]['ethname'] = ''
805 if val.type == 'Type_Ref':
806 self.type[ident]['attr'] = {}
808 (ftype, display) = val.eth_ftype(self)
809 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
810 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
811 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
812 self.type_ord.append(ident)
814 #--- eth_reg_objectclass ----------------------------------------------------------
815 def eth_reg_objectclass(self, ident):
816 #print "eth_reg_objectclass(ident='%s')" % (ident)
817 if self.objectclass.has_key(ident):
818 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
819 # replace imported object class
820 del self.objectclass[ident]
821 self.objectclass_imp.remove(ident)
823 raise "Duplicate object class for " + ident
824 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
825 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
826 self.objectclass_ord.append(ident)
828 #--- eth_reg_value ----------------------------------------------------------
829 def eth_reg_value(self, ident, type, value, ethname=None):
830 #print "eth_reg_value(ident='%s')" % (ident)
831 if self.value.has_key(ident):
832 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
833 # replace imported value
834 del self.value[ident]
835 self.value_imp.remove(ident)
837 self.value[ident]['ethname'] = ethname
840 raise "Duplicate value for " + ident
841 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
842 'type' : type, 'value' : value,
844 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
845 self.value[ident]['ethname'] = ''
846 if (ethname): self.value[ident]['ethname'] = ethname
847 self.value_ord.append(ident)
849 #--- eth_reg_field ----------------------------------------------------------
850 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
851 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
852 if self.field.has_key(ident):
853 raise "Duplicate field for " + ident
854 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
855 'modified' : '', 'attr' : {} , 'create_field' : False }
856 name = ident.split('/')[-1]
857 if len(ident.split('/')) > 1 and name == '_item': # Sequnce/Set of type
858 self.field[ident]['attr']['NAME'] = '"Item"'
859 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
861 self.field[ident]['attr']['NAME'] = '"%s"' % name
862 self.field[ident]['attr']['ABBREV'] = asn2c(name)
863 if self.conform.check_item('FIELD_ATTR', ident):
864 self.field[ident]['modified'] = '#' + str(id(self))
865 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
867 self.pdu_ord.append(ident)
869 self.field_ord.append(ident)
871 self.field[ident]['create_field'] = self.Fld(parent)
872 self.eth_dep_add(parent, type)
874 #--- eth_clean --------------------------------------------------------------
876 self.proto = self.proto_opt;
877 #--- ASN.1 tables ----------------
888 self.sel_req_ord = []
889 self.comp_req_ord = []
891 self.vassign_ord = []
895 self.objectclass = {}
896 self.objectclass_ord = []
897 self.objectclass_imp = []
898 #--- Modules ------------
900 self.exports_all = False
904 #--- types -------------------
906 self.eth_type_ord = []
907 self.eth_export_ord = []
908 self.eth_type_dupl = {}
910 #--- value dependencies -------------------
912 #--- values -------------------
914 self.eth_value_ord = []
915 #--- fields -------------------------
918 self.eth_hfpdu_ord = []
919 self.eth_hf_dupl = {}
920 #--- type dependencies -------------------
921 self.eth_type_ord1 = []
922 self.eth_dep_cycle = []
923 self.dep_cycle_eth_type = {}
924 #--- value dependencies and export -------------------
925 self.eth_value_ord1 = []
926 self.eth_vexport_ord = []
928 #--- eth_prepare ------------------------------------------------------------
929 def eth_prepare(self):
930 self.eproto = asn2c(self.proto)
932 #--- dummy types/fields for PDU registration ---
934 if (self.conform.check_item('PDU', nm)):
935 self.eth_reg_type('_dummy/'+nm, NullType())
936 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
938 #--- required PDUs ----------------------------
939 for t in self.type_ord:
940 pdu = self.type[t]['val'].eth_need_pdu(self)
944 pdu['hidden'] = False
945 pdu['need_decl'] = True
946 if not self.field.has_key(f):
947 self.eth_reg_field(f, f, pdu=pdu)
949 #--- values -> named values -------------------
951 for v in self.value_ord:
952 if (self.value[v]['type'].type == 'Type_Ref'):
953 tnm = self.value[v]['type'].val
954 if self.type.has_key(tnm) \
955 and not self.type[tnm]['import'] \
956 and (self.type[tnm]['val'].type == 'IntegerType'):
957 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
958 self.value[v]['no_emit'] = True
959 t_for_update[tnm] = True
960 for t in t_for_update.keys():
961 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
962 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
964 #--- required components of ---------------------------
965 #print "self.comp_req_ord = ", self.comp_req_ord
966 for t in self.comp_req_ord:
967 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
969 #--- required selection types ---------------------------
970 #print "self.sel_req_ord = ", self.sel_req_ord
971 for t in self.sel_req_ord:
972 tt = self.sel_req[t]['typ']
973 if not self.type.has_key(tt):
974 self.dummy_import_type(t)
975 elif self.type[tt]['import']:
976 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
978 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
980 #--- types -------------------
981 for t in self.type_imp:
983 self.eth_type[nm] = { 'import' : self.type[t]['import'],
984 'proto' : asn2c(self.type[t]['proto']),
985 'attr' : {}, 'create_field' : False, 'ref' : []}
986 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
987 self.type[t]['ethname'] = nm
988 for t in self.type_ord:
989 nm = self.type[t]['tname']
990 if ((nm.find('#') >= 0) or
991 ((len(t.split('/'))>1) and
992 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t)) and
993 not self.conform.check_item('TYPE_RENAME', t))):
994 if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequnce of type at the 1st level
995 nm = t.split('/')[0] + t.split('/')[1]
996 elif t.split('/')[-1] == '_item': # Sequnce/Set of type at next levels
997 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
998 elif t.split('/')[-1] == '_untag': # Untagged type
999 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1001 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1003 if self.eth_type.has_key(nm):
1004 if self.eth_type_dupl.has_key(nm):
1005 self.eth_type_dupl[nm].append(t)
1007 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1008 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1009 if self.eth_type.has_key(nm):
1010 self.eth_type[nm]['ref'].append(t)
1012 self.eth_type_ord.append(nm)
1013 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
1014 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1015 'val' : self.type[t]['val'],
1017 'create_field' : False, 'ref' : [t]}
1018 self.type[t]['ethname'] = nm
1019 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1020 self.eth_export_ord.append(nm)
1021 self.eth_type[nm]['export'] |= self.type[t]['export']
1022 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1023 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1024 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1025 if self.type[t]['attr'].get('STRINGS') == '$$':
1026 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1027 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1028 for t in self.eth_type_ord:
1029 bits = self.eth_type[t]['val'].eth_named_bits()
1031 for (val, id) in bits:
1032 self.named_bit.append({'name' : id, 'val' : val,
1033 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1034 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1036 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1037 if self.eth_type[t]['val'].eth_need_tree():
1038 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1040 self.eth_type[t]['tree'] = None
1042 #--- register values from enums ------------
1043 for t in self.eth_type_ord:
1044 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1045 self.eth_type[t]['val'].reg_enum_vals(t, self)
1047 #--- value dependencies -------------------
1048 for v in self.value_ord:
1049 if isinstance (self.value[v]['value'], Value):
1050 dep = self.value[v]['value'].get_dep()
1052 dep = self.value[v]['value']
1053 if dep and self.value.has_key(dep):
1054 self.value_dep.setdefault(v, []).append(dep)
1056 #--- exports all necessary values
1057 for v in self.value_ord:
1058 if not self.value[v]['export']: continue
1059 deparr = self.value_dep.get(v, [])
1062 if not self.value[d]['import']:
1063 if not self.value[d]['export']:
1064 self.value[d]['export'] = EF_TYPE
1065 deparr.extend(self.value_dep.get(d, []))
1067 #--- values -------------------
1068 for v in self.value_imp:
1070 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1071 'proto' : asn2c(self.value[v]['proto']),
1073 self.value[v]['ethname'] = nm
1074 for v in self.value_ord:
1075 if (self.value[v]['ethname']):
1077 if (self.value[v]['no_emit']):
1080 self.eth_value[nm] = { 'import' : None,
1081 'proto' : asn2c(self.value[v]['proto']),
1082 'export' : self.value[v]['export'], 'ref' : [v] }
1083 self.eth_value[nm]['value'] = self.value[v]['value']
1084 self.eth_value_ord.append(nm)
1085 self.value[v]['ethname'] = nm
1087 #--- fields -------------------------
1088 for f in (self.pdu_ord + self.field_ord):
1089 if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequnce/Set of type
1090 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1092 nm = f.split('/')[-1]
1093 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1095 if (self.field[f]['pdu']):
1097 t = self.field[f]['type']
1098 if self.type.has_key(t):
1099 ethtype = self.type[t]['ethname']
1100 else: # undefined type
1101 ethtype = self.dummy_import_type(t)
1102 ethtypemod = ethtype + self.field[f]['modified']
1103 if self.eth_hf.has_key(nm):
1104 if self.eth_hf_dupl.has_key(nm):
1105 if self.eth_hf_dupl[nm].has_key(ethtypemod):
1106 nm = self.eth_hf_dupl[nm][ethtypemod]
1107 self.eth_hf[nm]['create_field'] = self.eth_hf[nm]['create_field'] or self.field[f]['create_field']
1108 self.eth_hf[nm]['ref'].append(f)
1109 self.field[f]['ethname'] = nm
1110 self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
1113 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1114 self.eth_hf_dupl[nm][ethtype] = nmx
1117 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1118 self.eth_hf[nm]['create_field'] = self.eth_hf[nm]['create_field'] or self.field[f]['create_field']
1119 self.eth_hf[nm]['ref'].append(f)
1120 self.field[f]['ethname'] = nm
1121 self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
1125 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1128 if (self.field[f]['pdu']):
1129 self.eth_hfpdu_ord.append(nm)
1131 self.eth_hf_ord.append(nm)
1132 fullname = "hf_%s_%s" % (self.eproto, nm)
1133 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1134 attr.update(self.field[f]['attr'])
1135 if (self.NAPI() and attr.has_key('NAME')):
1136 attr['NAME'] += self.field[f]['idx']
1137 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1138 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1139 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1140 'attr' : attr.copy(),
1141 'create_field' : self.field[f]['create_field'],
1143 self.field[f]['ethname'] = nm
1144 self.eth_type[ethtype]['create_field'] = self.eth_type[ethtype]['create_field'] or self.eth_hf[nm]['create_field']
1145 #--- type dependencies -------------------
1146 (self.eth_type_ord1, self.eth_dep_cycle) = dependency_compute(self.type_ord, self.type_dep, map_fn = lambda t: self.type[t]['ethname'], ignore_fn = lambda t: self.type[t]['import'])
1148 while i < len(self.eth_dep_cycle):
1149 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1150 self.dep_cycle_eth_type.setdefault(t, []).append(i)
1153 #--- value dependencies and export -------------------
1154 for v in self.eth_value_ord:
1155 if self.eth_value[v]['export']:
1156 self.eth_vexport_ord.append(v)
1158 self.eth_value_ord1.append(v)
1160 #--- export tags, values, ... ---
1161 for t in self.exports:
1162 if not self.type.has_key(t):
1164 if self.type[t]['import']:
1166 m = self.type[t]['module']
1167 if not self.all_tags.has_key(m):
1168 self.all_tags[m] = {}
1169 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
1170 for v in self.vexports:
1171 if not self.value.has_key(v):
1173 if self.value[v]['import']:
1175 m = self.value[v]['module']
1176 if not self.all_vals.has_key(m):
1177 self.all_vals[m] = {}
1178 vv = self.value[v]['value']
1179 if isinstance (vv, Value):
1180 vv = vv.to_str(self)
1181 self.all_vals[m][v] = vv
1183 #--- eth_vals_nm ------------------------------------------------------------
1184 def eth_vals_nm(self, tname):
1186 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
1187 out += "%s_" % (self.eproto)
1188 out += "%s_vals" % (tname)
1191 #--- eth_vals ---------------------------------------------------------------
1192 def eth_vals(self, tname, vals):
1194 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
1195 if (not self.eth_type[tname]['export'] & EF_VALS):
1197 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
1199 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
1200 for (val, id) in vals:
1202 vval = self.eth_enum_item(tname, id)
1205 out += ' { %3s, "%s" },\n' % (vval, id)
1206 out += " { 0, NULL }\n};\n"
1209 #--- eth_enum_prefix ------------------------------------------------------------
1210 def eth_enum_prefix(self, tname, type=False):
1212 if (self.eth_type[tname]['export'] & EF_ENUM):
1213 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
1215 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
1218 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
1219 if (out): out += '_'
1221 if (self.eth_type[tname]['enum'] & EF_UCASE):
1223 if (out): out += '_'
1226 #--- eth_enum_nm ------------------------------------------------------------
1227 def eth_enum_nm(self, tname):
1228 out = self.eth_enum_prefix(tname, type=True)
1232 #--- eth_enum_item ---------------------------------------------------------------
1233 def eth_enum_item(self, tname, ident):
1234 out = self.eth_enum_prefix(tname)
1236 if (self.eth_type[tname]['enum'] & EF_UCASE):
1240 #--- eth_enum ---------------------------------------------------------------
1241 def eth_enum(self, tname, vals):
1243 if (self.eth_type[tname]['enum'] & EF_DEFINE):
1244 out += "/* enumerated values for %s */\n" % (tname)
1245 for (val, id) in vals:
1246 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1248 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1250 for (val, id) in vals:
1251 if (first_line == 1):
1255 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
1256 out += "\n} %s;\n" % (self.eth_enum_nm(tname))
1259 #--- eth_bits ---------------------------------------------------------------
1260 def eth_bits(self, tname, bits):
1262 out += "static const "
1263 out += "asn_namedbit %(TABLE)s[] = {\n"
1264 for (val, id) in bits:
1265 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1266 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1269 #--- eth_type_fn_h ----------------------------------------------------------
1270 def eth_type_fn_h(self, tname):
1272 if (not self.eth_type[tname]['export'] & EF_TYPE):
1276 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname)
1278 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)
1282 #--- eth_fn_call ------------------------------------------------------------
1283 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1286 if (ret == 'return'):
1292 for i in range(len(par)):
1293 if (i>0): out += ind * ' '
1294 out += ', '.join(par[i])
1295 if (i<(len(par)-1)): out += ',\n'
1299 #--- eth_type_fn_hdr --------------------------------------------------------
1300 def eth_type_fn_hdr(self, tname):
1302 if (not self.eth_type[tname]['export'] & EF_TYPE):
1306 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname)
1308 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)
1309 if self.conform.get_fn_presence(tname):
1310 out += self.conform.get_fn_text(tname, 'FN_HDR')
1311 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1312 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1315 #--- eth_type_fn_ftr --------------------------------------------------------
1316 def eth_type_fn_ftr(self, tname):
1318 if self.conform.get_fn_presence(tname):
1319 out += self.conform.get_fn_text(tname, 'FN_FTR')
1320 elif self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1321 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1322 out += " return offset;\n"
1326 #--- eth_type_fn_body -------------------------------------------------------
1327 def eth_type_fn_body(self, tname, body, pars=None):
1329 if self.conform.get_fn_body_presence(tname):
1330 out = self.conform.get_fn_text(tname, 'FN_BODY')
1331 elif self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1332 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1340 #--- eth_output_hf ----------------------------------------------------------
1341 def eth_output_hf (self):
1342 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1343 fx = self.output.file_open('hf')
1344 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1345 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1346 if (self.named_bit):
1347 fx.write('/* named bits */\n')
1348 for nb in self.named_bit:
1349 fx.write("static int %s = -1;\n" % (nb['ethname']))
1350 self.output.file_close(fx)
1352 #--- eth_output_hf_arr ------------------------------------------------------
1353 def eth_output_hf_arr (self):
1354 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1355 fx = self.output.file_open('hfarr')
1356 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1357 t = self.eth_hf[f]['ethtype']
1358 blurb = '"%s.%s"' % (self.eth_type[t]['proto'], t)
1359 attr = self.eth_hf[f]['attr'].copy()
1360 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1361 if not attr.has_key('BLURB'):
1362 attr['BLURB'] = blurb
1363 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1364 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1365 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1366 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1367 for nb in self.named_bit:
1369 fx.write(' { &%s,\n' % (nb['ethname']))
1370 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1371 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1372 fx.write(' "%s", HFILL }},\n' % (blurb))
1373 self.output.file_close(fx)
1375 #--- eth_output_ett ---------------------------------------------------------
1376 def eth_output_ett (self):
1377 fx = self.output.file_open('ett')
1379 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1380 for t in self.eth_type_ord:
1381 if self.eth_type[t]['tree']:
1382 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1384 self.output.file_close(fx, discard=fempty)
1386 #--- eth_output_ett_arr -----------------------------------------------------
1387 def eth_output_ett_arr(self):
1388 fx = self.output.file_open('ettarr')
1390 #fx.write(" &ett_%s,\n" % (self.eproto))
1391 for t in self.eth_type_ord:
1392 if self.eth_type[t]['tree']:
1393 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1395 self.output.file_close(fx, discard=fempty)
1397 #--- eth_output_export ------------------------------------------------------
1398 def eth_output_export(self):
1399 if (not len(self.eth_export_ord)): return
1400 fx = self.output.file_open('exp', ext='h')
1401 for t in self.eth_export_ord: # vals
1402 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1403 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1404 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1405 if not self.eth_type[t]['export'] & EF_TABLE:
1406 if self.eth_type[t]['export'] & EF_WS_VAR:
1407 fx.write("WS_VAR_IMPORT ")
1410 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1412 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1413 for t in self.eth_export_ord: # functions
1414 if (self.eth_type[t]['export'] & EF_TYPE):
1415 if self.eth_type[t]['export'] & EF_EXTERN:
1417 fx.write(self.eth_type_fn_h(t))
1418 self.output.file_close(fx)
1420 #--- eth_output_expcnf ------------------------------------------------------
1421 def eth_output_expcnf(self):
1422 fx = self.output.file_open('exp', ext='cnf')
1423 fx.write('#.MODULE\n')
1425 for (m, p) in self.modules:
1426 if (len(m) > maxw): maxw = len(m)
1427 for (m, p) in self.modules:
1428 fx.write("%-*s %s\n" % (maxw, m, p))
1429 fx.write('#.END\n\n')
1431 fx.write('#.IMPORT_TAG\n')
1432 for t in self.eth_export_ord: # tags
1433 if (self.eth_type[t]['export'] & EF_TYPE):
1434 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1435 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1436 fx.write('#.END\n\n')
1437 fx.write('#.TYPE_ATTR\n')
1438 for t in self.eth_export_ord: # attributes
1439 if (self.eth_type[t]['export'] & EF_TYPE):
1440 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1441 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1442 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1443 fx.write('#.END\n\n')
1444 self.output.file_close(fx, keep_anyway=True)
1446 #--- eth_output_val ------------------------------------------------------
1447 def eth_output_val(self):
1448 if (not len(self.eth_value_ord1)): return
1449 fx = self.output.file_open('val', ext='h')
1450 for v in self.eth_value_ord1:
1451 vv = self.eth_value[v]['value']
1452 if isinstance (vv, Value):
1453 vv = vv.to_str(self)
1454 fx.write("#define %-30s %s\n" % (v, vv))
1455 for t in self.eth_type_ord1:
1456 if self.eth_type[t]['import']:
1458 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1459 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1460 self.output.file_close(fx)
1462 #--- eth_output_valexp ------------------------------------------------------
1463 def eth_output_valexp(self):
1464 if (not len(self.eth_vexport_ord)): return
1465 fx = self.output.file_open('valexp', ext='h')
1466 for v in self.eth_vexport_ord:
1467 vv = self.eth_value[v]['value']
1468 if isinstance (vv, Value):
1469 vv = vv.to_str(self)
1470 fx.write("#define %-30s %s\n" % (v, vv))
1471 self.output.file_close(fx)
1473 #--- eth_output_types -------------------------------------------------------
1474 def eth_output_types(self):
1476 t = self.eth_hf[f]['ethtype']
1479 for r in self.eth_hf[f]['ref']:
1480 x[self.field[r]['impl']] = self.field[r]['impl']
1494 if (i): postfix = '_impl'; impl = 'TRUE'
1495 else: postfix = ''; impl = 'FALSE'
1496 out += 'static int dissect_'+f+postfix+'(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_) {\n'
1497 par=((impl, 'tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
1499 out += 'static int dissect_'+f+'(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_) {\n'
1500 par=(('tvb', 'offset', 'actx', 'tree', self.eth_hf[f]['fullname']),)
1501 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret='return',
1506 def out_pdu_decl(f):
1507 t = self.eth_hf[f]['ethtype']
1508 is_new = self.eth_hf[f]['pdu']['new']
1514 out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
1518 t = self.eth_hf[f]['ethtype']
1519 is_new = self.eth_hf[f]['pdu']['new']
1526 out += ' dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1528 out += ' int offset = 0;\n'
1535 if (self.Aligned()):
1539 out += " asn1_ctx_t asn1_ctx;\n"
1540 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1542 out += " asn1_ctx_t asn1_ctx;\n"
1543 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1544 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1546 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1549 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1550 if (self.Per() and is_new):
1551 out += ' offset += 7; offset >>= 3;\n'
1553 out += ' return offset;\n'
1557 fx = self.output.file_open('fn')
1559 if (len(self.eth_hfpdu_ord)):
1561 for f in self.eth_hfpdu_ord:
1562 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1564 fx.write('/*--- PDUs declarations ---*/\n')
1566 fx.write(out_pdu_decl(f))
1569 if self.eth_dep_cycle:
1570 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1572 while i < len(self.eth_dep_cycle):
1573 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1574 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1575 fx.write(''.join(map(lambda i: '/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]), self.dep_cycle_eth_type[t])))
1576 fx.write(self.eth_type_fn_h(t))
1577 if (self.Fld() or self.eth_type[t]['create_field']):
1579 for f in self.eth_hf_ord:
1580 if ((self.eth_hf[f]['ethtype'] == t) and (self.Fld() or self.eth_hf[f]['create_field'])):
1581 fx.write(out_field(f))
1585 if (self.Fld()): # fields for imported types
1586 fx.write('/*--- Fields for imported types ---*/\n\n')
1587 for f in self.eth_hf_ord:
1588 if (self.eth_type[self.eth_hf[f]['ethtype']]['import']):
1589 fx.write(out_field(f))
1591 for t in self.eth_type_ord1:
1592 if self.eth_type[t]['import']:
1594 if self.eth_type[t]['val'].eth_has_vals():
1595 if self.eth_type[t]['no_emit'] & EF_VALS:
1597 elif self.eth_type[t]['user_def'] & EF_VALS:
1598 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1599 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1602 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1603 if self.eth_type[t]['no_emit'] & EF_TYPE:
1605 elif self.eth_type[t]['user_def'] & EF_TYPE:
1606 fx.write(self.eth_type_fn_h(t))
1608 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1609 if ((self.Fld() or self.eth_type[t]['create_field']) and not self.dep_cycle_eth_type.has_key(t)):
1610 for f in self.eth_hf_ord:
1611 if ((self.eth_hf[f]['ethtype'] == t) and (self.Fld() or self.eth_hf[f]['create_field'])):
1612 fx.write(out_field(f))
1614 if (len(self.eth_hfpdu_ord)):
1615 fx.write('/*--- PDUs ---*/\n\n')
1616 for f in self.eth_hfpdu_ord:
1617 if (self.eth_hf[f]['pdu']):
1618 fx.write(out_pdu(f))
1620 fempty = pos == fx.tell()
1621 self.output.file_close(fx, discard=fempty)
1623 #--- eth_output_dis_hnd -----------------------------------------------------
1624 def eth_output_dis_hnd(self):
1625 fx = self.output.file_open('dis-hnd')
1627 for f in self.eth_hfpdu_ord:
1628 pdu = self.eth_hf[f]['pdu']
1629 if (pdu and pdu['reg'] and not pdu['hidden']):
1631 if (pdu['reg'] != '.'):
1632 dis += '.' + pdu['reg']
1633 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1636 self.output.file_close(fx, discard=fempty)
1638 #--- eth_output_dis_reg -----------------------------------------------------
1639 def eth_output_dis_reg(self):
1640 fx = self.output.file_open('dis-reg')
1642 for f in self.eth_hfpdu_ord:
1643 pdu = self.eth_hf[f]['pdu']
1644 if (pdu and pdu['reg']):
1646 if (pdu['new']): new_prefix = 'new_'
1648 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1649 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1650 if (not pdu['hidden']):
1651 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1654 self.output.file_close(fx, discard=fempty)
1656 #--- eth_output_dis_tab -----------------------------------------------------
1657 def eth_output_dis_tab(self):
1658 fx = self.output.file_open('dis-tab')
1660 for k in self.conform.get_order('REGISTER'):
1661 reg = self.conform.use_item('REGISTER', k)
1662 if not self.field.has_key(reg['pdu']): continue
1663 f = self.field[reg['pdu']]['ethname']
1664 pdu = self.eth_hf[f]['pdu']
1666 if (pdu['new']): new_prefix = 'new_'
1667 if (reg['rtype'] in ('NUM', 'STR')):
1669 if (reg['rtype'] == 'STR'): rstr = '_string'
1672 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1673 if (not pdu['hidden']):
1674 hnd = '%s_handle' % (asn2c(dis))
1676 hnd = 'find_dissector("%s")' % (dis)
1678 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1679 rport = self.value_get_eth(reg['rport'])
1680 fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1681 elif (reg['rtype'] in ('BER', 'PER')):
1682 roid = self.value_get_eth(reg['roid'])
1683 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1686 self.output.file_close(fx, discard=fempty)
1688 #--- dupl_report -----------------------------------------------------
1689 def dupl_report(self):
1691 tmplist = self.eth_type_dupl.keys()
1694 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1696 for tt in self.eth_type_dupl[t]:
1697 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
1698 warnings.warn_explicit(msg, UserWarning, '', '')
1700 tmplist = self.eth_hf_dupl.keys()
1703 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
1705 for tt in self.eth_hf_dupl[f].keys():
1706 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
1707 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
1709 warnings.warn_explicit(msg, UserWarning, '', '')
1711 #--- eth_do_output ------------------------------------------------------------
1712 def eth_do_output(self):
1714 print "\n# Assignments"
1715 for a in self.assign_ord:
1717 if (self.assign[a]['virt']): v = '*'
1719 print "\n# Value assignments"
1720 for a in self.vassign_ord:
1723 print "\n# Imported Types"
1724 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1726 for t in self.type_imp:
1727 print "%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto'])
1728 print "\n# Imported Values"
1729 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1731 for t in self.value_imp:
1732 print "%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto'])
1733 print "\n# Imported Object Classes"
1734 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1736 for t in self.objectclass_imp:
1737 print "%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto'])
1738 print "\n# Exported Types"
1739 print "%-31s %s" % ("Wireshark type", "Export Flag")
1741 for t in self.eth_export_ord:
1742 print "%-31s 0x%02X" % (t, self.eth_type[t]['export'])
1743 print "\n# Exported Values"
1744 print "%-40s %s" % ("Wireshark name", "Value")
1746 for v in self.eth_vexport_ord:
1747 vv = self.eth_value[v]['value']
1748 if isinstance (vv, Value):
1749 vv = vv.to_str(self)
1750 print "%-40s %s" % (v, vv)
1751 print "\n# ASN.1 Object Classes"
1752 print "%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol")
1754 for t in self.objectclass_ord:
1755 print "%-40s " % (t)
1756 print "\n# ASN.1 Types"
1757 print "%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type")
1759 for t in self.type_ord:
1760 print "%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname'])
1761 print "\n# Wireshark Types"
1762 print "Wireshark type References (ASN.1 types)"
1764 for t in self.eth_type_ord:
1765 print "%-31s %d" % (t, len(self.eth_type[t]['ref'])),
1766 print ', '.join(self.eth_type[t]['ref'])
1767 print "\n# ASN.1 Values"
1768 print "%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value")
1770 for v in self.value_ord:
1771 vv = self.value[v]['value']
1772 if isinstance (vv, Value):
1773 vv = vv.to_str(self)
1774 print "%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname'])
1775 #print "\n# Wireshark Values"
1776 #print "%-40s %s" % ("Wireshark name", "Value")
1778 #for v in self.eth_value_ord:
1779 # vv = self.eth_value[v]['value']
1780 # if isinstance (vv, Value):
1781 # vv = vv.to_str(self)
1782 # print "%-40s %s" % (v, vv)
1783 print "\n# ASN.1 Fields"
1784 print "ASN.1 unique name Wireshark name ASN.1 type"
1786 for f in (self.pdu_ord + self.field_ord):
1787 print "%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type'])
1788 print "\n# Wireshark Fields"
1789 print "Wireshark name Wireshark type References (ASN.1 fields)"
1791 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1792 print "%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])),
1793 print ', '.join(self.eth_hf[f]['ref'])
1794 #print "\n# Order after dependencies"
1795 #print '\n'.join(self.eth_type_ord1)
1796 print "\n# Cyclic dependencies"
1797 for c in self.eth_dep_cycle:
1798 print ' -> '.join(c)
1800 self.output.outnm = self.outnm_opt
1801 if (not self.output.outnm):
1802 self.output.outnm = self.proto
1803 self.output.outnm = self.output.outnm.replace('.', '-')
1804 self.eth_output_hf()
1805 self.eth_output_ett()
1806 self.eth_output_types()
1807 self.eth_output_hf_arr()
1808 self.eth_output_ett_arr()
1809 self.eth_output_export()
1811 self.eth_output_expcnf()
1812 self.eth_output_val()
1813 self.eth_output_valexp()
1814 self.eth_output_dis_hnd()
1815 self.eth_output_dis_reg()
1816 self.eth_output_dis_tab()
1818 def dbg_modules(self):
1820 print "%-30s " % (m),
1821 dep = self.module[m][:]
1822 for i in range(len(dep)):
1823 if not self.module.has_key(dep[i]):
1824 dep[i] = '*' + dep[i]
1825 print ', '.join(dep)
1826 # end of print_mod()
1827 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: not self.module.has_key(t))
1828 print "\n# ASN.1 Moudules"
1829 print "Module name Dependency"
1832 for m in (self.module_ord):
1834 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
1836 print "\n# ASN.1 Moudules - in dependency order"
1837 print "Module name Dependency"
1842 print "\nCyclic dependencies:"
1843 print "mod_cyc = ", mod_cyc
1846 #--- EthCnf -------------------------------------------------------------------
1854 self.suppress_line = False
1855 self.include_path = []
1856 # Value name Default value Duplicity check Usage check
1857 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1858 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1859 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1860 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1861 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1862 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
1863 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
1864 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
1865 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
1866 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1867 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1868 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1869 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
1870 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
1871 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1872 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1873 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
1874 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1875 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
1878 for k in self.tblcfg.keys() :
1882 def add_item(self, table, key, fn, lineno, **kw):
1883 if self.tblcfg[table]['chk_dup'] and self.table[table].has_key(key):
1884 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
1885 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
1886 UserWarning, fn, lineno)
1888 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
1889 self.table[table][key].update(kw)
1890 self.order[table].append(key)
1892 def update_item(self, table, key, fn, lineno, **kw):
1893 if not self.table[table].has_key(key):
1894 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
1895 self.order[table].append(key)
1896 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
1898 def get_order(self, table):
1899 return self.order[table]
1901 def check_item(self, table, key):
1902 return self.table[table].has_key(key)
1904 def check_item_value(self, table, key, **kw):
1905 return self.table[table].has_key(key) and self.table[table][key].has_key(kw.get('val_nm', self.tblcfg[table]['val_nm']))
1907 def use_item(self, table, key, **kw):
1908 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
1909 if not self.table[table].has_key(key): return vdflt
1910 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
1911 #print "use_item() - set used for %s %s" % (table, key)
1912 self.table[table][key]['used'] = True
1913 return self.table[table][key].get(vname, vdflt)
1915 def omit_assignment(self, type, ident, module):
1916 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
1918 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
1919 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
1920 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
1921 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
1922 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
1925 def add_fn_line(self, name, ctx, line, fn, lineno):
1926 if not self.fn.has_key(name):
1927 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
1928 if (self.fn[name][ctx]):
1929 self.fn[name][ctx]['text'] += line
1931 self.fn[name][ctx] = {'text' : line, 'used' : False,
1932 'fn' : fn, 'lineno' : lineno}
1933 def get_fn_presence(self, name):
1934 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
1935 #if self.fn.has_key(name): print self.fn[name]
1936 return self.fn.has_key(name)
1937 def get_fn_body_presence(self, name):
1938 return self.fn.has_key(name) and self.fn[name]['FN_BODY']
1939 def get_fn_text(self, name, ctx):
1940 if (not self.fn.has_key(name)):
1942 if (not self.fn[name][ctx]):
1944 self.fn[name][ctx]['used'] = True
1945 out = self.fn[name][ctx]['text']
1946 if (not self.suppress_line):
1947 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], self.fn[name][ctx]['fn'], out);
1950 def add_pdu(self, par, is_new, fn, lineno):
1951 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
1952 (reg, hidden) = (None, False)
1953 if (len(par) > 1): reg = par[1]
1954 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
1955 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False}
1956 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
1959 def add_register(self, pdu, par, fn, lineno):
1960 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
1961 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
1962 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
1963 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
1964 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
1965 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
1966 if ((len(par)-1) < pmin):
1967 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
1969 if ((len(par)-1) > pmax):
1970 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
1971 attr = {'pdu' : pdu, 'rtype' : rtype}
1972 if (rtype in ('NUM', 'STR')):
1973 attr['rtable'] = par[1]
1974 attr['rport'] = par[2]
1975 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
1976 elif (rtype in ('BER', 'PER')):
1977 attr['roid'] = par[1]
1978 attr['roidname'] = '""'
1980 attr['roidname'] = par[2]
1981 elif attr['roid'][0] != '"':
1982 attr['roidname'] = '"' + attr['roid'] + '"'
1983 rkey = '/'.join([rtype, attr['roid']])
1984 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
1986 def check_par(self, par, pmin, pmax, fn, lineno):
1987 for i in range(len(par)):
1991 if par[i][0] == '#':
1995 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
1997 if (pmax >= 0) and (len(par) > pmax):
1998 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2003 def get_par(line, pmin, pmax, fn, lineno):
2004 par = line.split(None, pmax)
2005 par = self.check_par(par, pmin, pmax, fn, lineno)
2008 def get_par_nm(line, pmin, pmax, fn, lineno):
2010 par = line.split(None, pmax)
2013 for i in range(len(par)):
2014 if par[i][0] == '#':
2018 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2025 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2026 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2027 nmpar_end = re.compile(r'\s*$')
2028 result = nmpar_first.search(nmpar)
2031 k = result.group('attr')
2033 result = nmpar_next.search(nmpar, pos)
2038 p2 = nmpar_end.search(nmpar, pos).start()
2046 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_]+)\s+')
2047 comment = re.compile(r'^\s*#[^.]')
2048 empty = re.compile(r'^\s*$')
2052 default_flags = 0x00
2065 fn, f, lineno = frec['fn'], frec['f'], frec['lineno']
2069 if comment.search(line): continue
2070 result = directive.search(line)
2071 if result: # directive
2072 if result.group('name') == 'END_OF_CNF':
2074 elif result.group('name') == 'OPT':
2075 ctx = result.group('name')
2076 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2077 if not par: continue
2078 self.set_opt(par[0], par[1:], fn, lineno)
2080 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
2081 'MODULE', 'MODULE_IMPORT',
2082 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2083 'VIRTUAL_ASSGN', 'SET_TYPE',
2084 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2085 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2086 ctx = result.group('name')
2087 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2088 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2089 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2090 ctx = result.group('name')
2092 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2094 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2096 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2099 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2100 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2101 ctx = 'NO_OMIT_ASSGN'
2104 elif result.group('name') in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2105 ctx = result.group('name')
2106 default_flags = EF_TYPE|EF_VALS
2107 if ctx == 'EXPORTS':
2108 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2110 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2111 if not par: continue
2113 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2114 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2115 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2116 elif (ctx == 'EXPORTS'): p = 0
2117 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2118 for i in range(p, len(par)):
2119 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2120 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2121 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2122 elif (par[i] == 'WS_VAR'): default_flags |= EF_WS_VAR
2123 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2124 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2125 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2126 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2127 ctx = result.group('name')
2128 default_flags = EF_ENUM
2129 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2130 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2131 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2132 for i in range(0, len(par)):
2133 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2134 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2135 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2136 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2137 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2138 elif result.group('name') in ('FN_HDR', 'FN_FTR'):
2139 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2140 if not par: continue
2141 ctx = result.group('name')
2143 elif result.group('name') == 'FN_BODY':
2144 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2145 if not par: continue
2146 ctx = result.group('name')
2149 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2150 elif result.group('name') == 'FN_PARS':
2151 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2152 ctx = result.group('name')
2157 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2159 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2161 elif result.group('name') == 'CLASS':
2162 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2163 if not par: continue
2164 ctx = result.group('name')
2166 add_class_ident(name)
2167 if not name.isupper():
2168 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2169 UserWarning, fn, lineno)
2170 elif result.group('name') == 'INCLUDE':
2171 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2173 warnings.warn_explicit("INCLUDE requires parameter", UserWarning, fn, lineno)
2176 #print "Try include: %s" % (fname)
2177 if (not os.path.exists(fname)):
2178 fname = os.path.join(os.path.split(fn)[0], par[0])
2179 #print "Try include: %s" % (fname)
2181 while not os.path.exists(fname) and (i < len(self.include_path)):
2182 fname = os.path.join(self.include_path[i], par[0])
2183 #print "Try include: %s" % (fname)
2185 if (not os.path.exists(fname)):
2187 fnew = open(fname, "r")
2188 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno})
2189 fn, f, lineno = par[0], fnew, 0
2190 elif result.group('name') == 'END':
2193 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2196 if not empty.match(line):
2197 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2199 if empty.match(line): continue
2200 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2201 if not par: continue
2202 self.set_opt(par[0], par[1:], fn, lineno)
2203 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2204 if empty.match(line): continue
2205 if ctx == 'EXPORTS':
2206 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2208 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2209 if not par: continue
2210 flags = default_flags
2213 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2214 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2215 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2216 elif (ctx == 'EXPORTS'): p = 1
2217 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2218 for i in range(p, len(par)):
2219 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2220 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2221 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2222 elif (par[i] == 'WS_VAR'): flags |= EF_WS_VAR
2223 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2224 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2225 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2226 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2227 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2228 if empty.match(line): continue
2229 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2230 if not par: continue
2231 flags = default_flags
2232 for i in range(1, len(par)):
2233 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2234 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2235 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2236 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2237 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2238 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2239 elif ctx in ('PDU', 'PDU_NEW'):
2240 if empty.match(line): continue
2241 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2242 if not par: continue
2244 if (ctx == 'PDU_NEW'): is_new = True
2245 self.add_pdu(par[0:2], is_new, fn, lineno)
2247 self.add_register(par[0], par[2:5], fn, lineno)
2248 elif ctx in ('REGISTER', 'REGISTER_NEW'):
2249 if empty.match(line): continue
2250 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2251 if not par: continue
2252 if not self.check_item('PDU', par[0]):
2254 if (ctx == 'REGISTER_NEW'): is_new = True
2255 self.add_pdu(par[0:1], is_new, fn, lineno)
2256 self.add_register(par[0], par[1:4], fn, lineno)
2257 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2258 if empty.match(line): continue
2259 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2260 if not par: continue
2261 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2262 elif ctx == 'IMPORT_TAG':
2263 if empty.match(line): continue
2264 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2265 if not par: continue
2266 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2267 elif ctx == 'OMIT_ASSIGNMENT':
2268 if empty.match(line): continue
2269 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2270 if not par: continue
2271 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2272 elif ctx == 'NO_OMIT_ASSGN':
2273 if empty.match(line): continue
2274 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2275 if not par: continue
2276 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2277 elif ctx == 'VIRTUAL_ASSGN':
2278 if empty.match(line): continue
2279 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2280 if not par: continue
2281 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2282 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2283 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2285 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2286 if not par[0][0].isupper():
2287 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2288 UserWarning, fn, lineno)
2289 elif ctx == 'SET_TYPE':
2290 if empty.match(line): continue
2291 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2292 if not par: continue
2293 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2294 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2295 if not par[1][0].isupper():
2296 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2297 UserWarning, fn, lineno)
2298 elif ctx == 'TYPE_RENAME':
2299 if empty.match(line): continue
2300 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2301 if not par: continue
2302 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2303 if not par[1][0].isupper():
2304 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2305 UserWarning, fn, lineno)
2306 elif ctx == 'FIELD_RENAME':
2307 if empty.match(line): continue
2308 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2309 if not par: continue
2310 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2311 if not par[1][0].islower():
2312 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2313 UserWarning, fn, lineno)
2314 elif ctx == 'TF_RENAME':
2315 if empty.match(line): continue
2316 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2317 if not par: continue
2318 tmpu = par[1][0].upper() + par[1][1:]
2319 tmpl = par[1][0].lower() + par[1][1:]
2320 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2321 if not tmpu[0].isupper():
2322 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2323 UserWarning, fn, lineno)
2324 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2325 if not tmpl[0].islower():
2326 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2327 UserWarning, fn, lineno)
2328 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2329 if empty.match(line): continue
2330 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2331 if not par: continue
2332 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2333 elif ctx == 'FN_PARS':
2334 if empty.match(line): continue
2336 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2338 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2339 if not par: continue
2341 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2343 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2344 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2345 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2346 elif ctx == 'CLASS':
2347 if empty.match(line): continue
2348 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2349 if not par: continue
2350 if (len(par) < 2): par.append('OpenType')
2351 if (len(par) < 3): par.append(None)
2352 if not set_type_to_class(name, par[0], par[1], par[2]):
2353 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2354 UserWarning, fn, lineno)
2356 def set_opt(self, opt, par, fn, lineno):
2357 #print "set_opt: %s, %s" % (opt, par)
2359 par = self.check_par(par, 1, 1, fn, lineno)
2361 self.include_path.append(par[0])
2362 elif opt in ("-b", "BER", "CER", "DER"):
2363 par = self.check_par(par, 0, 0, fn, lineno)
2364 self.ectx.encoding = 'ber'
2365 elif opt in ("-X", "NEW_BER"):
2366 par = self.check_par(par, 0, 0, fn, lineno)
2367 self.ectx.new_ber = True
2368 elif opt in ("PER",):
2369 par = self.check_par(par, 0, 0, fn, lineno)
2370 self.ectx.encoding = 'per'
2371 elif opt in ("-p", "PROTO"):
2372 par = self.check_par(par, 1, 1, fn, lineno)
2374 self.ectx.proto_opt = par[0]
2375 self.ectx.merge_modules = True
2376 elif opt in ("-F", "CREATE_FIELDS"):
2377 par = self.check_par(par, 0, 1, fn, lineno)
2379 if (len(par) > 0): tnm = par[0]
2380 self.ectx.fld_opt[tnm] = True
2381 elif opt in ("-T",):
2382 par = self.check_par(par, 0, 0, fn, lineno)
2383 self.ectx.tag_opt = True
2384 elif opt in ("ALIGNED",):
2385 par = self.check_par(par, 0, 0, fn, lineno)
2386 self.ectx.aligned = True
2387 elif opt in ("-u", "UNALIGNED"):
2388 par = self.check_par(par, 0, 0, fn, lineno)
2389 self.ectx.aligned = False
2390 elif opt in ("-d",):
2391 par = self.check_par(par, 1, 1, fn, lineno)
2393 self.ectx.dbgopt = par[0]
2394 elif opt in ("-e",):
2395 par = self.check_par(par, 0, 0, fn, lineno)
2396 self.ectx.expcnf = True
2397 elif opt in ("-S",):
2398 par = self.check_par(par, 0, 0, fn, lineno)
2399 self.ectx.merge_modules = True
2400 elif opt in ("-o",):
2401 par = self.check_par(par, 1, 1, fn, lineno)
2403 self.ectx.outnm_opt = par[0]
2404 elif opt in ("-O",):
2405 par = self.check_par(par, 1, 1, fn, lineno)
2407 self.ectx.output.outdir = par[0]
2408 elif opt in ("-s",):
2409 par = self.check_par(par, 1, 1, fn, lineno)
2411 self.ectx.output.single_file = par[0]
2412 elif opt in ("-k",):
2413 par = self.check_par(par, 0, 0, fn, lineno)
2414 self.ectx.output.keep = True
2415 elif opt in ("-L",):
2416 par = self.check_par(par, 0, 0, fn, lineno)
2417 self.suppress_line = True
2418 elif opt in ("EXTERNAL_TYPE_CB",):
2419 par = self.check_par(par, 1, 1, fn, lineno)
2421 self.ectx.default_external_type_cb = par[0]
2423 warnings.warn_explicit("Unknown option %s" % (opt),
2424 UserWarning, fn, lineno)
2426 def dbg_print(self):
2427 print "\n# Conformance values"
2428 print "%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value")
2430 tbls = self.table.keys()
2433 keys = self.table[t].keys()
2436 print "%-15s %4s %-15s %-20s %s" % (
2437 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']]))
2439 def unused_report(self):
2440 tbls = self.table.keys()
2443 if not self.tblcfg[t]['chk_use']: continue
2444 keys = self.table[t].keys()
2447 if not self.table[t][k]['used']:
2448 warnings.warn_explicit("Unused %s for %s" % (t, k),
2449 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2450 fnms = self.fn.keys()
2453 keys = self.fn[f].keys()
2456 if not self.fn[f][k]: continue
2457 if not self.fn[f][k]['used']:
2458 warnings.warn_explicit("Unused %s for %s" % (k, f),
2459 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2461 #--- EthOut -------------------------------------------------------------------
2467 self.single_file = None
2468 self.created_files = {}
2469 self.created_files_ord = []
2472 def outcomment(self, ln, comment=None):
2474 return '%s %s\n' % (comment, ln)
2476 return '/* %-74s */\n' % (ln)
2478 def created_file_add(self, name, keep_anyway):
2479 name = os.path.normcase(os.path.abspath(name))
2480 if not self.created_files.has_key(name):
2481 self.created_files_ord.append(name)
2482 self.created_files[name] = keep_anyway
2484 self.created_files[name] = self.created_files[name] or keep_anyway
2486 def created_file_exists(self, name):
2487 name = os.path.normcase(os.path.abspath(name))
2488 return self.created_files.has_key(name)
2490 #--- output_fname -------------------------------------------------------
2491 def output_fname(self, ftype, ext='c'):
2493 if not ext in ('cnf',):
2500 #--- output_fullname -------------------------------------------------------
2501 def output_fullname(self, ftype, ext='c'):
2502 return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
2503 #--- file_open -------------------------------------------------------
2504 def file_open(self, ftype, ext='c'):
2505 fn = self.output_fullname(ftype, ext=ext)
2506 if self.created_file_exists(fn):
2513 fx.write(self.fhdr(fn, comment = comment))
2515 if (not self.single_file and not self.created_file_exists(fn)):
2516 fx.write(self.fhdr(fn))
2517 if not self.ectx.merge_modules:
2519 fx.write(self.outcomment("--- Module %s --- --- ---" % (self.ectx.Module()), comment))
2522 #--- file_close -------------------------------------------------------
2523 def file_close(self, fx, discard=False, keep_anyway=False):
2525 if discard and not self.created_file_exists(fx.name):
2528 self.created_file_add(fx.name, keep_anyway)
2529 #--- fhdr -------------------------------------------------------
2530 def fhdr(self, fn, comment=None):
2532 out += self.outcomment('Do not modify this file.', comment)
2533 out += self.outcomment('It is created automatically by the ASN.1 to Wireshark dissector compiler', comment)
2534 out += self.outcomment(fn, comment)
2535 out += self.outcomment(' '.join(sys.argv), comment)
2539 #--- dbg_print -------------------------------------------------------
2540 def dbg_print(self):
2541 print "\n# Output files"
2542 print "\n".join(self.created_files_ord)
2545 #--- make_single_file -------------------------------------------------------
2546 def make_single_file(self):
2547 if (not self.single_file): return
2548 in_nm = self.single_file + '.c'
2549 out_nm = self.output_fullname('')
2550 self.do_include(out_nm, in_nm)
2551 in_nm = self.single_file + '.h'
2552 if (os.path.exists(in_nm)):
2553 out_nm = self.output_fullname('', ext='h')
2554 self.do_include(out_nm, in_nm)
2556 for fn in self.created_files_ord:
2557 if not self.created_files[fn]:
2560 #--- do_include -------------------------------------------------------
2561 def do_include(self, out_nm, in_nm):
2562 def check_file(fn, fnlist):
2563 fnfull = os.path.normcase(os.path.abspath(fn))
2564 if (fnlist.has_key(fnfull) and os.path.exists(fnfull)):
2565 return os.path.normpath(fn)
2567 fin = file(in_nm, "r")
2568 fout = file(out_nm, "w")
2569 fout.write(self.fhdr(out_nm))
2570 fout.write('/* Input file: ' + in_nm +' */\n')
2572 fout.write('#line 1 "%s"\n' % (in_nm))
2574 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2579 cont_linenum = cont_linenum + 1;
2580 line = fin.readline()
2581 if (line == ''): break
2583 result = include.search(line)
2584 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2586 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2588 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2590 ifile = check_file(result.group('fname'), self.created_files)
2593 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
2594 fout.write('#line 1 "' + ifile + '"\n')
2595 finc = file(ifile, "r")
2596 fout.write(finc.read())
2598 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
2599 fout.write('#line %i "%s"\n' % (cont_linenum+1,in_nm) )
2608 #--- Node ---------------------------------------------------------------------
2610 def __init__(self,*args, **kw):
2612 self.type = self.__class__.__name__
2614 assert (len(args) == 1)
2616 self.__dict__.update (kw)
2617 def str_child (self, key, child, depth):
2618 indent = " " * (2 * depth)
2619 keystr = indent + key + ": "
2620 if key == 'type': # already processed in str_depth
2622 if isinstance (child, Node): # ugh
2623 return keystr + "\n" + child.str_depth (depth+1)
2624 if type (child) == type ([]):
2627 if isinstance (x, Node):
2628 l.append (x.str_depth (depth+1))
2630 l.append (indent + " " + str(x) + "\n")
2631 return keystr + "[\n" + ''.join(l) + indent + "]\n"
2633 return keystr + str (child) + "\n"
2634 def str_depth (self, depth): # ugh
2635 indent = " " * (2 * depth)
2636 l = ["%s%s" % (indent, self.type)]
2637 l.append ("".join (map (lambda (k,v): self.str_child (k, v, depth + 1),
2638 self.__dict__.items ())))
2639 return "\n".join (l)
2641 return "\n" + self.str_depth (0)
2642 def to_python (self, ctx):
2643 return self.str_depth (ctx.indent_lev)
2645 def eth_reg(self, ident, ectx):
2648 #--- value_assign -------------------------------------------------------------
2649 class value_assign (Node):
2650 def __init__(self,*args, **kw) :
2651 Node.__init__ (self,*args, **kw)
2653 def eth_reg(self, ident, ectx):
2654 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
2655 ectx.eth_reg_vassign(self)
2656 ectx.eth_reg_value(self.ident, self.typ, self.val)
2659 #--- Type ---------------------------------------------------------------------
2661 def __init__(self,*args, **kw) :
2665 Node.__init__ (self,*args, **kw)
2668 if self.name is None :
2673 def HasConstraint(self):
2674 if self.constr is None :
2679 def HasSizeConstraint(self):
2680 return self.HasConstraint() and self.constr.IsSize()
2682 def HasValueConstraint(self):
2683 return self.HasConstraint() and self.constr.IsValue()
2685 def HasPermAlph(self):
2686 return self.HasConstraint() and self.constr.IsPermAlph()
2688 def HasContentsConstraint(self):
2689 return self.HasConstraint() and self.constr.IsContents()
2691 def HasOwnTag(self):
2692 return len(self.tags) > 0
2694 def HasImplicitTag(self, ectx):
2695 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
2697 def IndetermTag(self, ectx):
2700 def AddTag(self, tag):
2701 self.tags[0:0] = [tag]
2703 def GetTag(self, ectx):
2704 #print "GetTag(%s)\n" % self.name;
2705 if (self.HasOwnTag()):
2706 return self.tags[0].GetTag(ectx)
2708 return self.GetTTag(ectx)
2710 def GetTTag(self, ectx):
2711 print "#Unhandled GetTTag() in %s" % (self.type)
2712 print self.str_depth(1)
2713 return ('BER_CLASS_unknown', 'TAG_unknown')
2715 def SetName(self, name):
2718 def AddConstraint(self, constr):
2719 if not self.HasConstraint():
2720 self.constr = constr
2722 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
2724 def eth_tname(self):
2725 return '#' + self.type + '_' + str(id(self))
2727 def eth_ftype(self, ectx):
2728 return ('FT_NONE', 'BASE_NONE')
2730 def eth_strings(self):
2733 def eth_need_tree(self):
2736 def eth_has_vals(self):
2739 def eth_has_enum(self, tname, ectx):
2740 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
2742 def eth_need_pdu(self, ectx):
2745 def eth_named_bits(self):
2748 def eth_reg_sub(self, ident, ectx):
2751 def get_components(self, ectx):
2752 print "#Unhandled get_components() in %s" % (self.type)
2753 print self.str_depth(1)
2756 def sel_req(self, sel, ectx):
2757 print "#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)
2758 print self.str_depth(1)
2760 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
2761 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
2762 if (ectx.Tag() and (len(self.tags) > tstrip)):
2763 tagged_type = TaggedType(val=self, tstrip=tstrip)
2764 tagged_type.AddTag(self.tags[tstrip])
2765 if not tagflag: # 1st tagged level
2766 if self.IsNamed() and not selflag:
2767 tagged_type.SetName(self.name)
2768 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
2771 if ident and self.IsNamed() and not tagflag and not selflag:
2772 nm = ident + '/' + self.name
2775 elif self.IsNamed():
2777 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
2778 if not ident: # Assignment
2779 ectx.eth_reg_assign(nm, self)
2780 if self.type == 'Type_Ref':
2781 ectx.eth_reg_type(nm, self)
2782 if (ectx.conform.check_item('PDU', nm)):
2783 ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
2784 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
2785 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
2786 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm)):
2787 if ectx.conform.check_item('SET_TYPE', nm):
2788 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
2790 ectx.eth_reg_type(nm, self) # new type
2792 elif ectx.conform.check_item('SET_TYPE', nm):
2793 trnm = ectx.conform.use_item('SET_TYPE', nm)
2797 ectx.eth_reg_type(nm, self)
2799 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
2800 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
2801 ectx.eth_reg_assign(vnm, self, virt=True)
2802 ectx.eth_reg_type(vnm, self)
2803 self.eth_reg_sub(vnm, ectx)
2804 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
2805 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
2806 if ident and not tagflag:
2807 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
2808 if ectx.conform.check_item('SET_TYPE', nm):
2809 virtual_tr.eth_reg_sub(nm, ectx)
2811 self.eth_reg_sub(nm, ectx)
2813 def eth_get_size_constr(self, ectx):
2814 (minv, maxv, ext) = ('MIN', 'MAX', False)
2815 if self.HasSizeConstraint():
2816 if self.constr.IsSize():
2817 (minv, maxv, ext) = self.constr.GetSize(ectx)
2818 if (self.constr.type == 'Intersection'):
2819 if self.constr.subtype[0].IsSize():
2820 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
2821 elif self.constr.subtype[1].IsSize():
2822 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
2823 if minv == 'MIN': minv = 'NO_BOUND'
2824 if maxv == 'MAX': maxv = 'NO_BOUND'
2825 if (ext): ext = 'TRUE'
2827 return (minv, maxv, ext)
2829 def eth_get_value_constr(self, ectx):
2830 (minv, maxv, ext) = ('MIN', 'MAX', False)
2831 if self.HasValueConstraint():
2832 (minv, maxv, ext) = self.constr.GetValue(ectx)
2833 if minv == 'MIN': minv = 'NO_BOUND'
2834 if maxv == 'MAX': maxv = 'NO_BOUND'
2835 if str(minv).isdigit(): minv += 'U'
2836 if str(maxv).isdigit(): maxv += 'U'
2837 if (ext): ext = 'TRUE'
2839 return (minv, maxv, ext)
2841 def eth_get_alphabet_constr(self, ectx):
2842 (alph, alphlen) = ('NULL', '0')
2843 if self.HasPermAlph():
2844 alph = self.constr.GetPermAlph(ectx)
2847 if (alph != 'NULL'):
2848 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
2849 alphlen = str(len(alph) - 2)
2851 alphlen = 'strlen(%s)' % (alph)
2852 return (alph, alphlen)
2854 def eth_type_vals(self, tname, ectx):
2855 if self.eth_has_vals():
2856 print "#Unhandled eth_type_vals('%s') in %s" % (tname, self.type)
2857 print self.str_depth(1)
2860 def eth_type_enum(self, tname, ectx):
2861 if self.eth_has_enum(tname, ectx):
2862 print "#Unhandled eth_type_enum('%s') in %s" % (tname, self.type)
2863 print self.str_depth(1)
2866 def eth_type_default_table(self, ectx, tname):
2869 def eth_type_default_body(self, ectx):
2870 print "#Unhandled eth_type_default_body() in %s" % (self.type)
2871 print self.str_depth(1)
2874 def eth_type_default_pars(self, ectx, tname):
2881 'OFFSET' : 'offset',
2883 'HF_INDEX' : 'hf_index',
2885 'IMPLICIT_TAG' : 'implicit_tag',
2887 if (ectx.eth_type[tname]['tree']):
2888 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
2889 if (not ectx.Per()):
2890 pars['PINFO'] = 'pinfo'
2893 def eth_type_fn(self, proto, tname, ectx):
2894 body = self.eth_type_default_body(ectx, tname)
2895 pars = self.eth_type_default_pars(ectx, tname)
2896 if ectx.conform.check_item('FN_PARS', tname):
2897 pars.update(ectx.conform.use_item('FN_PARS', tname))
2898 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
2899 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
2900 pars['DEFAULT_BODY'] = body
2902 for k in pars.keys(): pars[k] = pars[k] % pars
2904 out += self.eth_type_default_table(ectx, tname) % pars
2905 out += ectx.eth_type_fn_hdr(tname)
2906 out += ectx.eth_type_fn_body(tname, body, pars=pars)
2907 out += ectx.eth_type_fn_ftr(tname)
2910 #--- Value --------------------------------------------------------------------
2912 def __init__(self,*args, **kw) :
2914 Node.__init__ (self,*args, **kw)
2916 def SetName(self, name) :
2919 def to_str(self, ectx):
2925 #--- ObjectClass ---------------------------------------------------------------------
2926 class ObjectClass (Node):
2927 def __init__(self,*args, **kw) :
2929 Node.__init__ (self,*args, **kw)
2931 def SetName(self, name):
2933 add_class_ident(self.name)
2935 def eth_reg(self, ident, ectx):
2936 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
2937 ectx.eth_reg_objectclass(self.name)
2939 #--- Tag ---------------------------------------------------------------
2941 def to_python (self, ctx):
2942 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
2945 self.typ.to_python (ctx))
2946 def IsImplicit(self, ectx):
2947 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
2949 def GetTag(self, ectx):
2951 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
2952 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
2953 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
2954 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
2955 return (tc, self.num)
2957 def eth_tname(self):
2959 if (self.cls == 'UNIVERSAL'): n = 'U'
2960 elif (self.cls == 'APPLICATION'): n = 'A'
2961 elif (self.cls == 'CONTEXT'): n = 'C'
2962 elif (self.cls == 'PRIVATE'): n = 'P'
2963 return n + str(self.num)
2965 #--- Constraint ---------------------------------------------------------------
2966 class Constraint (Node):
2967 def to_python (self, ctx):
2968 print "Ignoring constraint:", self.type
2969 return self.subtype.typ.to_python (ctx)
2971 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
2974 return (self.type == 'Size' and self.subtype.IsValue()) \
2975 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
2977 def GetSize(self, ectx):
2978 (minv, maxv, ext) = ('MIN', 'MAX', False)
2980 if self.type == 'Size':
2981 (minv, maxv, ext) = self.subtype.GetValue(ectx)
2982 elif self.type == 'Intersection':
2983 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
2984 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
2985 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
2986 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
2987 return (minv, maxv, ext)
2990 return self.type == 'SingleValue' \
2991 or self.type == 'ValueRange' \
2992 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
2993 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
2995 def GetValue(self, ectx):
2996 (minv, maxv, ext) = ('MIN', 'MAX', False)
2998 if self.type == 'SingleValue':
2999 minv = ectx.value_get_eth(self.subtype)
3000 maxv = ectx.value_get_eth(self.subtype)
3001 ext = hasattr(self, 'ext') and self.ext
3002 elif self.type == 'ValueRange':
3003 minv = ectx.value_get_eth(self.subtype[0])
3004 maxv = ectx.value_get_eth(self.subtype[1])
3005 ext = hasattr(self, 'ext') and self.ext
3006 elif self.type == 'Intersection':
3007 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3008 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3009 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3010 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3011 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3012 v0 = self.subtype[0].GetValue(ectx)
3013 v1 = self.subtype[1].GetValue(ectx)
3014 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3015 elif self.type == 'Union':
3016 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3017 v0 = self.subtype[0].GetValue(ectx)
3018 v1 = self.subtype[1].GetValue(ectx)
3019 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3020 return (minv, maxv, ext)
3022 def IsAlphabet(self):
3023 return self.type == 'SingleValue' \
3024 or self.type == 'ValueRange' \
3025 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3026 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3028 def GetAlphabet(self, ectx):
3030 if self.IsAlphabet():
3031 if self.type == 'SingleValue':
3032 alph = ectx.value_get_eth(self.subtype)
3033 elif self.type == 'ValueRange':
3034 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3035 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3037 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3040 elif self.type == 'Union':
3041 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3042 a0 = self.subtype[0].GetAlphabet(ectx)
3043 a1 = self.subtype[1].GetAlphabet(ectx)
3044 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3045 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3046 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3048 alph = a0 + ' ' + a1
3051 def IsPermAlph(self):
3052 return self.type == 'From' and self.subtype.IsAlphabet() \
3053 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3055 def GetPermAlph(self, ectx):
3057 if self.IsPermAlph():
3058 if self.type == 'From':
3059 alph = self.subtype.GetAlphabet(ectx)
3060 elif self.type == 'Intersection':
3061 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3062 alph = self.subtype[0].GetPermAlph(ectx)
3063 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3064 alph = self.subtype[1].GetPermAlph(ectx)
3067 def IsContents(self):
3068 return self.type == 'Contents' \
3069 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3071 def GetContents(self, ectx):
3073 if self.IsContents():
3074 if self.type == 'Contents':
3075 if self.subtype.type == 'Type_Ref':
3076 contents = self.subtype.val
3077 elif self.type == 'Intersection':
3078 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3079 contents = self.subtype[0].GetContents(ectx)
3080 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3081 contents = self.subtype[1].GetContents(ectx)
3084 def IsNegativ(self):
3086 return sval[0] == '-'
3087 if self.type == 'SingleValue':
3088 return is_neg(self.subtype)
3089 elif self.type == 'ValueRange':
3090 if self.subtype[0] == 'MIN': return True
3091 return is_neg(self.subtype[0])
3094 def eth_constrname(self):
3098 return 'M' + str(-int(val))
3101 except (ValueError, TypeError):
3102 return asn2c(str(val))
3105 if hasattr(self, 'ext') and self.ext:
3107 if self.type == 'SingleValue':
3108 return int2str(self.subtype) + ext
3109 elif self.type == 'ValueRange':
3110 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3111 elif self.type == 'Size':
3112 return 'SIZE_' + self.subtype.eth_constrname() + ext
3114 return 'CONSTR' + str(id(self)) + ext
3117 class Module (Node):
3118 def to_python (self, ctx):
3119 ctx.tag_def = self.tag_def.dfl_tag
3121 %s""" % (self.ident, self.body.to_python (ctx))
3123 def to_eth (self, ectx):
3124 ectx.tags_def = 'EXPLICIT' # default = explicit
3125 if (not ectx.proto):
3126 ectx.proto = ectx.conform.use_item('MODULE', self.ident.val, val_dflt=self.ident.val)
3127 ectx.tag_def = self.tag_def.dfl_tag
3128 ectx.eth_reg_module(self.ident.val)
3129 self.body.to_eth(ectx)
3131 class Module_Body (Node):
3132 def to_python (self, ctx):
3133 # XXX handle exports, imports.
3134 l = map (lambda x: x.to_python (ctx), self.assign_list)
3135 l = [a for a in l if a <> '']
3136 return "\n".join (l)
3138 def to_eth(self, ectx):
3140 ectx.eth_exports(self.exports)
3142 for i in self.imports:
3144 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3145 ectx.eth_module_dep_add(ectx.Module(), mod)
3146 for s in i.symbol_list:
3147 if isinstance(s, Type_Ref):
3148 ectx.eth_import_type(s.val, mod, proto)
3149 elif isinstance(s, Class_Ref):
3150 ectx.eth_import_class(s.val, mod, proto)
3152 ectx.eth_import_value(s, mod, proto)
3154 for a in self.assign_list:
3157 class Default_Tags (Node):
3158 def to_python (self, ctx): # not to be used directly
3161 # XXX should just calculate dependencies as we go along.
3162 def calc_dependencies (node, dict, trace = 0):
3163 if not hasattr (node, '__dict__'):
3164 if trace: print "#returning, node=", node
3166 if isinstance (node, Type_Ref):
3168 if trace: print "#Setting", node.val
3170 for (a, val) in node.__dict__.items ():
3171 if trace: print "# Testing node ", node, "attr", a, " val", val
3174 elif isinstance (val, Node):
3175 calc_dependencies (val, dict, trace)
3176 elif isinstance (val, type ([])):
3178 calc_dependencies (v, dict, trace)
3181 class Type_Assign (Node):
3182 def __init__ (self, *args, **kw):
3183 Node.__init__ (self, *args, **kw)
3184 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3185 to_test = self.val.typ
3188 if isinstance (to_test, SequenceType):
3189 to_test.sequence_name = self.name.name
3191 def to_python (self, ctx):
3193 calc_dependencies (self.val, dep_dict, 0)
3194 depend_list = dep_dict.keys ()
3195 return ctx.register_assignment (self.name.name,
3196 self.val.to_python (ctx),
3199 class PyQuote (Node):
3200 def to_python (self, ctx):
3201 return ctx.register_pyquote (self.val)
3203 #--- Class_Ref -----------------------------------------------------------------
3204 class Class_Ref (Type):
3205 def to_python (self, ctx):
3208 def eth_tname(self):
3209 return asn2c(self.val)
3211 #--- Type_Ref -----------------------------------------------------------------
3212 class Type_Ref (Type):
3213 def to_python (self, ctx):
3216 def eth_reg_sub(self, ident, ectx):
3217 ectx.eth_dep_add(ident, self.val)
3219 def eth_tname(self):
3220 return asn2c(self.val)
3222 def get_components(self, ectx):
3223 if not ectx.type.has_key(self.val) or ectx.type[self.val]['import']:
3224 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3225 warnings.warn_explicit(msg, UserWarning, '', '')
3228 return ectx.type[self.val]['val'].get_components(ectx)
3230 def GetTTag(self, ectx):
3231 #print "GetTTag(%s)\n" % self.val;
3232 if (ectx.type[self.val]['import']):
3233 if not ectx.type[self.val].has_key('ttag'):
3234 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3235 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3236 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3237 warnings.warn_explicit(msg, UserWarning, '', '')
3238 ttag = ('-1 /*imported*/', '-1 /*imported*/')
3239 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3240 return ectx.type[self.val]['ttag']
3242 return ectx.type[self.val]['val'].GetTag(ectx)
3244 def IndetermTag(self, ectx):
3245 if (ectx.type[self.val]['import']):
3248 return ectx.type[self.val]['val'].IndetermTag(ectx)
3250 def eth_type_default_pars(self, ectx, tname):
3251 pars = Type.eth_type_default_pars(self, ectx, tname)
3252 t = ectx.type[self.val]['ethname']
3253 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3254 pars['TYPE_REF_TNAME'] = t
3255 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3258 def eth_type_default_body(self, ectx, tname):
3260 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3261 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3263 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3264 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3266 body = '#error Can not decode %s' % (tname)
3269 #--- SelectionType ------------------------------------------------------------
3270 class SelectionType (Type):
3271 def to_python (self, ctx):
3274 def sel_of_typeref(self):
3275 return self.typ.type == 'Type_Ref'
3277 def eth_reg_sub(self, ident, ectx):
3278 if not self.sel_of_typeref():
3281 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3282 ectx.eth_dep_add(ident, self.seltype)
3284 def GetTTag(self, ectx):
3285 #print "GetTTag(%s)\n" % self.seltype;
3286 if (ectx.type[self.seltype]['import']):
3287 if not ectx.type[self.seltype].has_key('ttag'):
3288 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3289 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3290 warnings.warn_explicit(msg, UserWarning, '', '')
3291 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3292 return ectx.type[self.seltype]['ttag']
3294 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3296 def eth_type_default_pars(self, ectx, tname):
3297 pars = Type.eth_type_default_pars(self, ectx, tname)
3298 if self.sel_of_typeref():
3299 t = ectx.type[self.seltype]['ethname']
3300 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3301 pars['TYPE_REF_TNAME'] = t
3302 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3305 def eth_type_default_body(self, ectx, tname):
3306 if not self.sel_of_typeref():
3307 body = '#error Can not decode %s' % (tname)
3309 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3310 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3312 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3313 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3315 body = '#error Can not decode %s' % (tname)
3318 #--- TaggedType -----------------------------------------------------------------
3319 class TaggedType (Type):
3320 def eth_tname(self):
3322 for i in range(self.tstrip, len(self.val.tags)):
3323 tn += self.val.tags[i].eth_tname()
3325 tn += self.val.eth_tname()
3328 def eth_set_val_name(self, ident, val_name, ectx):
3329 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3330 self.val_name = val_name
3331 ectx.eth_dep_add(ident, self.val_name)
3333 def eth_reg_sub(self, ident, ectx):
3334 self.val_name = ident + '/' + '_untag'
3335 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3337 def GetTTag(self, ectx):
3338 #print "GetTTag(%s)\n" % self.seltype;
3339 return self.GetTag(ectx)
3341 def eth_ftype(self, ectx):
3342 return self.val.eth_ftype(ectx)
3344 def eth_type_default_pars(self, ectx, tname):
3345 pars = Type.eth_type_default_pars(self, ectx, tname)
3346 t = ectx.type[self.val_name]['ethname']
3347 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3348 pars['TYPE_REF_TNAME'] = t
3349 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3350 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3351 if self.HasImplicitTag(ectx):
3352 pars['TAG_IMPL'] = 'TRUE'
3354 pars['TAG_IMPL'] = 'FALSE'
3357 def eth_type_default_body(self, ectx, tname):
3359 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3360 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3361 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3363 body = '#error Can not decode %s' % (tname)
3366 #--- SqType -----------------------------------------------------------
3367 class SqType (Type):
3368 def out_item(self, f, val, optional, ext, ectx):
3369 ef = ectx.field[f]['ethname']
3370 t = ectx.eth_hf[ef]['ethtype']
3372 if (ectx.Ber() and ectx.field[f]['impl']):
3375 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3376 #print val.str_depth(1)
3379 opt = 'BER_FLAGS_OPTIONAL'
3380 if (not val.HasOwnTag()):
3381 if (opt): opt += '|'
3382 opt += 'BER_FLAGS_NOOWNTAG'
3383 elif (val.HasImplicitTag(ectx)):
3384 if (opt): opt += '|'
3385 opt += 'BER_FLAGS_IMPLTAG'
3386 if (val.IndetermTag(ectx)):
3387 if (opt): opt += '|'
3388 opt += 'BER_FLAGS_NOTCHKTAG'
3389 if (not opt): opt = '0'
3392 opt = 'ASN1_OPTIONAL'
3394 opt = 'ASN1_NOT_OPTIONAL'
3396 (tc, tn) = val.GetTag(ectx)
3398 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3399 % ('&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
3401 out = ' { %-13s, %s, %s, dissect_%s },\n' \
3402 % (tc, tn, opt, efd)
3404 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3405 % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
3410 #--- SeqType -----------------------------------------------------------
3411 class SeqType (SqType):
3413 def need_components(self):
3414 lst = self.elt_list[:]
3415 if hasattr(self, 'ext_list'):
3416 lst.extend(self.ext_list)
3417 for e in (self.elt_list):
3418 if e.type == 'components_of':
3422 def expand_components(self, ectx):
3423 while self.need_components():
3424 for i in range(len(self.elt_list)):
3425 if self.elt_list[i].type == 'components_of':
3426 comp = self.elt_list[i].typ.get_components(ectx)
3427 self.elt_list[i:i+1] = comp
3429 if hasattr(self, 'ext_list'):
3430 for i in range(len(self.ext_list)):
3431 if self.ext_list[i].type == 'components_of':
3432 comp = self.ext_list[i].typ.get_components(ectx)
3433 self.ext_list[i:i+1] = comp
3436 def get_components(self, ectx):
3437 return self.elt_list[:]
3439 def eth_type_default_table(self, ectx, tname):
3440 #print "eth_type_default_table(tname='%s')" % (tname)
3441 fname = ectx.eth_type[tname]['ref'][0]
3444 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
3446 table = "static const %(ER)s_old_sequence_t %(TABLE)s[] = {\n"
3448 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
3449 if hasattr(self, 'ext_list'):
3450 ext = 'ASN1_EXTENSION_ROOT'
3452 ext = 'ASN1_NO_EXTENSIONS'
3453 for e in (self.elt_list):
3454 f = fname + '/' + e.val.name
3455 table += self.out_item(f, e.val, e.optional, ext, ectx)
3456 if hasattr(self, 'ext_list'):
3457 for e in (self.ext_list):
3458 f = fname + '/' + e.val.name
3459 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3462 table += " { NULL, 0, 0, 0, NULL }\n};\n"
3464 table += " { 0, 0, 0, NULL }\n};\n"
3466 table += " { NULL, 0, 0, NULL }\n};\n"
3469 #--- SeqOfType -----------------------------------------------------------
3470 class SeqOfType (SqType):
3471 def eth_type_default_table(self, ectx, tname):
3472 #print "eth_type_default_table(tname='%s')" % (tname)
3473 fname = ectx.eth_type[tname]['ref'][0]
3474 if self.val.IsNamed ():
3475 f = fname + '/' + self.val.name
3477 f = fname + '/' + '_item'
3480 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
3482 table = "static const %(ER)s_old_sequence_t %(TABLE)s[1] = {\n"
3484 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
3485 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
3489 #--- SequenceOfType -----------------------------------------------------------
3490 class SequenceOfType (SeqOfType):
3491 def to_python (self, ctx):
3492 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3493 # or '' + (1,) for optional
3495 if self.size_constr <> None:
3496 print "#Ignoring size constraint:", self.size_constr.subtype
3497 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
3498 self.val.to_python (ctx),
3501 def eth_reg_sub(self, ident, ectx):
3503 if not self.val.IsNamed ():
3504 itmnm += '/' + '_item'
3505 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
3507 def eth_tname(self):
3508 if self.val.type != 'Type_Ref':
3509 return '#' + self.type + '_' + str(id(self))
3510 if not self.HasConstraint():
3511 return "SEQUENCE_OF_" + self.val.eth_tname()
3512 elif self.constr.IsSize():
3513 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
3515 return '#' + self.type + '_' + str(id(self))
3517 def eth_ftype(self, ectx):
3518 return ('FT_UINT32', 'BASE_DEC')
3520 def eth_need_tree(self):
3523 def GetTTag(self, ectx):
3524 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
3526 def eth_type_default_pars(self, ectx, tname):
3527 pars = Type.eth_type_default_pars(self, ectx, tname)
3528 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3529 pars['TABLE'] = '%(TNAME)s_sequence_of'
3532 def eth_type_default_body(self, ectx, tname):
3535 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
3536 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3537 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3539 body = ectx.eth_fn_call('dissect_%(ER)s_old_sequence_of', ret='offset',
3540 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3541 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3542 elif (ectx.Per() and not self.HasConstraint()):
3543 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
3544 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3545 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3546 elif (ectx.Per() and self.constr.type == 'Size'):
3547 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
3548 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3549 ('%(ETT_INDEX)s', '%(TABLE)s',),
3550 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3552 body = '#error Can not decode %s' % (tname)
3556 #--- SetOfType ----------------------------------------------------------------
3557 class SetOfType (SeqOfType):
3558 def eth_reg_sub(self, ident, ectx):
3560 if not self.val.IsNamed ():
3561 itmnm += '/' + '_item'
3562 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
3564 def eth_tname(self):
3565 if self.val.type != 'Type_Ref':
3566 return '#' + self.type + '_' + str(id(self))
3567 if not self.HasConstraint():
3568 return "SET_OF_" + self.val.eth_tname()
3569 elif self.constr.IsSize():
3570 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
3572 return '#' + self.type + '_' + str(id(self))
3574 def eth_ftype(self, ectx):
3575 return ('FT_UINT32', 'BASE_DEC')
3577 def eth_need_tree(self):
3580 def GetTTag(self, ectx):
3581 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
3583 def eth_type_default_pars(self, ectx, tname):
3584 pars = Type.eth_type_default_pars(self, ectx, tname)
3585 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3586 pars['TABLE'] = '%(TNAME)s_set_of'
3589 def eth_type_default_body(self, ectx, tname):
3592 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
3593 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3594 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3596 body = ectx.eth_fn_call('dissect_%(ER)s_old_set_of', ret='offset',
3597 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3598 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3599 elif (ectx.Per() and not self.HasConstraint()):
3600 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
3601 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3602 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3603 elif (ectx.Per() and self.constr.type == 'Size'):
3604 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
3605 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3606 ('%(ETT_INDEX)s', '%(TABLE)s',),
3607 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
3609 body = '#error Can not decode %s' % (tname)
3612 def mk_tag_str (ctx, cls, typ, num):
3614 # XXX should do conversion to int earlier!
3617 if typ == 'DEFAULT':
3619 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
3621 #--- SequenceType -------------------------------------------------------------
3622 class SequenceType (SeqType):
3623 def to_python (self, ctx):
3624 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3625 # or '' + (1,) for optional
3626 # XXX should also collect names for SEQUENCE inside SEQUENCE or
3627 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
3628 # from? for others, element or arm name would be fine)
3629 seq_name = getattr (self, 'sequence_name', None)
3630 if seq_name == None:
3633 seq_name = "'" + seq_name + "'"
3634 if self.__dict__.has_key('ext_list'):
3635 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
3636 self.elts_to_py (self.elt_list, ctx),
3637 self.elts_to_py (self.ext_list, ctx), seq_name)
3639 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
3640 self.elts_to_py (self.elt_list, ctx), seq_name)
3641 def elts_to_py (self, list, ctx):
3642 # we have elt_type, val= named_type, maybe default=, optional=
3643 # named_type node: either ident = or typ =
3644 # need to dismember these in order to generate Python output syntax.
3647 assert (e.type == 'elt_type')
3649 optflag = e.optional
3650 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
3651 assert (nt.type == 'named_type')
3654 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
3655 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
3656 nt.typ.tag.tag_typ,nt.typ.tag.num)
3660 return "('%s',%s,%s,%d)" % (identstr, tagstr,
3661 nt.typ.to_python (ctx), optflag)
3662 indentstr = ",\n" + ctx.spaces ()
3663 rv = indentstr.join ([elt_to_py (e) for e in list])
3667 def eth_reg_sub(self, ident, ectx, components_available=False):
3668 if self.need_components():
3669 if components_available:
3670 self.expand_components(ectx)
3672 ectx.eth_comp_req(ident)
3674 for e in (self.elt_list):
3675 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3676 if hasattr(self, 'ext_list'):
3677 for e in (self.ext_list):
3678 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3680 def eth_need_tree(self):
3683 def GetTTag(self, ectx):
3684 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
3686 def eth_type_default_pars(self, ectx, tname):
3687 pars = Type.eth_type_default_pars(self, ectx, tname)
3688 pars['TABLE'] = '%(TNAME)s_sequence'
3691 def eth_type_default_body(self, ectx, tname):
3694 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
3695 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3696 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3698 body = ectx.eth_fn_call('dissect_%(ER)s_old_sequence', ret='offset',
3699 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3700 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3702 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
3703 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3704 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3706 body = '#error Can not decode %s' % (tname)
3709 #--- SetType ------------------------------------------------------------------
3710 class SetType(SeqType):
3712 def eth_reg_sub(self, ident, ectx, components_available=False):
3713 if self.need_components():
3714 if components_available:
3715 self.expand_components(ectx)
3717 ectx.eth_comp_req(ident)
3719 for e in (self.elt_list):
3720 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3721 if hasattr(self, 'ext_list'):
3722 for e in (self.ext_list):
3723 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
3725 def eth_need_tree(self):
3728 def GetTTag(self, ectx):
3729 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
3731 def eth_type_default_pars(self, ectx, tname):
3732 pars = Type.eth_type_default_pars(self, ectx, tname)
3733 pars['TABLE'] = '%(TNAME)s_set'
3736 def eth_type_default_body(self, ectx, tname):
3739 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
3740 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3741 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3743 body = ectx.eth_fn_call('dissect_%(ER)s_old_set', ret='offset',
3744 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3745 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
3747 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
3748 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3749 ('%(ETT_INDEX)s', '%(TABLE)s',),))
3751 body = '#error Can not decode %s' % (tname)
3754 #--- ChoiceType ---------------------------------------------------------------
3755 class ChoiceType (Type):
3756 def to_python (self, ctx):
3757 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
3758 # or '' + (1,) for optional
3759 if self.__dict__.has_key('ext_list'):
3760 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
3761 self.elts_to_py (self.elt_list, ctx),
3762 self.elts_to_py (self.ext_list, ctx))
3764 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
3765 def elts_to_py (self, list, ctx):
3768 assert (nt.type == 'named_type')
3770 if hasattr (nt, 'ident'):
3773 if hasattr (nt.typ, 'val'):
3774 identstr = nt.typ.val # XXX, making up name
3775 elif hasattr (nt.typ, 'name'):
3776 identstr = nt.typ.name
3778 identstr = ctx.make_new_name ()
3780 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
3781 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
3782 nt.typ.tag.tag_typ,nt.typ.tag.num)
3786 return "('%s',%s,%s)" % (identstr, tagstr,
3787 nt.typ.to_python (ctx))
3788 indentstr = ",\n" + ctx.spaces ()
3789 rv = indentstr.join ([elt_to_py (e) for e in list])
3793 def eth_reg_sub(self, ident, ectx):
3794 #print "eth_reg_sub(ident='%s')" % (ident)
3795 for e in (self.elt_list):
3796 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
3797 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
3798 ectx.eth_sel_req(ident, e.name)
3799 if hasattr(self, 'ext_list'):
3800 for e in (self.ext_list):
3801 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
3802 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
3803 ectx.eth_sel_req(ident, e.name)
3805 def sel_item(self, ident, sel, ectx):
3806 lst = self.elt_list[:]
3807 if hasattr(self, 'ext_list'):
3808 lst.extend(self.ext_list)
3810 for e in (self.elt_list):
3811 if e.IsNamed() and (e.name == sel):
3815 print "#CHOICE %s does not contain item %s" % (ident, sel)
3818 def sel_req(self, ident, sel, ectx):
3819 #print "sel_req(ident='%s', sel=%s)" % (ident, sel)
3820 ee = self.sel_item(ident, sel, ectx)
3822 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
3824 def eth_ftype(self, ectx):
3825 return ('FT_UINT32', 'BASE_DEC')
3827 def eth_strings(self):
3830 def eth_need_tree(self):
3833 def eth_has_vals(self):
3836 def GetTTag(self, ectx):
3838 cls = 'BER_CLASS_ANY/*choice*/'
3839 #if hasattr(self, 'ext_list'):
3840 # lst.extend(self.ext_list)
3842 # cls = lst[0].GetTag(ectx)[0]
3844 # if (e.GetTag(ectx)[0] != cls):
3845 # cls = '-1/*choice*/'
3846 return (cls, '-1/*choice*/')
3848 def GetTTagSel(self, sel, ectx):
3849 ee = self.sel_item('', sel, ectx)
3851 return ee.GetTag(ectx)
3853 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
3855 def IndetermTag(self, ectx):
3856 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
3857 return not self.HasOwnTag()
3859 def get_vals(self, ectx):
3862 lst = self.elt_list[:]
3863 if hasattr(self, 'ext_list'):
3864 lst.extend(self.ext_list)
3866 t = lst[0].GetTag(ectx)[0]
3868 if (t == 'BER_CLASS_UNI'):
3871 if (e.GetTag(ectx)[0] != t):
3875 for e in (self.elt_list):
3876 if (tagval): val = e.GetTag(ectx)[1]
3877 else: val = str(cnt)
3878 vals.append((val, e.name))
3880 if hasattr(self, 'ext_list'):
3881 for e in (self.ext_list):
3882 if (tagval): val = e.GetTag(ectx)[1]
3883 else: val = str(cnt)
3884 vals.append((val, e.name))
3888 def eth_type_vals(self, tname, ectx):
3890 vals = self.get_vals(ectx)
3891 out += ectx.eth_vals(tname, vals)
3894 def eth_type_enum(self, tname, ectx):
3896 vals = self.get_vals(ectx)
3897 out += ectx.eth_enum(tname, vals)
3900 def eth_type_default_pars(self, ectx, tname):
3901 pars = Type.eth_type_default_pars(self, ectx, tname)
3902 pars['TABLE'] = '%(TNAME)s_choice'
3905 def eth_type_default_table(self, ectx, tname):
3906 def out_item(val, e, ext, ectx):
3907 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
3909 vval = ectx.eth_enum_item(tname, e.name)
3912 f = fname + '/' + e.name
3913 ef = ectx.field[f]['ethname']
3914 t = ectx.eth_hf[ef]['ethtype']
3916 if (ectx.field[f]['impl']):
3920 if (not e.HasOwnTag()):
3921 opt = 'BER_FLAGS_NOOWNTAG'
3922 elif (e.HasImplicitTag(ectx)):
3923 if (opt): opt += '|'
3924 opt += 'BER_FLAGS_IMPLTAG'
3925 if (not opt): opt = '0'
3927 (tc, tn) = e.GetTag(ectx)
3929 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3930 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
3932 out = ' { %3s, %-13s, %s, %s, dissect_%s },\n' \
3933 % (vval, tc, tn, opt, efd)
3935 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
3936 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
3941 #print "eth_type_default_table(tname='%s')" % (tname)
3942 fname = ectx.eth_type[tname]['ref'][0]
3945 lst = self.elt_list[:]
3946 if hasattr(self, 'ext_list'):
3947 lst.extend(self.ext_list)
3949 t = lst[0].GetTag(ectx)[0]
3951 if (t == 'BER_CLASS_UNI'):
3954 if (e.GetTag(ectx)[0] != t):
3958 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
3960 table = "static const %(ER)s_old_choice_t %(TABLE)s[] = {\n"
3962 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
3964 if hasattr(self, 'ext_list'):
3965 ext = 'ASN1_EXTENSION_ROOT'
3967 ext = 'ASN1_NO_EXTENSIONS'
3968 for e in (self.elt_list):
3969 if (tagval): val = e.GetTag(ectx)[1]
3970 else: val = str(cnt)
3971 table += out_item(val, e, ext, ectx)
3973 if hasattr(self, 'ext_list'):
3974 for e in (self.ext_list):
3975 if (tagval): val = e.GetTag(ectx)[1]
3976 else: val = str(cnt)
3977 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
3981 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
3983 table += " { 0, 0, 0, 0, NULL }\n};\n"
3985 table += " { 0, NULL, 0, NULL }\n};\n"
3988 def eth_type_default_body(self, ectx, tname):
3991 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
3992 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3993 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
3996 body = ectx.eth_fn_call('dissect_%(ER)s_old_choice', ret='offset',
3997 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3998 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4001 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4002 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4003 ('%(ETT_INDEX)s', '%(TABLE)s',),
4006 body = '#error Can not decode %s' % (tname)
4009 #--- EnumeratedType -----------------------------------------------------------
4010 class EnumeratedType (Type):
4011 def to_python (self, ctx):
4012 def strify_one (named_num):
4013 return "%s=%s" % (named_num.ident, named_num.val)
4014 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4016 def eth_ftype(self, ectx):
4017 return ('FT_UINT32', 'BASE_DEC')
4019 def eth_strings(self):
4022 def eth_has_vals(self):
4025 def GetTTag(self, ectx):
4026 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4028 def get_vals_etc(self, ectx):
4036 for e in (self.val):
4037 if e.type == 'NamedNumber':
4038 used[int(e.val)] = True
4039 for e in (self.val):
4040 if e.type == 'NamedNumber':
4043 while used.has_key(lastv):
4047 vals.append((val, e.ident))
4048 map_table.append(val)
4052 if self.ext is not None:
4053 for e in (self.ext):
4054 if e.type == 'NamedNumber':
4055 used[int(e.val)] = True
4056 for e in (self.ext):
4057 if e.type == 'NamedNumber':
4060 while used.has_key(lastv):
4064 vals.append((val, e.ident))
4065 map_table.append(val)
4070 for i in range(len(map_table)):
4071 need_map = need_map or (map_table[i] != i)
4074 return (vals, root_num, ext_num, map_table)
4076 def eth_type_vals(self, tname, ectx):
4078 vals = self.get_vals_etc(ectx)[0]
4079 out += ectx.eth_vals(tname, vals)
4082 def reg_enum_vals(self, tname, ectx):
4083 vals = self.get_vals_etc(ectx)[0]
4084 for (val, id) in vals:
4085 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4087 def eth_type_enum(self, tname, ectx):
4089 vals = self.get_vals_etc(ectx)[0]
4090 out += ectx.eth_enum(tname, vals)
4093 def eth_type_default_pars(self, ectx, tname):
4094 pars = Type.eth_type_default_pars(self, ectx, tname)
4095 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4096 if (self.ext != None):
4100 pars['ROOT_NUM'] = str(root_num)
4102 pars['EXT_NUM'] = str(ext_num)
4104 pars['TABLE'] = '%(TNAME)s_value_map'
4106 pars['TABLE'] = 'NULL'
4109 def eth_type_default_table(self, ectx, tname):
4110 if (not ectx.Per()): return ''
4111 map_table = self.get_vals_etc(ectx)[3]
4112 if (map_table == None): return ''
4113 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4114 table += ", ".join([str(v) for v in map_table])
4118 def eth_type_default_body(self, ectx, tname):
4120 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4121 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4124 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4125 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4126 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4128 body = '#error Can not decode %s' % (tname)
4130 #--- EmbeddedPDVType -----------------------------------------------------------
4131 class EmbeddedPDVType (Type):
4132 def eth_tname(self):
4133 return 'EMBEDDED_PDV'
4135 def eth_ftype(self, ectx):
4136 return ('FT_NONE', 'BASE_NONE')
4138 def GetTTag(self, ectx):
4139 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4142 def eth_type_default_body(self, ectx, tname):
4143 body = '#error Can not decode %s' % (tname)
4146 #--- ExternalType -----------------------------------------------------------
4147 class ExternalType (Type):
4148 def eth_tname(self):
4151 def eth_ftype(self, ectx):
4152 return ('FT_NONE', 'BASE_NONE')
4154 def GetTTag(self, ectx):
4155 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4157 def eth_type_default_pars(self, ectx, tname):
4158 pars = Type.eth_type_default_pars(self, ectx, tname)
4159 if ectx.default_external_type_cb:
4160 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4162 pars['TYPE_REF_FN'] = 'NULL'
4165 def eth_type_default_body(self, ectx, tname):
4167 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4168 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4170 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4171 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4173 body = '#error Can not decode %s' % (tname)
4176 #--- OpenType -----------------------------------------------------------
4177 class OpenType (Type):
4178 def to_python (self, ctx):
4181 def single_type(self):
4182 if (self.HasConstraint() and
4183 self.constr.type == 'Type' and
4184 self.constr.subtype.type == 'Type_Ref'):
4185 return self.constr.subtype.val
4188 def eth_reg_sub(self, ident, ectx):
4189 t = self.single_type()
4191 ectx.eth_dep_add(ident, t)
4193 def eth_tname(self):
4194 t = self.single_type()
4196 return 'OpenType_' + t
4198 return Type.eth_tname(self)
4200 def eth_ftype(self, ectx):
4201 return ('FT_NONE', 'BASE_NONE')
4203 def GetTTag(self, ectx):
4204 return ('BER_CLASS_ANY', '0')
4206 def eth_type_default_pars(self, ectx, tname):
4207 pars = Type.eth_type_default_pars(self, ectx, tname)
4208 pars['FN_VARIANT'] = ectx.default_opentype_variant
4209 t = self.single_type()
4211 t = ectx.type[t]['ethname']
4212 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4213 pars['TYPE_REF_TNAME'] = t
4214 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4216 pars['TYPE_REF_FN'] = 'NULL'
4219 def eth_type_default_body(self, ectx, tname):
4221 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4222 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4224 body = '#error Can not decode %s' % (tname)
4227 #--- AnyType -----------------------------------------------------------
4228 class AnyType (Type):
4229 def to_python (self, ctx):
4232 def eth_ftype(self, ectx):
4233 return ('FT_NONE', 'BASE_NONE')
4235 def GetTTag(self, ectx):
4236 return ('BER_CLASS_ANY', '0')
4238 def eth_type_default_body(self, ectx, tname):
4239 body = '#error Can not decode %s' % (tname)
4242 class Literal (Node):
4243 def to_python (self, ctx):
4246 #--- NullType -----------------------------------------------------------------
4247 class NullType (Type):
4248 def to_python (self, ctx):
4251 def eth_tname(self):
4254 def GetTTag(self, ectx):
4255 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4257 def eth_type_default_body(self, ectx, tname):
4259 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4260 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4262 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4263 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4265 body = '#error Can not decode %s' % (tname)
4268 #--- RealType -----------------------------------------------------------------
4269 class RealType (Type):
4270 def to_python (self, ctx):
4273 def eth_tname(self):
4276 def GetTTag(self, ectx):
4277 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4279 def eth_ftype(self, ectx):
4280 return ('FT_DOUBLE', 'BASE_NONE')
4282 def eth_type_default_body(self, ectx, tname):
4284 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4285 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4288 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4289 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4291 body = '#error Can not decode %s' % (tname)
4294 #--- BooleanType --------------------------------------------------------------
4295 class BooleanType (Type):
4296 def to_python (self, ctx):
4297 return 'asn1.BOOLEAN'
4299 def eth_tname(self):
4302 def GetTTag(self, ectx):
4303 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4305 def eth_ftype(self, ectx):
4306 return ('FT_BOOLEAN', '8')
4308 def eth_type_default_body(self, ectx, tname):
4310 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4311 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4313 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4314 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4316 body = '#error Can not decode %s' % (tname)
4319 #--- OctetStringType ----------------------------------------------------------
4320 class OctetStringType (Type):
4321 def to_python (self, ctx):
4322 return 'asn1.OCTSTRING'
4324 def eth_tname(self):
4325 if not self.HasConstraint():
4326 return 'OCTET_STRING'
4327 elif self.constr.type == 'Size':
4328 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
4330 return '#' + self.type + '_' + str(id(self))
4332 def eth_ftype(self, ectx):
4333 return ('FT_BYTES', 'BASE_HEX')
4335 def GetTTag(self, ectx):
4336 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
4338 def eth_need_pdu(self, ectx):
4340 if self.HasContentsConstraint():
4341 t = self.constr.GetContents(ectx)
4342 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
4344 'new' : ectx.default_containing_variant == '_pdu_new' }
4347 def eth_type_default_pars(self, ectx, tname):
4348 pars = Type.eth_type_default_pars(self, ectx, tname)
4349 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4350 if self.HasContentsConstraint():
4351 pars['FN_VARIANT'] = ectx.default_containing_variant
4352 t = self.constr.GetContents(ectx)
4354 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
4355 t = ectx.field[t]['ethname']
4356 pars['TYPE_REF_PROTO'] = ''
4357 pars['TYPE_REF_TNAME'] = t
4358 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
4360 t = ectx.type[t]['ethname']
4361 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4362 pars['TYPE_REF_TNAME'] = t
4363 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4365 pars['TYPE_REF_FN'] = 'NULL'
4368 def eth_type_default_body(self, ectx, tname):
4370 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
4371 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4374 if self.HasContentsConstraint():
4375 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
4376 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4377 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TYPE_REF_FN)s',),))
4379 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
4380 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4381 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s',),))
4383 body = '#error Can not decode %s' % (tname)
4386 #--- CharacterStringType ------------------------------------------------------
4387 class CharacterStringType (Type):
4388 def eth_tname(self):
4389 if not self.HasConstraint():
4390 return self.eth_tsname()
4391 elif self.constr.type == 'Size':
4392 return self.eth_tsname() + '_' + self.constr.eth_constrname()
4394 return '#' + self.type + '_' + str(id(self))
4396 def eth_ftype(self, ectx):
4397 return ('FT_STRING', 'BASE_NONE')
4399 class RestrictedCharacterStringType (CharacterStringType):
4400 def to_python (self, ctx):
4401 return 'asn1.' + self.eth_tsname()
4403 def GetTTag(self, ectx):
4404 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
4406 def eth_type_default_pars(self, ectx, tname):
4407 pars = Type.eth_type_default_pars(self, ectx, tname)
4408 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4409 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
4410 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
4413 def eth_type_default_body(self, ectx, tname):
4415 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
4416 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
4417 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4419 elif (ectx.Per() and self.HasPermAlph()):
4420 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
4421 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4422 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
4425 if (self.eth_tsname() == 'GeneralString'):
4426 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4427 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4428 elif (self.eth_tsname() == 'GeneralizedTime'):
4429 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
4430 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4431 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4432 elif (self.eth_tsname() == 'UTCTime'):
4433 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
4434 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4435 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4437 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4438 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4439 ('%(MIN_VAL)s', '%(MAX_VAL)s',),))
4441 body = '#error Can not decode %s' % (tname)
4444 class BMPStringType (RestrictedCharacterStringType):
4445 def eth_tsname(self):
4448 class GeneralStringType (RestrictedCharacterStringType):
4449 def eth_tsname(self):
4450 return 'GeneralString'
4452 class GraphicStringType (RestrictedCharacterStringType):
4453 def eth_tsname(self):
4454 return 'GraphicString'
4456 class IA5StringType (RestrictedCharacterStringType):
4457 def eth_tsname(self):
4460 class NumericStringType (RestrictedCharacterStringType):
4461 def eth_tsname(self):
4462 return 'NumericString'
4464 class PrintableStringType (RestrictedCharacterStringType):
4465 def eth_tsname(self):
4466 return 'PrintableString'
4468 class TeletexStringType (RestrictedCharacterStringType):
4469 def eth_tsname(self):
4470 return 'TeletexString'
4472 class T61StringType (RestrictedCharacterStringType):
4473 def eth_tsname(self):
4475 def GetTTag(self, ectx):
4476 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
4478 class UniversalStringType (RestrictedCharacterStringType):
4479 def eth_tsname(self):
4480 return 'UniversalString'
4482 class UTF8StringType (RestrictedCharacterStringType):
4483 def eth_tsname(self):
4486 class VideotexStringType (RestrictedCharacterStringType):
4487 def eth_tsname(self):
4488 return 'VideotexString'
4490 class VisibleStringType (RestrictedCharacterStringType):
4491 def eth_tsname(self):
4492 return 'VisibleString'
4494 class ISO646StringType (RestrictedCharacterStringType):
4495 def eth_tsname(self):
4496 return 'ISO646String'
4497 def GetTTag(self, ectx):
4498 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
4500 class UnrestrictedCharacterStringType (CharacterStringType):
4501 def to_python (self, ctx):
4502 return 'asn1.UnrestrictedCharacterString'
4503 def eth_tsname(self):
4504 return 'CHARACTER_STRING'
4506 #--- UsefulType ---------------------------------------------------------------
4507 class GeneralizedTime (RestrictedCharacterStringType):
4508 def eth_tsname(self):
4509 return 'GeneralizedTime'
4511 def eth_type_default_body(self, ectx, tname):
4513 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
4514 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4517 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4519 class UTCTime (RestrictedCharacterStringType):
4520 def eth_tsname(self):
4523 class ObjectDescriptor (RestrictedCharacterStringType):
4524 def eth_tsname(self):
4525 return 'ObjectDescriptor'
4527 def eth_type_default_body(self, ectx, tname):
4529 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
4531 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
4532 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4534 body = '#error Can not decode %s' % (tname)
4537 #--- ObjectIdentifierType -----------------------------------------------------
4538 class ObjectIdentifierType (Type):
4539 def to_python (self, ctx):
4540 return 'asn1.OBJECT_IDENTIFIER'
4542 def eth_tname(self):
4543 return 'OBJECT_IDENTIFIER'
4545 def eth_ftype(self, ectx):
4546 return ('FT_OID', 'BASE_NONE')
4548 def GetTTag(self, ectx):
4549 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
4551 def eth_type_default_pars(self, ectx, tname):
4552 pars = Type.eth_type_default_pars(self, ectx, tname)
4553 pars['FN_VARIANT'] = ectx.default_oid_variant
4556 def eth_type_default_body(self, ectx, tname):
4558 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
4559 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4561 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
4562 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4564 body = '#error Can not decode %s' % (tname)
4567 #--- ObjectIdentifierValue ----------------------------------------------------
4568 class ObjectIdentifierValue (Value):
4569 def get_num(self, path, val):
4570 return str(oid_names.get(path + '/' + val, val))
4572 def to_str(self, ectx):
4577 for v in self.comp_list:
4578 if isinstance(v, Node) and (v.type == 'name_and_number'):
4583 vstr = self.get_num(path, v)
4584 if not first and not vstr.isdigit():
4585 vstr = ectx.value_get_val(vstr)
4590 out += ectx.value_get_eth(vstr) + '"'
4600 v = self.comp_list[0]
4601 if isinstance(v, Node) and (v.type == 'name_and_number'):
4606 vstr = self.get_num('', v)
4612 class NamedNumber(Node):
4613 def to_python (self, ctx):
4614 return "('%s',%s)" % (self.ident, self.val)
4616 class NamedNumListBase(Node):
4617 def to_python (self, ctx):
4618 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
4619 map (lambda x: x.to_python (ctx), self.named_list)))
4621 #--- IntegerType --------------------------------------------------------------
4622 class IntegerType (Type):
4623 def to_python (self, ctx):
4624 return "asn1.INTEGER_class ([%s])" % (",".join (
4625 map (lambda x: x.to_python (ctx), self.named_list)))
4627 def add_named_value(self, ident, val):
4628 e = NamedNumber(ident = ident, val = val)
4629 if not self.named_list:
4630 self.named_list = []
4631 self.named_list.append(e)
4633 def eth_tname(self):
4635 return Type.eth_tname(self)
4636 if not self.HasConstraint():
4638 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
4639 return 'INTEGER' + '_' + self.constr.eth_constrname()
4641 return 'INTEGER' + '_' + self.constr.eth_tname()
4643 def GetTTag(self, ectx):
4644 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
4647 def eth_ftype(self, ectx):
4648 if self.HasConstraint():
4649 if not self.constr.IsNegativ():
4650 return ('FT_UINT32', 'BASE_DEC')
4651 return ('FT_INT32', 'BASE_DEC')
4653 def eth_strings(self):
4654 if (self.named_list):
4659 def eth_has_vals(self):
4660 if (self.named_list):
4665 def get_vals(self, ectx):
4667 for e in (self.named_list):
4668 vals.append((int(e.val), e.ident))
4671 def eth_type_vals(self, tname, ectx):
4672 if not self.eth_has_vals(): return ''
4674 vals = self.get_vals(ectx)
4675 out += ectx.eth_vals(tname, vals)
4678 def reg_enum_vals(self, tname, ectx):
4679 vals = self.get_vals(ectx)
4680 for (val, id) in vals:
4681 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4683 def eth_type_enum(self, tname, ectx):
4684 if not self.eth_has_enum(tname, ectx): return ''
4686 vals = self.get_vals(ectx)
4687 out += ectx.eth_enum(tname, vals)
4690 def eth_type_default_pars(self, ectx, tname):
4691 pars = Type.eth_type_default_pars(self, ectx, tname)
4692 if self.HasValueConstraint():
4693 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
4696 def eth_type_default_body(self, ectx, tname):
4698 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4699 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4701 elif (ectx.Per() and not self.HasValueConstraint()):
4702 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4703 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
4704 elif (ectx.Per() and self.HasValueConstraint()):
4705 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
4706 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4707 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
4709 body = '#error Can not decode %s' % (tname)
4712 #--- BitStringType ------------------------------------------------------------
4713 class BitStringType (Type):
4714 def to_python (self, ctx):
4715 return "asn1.BITSTRING_class ([%s])" % (",".join (
4716 map (lambda x: x.to_python (ctx), self.named_list)))
4718 def eth_tname(self):
4720 return Type.eth_tname(self)
4721 elif not self.HasConstraint():
4723 elif self.constr.IsSize():
4724 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
4726 return '#' + self.type + '_' + str(id(self))
4728 def GetTTag(self, ectx):
4729 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
4731 def eth_ftype(self, ectx):
4732 return ('FT_BYTES', 'BASE_HEX')
4734 def eth_need_tree(self):
4735 return self.named_list
4737 def eth_need_pdu(self, ectx):
4739 if self.HasContentsConstraint():
4740 t = self.constr.GetContents(ectx)
4741 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
4743 'new' : ectx.default_containing_variant == '_pdu_new' }
4746 def eth_named_bits(self):
4748 if (self.named_list):
4749 for e in (self.named_list):
4750 bits.append((int(e.val), e.ident))
4753 def eth_type_default_pars(self, ectx, tname):
4754 pars = Type.eth_type_default_pars(self, ectx, tname)
4755 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4756 if not pars.has_key('ETT_INDEX'):
4757 pars['ETT_INDEX'] = '-1'
4758 pars['TABLE'] = 'NULL'
4759 if self.eth_named_bits():
4760 pars['TABLE'] = '%(TNAME)s_bits'
4761 if self.HasContentsConstraint():
4762 pars['FN_VARIANT'] = ectx.default_containing_variant
4763 t = self.constr.GetContents(ectx)
4765 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
4766 t = ectx.field[t]['ethname']
4767 pars['TYPE_REF_PROTO'] = ''
4768 pars['TYPE_REF_TNAME'] = t
4769 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
4771 t = ectx.type[t]['ethname']
4772 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4773 pars['TYPE_REF_TNAME'] = t
4774 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4776 pars['TYPE_REF_FN'] = 'NULL'
4779 def eth_type_default_table(self, ectx, tname):
4780 #print "eth_type_default_table(tname='%s')" % (tname)
4782 bits = self.eth_named_bits()
4784 table = ectx.eth_bits(tname, bits)
4787 def eth_type_default_body(self, ectx, tname):
4789 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
4790 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4791 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
4794 if self.HasContentsConstraint():
4795 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
4796 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4797 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
4799 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
4800 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4801 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s'),))
4803 body = '#error Can not decode %s' % (tname)
4806 #--- BStringValue ------------------------------------------------------------
4825 class BStringValue (Value):
4826 def to_str(self, ectx):
4829 v += '0' * (8 - len(v) % 8)
4831 for i in (range(0, len(v), 4)):
4832 vv += bstring_tab[v[i:i+4]]
4835 #==============================================================================
4837 def p_module_list_1 (t):
4838 'module_list : module_list ModuleDefinition'
4839 t[0] = t[1] + [t[2]]
4841 def p_module_list_2 (t):
4842 'module_list : ModuleDefinition'
4846 #--- ITU-T Recommendation X.680 -----------------------------------------------
4849 # 11 ASN.1 lexical items --------------------------------------------------------
4851 # 11.2 Type references
4853 'type_ref : UCASE_IDENT'
4854 t[0] = Type_Ref(val=t[1])
4857 def p_identifier (t):
4858 'identifier : LCASE_IDENT'
4861 # 11.4 Value references
4862 def p_valuereference (t):
4863 'valuereference : LCASE_IDENT'
4866 # 11.5 Module references
4867 def p_modulereference (t):
4868 'modulereference : UCASE_IDENT'
4872 # 12 Module definition --------------------------------------------------------
4875 def p_ModuleDefinition (t):
4876 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT BEGIN ModuleBody END'
4877 t[0] = Module (ident = t[1], tag_def = t[3], body = t[6])
4879 def p_TagDefault_1 (t):
4880 '''TagDefault : EXPLICIT TAGS
4883 t[0] = Default_Tags (dfl_tag = t[1])
4885 def p_TagDefault_2 (t):
4887 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
4888 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
4890 def p_ModuleIdentifier_1 (t):
4891 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
4892 t [0] = Node('module_ident', val = t[1], ident = t[2])
4894 def p_ModuleIdentifier_2 (t):
4895 'ModuleIdentifier : modulereference' # name, oid
4896 t [0] = Node('module_ident', val = t[1], ident = None)
4898 def p_DefinitiveIdentifier (t):
4899 'DefinitiveIdentifier : ObjectIdentifierValue'
4902 #def p_module_ref (t):
4903 # 'module_ref : UCASE_IDENT'
4906 def p_ModuleBody_1 (t):
4907 'ModuleBody : Exports Imports AssignmentList'
4908 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
4910 def p_ModuleBody_2 (t):
4912 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
4914 def p_Exports_1 (t):
4915 'Exports : EXPORTS syms_exported SEMICOLON'
4918 def p_Exports_2 (t):
4919 'Exports : EXPORTS ALL SEMICOLON'
4922 def p_Exports_3 (t):
4926 def p_syms_exported_1 (t):
4927 'syms_exported : exp_sym_list'
4930 def p_syms_exported_2 (t):
4934 def p_exp_sym_list_1 (t):
4935 'exp_sym_list : Symbol'
4938 def p_exp_sym_list_2 (t):
4939 'exp_sym_list : exp_sym_list COMMA Symbol'
4940 t[0] = t[1] + [t[3]]
4943 def p_Imports_1 (t):
4944 'Imports : IMPORTS SymbolsImported SEMICOLON'
4946 global lcase_ident_assigned
4947 lcase_ident_assigned = {}
4949 def p_Imports_2 (t):
4953 def p_SymbolsImported_1(t):
4954 'SymbolsImported : '
4957 def p_SymbolsImported_2 (t):
4958 'SymbolsImported : SymbolsFromModuleList'
4961 def p_SymbolsFromModuleList_1 (t):
4962 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
4963 t[0] = t[1] + [t[2]]
4965 def p_SymbolsFromModuleList_2 (t):
4966 'SymbolsFromModuleList : SymbolsFromModule'
4969 def p_SymbolsFromModule (t):
4970 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
4971 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
4972 for s in (t[0].symbol_list):
4973 if (isinstance(s, str) and s[0].islower()): lcase_ident_assigned[s] = t[3]
4974 if t[0].module.val == 'Remote-Operations-Information-Objects':
4975 for i in range(len(t[0].symbol_list)):
4976 s = t[0].symbol_list[i]
4977 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
4979 if isinstance(s, Type_Ref) and is_class_ident(s.val):
4980 t[0].symbol_list[i] = Class_Ref (val = s.val)
4982 def p_GlobalModuleReference (t):
4983 'GlobalModuleReference : modulereference AssignedIdentifier'
4984 t [0] = Node('module_ident', val = t[1], ident = t[2])
4986 def p_AssignedIdentifier_1 (t):
4987 'AssignedIdentifier : ObjectIdentifierValue'
4990 def p_AssignedIdentifier_2 (t):
4991 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
4994 def p_AssignedIdentifier_3 (t):
4995 'AssignedIdentifier : '
4998 def p_SymbolList_1 (t):
4999 'SymbolList : Symbol'
5002 def p_SymbolList_2 (t):
5003 'SymbolList : SymbolList COMMA Symbol'
5004 t[0] = t[1] + [t[3]]
5007 '''Symbol : Reference
5008 | ParameterizedReference'''
5011 def p_Reference (t):
5012 '''Reference : type_ref
5014 | objectclassreference'''
5017 def p_AssignmentList_1 (t):
5018 'AssignmentList : AssignmentList Assignment'
5019 t[0] = t[1] + [t[2]]
5021 def p_AssignmentList_2 (t):
5022 'AssignmentList : Assignment SEMICOLON'
5025 def p_AssignmentList_3 (t):
5026 'AssignmentList : Assignment'
5029 def p_Assignment (t):
5030 '''Assignment : TypeAssignment
5032 | ObjectClassAssignment
5034 | ObjectSetAssignment
5035 | ParameterizedTypeAssignment
5040 # 13 Referencing type and value definitions -----------------------------------
5043 def p_DefinedType (t):
5044 '''DefinedType : ExternalTypeReference
5046 | ParameterizedType'''
5049 def p_DefinedValue(t):
5050 '''DefinedValue : ExternalValueReference
5055 def p_ExternalTypeReference (t):
5056 'ExternalTypeReference : modulereference DOT type_ref'
5057 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5059 def p_ExternalValueReference (t):
5060 'ExternalValueReference : modulereference DOT identifier'
5061 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5064 # 15 Assigning types and values -----------------------------------------------
5067 def p_TypeAssignment (t):
5068 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5073 def p_ValueAssignment (t):
5074 'ValueAssignment : valuereference ValueType ASSIGNMENT Value'
5075 t[0] = value_assign (ident = t[1], typ = t[2], val = t[4])
5077 # only "simple" types are supported to simplify grammer
5078 def p_ValueType (t):
5079 '''ValueType : type_ref
5082 | ObjectIdentifierType
5089 # 16 Definition of types and values -------------------------------------------
5093 '''Type : BuiltinType
5095 | ConstrainedType'''
5099 def p_BuiltinType (t):
5100 '''BuiltinType : AnyType
5103 | CharacterStringType
5110 | ObjectClassFieldType
5111 | ObjectIdentifierType
5122 def p_ReferencedType (t):
5123 '''ReferencedType : DefinedType
5129 def p_NamedType (t):
5130 'NamedType : identifier Type'
5136 '''Value : BuiltinValue
5137 | ReferencedValue'''
5141 def p_BuiltinValue (t):
5142 '''BuiltinValue : BooleanValue
5144 | ObjectIdentifierValue
5149 | char_string''' # XXX we don't support {data} here
5153 def p_ReferencedValue (t):
5154 '''ReferencedValue : DefinedValue'''
5158 #def p_NamedValue (t):
5159 # 'NamedValue : identifier Value'
5160 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
5163 # 17 Notation for the boolean type --------------------------------------------
5166 def p_BooleanType (t):
5167 'BooleanType : BOOLEAN'
5168 t[0] = BooleanType ()
5171 def p_BooleanValue (t):
5172 '''BooleanValue : TRUE
5177 # 18 Notation for the integer type --------------------------------------------
5180 def p_IntegerType_1 (t):
5181 'IntegerType : INTEGER'
5182 t[0] = IntegerType (named_list = None)
5184 def p_IntegerType_2 (t):
5185 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
5186 t[0] = IntegerType(named_list = t[3])
5188 def p_NamedNumberList_1 (t):
5189 'NamedNumberList : NamedNumber'
5192 def p_NamedNumberList_2 (t):
5193 'NamedNumberList : NamedNumberList COMMA NamedNumber'
5194 t[0] = t[1] + [t[3]]
5196 def p_NamedNumber (t):
5197 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
5198 | identifier LPAREN DefinedValue RPAREN'''
5199 t[0] = NamedNumber(ident = t[1], val = t[3])
5201 def p_SignedNumber_1 (t):
5202 'SignedNumber : NUMBER'
5205 def p_SignedNumber_2 (t):
5206 'SignedNumber : MINUS NUMBER'
5210 def p_IntegerValue (t):
5211 'IntegerValue : SignedNumber'
5214 # 19 Notation for the enumerated type -----------------------------------------
5217 def p_EnumeratedType (t):
5218 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
5219 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
5221 def p_Enumerations_1 (t):
5222 'Enumerations : Enumeration'
5223 t[0] = { 'val' : t[1], 'ext' : None }
5225 def p_Enumerations_2 (t):
5226 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
5227 t[0] = { 'val' : t[1], 'ext' : [] }
5229 def p_Enumerations_3 (t):
5230 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
5231 t[0] = { 'val' : t[1], 'ext' : t[6] }
5233 def p_Enumeration_1 (t):
5234 'Enumeration : EnumerationItem'
5237 def p_Enumeration_2 (t):
5238 'Enumeration : Enumeration COMMA EnumerationItem'
5239 t[0] = t[1] + [t[3]]
5241 def p_EnumerationItem (t):
5242 '''EnumerationItem : Identifier
5246 def p_Identifier (t):
5247 'Identifier : identifier'
5248 t[0] = Node ('Identifier', ident = t[1])
5251 # 20 Notation for the real type -----------------------------------------------
5259 def p_RealValue (t):
5260 '''RealValue : REAL_NUMBER
5261 | SpecialRealValue'''
5264 def p_SpecialRealValue (t):
5265 '''SpecialRealValue : PLUS_INFINITY
5270 # 21 Notation for the bitstring type ------------------------------------------
5273 def p_BitStringType_1 (t):
5274 'BitStringType : BIT STRING'
5275 t[0] = BitStringType (named_list = None)
5277 def p_BitStringType_2 (t):
5278 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
5279 t[0] = BitStringType (named_list = t[4])
5281 def p_NamedBitList_1 (t):
5282 'NamedBitList : NamedBit'
5285 def p_NamedBitList_2 (t):
5286 'NamedBitList : NamedBitList COMMA NamedBit'
5287 t[0] = t[1] + [t[3]]
5290 '''NamedBit : identifier LPAREN NUMBER RPAREN
5291 | identifier LPAREN DefinedValue RPAREN'''
5292 t[0] = NamedNumber (ident = t[1], val = t[3])
5295 # 22 Notation for the octetstring type ----------------------------------------
5298 def p_OctetStringType (t):
5299 'OctetStringType : OCTET STRING'
5300 t[0] = OctetStringType ()
5303 # 23 Notation for the null type -----------------------------------------------
5311 #def p_NullValue (t):
5312 # 'NullValue : NULL'
5316 # 24 Notation for sequence types ----------------------------------------------
5319 def p_SequenceType_1 (t):
5320 'SequenceType : SEQUENCE LBRACE RBRACE'
5321 t[0] = SequenceType (elt_list = [])
5323 def p_SequenceType_2 (t):
5324 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
5325 if t[3].has_key('ext_list'):
5326 t[0] = SequenceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5328 t[0] = SequenceType (elt_list = t[3]['elt_list'])
5330 def p_ExtensionAndException_1 (t):
5331 'ExtensionAndException : ELLIPSIS'
5334 def p_OptionalExtensionMarker_1 (t):
5335 'OptionalExtensionMarker : COMMA ELLIPSIS'
5338 def p_OptionalExtensionMarker_2 (t):
5339 'OptionalExtensionMarker : '
5342 def p_ComponentTypeLists_1 (t):
5343 'ComponentTypeLists : ComponentTypeList'
5344 t[0] = {'elt_list' : t[1]}
5346 def p_ComponentTypeLists_2 (t):
5347 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException extension_additions OptionalExtensionMarker'
5348 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
5350 def p_ComponentTypeLists_3 (t):
5351 'ComponentTypeLists : ExtensionAndException extension_additions OptionalExtensionMarker'
5352 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
5354 #def p_RootComponentTypeList (t):
5355 # 'RootComponentTypeList : ComponentTypeList'
5358 def p_extension_additions_1 (t):
5359 'extension_additions : extension_addition_list'
5362 def p_extension_additions_2 (t):
5363 'extension_additions : '
5366 def p_extension_addition_list_1 (t):
5367 'extension_addition_list : COMMA extension_addition'
5370 def p_extension_addition_list_2 (t):
5371 'extension_addition_list : extension_addition_list COMMA extension_addition'
5372 t[0] = t[1] + [t[3]]
5374 def p_extension_addition_1 (t):
5375 'extension_addition : ComponentType'
5378 def p_ComponentTypeList_1 (t):
5379 'ComponentTypeList : ComponentType'
5382 def p_ComponentTypeList_2 (t):
5383 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
5384 t[0] = t[1] + [t[3]]
5386 def p_ComponentType_1 (t):
5387 'ComponentType : NamedType'
5388 t[0] = Node ('elt_type', val = t[1], optional = 0)
5390 def p_ComponentType_2 (t):
5391 'ComponentType : NamedType OPTIONAL'
5392 t[0] = Node ('elt_type', val = t[1], optional = 1)
5394 def p_ComponentType_3 (t):
5395 'ComponentType : NamedType DEFAULT DefaultValue'
5396 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
5398 def p_ComponentType_4 (t):
5399 'ComponentType : COMPONENTS OF Type'
5400 t[0] = Node ('components_of', typ = t[3])
5402 def p_DefaultValue_1 (t):
5403 '''DefaultValue : ReferencedValue
5412 def p_DefaultValue_2 (t):
5413 'DefaultValue : lbraceignore rbraceignore'
5417 def p_SequenceValue_1 (t):
5418 'SequenceValue : LBRACE RBRACE'
5422 #def p_SequenceValue_2 (t):
5423 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
5426 #def p_ComponentValueList_1 (t):
5427 # 'ComponentValueList : NamedValue'
5430 #def p_ComponentValueList_2 (t):
5431 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
5432 # t[0] = t[1] + [t[3]]
5435 # 25 Notation for sequence-of types -------------------------------------------
5438 def p_SequenceOfType (t):
5439 '''SequenceOfType : SEQUENCE OF Type
5440 | SEQUENCE OF NamedType'''
5441 t[0] = SequenceOfType (val = t[3], size_constr = None)
5444 # 26 Notation for set types ---------------------------------------------------
5447 def p_SetType_1 (t):
5448 'SetType : SET LBRACE RBRACE'
5449 if t[3].has_key('ext_list'):
5450 t[0] = SetType (elt_list = [])
5452 def p_SetType_2 (t):
5453 'SetType : SET LBRACE ComponentTypeLists RBRACE'
5454 if t[3].has_key('ext_list'):
5455 t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5457 t[0] = SetType (elt_list = t[3]['elt_list'])
5460 # 27 Notation for set-of types ------------------------------------------------
5463 def p_SetOfType (t):
5464 '''SetOfType : SET OF Type
5465 | SET OF NamedType'''
5466 t[0] = SetOfType (val = t[3])
5468 # 28 Notation for choice types ------------------------------------------------
5471 def p_ChoiceType (t):
5472 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
5473 if t[3].has_key('ext_list'):
5474 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
5476 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
5478 def p_alternative_type_lists_1 (t):
5479 'alternative_type_lists : alternative_type_list'
5480 t[0] = {'elt_list' : t[1]}
5482 def p_alternative_type_lists_2 (t):
5483 '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
5484 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
5486 def p_extension_addition_alternatives_1 (t):
5487 'extension_addition_alternatives : extension_addition_alternatives_list'
5490 def p_extension_addition_alternatives_2 (t):
5491 'extension_addition_alternatives : '
5494 def p_extension_addition_alternatives_list_1 (t):
5495 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
5498 def p_extension_addition_alternatives_list_2 (t):
5499 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
5500 t[0] = t[1] + [t[3]]
5502 def p_extension_addition_alternative_1 (t):
5503 'extension_addition_alternative : NamedType'
5506 def p_alternative_type_list_1 (t):
5507 'alternative_type_list : NamedType'
5510 def p_alternative_type_list_2 (t):
5511 'alternative_type_list : alternative_type_list COMMA NamedType'
5512 t[0] = t[1] + [t[3]]
5514 # 29 Notation for selection types
5517 def p_SelectionType (t): #
5518 'SelectionType : identifier LT Type'
5519 t[0] = SelectionType (typ = t[3], sel = t[1])
5521 # 30 Notation for tagged types ------------------------------------------------
5524 def p_TaggedType_1 (t):
5525 'TaggedType : Tag Type'
5526 t[1].mode = 'default'
5530 def p_TaggedType_2 (t):
5531 '''TaggedType : Tag IMPLICIT Type
5532 | Tag EXPLICIT Type'''
5538 'Tag : LBRACK Class ClassNumber RBRACK'
5539 t[0] = Tag(cls = t[2], num = t[3])
5541 def p_ClassNumber_1 (t):
5542 'ClassNumber : number'
5545 def p_ClassNumber_2 (t):
5546 'ClassNumber : DefinedValue'
5550 '''Class : UNIVERSAL
5565 # 31 Notation for the object identifier type ----------------------------------
5568 def p_ObjectIdentifierType (t):
5569 'ObjectIdentifierType : OBJECT IDENTIFIER'
5570 t[0] = ObjectIdentifierType()
5573 def p_ObjectIdentifierValue (t):
5574 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
5575 t[0] = ObjectIdentifierValue (comp_list=t[2])
5577 def p_oid_comp_list_1 (t):
5578 'oid_comp_list : oid_comp_list ObjIdComponents'
5579 t[0] = t[1] + [t[2]]
5581 def p_oid_comp_list_2 (t):
5582 'oid_comp_list : ObjIdComponents'
5585 def p_ObjIdComponents (t):
5586 '''ObjIdComponents : NameForm
5588 | NameAndNumberForm'''
5592 '''NameForm : LCASE_IDENT
5593 | LCASE_IDENT_ASSIGNED'''
5596 def p_NumberForm (t):
5597 '''NumberForm : NUMBER'''
5601 def p_NameAndNumberForm (t):
5602 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
5603 | LCASE_IDENT LPAREN NumberForm RPAREN'''
5604 t[0] = Node('name_and_number', ident = t[1], number = t[3])
5606 # 33 Notation for the embedded-pdv type -------------------------------------------
5608 def p_EmbeddedPDVType (t):
5609 'EmbeddedPDVType : EMBEDDED PDV'
5610 t[0] = EmbeddedPDVType()
5612 # 34 Notation for the external type -------------------------------------------
5615 def p_ExternalType (t):
5616 'ExternalType : EXTERNAL'
5617 t[0] = ExternalType()
5619 # 36 Notation for character string types --------------------------------------
5622 def p_CharacterStringType (t):
5623 '''CharacterStringType : RestrictedCharacterStringType
5624 | UnrestrictedCharacterStringType'''
5628 # 37 Definition of restricted character string types --------------------------
5630 def p_RestrictedCharacterStringType_1 (t):
5631 'RestrictedCharacterStringType : BMPString'
5632 t[0] = BMPStringType ()
5633 def p_RestrictedCharacterStringType_2 (t):
5634 'RestrictedCharacterStringType : GeneralString'
5635 t[0] = GeneralStringType ()
5636 def p_RestrictedCharacterStringType_3 (t):
5637 'RestrictedCharacterStringType : GraphicString'
5638 t[0] = GraphicStringType ()
5639 def p_RestrictedCharacterStringType_4 (t):
5640 'RestrictedCharacterStringType : IA5String'
5641 t[0] = IA5StringType ()
5642 def p_RestrictedCharacterStringType_5 (t):
5643 'RestrictedCharacterStringType : ISO646String'
5644 t[0] = ISO646StringType ()
5645 def p_RestrictedCharacterStringType_6 (t):
5646 'RestrictedCharacterStringType : NumericString'
5647 t[0] = NumericStringType ()
5648 def p_RestrictedCharacterStringType_7 (t):
5649 'RestrictedCharacterStringType : PrintableString'
5650 t[0] = PrintableStringType ()
5651 def p_RestrictedCharacterStringType_8 (t):
5652 'RestrictedCharacterStringType : TeletexString'
5653 t[0] = TeletexStringType ()
5654 def p_RestrictedCharacterStringType_9 (t):
5655 'RestrictedCharacterStringType : T61String'
5656 t[0] = T61StringType ()
5657 def p_RestrictedCharacterStringType_10 (t):
5658 'RestrictedCharacterStringType : UniversalString'
5659 t[0] = UniversalStringType ()
5660 def p_RestrictedCharacterStringType_11 (t):
5661 'RestrictedCharacterStringType : UTF8String'
5662 t[0] = UTF8StringType ()
5663 def p_RestrictedCharacterStringType_12 (t):
5664 'RestrictedCharacterStringType : VideotexString'
5665 t[0] = VideotexStringType ()
5666 def p_RestrictedCharacterStringType_13 (t):
5667 'RestrictedCharacterStringType : VisibleString'
5668 t[0] = VisibleStringType ()
5671 # 40 Definition of unrestricted character string types ------------------------
5674 def p_UnrestrictedCharacterStringType (t):
5675 'UnrestrictedCharacterStringType : CHARACTER STRING'
5676 t[0] = UnrestrictedCharacterStringType ()
5679 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
5681 # 42 Generalized time ---------------------------------------------------------
5683 def p_UsefulType_1 (t):
5684 'UsefulType : GeneralizedTime'
5685 t[0] = GeneralizedTime()
5687 # 43 Universal time -----------------------------------------------------------
5689 def p_UsefulType_2 (t):
5690 'UsefulType : UTCTime'
5693 # 44 The object descriptor type -----------------------------------------------
5695 def p_UsefulType_3 (t):
5696 'UsefulType : ObjectDescriptor'
5697 t[0] = ObjectDescriptor()
5700 # 45 Constrained types --------------------------------------------------------
5703 def p_ConstrainedType_1 (t):
5704 'ConstrainedType : Type Constraint'
5706 t[0].AddConstraint(t[2])
5708 def p_ConstrainedType_2 (t):
5709 'ConstrainedType : TypeWithConstraint'
5713 def p_TypeWithConstraint_1 (t):
5714 '''TypeWithConstraint : SET Constraint OF Type
5715 | SET SizeConstraint OF Type'''
5716 t[0] = SetOfType (val = t[4], constr = t[2])
5718 def p_TypeWithConstraint_2 (t):
5719 '''TypeWithConstraint : SEQUENCE Constraint OF Type
5720 | SEQUENCE SizeConstraint OF Type'''
5721 t[0] = SequenceOfType (val = t[4], constr = t[2])
5723 def p_TypeWithConstraint_3 (t):
5724 '''TypeWithConstraint : SET Constraint OF NamedType
5725 | SET SizeConstraint OF NamedType'''
5726 t[0] = SetOfType (val = t[4], constr = t[2])
5728 def p_TypeWithConstraint_4 (t):
5729 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
5730 | SEQUENCE SizeConstraint OF NamedType'''
5731 t[0] = SequenceOfType (val = t[4], constr = t[2])
5735 def p_Constraint (t):
5736 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
5739 def p_ConstraintSpec (t):
5740 '''ConstraintSpec : ElementSetSpecs
5741 | GeneralConstraint'''
5744 # 46 Element set specification ------------------------------------------------
5747 def p_ElementSetSpecs_1 (t):
5748 'ElementSetSpecs : RootElementSetSpec'
5751 def p_ElementSetSpecs_2 (t):
5752 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
5756 def p_ElementSetSpecs_3 (t):
5757 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
5761 def p_RootElementSetSpec (t):
5762 'RootElementSetSpec : ElementSetSpec'
5765 def p_AdditionalElementSetSpec (t):
5766 'AdditionalElementSetSpec : ElementSetSpec'
5769 def p_ElementSetSpec (t):
5770 'ElementSetSpec : Unions'
5774 'Unions : Intersections'
5778 'Unions : UElems UnionMark Intersections'
5779 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
5785 def p_Intersections_1 (t):
5786 'Intersections : IntersectionElements'
5789 def p_Intersections_2 (t):
5790 'Intersections : IElems IntersectionMark IntersectionElements'
5791 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
5794 'IElems : Intersections'
5797 def p_IntersectionElements (t):
5798 'IntersectionElements : SubtypeElements'
5801 def p_UnionMark (t):
5805 def p_IntersectionMark (t):
5806 '''IntersectionMark : CIRCUMFLEX
5809 # 47 Subtype elements ---------------------------------------------------------
5812 def p_SubtypeElements (t):
5813 '''SubtypeElements : SingleValue
5819 | InnerTypeConstraints
5820 | PatternConstraint'''
5825 def p_SingleValue (t):
5826 'SingleValue : Value'
5827 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
5829 # 47.3 Contained subtype
5831 def p_ContainedSubtype (t):
5832 'ContainedSubtype : Includes Type'
5833 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
5836 '''Includes : INCLUDES
5841 def p_ValueRange (t):
5842 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
5843 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
5846 def p_LowerEndpoint_1 (t):
5847 'LowerEndpoint : LowerEndValue'
5850 def p_LowerEndpoint_2 (t):
5851 'LowerEndpoint : LowerEndValue LT'
5852 t[0] = t[1] # but not inclusive range
5854 def p_UpperEndpoint_1 (t):
5855 'UpperEndpoint : UpperEndValue'
5858 def p_UpperEndpoint_2 (t):
5859 'UpperEndpoint : LT UpperEndValue'
5860 t[0] = t[1] # but not inclusive range
5863 def p_LowerEndValue (t):
5864 '''LowerEndValue : Value
5868 def p_UpperEndValue (t):
5869 '''UpperEndValue : Value
5873 # 47.5 Size constraint
5875 def p_SizeConstraint (t):
5876 'SizeConstraint : SIZE Constraint'
5877 t[0] = Constraint (type = 'Size', subtype = t[2])
5879 # 47.6 Type constraint
5881 def p_TypeConstraint (t):
5882 'TypeConstraint : Type'
5883 t[0] = Constraint (type = 'Type', subtype = t[1])
5885 # 47.7 Permitted alphabet
5887 def p_PermittedAlphabet (t):
5888 'PermittedAlphabet : FROM Constraint'
5889 t[0] = Constraint (type = 'From', subtype = t[2])
5891 # 47.8 Inner subtyping
5893 def p_InnerTypeConstraints (t):
5894 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
5895 | WITH COMPONENTS MultipleTypeConstraints'''
5896 pass # ignore PER invisible constraint
5899 def p_SingleTypeConstraint (t):
5900 'SingleTypeConstraint : Constraint'
5904 def p_MultipleTypeConstraints (t):
5905 '''MultipleTypeConstraints : FullSpecification
5906 | PartialSpecification'''
5909 def p_FullSpecification (t):
5910 'FullSpecification : LBRACE TypeConstraints RBRACE'
5913 def p_PartialSpecification (t):
5914 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
5917 def p_TypeConstraints_1 (t):
5918 'TypeConstraints : named_constraint'
5921 def p_TypeConstraints_2 (t):
5922 'TypeConstraints : TypeConstraints COMMA named_constraint'
5923 t[0] = t[1] + [t[3]]
5925 def p_named_constraint_1 (t):
5926 'named_constraint : identifier constraint'
5927 return Node ('named_constraint', ident = t[1], constr = t[2])
5929 def p_named_constraint_2 (t):
5930 'named_constraint : constraint'
5931 return Node ('named_constraint', constr = t[1])
5933 def p_constraint (t):
5934 'constraint : value_constraint presence_constraint'
5935 t[0] = Node ('constraint', value = t[1], presence = t[2])
5937 def p_value_constraint_1 (t):
5938 'value_constraint : Constraint'
5941 def p_value_constraint_2 (t):
5942 'value_constraint : '
5945 def p_presence_constraint_1 (t):
5946 '''presence_constraint : PRESENT
5951 def p_presence_constraint_2 (t):
5952 '''presence_constraint : '''
5955 # 47.9 Pattern constraint
5957 def p_PatternConstraint (t):
5958 'PatternConstraint : PATTERN Value'
5959 t[0] = Constraint (type = 'Pattern', subtype = t[2])
5961 # 49 The exception identifier
5964 def p_ExceptionSpec (t):
5968 # /*-----------------------------------------------------------------------*/
5969 # /* Value Notation Productions */
5970 # /*-----------------------------------------------------------------------*/
5974 def p_binary_string (t):
5975 'binary_string : BSTRING'
5976 t[0] = BStringValue(val = t[1])
5978 def p_hex_string (t):
5979 'hex_string : HSTRING'
5982 def p_char_string (t):
5983 'char_string : QSTRING'
5991 #--- ITU-T Recommendation X.681 -----------------------------------------------
5993 # 7 ASN.1 lexical items -------------------------------------------------------
5995 # 7.1 Information object class references
5997 def p_objectclassreference (t):
5998 'objectclassreference : CLASS_IDENT'
5999 t[0] = Class_Ref(val=t[1])
6001 # 7.2 Information object references
6003 def p_objectreference (t):
6004 'objectreference : LCASE_IDENT'
6007 # 7.3 Information object set references
6009 def p_objectsetreference (t):
6010 'objectsetreference : UCASE_IDENT'
6013 # 7.4 Type field references
6015 def p_typefieldreference (t):
6016 'typefieldreference : AMPERSAND UCASE_IDENT'
6019 # 7.5 Value field references
6021 def p_valuefieldreference (t):
6022 'valuefieldreference : AMPERSAND LCASE_IDENT'
6025 # 8 Referencing definitions
6028 def p_DefinedObjectClass (t):
6029 '''DefinedObjectClass : objectclassreference
6030 | UsefulObjectClassReference'''
6033 def p_DefinedObject (t):
6034 '''DefinedObject : objectreference'''
6038 def p_UsefulObjectClassReference (t):
6039 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6040 | ABSTRACT_SYNTAX'''
6043 # 9 Information object class definition and assignment
6046 def p_ObjectClassAssignment (t):
6047 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6048 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6053 def p_ObjectClass (t):
6054 '''ObjectClass : ObjectClassDefn'''
6058 def p_ObjectClassDefn (t):
6059 '''ObjectClassDefn : CLASS lbraceignore rbraceignore
6060 | CLASS lbraceignore rbraceignore WithSyntaxSpec'''
6061 t[0] = ObjectClass()
6063 def p_WithSyntaxSpec (t):
6064 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
6068 def p_FieldName (t):
6069 '''FieldName : typefieldreference
6070 | valuefieldreference'''
6073 # 11 Information object definition and assignment
6076 def p_ObjectAssignment (t):
6077 'ObjectAssignment : objectreference CLASS_IDENT ASSIGNMENT Object'
6078 t[0] = Node('ObjectAssignment', name=t[1], cls=t[2], val=t[4])
6082 '''Object : DefinedObject
6087 def p_ObjectDefn (t):
6088 'ObjectDefn : lbraceignore rbraceignore'
6091 # 12 Information object set definition and assignment
6094 def p_ObjectSetAssignment (t):
6095 'ObjectSetAssignment : objectsetreference CLASS_IDENT ASSIGNMENT ObjectSet'
6096 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
6099 def p_ObjectSet (t):
6100 'ObjectSet : lbraceignore rbraceignore'
6103 # 14 Notation for the object class field type ---------------------------------
6106 def p_ObjectClassFieldType (t):
6107 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
6108 t[0] = get_type_from_class(t[1], t[3])
6110 useful_object_class_types = {
6112 'TYPE-IDENTIFIER/id' : lambda : ObjectIdentifierType(),
6113 'TYPE-IDENTIFIER/Type' : lambda : OpenType(),
6115 'ABSTRACT-SYNTAX/id' : lambda : ObjectIdentifierType(),
6116 'ABSTRACT-SYNTAX/Type' : lambda : OpenType(),
6117 'ABSTRACT-SYNTAX/property' : lambda : BitStringType(),
6120 object_class_types = { }
6122 object_class_typerefs = { }
6124 class_types_creator = {
6125 'IntegerType' : lambda : IntegerType(),
6126 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
6127 'OpenType' : lambda : OpenType(),
6132 def is_class_ident(name):
6133 return class_names.has_key(name)
6135 def add_class_ident(name):
6136 class_names[name] = name
6138 def get_type_from_class(cls, fld):
6139 if (isinstance(cls, Class_Ref)):
6140 key = cls.val + '/' + fld
6142 key = cls + '/' + fld
6144 if object_class_typerefs.has_key(key):
6145 return Type_Ref(val=object_class_typerefs[key])
6147 creator = lambda : AnyType()
6148 creator = useful_object_class_types.get(key, creator)
6149 creator = object_class_types.get(key, creator)
6152 def set_type_to_class(cls, fld, typename, typeref = None):
6153 key = cls + '/' + fld
6154 if object_class_types.has_key(key): return False
6155 if object_class_typerefs.has_key(key): return False
6157 if (typename == 'TypeReference'):
6158 if not typeref: return False
6159 object_class_typerefs[key] = typeref
6162 creator = class_types_creator.get(typename)
6164 object_class_types[key] = creator
6169 #--- ITU-T Recommendation X.682 -----------------------------------------------
6171 # 8 General constraint specification ------------------------------------------
6174 def p_GeneralConstraint (t):
6175 '''GeneralConstraint : UserDefinedConstraint
6177 | ContentsConstraint'''
6180 # 9 User-defined constraints --------------------------------------------------
6183 def p_UserDefinedConstraint (t):
6184 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
6185 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
6187 def p_UserDefinedConstraintParameterList_1 (t):
6188 'UserDefinedConstraintParameterList : '
6191 def p_UserDefinedConstraintParameterList_2 (t):
6192 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
6195 def p_UserDefinedConstraintParameterList_3 (t):
6196 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
6197 t[0] = t[1] + [t[3]]
6200 def p_UserDefinedConstraintParameter (t):
6201 'UserDefinedConstraintParameter : type_ref'
6204 # 10 Table constraints, including component relation constraints --------------
6207 def p_TableConstraint (t):
6208 '''TableConstraint : SimpleTableConstraint
6209 | ComponentRelationConstraint'''
6210 t[0] = Constraint(type = 'Table', subtype = t[1])
6212 def p_SimpleTableConstraint (t):
6213 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
6217 def p_ComponentRelationConstraint (t):
6218 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AT LCASE_IDENT RBRACE'
6219 t[0] = t[2] + '@' + t[6]
6221 # 11 Contents constraints -----------------------------------------------------
6224 def p_ContentsConstraint (t):
6225 'ContentsConstraint : CONTAINING type_ref'
6226 t[0] = Constraint(type = 'Contents', subtype = t[2])
6229 #--- ITU-T Recommendation X.683 -----------------------------------------------
6231 # 8 Parameterized assignments -------------------------------------------------
6236 def p_ParameterizedTypeAssignment (t):
6237 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
6239 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
6242 def p_ParameterList (t):
6243 'ParameterList : lbraceignore rbraceignore'
6245 #def p_ParameterList (t):
6246 # 'ParameterList : LBRACE Parameters RBRACE'
6249 #def p_Parameters_1 (t):
6250 # 'Parameters : Parameter'
6253 #def p_Parameters_2 (t):
6254 # 'Parameters : Parameters COMMA Parameter'
6255 # t[0] = t[1] + [t[3]]
6257 #def p_Parameter_1 (t):
6258 # 'Parameter : Type COLON Reference'
6259 # t[0] = [t[1], t[3]]
6261 #def p_Parameter_2 (t):
6262 # 'Parameter : Reference'
6266 # 9 Referencing parameterized definitions -------------------------------------
6269 def p_ParameterizedReference (t):
6270 'ParameterizedReference : type_ref LBRACE RBRACE'
6275 def p_ParameterizedType (t):
6276 'ParameterizedType : type_ref ActualParameterList'
6281 def p_ActualParameterList (t):
6282 'ActualParameterList : lbraceignore rbraceignore'
6284 #def p_ActualParameterList (t):
6285 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
6288 #def p_ActualParameters_1 (t):
6289 # 'ActualParameters : ActualParameter'
6292 #def p_ActualParameters_2 (t):
6293 # 'ActualParameters : ActualParameters COMMA ActualParameter'
6294 # t[0] = t[1] + [t[3]]
6296 #def p_ActualParameter (t):
6297 # '''ActualParameter : Type
6302 #--- ITU-T Recommendation X.880 -----------------------------------------------
6306 'ARGUMENT' : 'ARGUMENT',
6307 'RESULT' : 'RESULT',
6308 'RETURN' : 'RETURN',
6309 'ERRORS' : 'ERRORS',
6310 'LINKED' : 'LINKED',
6311 'SYNCHRONOUS' : 'SYNCHRONOUS',
6312 'IDEMPOTENT' : 'IDEMPOTENT',
6313 'ALWAYS' : 'ALWAYS',
6314 'RESPONDS' : 'RESPONDS',
6315 'INVOKE' : 'INVOKE',
6316 'PRIORITY' : 'PRIORITY',
6317 'RESULT-PRIORITY': 'RESULT-PRIORITY',
6322 'OPERATION-PACKAGE' : {
6324 'CONNECTION-PACKAGE' : {
6328 'ROS-OBJECT-CLASS' : {
6333 x880_syntaxes_enabled = { }
6334 x880_current_syntaxes = None
6336 def x880_import(name):
6337 if x880_syntaxes.has_key(name):
6338 x880_syntaxes_enabled[name] = True
6339 add_class_ident(name)
6341 def is_x880_syntax(name):
6345 #def p_lbrace_oid(t):
6346 # 'lbrace_oid : brace_oid_begin LBRACE'
6349 #def p_brace_oid_begin(t):
6350 # 'brace_oid_begin : '
6354 #def p_rbrace_oid(t):
6355 # 'rbrace_oid : brace_oid_end RBRACE'
6358 #def p_brace_oid_end(t):
6359 # 'brace_oid_end : '
6363 # {...} block to be ignored
6364 def p_lbraceignore(t):
6365 'lbraceignore : braceignorebegin LBRACE'
6368 def p_braceignorebegin(t):
6369 'braceignorebegin : '
6372 lexer.begin('braceignore')
6374 def p_rbraceignore(t):
6375 'rbraceignore : braceignoreend RBRACE'
6378 def p_braceignoreend(t):
6381 lexer.begin('INITIAL')
6385 raise ParseError(t, input_file)
6388 '''pyquote : PYQUOTE'''
6389 t[0] = PyQuote (val = t[1])
6395 token = lexer.token ()
6401 def do_module (ast, defined_dict):
6402 assert (ast.type == 'Module')
6403 ctx = Ctx (defined_dict)
6404 print ast.to_python (ctx)
6405 print ctx.output_assignments ()
6406 print ctx.output_pyquotes ()
6408 def eth_do_module (ast, ectx):
6409 assert (ast.type == 'Module')
6410 if ectx.dbg('s'): print ast.str_depth(0)
6413 def testyacc(s, fn, defined_dict):
6414 ast = yacc.parse(s, debug=0)
6415 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
6416 print """#!/usr/bin/env python
6417 # Auto-generated from %s at %s
6418 from PyZ3950 import asn1""" % (fn, time_str)
6420 eth_do_module (module, defined_dict)
6423 # Wireshark compiler
6426 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c conform_file] [-e] input_file(s) ...
6428 -b : BER (default is PER)
6429 -u : unaligned (default is aligned)
6430 -p proto : protocol name (implies -S)
6431 default is module-name from input_file (renamed by #.MODULE if present)
6432 -F : create 'field functions'
6433 -T : tagged type support (experimental)
6434 -o name : output files name core (default is <proto>)
6435 -O dir : output directory
6436 -c conform_file : conformation file
6437 -I path : path for conformance file includes
6438 -e : create conformation file for exported types
6439 -S : single output for multiple modules
6440 -s template : single file output (template is input file without .c/.h extension)
6441 -k : keep intermediate files though single file output is used
6442 -L : suppress #line directive from .cnf file
6443 input_file(s) : input ASN.1 file(s)
6445 -d dbg : debug output, dbg = [l][y][p][s][a][t][c][m][o]
6449 s - internal ASN.1 structure
6450 a - list of assignments
6452 c - conformance values
6453 m - list of compiled modules with dependency
6454 o - list of output files
6460 print "ASN.1 to Wireshark dissector compiler";
6462 opts, args = getopt.getopt(sys.argv[1:], "h?d:buXp:FTo:O:c:I:eSs:kL");
6463 except getopt.GetoptError:
6464 eth_usage(); sys.exit(2)
6466 eth_usage(); sys.exit(2)
6471 ectx = EthCtx(conform, output)
6472 ectx.encoding = 'per'
6473 ectx.proto_opt = None
6475 ectx.tag_opt = False
6476 ectx.outnm_opt = None
6481 ectx.merge_modules = False
6482 ectx.conform.suppress_line = False;
6483 ectx.output.outnm = None
6484 ectx.output.single_file = None
6486 if o in ("-h", "-?"):
6487 eth_usage(); sys.exit(2)
6491 ectx.conform.include_path.append(a)
6493 # warnings.warn("Command line option -X is obsolete and can be removed")
6496 ectx.conform.read(conf_to_read)
6499 if o in ("-h", "-?", "-c", "-I"):
6500 pass # already processed
6504 ectx.conform.set_opt(o, par, "commandline", 0)
6506 (ld, yd, pd) = (0, 0, 0);
6507 if ectx.dbg('l'): ld = 1
6508 if ectx.dbg('y'): yd = 1
6509 if ectx.dbg('p'): pd = 2
6510 lexer = lex.lex(debug=ld)
6511 yacc.yacc(method='LALR', debug=yd)
6517 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
6521 eth_do_module(module, ectx)
6522 if (not ectx.merge_modules): # output for each module
6524 ectx.eth_do_output()
6526 if (ectx.merge_modules): # common output for all module
6528 ectx.eth_do_output()
6534 ectx.conform.dbg_print()
6535 ectx.conform.unused_report()
6538 ectx.output.dbg_print()
6539 ectx.output.make_single_file()
6545 if len (sys.argv) == 1:
6547 s = raw_input ('Query: ')
6550 testfn (s, 'console', {})
6553 for fn in sys.argv [1:]:
6555 testfn (f.read (), fn, defined_dict)
6560 #--- BODY ---------------------------------------------------------------------
6562 if __name__ == '__main__':
6563 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
6568 #------------------------------------------------------------------------------