5 # ASN.1 to Wireshark dissector compiler
6 # Copyright 2004 Tomas Kukosa
10 # Permission is hereby granted, free of charge, to any person obtaining a
11 # copy of this software and associated documentation files (the
12 # "Software"), to deal in the Software without restriction, including
13 # without limitation the rights to use, copy, modify, merge, publish,
14 # distribute, and/or sell copies of the Software, and to permit persons
15 # to whom the Software is furnished to do so, provided that the above
16 # copyright notice(s) and this permission notice appear in all copies of
17 # the Software and that both the above copyright notice(s) and this
18 # permission notice appear in supporting documentation.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
23 # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
25 # INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
26 # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
27 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
28 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 # Except as contained in this notice, the name of a copyright holder
31 # shall not be used in advertising or otherwise to promote the sale, use
32 # or other dealings in this Software without prior written authorization
33 # of the copyright holder.
36 """ASN.1 to Wireshark dissector compiler"""
39 # Compiler from ASN.1 specification to the Wireshark dissector
41 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
42 # http://www.pobox.com/~asl2/software/PyZ3950/
43 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
45 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
46 # http://www.dabeaz.com/ply/
49 # ITU-T Recommendation X.680 (07/2002),
50 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
52 # ITU-T Recommendation X.681 (07/2002),
53 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
55 # ITU-T Recommendation X.682 (07/2002),
56 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
58 # ITU-T Recommendation X.683 (07/2002),
59 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
61 # ITU-T Recommendation X.880 (07/1994),
62 # Information technology - Remote Operations: Concepts, model and notation
78 from functools import partial
80 if sys.version_info[0] < 3:
81 from string import maketrans
84 # OID name -> number conversion table
90 '0/recommendation' : 0,
119 '0/administration' : 2,
120 '0/network-operator' : 3,
121 '0/identified-organization' : 4,
122 '0/r-recommendation' : 5,
126 '1/registration-authority' : 1,
128 '1/identified-organization' : 3,
129 '/joint-iso-itu-t' : 2,
130 '/joint-iso-ccitt' : 2,
131 '2/presentation' : 0,
133 '2/association-control' : 2,
134 '2/reliable-transfer' : 3,
135 '2/remote-operations' : 4,
143 '2/osi-management' : 9,
144 '2/transaction-processing' : 10,
146 '2/distinguished-object-reference' : 11,
147 '2/reference-data-transfe' : 12,
148 '2/network-layer' : 13,
149 '2/network-layer-management' : 13,
150 '2/transport-layer' : 14,
151 '2/transport-layer-management' : 14,
152 '2/datalink-layer' : 15,
153 '2/datalink-layer-managemen' : 15,
154 '2/datalink-layer-management-information' : 15,
156 '2/registration-procedures' : 17,
157 '2/registration-procedure' : 17,
158 '2/physical-layer' : 18,
159 '2/physical-layer-management' : 18,
162 '2/generic-upper-layers-security' : 20,
164 '2/transport-layer-security-protocol' : 21,
165 '2/network-layer-security-protocol' : 22,
166 '2/international-organizations' : 23,
167 '2/internationalRA' : 23,
174 ITEM_FIELD_NAME = '_item'
175 UNTAG_TYPE_NAME = '_untag'
178 return id.replace('-', '_').replace('.', '_').replace('&', '_')
185 class LexError(Exception):
186 def __init__(self, tok, filename=None):
188 self.filename = filename
189 self.msg = "Unexpected character %r" % (self.tok.value[0])
190 Exception.__init__(self, self.msg)
192 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
196 class ParseError(Exception):
197 def __init__(self, tok, filename=None):
199 self.filename = filename
200 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
201 Exception.__init__(self, self.msg)
203 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
207 class DuplicateError(Exception):
208 def __init__(self, type, ident):
211 self.msg = "Duplicate %s for %s" % (self.type, self.ident)
212 Exception.__init__(self, self.msg)
217 class CompError(Exception):
218 def __init__(self, msg):
220 Exception.__init__(self, self.msg)
227 ('braceignore','exclusive'),
231 ('left', 'UNION', 'BAR'),
232 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
234 # 11 ASN.1 lexical items
237 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
238 r'\.\.' : 'RANGE', # 11.17 Range separator
239 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
240 r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
241 r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
242 # 11.26 Single character lexical items
257 #r"'" : 'APOSTROPHE',
260 r'\!' : 'EXCLAMATION',
261 r'\^' : 'CIRCUMFLEX',
266 # 11.27 Reserved words
268 # all keys in reserved_words must start w/ upper case
271 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
273 'APPLICATION' : 'APPLICATION',
274 'AUTOMATIC' : 'AUTOMATIC',
277 'BOOLEAN' : 'BOOLEAN',
279 'CHARACTER' : 'CHARACTER',
282 'COMPONENT' : 'COMPONENT',
283 'COMPONENTS' : 'COMPONENTS',
284 'CONSTRAINED' : 'CONSTRAINED',
285 'CONTAINING' : 'CONTAINING',
286 'DEFAULT' : 'DEFAULT',
287 'DEFINITIONS' : 'DEFINITIONS',
288 'EMBEDDED' : 'EMBEDDED',
289 # 'ENCODED' : 'ENCODED',
291 'ENUMERATED' : 'ENUMERATED',
292 # 'EXCEPT' : 'EXCEPT',
293 'EXPLICIT' : 'EXPLICIT',
294 'EXPORTS' : 'EXPORTS',
295 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
296 'EXTERNAL' : 'EXTERNAL',
299 'GeneralizedTime' : 'GeneralizedTime',
300 'IDENTIFIER' : 'IDENTIFIER',
301 'IMPLICIT' : 'IMPLICIT',
302 # 'IMPLIED' : 'IMPLIED',
303 'IMPORTS' : 'IMPORTS',
304 'INCLUDES' : 'INCLUDES',
305 'INSTANCE' : 'INSTANCE',
306 'INTEGER' : 'INTEGER',
307 'INTERSECTION' : 'INTERSECTION',
310 'MINUS-INFINITY' : 'MINUS_INFINITY',
313 'ObjectDescriptor' : 'ObjectDescriptor',
316 'OPTIONAL' : 'OPTIONAL',
317 'PATTERN' : 'PATTERN',
319 'PLUS-INFINITY' : 'PLUS_INFINITY',
320 'PRESENT' : 'PRESENT',
321 'PRIVATE' : 'PRIVATE',
323 'RELATIVE-OID' : 'RELATIVE_OID',
324 'SEQUENCE' : 'SEQUENCE',
331 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
334 'UNIVERSAL' : 'UNIVERSAL',
335 'UTCTime' : 'UTCTime',
337 # X.208 obsolete but still used
339 'DEFINED' : 'DEFINED',
342 for k in list(static_tokens.keys()):
343 if static_tokens [k] == None:
344 static_tokens [k] = k
346 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
347 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
350 for s in StringTypes:
351 reserved_words[s + 'String'] = s + 'String'
353 tokens = list(static_tokens.values()) \
354 + list(reserved_words.values()) \
355 + ['BSTRING', 'HSTRING', 'QSTRING',
356 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
357 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
360 cur_mod = __import__ (__name__) # XXX blech!
362 for (k, v) in list(static_tokens.items ()):
363 cur_mod.__dict__['t_' + v] = k
365 # 11.10 Binary strings
370 # 11.12 Hexadecimal strings
379 def t_UCASE_IDENT (t):
380 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
381 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
382 if (is_class_syntax(t.value)): t.type = t.value
383 t.type = reserved_words.get(t.value, t.type)
386 lcase_ident_assigned = {}
387 def t_LCASE_IDENT (t):
388 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
389 if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED'
393 def t_REAL_NUMBER (t):
394 r"[0-9]+\.[0-9]*(?!\.)"
403 pyquote_str = 'PYQUOTE'
405 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
406 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
407 if t.value[2:2+len (pyquote_str)] == pyquote_str:
408 t.value = t.value[2+len(pyquote_str):]
409 t.value = t.value.lstrip ()
418 t.lexer.lineno += t.value.count("\n")
422 raise LexError(t, input_file)
424 # state 'braceignore'
426 def t_braceignore_lbrace(t):
430 def t_braceignore_rbrace(t):
433 # If closing brace, return token
434 if t.lexer.level == 0:
438 def t_braceignore_QSTRING (t):
440 t.lexer.lineno += t.value.count("\n")
442 def t_braceignore_COMMENT(t):
443 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
444 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
446 def t_braceignore_nonspace(t):
447 r'[^\s\{\}\"-]+|-(?!-)'
449 t_braceignore_ignore = " \t\r"
451 def t_braceignore_NEWLINE(t):
453 t.lexer.lineno += t.value.count("\n")
455 def t_braceignore_error(t):
459 def __init__ (self, defined_dict, indent = 0):
460 self.tags_def = 'EXPLICIT' # default = explicit
462 self.assignments = {}
463 self.dependencies = {}
465 self.defined_dict = defined_dict
468 return " " * (4 * self.indent_lev)
473 assert (self.indent_lev >= 0)
474 def register_assignment (self, ident, val, dependencies):
475 if ident in self.assignments:
476 raise DuplicateError("assignment", ident)
477 if ident in self.defined_dict:
478 raise Exception("cross-module duplicates for %s" % ident)
479 self.defined_dict [ident] = 1
480 self.assignments[ident] = val
481 self.dependencies [ident] = dependencies
483 # return "#%s depends on %s" % (ident, str (dependencies))
484 def register_pyquote (self, val):
485 self.pyquotes.append (val)
487 def output_assignments (self):
490 assign_keys = list(self.assignments.keys())
491 to_output_count = len (assign_keys)
494 for (ident, val) in list(self.assignments.items ()):
495 if ident in already_output:
498 for d in self.dependencies [ident]:
499 if ((d not in already_output) and
503 text_list.append ("%s=%s" % (ident,
504 self.assignments [ident]))
505 already_output [ident] = 1
508 assert (to_output_count >= 0)
510 if to_output_count == 0:
512 # OK, we detected a cycle
514 for ident in list(self.assignments.keys ()):
515 if ident not in already_output:
516 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
517 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
519 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
520 for (ident, val) in list(self.assignments.items ()):
521 if ident not in already_output:
522 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
525 return "\n".join (text_list)
526 def output_pyquotes (self):
527 return "\n".join (self.pyquotes)
528 def make_new_name (self):
530 return "_compiler_generated_name_%d" % (self.name_ctr,)
532 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
536 EF_WS_DLL = 0x0010 # exported from shared library
545 #--- common dependency computation ---
546 # Input : list of items
547 # dictionary with lists of dependency
550 # Output : list of two outputs:
551 # [0] list of items in dependency
552 # [1] list of cycle dependency cycles
553 def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
556 x = {} # already emitted
557 #print '# Dependency computation'
560 #print 'Continue: %s : %s' % (t, (map_fn(t))
563 stackx = {t : dependency.get(t, [])[:]}
564 #print 'Push: %s : %s' % (t, str(stackx[t]))
566 if stackx[stack[-1]]: # has dependencies
567 d = stackx[stack[-1]].pop(0)
568 if map_fn(d) in x or ignore_fn(d):
570 if d in stackx: # cyclic dependency
573 c = [d] + c[0:c.index(d)+1]
576 #print 'Cyclic: %s ' % (' -> '.join(c))
579 stackx[d] = dependency.get(d, [])[:]
580 #print 'Push: %s : %s' % (d, str(stackx[d]))
582 #print 'Pop: %s' % (stack[-1])
583 del stackx[stack[-1]]
584 e = map_fn(stack.pop())
587 #print 'Add: %s' % (e)
590 return (item_ord, item_cyc)
592 # Given a filename, return a relative path from epan/dissectors
593 def rel_dissector_path(filename):
594 path_parts = os.path.abspath(filename).split(os.sep)
595 while (len(path_parts) > 3 and path_parts[0] != 'asn1'):
597 path_parts.insert(0, '..')
598 path_parts.insert(0, '..')
599 return '/'.join(path_parts)
602 #--- EthCtx -------------------------------------------------------------------
604 def __init__(self, conform, output, indent = 0):
605 self.conform = conform
607 self.conform.ectx = self
608 self.output.ectx = self
609 self.encoding = 'per'
611 self.default_oid_variant = ''
612 self.default_opentype_variant = ''
613 self.default_containing_variant = '_pdu_new'
614 self.default_embedded_pdv_cb = None
615 self.default_external_type_cb = None
616 self.remove_prefix = None
618 self.emitted_pdu = {}
621 self.all_type_attr = {}
625 def encp(self): # encoding protocol
630 def Per(self): return self.encoding == 'per'
631 def Ber(self): return self.encoding == 'ber'
632 def Aligned(self): return self.aligned
633 def Unaligned(self): return not self.aligned
634 def NeedTags(self): return self.tag_opt or self.Ber()
635 def NAPI(self): return False # disable planned features
637 def Module(self): # current module name
638 return self.modules[-1][0]
641 return self.group_by_prot or (self.conform.last_group > 0)
644 if (self.dbgopt.find(d) >= 0):
649 def value_max(self, a, b):
650 if (a == 'MAX') or (b == 'MAX'): return 'MAX';
651 if a == 'MIN': return b;
652 if b == 'MIN': return a;
654 if (int(a) > int(b)):
658 except (ValueError, TypeError):
660 return "MAX((%s),(%s))" % (a, b)
662 def value_min(self, a, b):
663 if (a == 'MIN') or (b == 'MIN'): return 'MIN';
664 if a == 'MAX': return b;
665 if b == 'MAX': return a;
667 if (int(a) < int(b)):
671 except (ValueError, TypeError):
673 return "MIN((%s),(%s))" % (a, b)
675 def value_get_eth(self, val):
676 if isinstance(val, Value):
677 return val.to_str(self)
679 if val in self.value:
680 ethname = self.value[val]['ethname']
683 def value_get_val(self, nm):
686 if self.value[nm]['import']:
687 v = self.get_val_from_all(nm, self.value[nm]['import'])
689 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
690 warnings.warn_explicit(msg, UserWarning, '', 0)
694 val = self.value[nm]['value']
695 if isinstance (val, Value):
696 val = val.to_str(self)
698 msg = 'Need value of unknown value identifier %s' % (nm)
699 warnings.warn_explicit(msg, UserWarning, '', 0)
702 def eth_get_type_attr(self, type):
703 #print "eth_get_type_attr(%s)" % (type)
705 while (not self.type[type]['import']):
706 val = self.type[type]['val']
709 while (val.type == 'TaggedType'):
711 ttype += '/' + UNTAG_TYPE_NAME
712 if (val.type != 'Type_Ref'):
722 if (self.type[t]['import']):
723 attr.update(self.type[t]['attr'])
724 attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import']))
725 elif (self.type[t]['val'].type == 'SelectionType'):
726 val = self.type[t]['val']
727 (ftype, display) = val.eth_ftype(self)
728 attr.update({ 'TYPE' : ftype, 'DISPLAY' : display,
729 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' });
731 attr.update(self.type[t]['attr'])
732 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
736 def eth_get_type_attr_from_all(self, type, module):
738 if module in self.all_type_attr and type in self.all_type_attr[module]:
739 attr = self.all_type_attr[module][type]
742 def get_ttag_from_all(self, type, module):
744 if module in self.all_tags and type in self.all_tags[module]:
745 ttag = self.all_tags[module][type]
748 def get_val_from_all(self, nm, module):
750 if module in self.all_vals and nm in self.all_vals[module]:
751 val = self.all_vals[module][nm]
754 def get_obj_repr(self, ident, flds=[], not_flds=[]):
755 def set_type_fn(cls, field, fnfield):
756 obj[fnfield + '_fn'] = 'NULL'
757 obj[fnfield + '_pdu'] = 'NULL'
758 if field in val and isinstance(val[field], Type_Ref):
759 p = val[field].eth_type_default_pars(self, '')
760 obj[fnfield + '_fn'] = p['TYPE_REF_FN']
761 obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration
762 if (self.conform.check_item('PDU', cls + '.' + field)):
763 obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
765 # end of get_type_fn()
766 obj = { '_name' : ident, '_ident' : asn2c(ident)}
767 obj['_class'] = self.oassign[ident].cls
768 obj['_module'] = self.oassign[ident].module
769 val = self.oassign[ident].val
776 for f in list(val.keys()):
777 if isinstance(val[f], Node):
778 obj[f] = val[f].fld_obj_repr(self)
781 if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
782 set_type_fn(obj['_class'], '&Type', '_type')
783 if (obj['_class'] == 'OPERATION'):
784 set_type_fn(obj['_class'], '&ArgumentType', '_argument')
785 set_type_fn(obj['_class'], '&ResultType', '_result')
786 if (obj['_class'] == 'ERROR'):
787 set_type_fn(obj['_class'], '&ParameterType', '_parameter')
790 #--- eth_reg_module -----------------------------------------------------------
791 def eth_reg_module(self, module):
792 #print "eth_reg_module(module='%s')" % (module)
793 name = module.get_name()
794 self.modules.append([name, module.get_proto(self)])
795 if name in self.module:
796 raise DuplicateError("module", name)
797 self.module[name] = []
798 self.module_ord.append(name)
800 #--- eth_module_dep_add ------------------------------------------------------------
801 def eth_module_dep_add(self, module, dep):
802 self.module[module].append(dep)
804 #--- eth_exports ------------------------------------------------------------
805 def eth_exports(self, exports):
806 self.exports_all = False
807 if ((len(exports) == 1) and (exports[0] == 'ALL')):
808 self.exports_all = True
811 if isinstance(e, Type_Ref):
812 self.exports.append(e.val)
813 elif isinstance(e, Class_Ref):
814 self.cexports.append(e.val)
816 self.vexports.append(e)
818 #--- eth_reg_assign ---------------------------------------------------------
819 def eth_reg_assign(self, ident, val, virt=False):
820 #print "eth_reg_assign(ident='%s')" % (ident)
821 if ident in self.assign:
822 raise DuplicateError("assignment", ident)
823 self.assign[ident] = { 'val' : val , 'virt' : virt }
824 self.assign_ord.append(ident)
825 if (self.exports_all):
826 self.exports.append(ident)
828 #--- eth_reg_vassign --------------------------------------------------------
829 def eth_reg_vassign(self, vassign):
830 ident = vassign.ident
831 #print "eth_reg_vassign(ident='%s')" % (ident)
832 if ident in self.vassign:
833 raise DuplicateError("value assignment", ident)
834 self.vassign[ident] = vassign
835 self.vassign_ord.append(ident)
836 if (self.exports_all):
837 self.vexports.append(ident)
839 #--- eth_reg_oassign --------------------------------------------------------
840 def eth_reg_oassign(self, oassign):
841 ident = oassign.ident
842 #print "eth_reg_oassign(ident='%s')" % (ident)
843 if ident in self.oassign:
844 if self.oassign[ident] == oassign:
845 return # OK - already defined
847 raise DuplicateError("information object assignment", ident)
848 self.oassign[ident] = oassign
849 self.oassign_ord.append(ident)
850 self.oassign_cls.setdefault(oassign.cls, []).append(ident)
852 #--- eth_import_type --------------------------------------------------------
853 def eth_import_type(self, ident, mod, proto):
854 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
855 if ident in self.type:
856 #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-'))
857 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
858 return # OK - already defined
859 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
860 return # OK - already imported
862 raise DuplicateError("type", ident)
863 self.type[ident] = {'import' : mod, 'proto' : proto,
865 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
866 'STRINGS' : 'NULL', 'BITMASK' : '0' }
867 mident = "$%s$%s" % (mod, ident)
868 if (self.conform.check_item('TYPE_ATTR', mident)):
869 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident))
871 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
872 if (self.conform.check_item('IMPORT_TAG', mident)):
873 self.conform.copy_item('IMPORT_TAG', ident, mident)
874 self.type_imp.append(ident)
876 #--- dummy_import_type --------------------------------------------------------
877 def dummy_import_type(self, ident):
879 if ident in self.type:
880 raise Exception("Try to dummy import for existing type :%s" % ident)
881 ethtype = asn2c(ident)
882 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
883 'ethname' : ethtype }
884 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
885 'STRINGS' : 'NULL', 'BITMASK' : '0' }
886 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
887 print("Dummy imported: %s (%s)" % (ident, ethtype))
890 #--- eth_import_class --------------------------------------------------------
891 def eth_import_class(self, ident, mod, proto):
892 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
893 if ident in self.objectclass:
894 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
895 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
896 return # OK - already defined
897 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
898 return # OK - already imported
900 raise DuplicateError("object class", ident)
901 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
903 self.objectclass_imp.append(ident)
905 #--- eth_import_value -------------------------------------------------------
906 def eth_import_value(self, ident, mod, proto):
907 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
908 if ident in self.value:
909 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
910 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
911 return # OK - already defined
912 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
913 return # OK - already imported
915 raise DuplicateError("value", ident)
916 self.value[ident] = {'import' : mod, 'proto' : proto,
918 self.value_imp.append(ident)
920 #--- eth_sel_req ------------------------------------------------------------
921 def eth_sel_req(self, typ, sel):
922 key = typ + '.' + sel
923 if key not in self.sel_req:
924 self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
925 self.sel_req_ord.append(key)
928 #--- eth_comp_req ------------------------------------------------------------
929 def eth_comp_req(self, type):
930 self.comp_req_ord.append(type)
932 #--- eth_dep_add ------------------------------------------------------------
933 def eth_dep_add(self, type, dep):
934 if type not in self.type_dep:
935 self.type_dep[type] = []
936 self.type_dep[type].append(dep)
938 #--- eth_reg_type -----------------------------------------------------------
939 def eth_reg_type(self, ident, val):
940 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
941 if ident in self.type:
942 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
943 # replace imported type
945 self.type_imp.remove(ident)
947 raise DuplicateError("type", ident)
949 self.type[ident] = { 'val' : val, 'import' : None }
950 self.type[ident]['module'] = self.Module()
951 self.type[ident]['proto'] = self.proto
952 if len(ident.split('/')) > 1:
953 self.type[ident]['tname'] = val.eth_tname()
955 self.type[ident]['tname'] = asn2c(ident)
956 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
957 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
958 self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident)
959 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
960 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
961 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
962 self.type[ident]['ethname'] = ''
963 if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') :
964 self.type[ident]['attr'] = {}
966 (ftype, display) = val.eth_ftype(self)
967 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
968 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
969 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
970 self.type_ord.append(ident)
972 if (self.conform.check_item('PDU', ident)):
973 self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
975 #--- eth_reg_objectclass ----------------------------------------------------------
976 def eth_reg_objectclass(self, ident, val):
977 #print "eth_reg_objectclass(ident='%s')" % (ident)
978 if ident in self.objectclass:
979 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
980 # replace imported object class
981 del self.objectclass[ident]
982 self.objectclass_imp.remove(ident)
983 elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \
984 isinstance(val, Class_Ref) and \
985 (self.objectclass[ident]['val'].val == val.val):
986 pass # ignore duplicated CLASS1 ::= CLASS2
988 raise DuplicateError("object class", ident)
989 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
990 self.objectclass[ident]['val'] = val
991 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
992 self.objectclass_ord.append(ident)
994 #--- eth_reg_value ----------------------------------------------------------
995 def eth_reg_value(self, ident, type, value, ethname=None):
996 #print "eth_reg_value(ident='%s')" % (ident)
997 if ident in self.value:
998 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
999 # replace imported value
1000 del self.value[ident]
1001 self.value_imp.remove(ident)
1003 self.value[ident]['ethname'] = ethname
1006 raise DuplicateError("value", ident)
1007 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
1008 'type' : type, 'value' : value,
1010 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
1011 self.value[ident]['ethname'] = ''
1012 if (ethname): self.value[ident]['ethname'] = ethname
1013 self.value_ord.append(ident)
1015 #--- eth_reg_field ----------------------------------------------------------
1016 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
1017 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
1018 if ident in self.field:
1019 if pdu and (type == self.field[ident]['type']):
1020 pass # OK already created PDU
1022 raise DuplicateError("field", ident)
1023 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
1024 'modified' : '', 'attr' : {} }
1025 name = ident.split('/')[-1]
1026 if self.remove_prefix and name.startswith(self.remove_prefix):
1027 name = name[len(self.remove_prefix):]
1029 if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type
1030 if len(self.field[ident]['type'].split('/')) > 1:
1031 self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2]
1032 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
1034 self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type']
1035 self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type'])
1037 self.field[ident]['attr']['NAME'] = '"%s"' % name
1038 self.field[ident]['attr']['ABBREV'] = asn2c(name)
1039 if self.conform.check_item('FIELD_ATTR', ident):
1040 self.field[ident]['modified'] = '#' + str(id(self))
1041 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
1043 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0)
1044 self.pdu_ord.append(ident)
1046 self.field_ord.append(ident)
1048 self.eth_dep_add(parent, type)
1050 def eth_dummy_eag_field_required(self):
1051 if (not self.dummy_eag_field):
1052 self.dummy_eag_field = 'dummy_eag_field'
1054 #--- eth_clean --------------------------------------------------------------
1055 def eth_clean(self):
1056 self.proto = self.proto_opt;
1057 #--- ASN.1 tables ----------------
1059 self.assign_ord = []
1068 self.sel_req_ord = []
1069 self.comp_req_ord = []
1071 self.vassign_ord = []
1075 self.objectclass = {}
1076 self.objectclass_ord = []
1077 self.objectclass_imp = []
1079 self.oassign_ord = []
1080 self.oassign_cls = {}
1081 #--- Modules ------------
1083 self.exports_all = False
1087 #--- types -------------------
1089 self.eth_type_ord = []
1090 self.eth_export_ord = []
1091 self.eth_type_dupl = {}
1093 #--- value dependencies -------------------
1095 #--- values -------------------
1097 self.eth_value_ord = []
1098 #--- fields -------------------------
1100 self.eth_hf_ord = []
1101 self.eth_hfpdu_ord = []
1102 self.eth_hf_dupl = {}
1103 self.dummy_eag_field = None
1104 #--- type dependencies -------------------
1105 self.eth_type_ord1 = []
1106 self.eth_dep_cycle = []
1107 self.dep_cycle_eth_type = {}
1108 #--- value dependencies and export -------------------
1109 self.eth_value_ord1 = []
1110 self.eth_vexport_ord = []
1112 #--- eth_prepare ------------------------------------------------------------
1113 def eth_prepare(self):
1114 self.eproto = asn2c(self.proto)
1116 #--- dummy types/fields for PDU registration ---
1118 if (self.conform.check_item('PDU', nm)):
1119 self.eth_reg_type('_dummy/'+nm, NullType())
1120 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
1122 #--- required PDUs ----------------------------
1123 for t in self.type_ord:
1124 pdu = self.type[t]['val'].eth_need_pdu(self)
1125 if not pdu: continue
1128 pdu['hidden'] = False
1129 pdu['need_decl'] = True
1130 if f not in self.field:
1131 self.eth_reg_field(f, f, pdu=pdu)
1133 #--- values -> named values -------------------
1135 for v in self.value_ord:
1136 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1137 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1138 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v)
1140 tnm = self.value[v]['type'].val
1141 if tnm in self.type \
1142 and not self.type[tnm]['import'] \
1143 and (self.type[tnm]['val'].type == 'IntegerType'):
1144 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
1145 self.value[v]['no_emit'] = True
1146 t_for_update[tnm] = True
1147 for t in list(t_for_update.keys()):
1148 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
1149 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
1151 #--- required components of ---------------------------
1152 #print "self.comp_req_ord = ", self.comp_req_ord
1153 for t in self.comp_req_ord:
1154 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
1156 #--- required selection types ---------------------------
1157 #print "self.sel_req_ord = ", self.sel_req_ord
1158 for t in self.sel_req_ord:
1159 tt = self.sel_req[t]['typ']
1160 if tt not in self.type:
1161 self.dummy_import_type(t)
1162 elif self.type[tt]['import']:
1163 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
1165 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
1167 #--- types -------------------
1168 for t in self.type_imp: # imported types
1170 self.eth_type[nm] = { 'import' : self.type[t]['import'],
1171 'proto' : asn2c(self.type[t]['proto']),
1172 'attr' : {}, 'ref' : []}
1173 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1174 self.type[t]['ethname'] = nm
1175 for t in self.type_ord: # dummy import for missing type reference
1176 tp = self.type[t]['val']
1177 #print "X : %s %s " % (t, tp.type)
1178 if isinstance(tp, TaggedType):
1179 #print "%s : %s " % (tp.type, t)
1181 if isinstance(tp, Type_Ref):
1182 #print "%s : %s ::= %s " % (tp.type, t, tp.val)
1183 if tp.val not in self.type:
1184 self.dummy_import_type(tp.val)
1185 for t in self.type_ord:
1186 nm = self.type[t]['tname']
1187 if ((nm.find('#') >= 0) or
1188 ((len(t.split('/'))>1) and
1189 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
1190 self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and
1191 not self.conform.check_item('TYPE_RENAME', t))):
1192 if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level
1193 nm = t.split('/')[0] + t.split('/')[1]
1194 elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels
1195 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
1196 elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type
1197 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1199 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1201 if nm in self.eth_type:
1202 if nm in self.eth_type_dupl:
1203 self.eth_type_dupl[nm].append(t)
1205 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1206 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1207 if nm in self.eth_type:
1208 self.eth_type[nm]['ref'].append(t)
1210 self.eth_type_ord.append(nm)
1211 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
1212 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1213 'val' : self.type[t]['val'],
1214 'attr' : {}, 'ref' : [t]}
1215 self.type[t]['ethname'] = nm
1216 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1217 self.eth_export_ord.append(nm)
1218 self.eth_type[nm]['export'] |= self.type[t]['export']
1219 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1220 self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext']
1221 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1222 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1223 if self.type[t]['attr'].get('STRINGS') == '$$':
1224 use_ext = self.type[t]['vals_ext']
1226 self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm))
1228 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1229 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1230 for t in self.eth_type_ord:
1231 bits = self.eth_type[t]['val'].eth_named_bits()
1233 for (val, id) in bits:
1234 self.named_bit.append({'name' : id, 'val' : val,
1235 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1236 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1238 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1239 if self.eth_type[t]['val'].eth_need_tree():
1240 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1242 self.eth_type[t]['tree'] = None
1244 #--- register values from enums ------------
1245 for t in self.eth_type_ord:
1246 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1247 self.eth_type[t]['val'].reg_enum_vals(t, self)
1249 #--- value dependencies -------------------
1250 for v in self.value_ord:
1251 if isinstance (self.value[v]['value'], Value):
1252 dep = self.value[v]['value'].get_dep()
1254 dep = self.value[v]['value']
1255 if dep and dep in self.value:
1256 self.value_dep.setdefault(v, []).append(dep)
1258 #--- exports all necessary values
1259 for v in self.value_ord:
1260 if not self.value[v]['export']: continue
1261 deparr = self.value_dep.get(v, [])
1264 if not self.value[d]['import']:
1265 if not self.value[d]['export']:
1266 self.value[d]['export'] = EF_TYPE
1267 deparr.extend(self.value_dep.get(d, []))
1269 #--- values -------------------
1270 for v in self.value_imp:
1272 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1273 'proto' : asn2c(self.value[v]['proto']),
1275 self.value[v]['ethname'] = nm
1276 for v in self.value_ord:
1277 if (self.value[v]['ethname']):
1279 if (self.value[v]['no_emit']):
1282 self.eth_value[nm] = { 'import' : None,
1283 'proto' : asn2c(self.value[v]['proto']),
1284 'export' : self.value[v]['export'], 'ref' : [v] }
1285 self.eth_value[nm]['value'] = self.value[v]['value']
1286 self.eth_value_ord.append(nm)
1287 self.value[v]['ethname'] = nm
1289 #--- fields -------------------------
1290 for f in (self.pdu_ord + self.field_ord):
1291 if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type
1292 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1294 nm = f.split('/')[-1]
1295 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1297 if (self.field[f]['pdu']):
1299 if (not self.merge_modules or self.field[f]['pdu']['export']):
1300 nm = self.eproto + '_' + nm
1301 t = self.field[f]['type']
1303 ethtype = self.type[t]['ethname']
1304 else: # undefined type
1305 ethtype = self.dummy_import_type(t)
1306 ethtypemod = ethtype + self.field[f]['modified']
1307 if nm in self.eth_hf:
1308 if nm in self.eth_hf_dupl:
1309 if ethtypemod in self.eth_hf_dupl[nm]:
1310 nm = self.eth_hf_dupl[nm][ethtypemod]
1311 self.eth_hf[nm]['ref'].append(f)
1312 self.field[f]['ethname'] = nm
1315 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1316 self.eth_hf_dupl[nm][ethtype] = nmx
1319 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1320 self.eth_hf[nm]['ref'].append(f)
1321 self.field[f]['ethname'] = nm
1325 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1328 if (self.field[f]['pdu']):
1329 self.eth_hfpdu_ord.append(nm)
1331 self.eth_hf_ord.append(nm)
1332 fullname = 'hf_%s_%s' % (self.eproto, nm)
1333 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1334 attr.update(self.field[f]['attr'])
1335 if (self.NAPI() and 'NAME' in attr):
1336 attr['NAME'] += self.field[f]['idx']
1337 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1338 use_vals_ext = self.eth_type[ethtype].get('vals_ext')
1340 attr['DISPLAY'] += '|BASE_EXT_STRING'
1341 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1342 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1343 'attr' : attr.copy(),
1345 self.field[f]['ethname'] = nm
1346 if (self.dummy_eag_field):
1347 self.dummy_eag_field = 'hf_%s_%s' % (self.eproto, self.dummy_eag_field)
1348 #--- type dependencies -------------------
1349 (self.eth_type_ord1, self.eth_dep_cycle) = dependency_compute(self.type_ord, self.type_dep, map_fn = lambda t: self.type[t]['ethname'], ignore_fn = lambda t: self.type[t]['import'])
1351 while i < len(self.eth_dep_cycle):
1352 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1353 self.dep_cycle_eth_type.setdefault(t, []).append(i)
1356 #--- value dependencies and export -------------------
1357 for v in self.eth_value_ord:
1358 if self.eth_value[v]['export']:
1359 self.eth_vexport_ord.append(v)
1361 self.eth_value_ord1.append(v)
1363 #--- export tags, values, ... ---
1364 for t in self.exports:
1365 if t not in self.type:
1367 if self.type[t]['import']:
1369 m = self.type[t]['module']
1371 if m not in self.all_tags:
1372 self.all_tags[m] = {}
1373 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
1374 if m not in self.all_type_attr:
1375 self.all_type_attr[m] = {}
1376 self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy()
1377 for v in self.vexports:
1378 if v not in self.value:
1380 if self.value[v]['import']:
1382 m = self.value[v]['module']
1383 if m not in self.all_vals:
1384 self.all_vals[m] = {}
1385 vv = self.value[v]['value']
1386 if isinstance (vv, Value):
1387 vv = vv.to_str(self)
1388 self.all_vals[m][v] = vv
1390 #--- eth_vals_nm ------------------------------------------------------------
1391 def eth_vals_nm(self, tname):
1393 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
1394 out += "%s_" % (self.eproto)
1395 out += "%s_vals" % (tname)
1398 #--- eth_vals ---------------------------------------------------------------
1399 def eth_vals(self, tname, vals):
1401 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
1402 use_ext = self.eth_type[tname]['vals_ext']
1404 vals.sort(key=lambda vals_entry: int(vals_entry[0]))
1405 if (not self.eth_type[tname]['export'] & EF_VALS):
1407 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
1409 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
1410 for (val, id) in vals:
1412 vval = self.eth_enum_item(tname, id)
1415 out += ' { %3s, "%s" },\n' % (vval, id)
1416 out += " { 0, NULL }\n};\n"
1418 out += "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self.eth_vals_nm(tname), self.eth_vals_nm(tname))
1421 #--- eth_enum_prefix ------------------------------------------------------------
1422 def eth_enum_prefix(self, tname, type=False):
1424 if (self.eth_type[tname]['export'] & EF_ENUM):
1425 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
1427 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
1430 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
1431 if (out): out += '_'
1433 if (self.eth_type[tname]['enum'] & EF_UCASE):
1435 if (out): out += '_'
1438 #--- eth_enum_nm ------------------------------------------------------------
1439 def eth_enum_nm(self, tname):
1440 out = self.eth_enum_prefix(tname, type=True)
1444 #--- eth_enum_item ---------------------------------------------------------------
1445 def eth_enum_item(self, tname, ident):
1446 out = self.eth_enum_prefix(tname)
1448 if (self.eth_type[tname]['enum'] & EF_UCASE):
1452 #--- eth_enum ---------------------------------------------------------------
1453 def eth_enum(self, tname, vals):
1455 if (self.eth_type[tname]['enum'] & EF_DEFINE):
1456 out += "/* enumerated values for %s */\n" % (tname)
1457 for (val, id) in vals:
1458 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1460 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1462 for (val, id) in vals:
1463 if (first_line == 1):
1467 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
1468 out += "\n} %s;\n" % (self.eth_enum_nm(tname))
1471 #--- eth_bits ---------------------------------------------------------------
1472 def eth_bits(self, tname, bits):
1474 out += "static const "
1475 out += "asn_namedbit %(TABLE)s[] = {\n"
1476 for (val, id) in bits:
1477 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1478 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1481 #--- eth_type_fn_h ----------------------------------------------------------
1482 def eth_type_fn_h(self, tname):
1484 if (not self.eth_type[tname]['export'] & EF_TYPE):
1488 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)
1490 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)
1494 #--- eth_fn_call ------------------------------------------------------------
1495 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1498 if (ret == 'return'):
1504 for i in range(len(par)):
1505 if (i>0): out += ind * ' '
1506 out += ', '.join(par[i])
1507 if (i<(len(par)-1)): out += ',\n'
1511 #--- eth_type_fn_hdr --------------------------------------------------------
1512 def eth_type_fn_hdr(self, tname):
1514 if (not self.eth_type[tname]['export'] & EF_TYPE):
1518 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)
1520 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)
1521 #if self.conform.get_fn_presence(tname):
1522 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1524 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1525 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1528 #--- eth_type_fn_ftr --------------------------------------------------------
1529 def eth_type_fn_ftr(self, tname):
1531 #if self.conform.get_fn_presence(tname):
1532 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1534 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1535 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1536 out += " return offset;\n"
1540 #--- eth_type_fn_body -------------------------------------------------------
1541 def eth_type_fn_body(self, tname, body, pars=None):
1543 #if self.conform.get_fn_body_presence(tname):
1544 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1546 if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1547 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1555 #--- eth_out_pdu_decl ----------------------------------------------------------
1556 def eth_out_pdu_decl(self, f):
1557 t = self.eth_hf[f]['ethtype']
1558 is_new = self.eth_hf[f]['pdu']['new']
1560 if (not self.eth_hf[f]['pdu']['export']):
1564 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n'
1567 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);\n'
1570 #--- eth_output_hf ----------------------------------------------------------
1571 def eth_output_hf (self):
1572 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1573 fx = self.output.file_open('hf')
1574 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1575 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1576 if (self.named_bit):
1577 fx.write('/* named bits */\n')
1578 for nb in self.named_bit:
1579 fx.write("static int %s = -1;\n" % (nb['ethname']))
1580 if (self.dummy_eag_field):
1581 fx.write("static int %s = -1; /* never registered */ \n" % (self.dummy_eag_field))
1582 self.output.file_close(fx)
1584 #--- eth_output_hf_arr ------------------------------------------------------
1585 def eth_output_hf_arr (self):
1586 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1587 fx = self.output.file_open('hfarr')
1588 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1589 t = self.eth_hf[f]['ethtype']
1590 if self.remove_prefix and t.startswith(self.remove_prefix):
1591 t = t[len(self.remove_prefix):]
1592 name=self.eth_hf[f]['attr']['NAME']
1594 trantab = maketrans("- ", "__")
1596 trantab = str.maketrans("- ", "__")
1597 name = name.translate(trantab)
1598 namelower = name.lower()
1599 tquoted_lower = '"' + t.lower() + '"'
1600 # Try to avoid giving blurbs that give no more info than the name
1601 if tquoted_lower == namelower or \
1603 tquoted_lower.replace("t_", "") == namelower:
1606 blurb = '"%s"' % (t)
1607 attr = self.eth_hf[f]['attr'].copy()
1608 if attr['TYPE'] == 'FT_NONE':
1609 attr['ABBREV'] = '"%s.%s_element"' % (self.proto, attr['ABBREV'])
1611 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1612 if 'BLURB' not in attr:
1613 attr['BLURB'] = blurb
1614 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1615 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1616 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1617 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1618 for nb in self.named_bit:
1619 fx.write(' { &%s,\n' % (nb['ethname']))
1620 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1621 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1622 fx.write(' NULL, HFILL }},\n')
1623 self.output.file_close(fx)
1625 #--- eth_output_ett ---------------------------------------------------------
1626 def eth_output_ett (self):
1627 fx = self.output.file_open('ett')
1629 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1630 for t in self.eth_type_ord:
1631 if self.eth_type[t]['tree']:
1632 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1634 self.output.file_close(fx, discard=fempty)
1636 #--- eth_output_ett_arr -----------------------------------------------------
1637 def eth_output_ett_arr(self):
1638 fx = self.output.file_open('ettarr')
1640 #fx.write(" &ett_%s,\n" % (self.eproto))
1641 for t in self.eth_type_ord:
1642 if self.eth_type[t]['tree']:
1643 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1645 self.output.file_close(fx, discard=fempty)
1647 #--- eth_output_export ------------------------------------------------------
1648 def eth_output_export(self):
1649 fx = self.output.file_open('exp', ext='h')
1650 for t in self.eth_export_ord: # vals
1651 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1652 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1653 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1654 if not self.eth_type[t]['export'] & EF_TABLE:
1655 if self.eth_type[t]['export'] & EF_WS_DLL:
1656 fx.write("WS_DLL_PUBLIC ")
1659 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1661 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1662 for t in self.eth_export_ord: # functions
1663 if (self.eth_type[t]['export'] & EF_TYPE):
1664 if self.eth_type[t]['export'] & EF_EXTERN:
1665 if self.eth_type[t]['export'] & EF_WS_DLL:
1666 fx.write("WS_DLL_PUBLIC ")
1669 fx.write(self.eth_type_fn_h(t))
1670 for f in self.eth_hfpdu_ord: # PDUs
1671 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']):
1672 fx.write(self.eth_out_pdu_decl(f))
1673 self.output.file_close(fx)
1675 #--- eth_output_expcnf ------------------------------------------------------
1676 def eth_output_expcnf(self):
1677 fx = self.output.file_open('exp', ext='cnf')
1678 fx.write('#.MODULE\n')
1680 for (m, p) in self.modules:
1681 if (len(m) > maxw): maxw = len(m)
1682 for (m, p) in self.modules:
1683 fx.write("%-*s %s\n" % (maxw, m, p))
1684 fx.write('#.END\n\n')
1685 for cls in self.objectclass_ord:
1686 if self.objectclass[cls]['export']:
1688 if self.objectclass[cls]['export'] & EF_MODULE:
1689 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm)
1690 fx.write('#.CLASS %s\n' % (cnm))
1692 for fld in self.objectclass[cls]['val'].fields:
1693 w = len(fld.fld_repr()[0])
1694 if (w > maxw): maxw = w
1695 for fld in self.objectclass[cls]['val'].fields:
1696 repr = fld.fld_repr()
1697 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
1698 fx.write('#.END\n\n')
1700 fx.write('#.IMPORT_TAG\n')
1701 for t in self.eth_export_ord: # tags
1702 if (self.eth_type[t]['export'] & EF_TYPE):
1703 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1704 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1705 fx.write('#.END\n\n')
1706 fx.write('#.TYPE_ATTR\n')
1707 for t in self.eth_export_ord: # attributes
1708 if (self.eth_type[t]['export'] & EF_TYPE):
1709 tnm = self.eth_type[t]['ref'][0]
1710 if self.eth_type[t]['export'] & EF_MODULE:
1711 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm)
1712 fx.write('%-24s ' % tnm)
1713 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1714 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1715 fx.write('#.END\n\n')
1716 self.output.file_close(fx, keep_anyway=True)
1718 #--- eth_output_val ------------------------------------------------------
1719 def eth_output_val(self):
1720 fx = self.output.file_open('val', ext='h')
1721 for v in self.eth_value_ord1:
1722 vv = self.eth_value[v]['value']
1723 if isinstance (vv, Value):
1724 vv = vv.to_str(self)
1725 fx.write("#define %-30s %s\n" % (v, vv))
1726 for t in self.eth_type_ord1:
1727 if self.eth_type[t]['import']:
1729 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1730 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1731 self.output.file_close(fx)
1733 #--- eth_output_valexp ------------------------------------------------------
1734 def eth_output_valexp(self):
1735 if (not len(self.eth_vexport_ord)): return
1736 fx = self.output.file_open('valexp', ext='h')
1737 for v in self.eth_vexport_ord:
1738 vv = self.eth_value[v]['value']
1739 if isinstance (vv, Value):
1740 vv = vv.to_str(self)
1741 fx.write("#define %-30s %s\n" % (v, vv))
1742 self.output.file_close(fx)
1744 #--- eth_output_types -------------------------------------------------------
1745 def eth_output_types(self):
1747 t = self.eth_hf[f]['ethtype']
1748 is_new = self.eth_hf[f]['pdu']['new']
1751 if (not self.eth_hf[f]['pdu']['export']):
1755 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n'
1758 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {\n'
1760 out += ' int offset = 0;\n'
1767 if (self.Aligned()):
1771 out += " asn1_ctx_t asn1_ctx;\n"
1772 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1774 out += " asn1_ctx_t asn1_ctx;\n"
1775 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1776 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1778 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1781 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1782 if (self.Per() and is_new):
1783 out += ' offset += 7; offset >>= 3;\n'
1785 out += ' return offset;\n'
1789 fx = self.output.file_open('fn')
1791 if (len(self.eth_hfpdu_ord)):
1793 for f in self.eth_hfpdu_ord:
1794 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1796 fx.write('/*--- PDUs declarations ---*/\n')
1798 fx.write(self.eth_out_pdu_decl(f))
1801 if self.eth_dep_cycle:
1802 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1804 while i < len(self.eth_dep_cycle):
1805 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1806 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1807 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]]))
1808 fx.write(self.eth_type_fn_h(t))
1812 for t in self.eth_type_ord1:
1813 if self.eth_type[t]['import']:
1815 if self.eth_type[t]['val'].eth_has_vals():
1816 if self.eth_type[t]['no_emit'] & EF_VALS:
1818 elif self.eth_type[t]['user_def'] & EF_VALS:
1819 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1820 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1823 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1824 if self.eth_type[t]['no_emit'] & EF_TYPE:
1826 elif self.eth_type[t]['user_def'] & EF_TYPE:
1827 fx.write(self.eth_type_fn_h(t))
1829 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1831 if (len(self.eth_hfpdu_ord)):
1832 fx.write('/*--- PDUs ---*/\n\n')
1833 for f in self.eth_hfpdu_ord:
1834 if (self.eth_hf[f]['pdu']):
1835 if (f in self.emitted_pdu):
1836 fx.write(" /* %s already emitted */\n" % (f))
1838 fx.write(out_pdu(f))
1839 self.emitted_pdu[f] = True
1841 fempty = pos == fx.tell()
1842 self.output.file_close(fx, discard=fempty)
1844 #--- eth_output_dis_hnd -----------------------------------------------------
1845 def eth_output_dis_hnd(self):
1846 fx = self.output.file_open('dis-hnd')
1848 for f in self.eth_hfpdu_ord:
1849 pdu = self.eth_hf[f]['pdu']
1850 if (pdu and pdu['reg'] and not pdu['hidden']):
1852 if (pdu['reg'] != '.'):
1853 dis += '.' + pdu['reg']
1854 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1857 self.output.file_close(fx, discard=fempty)
1859 #--- eth_output_dis_reg -----------------------------------------------------
1860 def eth_output_dis_reg(self):
1861 fx = self.output.file_open('dis-reg')
1863 for f in self.eth_hfpdu_ord:
1864 pdu = self.eth_hf[f]['pdu']
1865 if (pdu and pdu['reg']):
1867 if (pdu['new']): new_prefix = 'new_'
1869 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1870 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1871 if (not pdu['hidden']):
1872 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1875 self.output.file_close(fx, discard=fempty)
1877 #--- eth_output_dis_tab -----------------------------------------------------
1878 def eth_output_dis_tab(self):
1879 fx = self.output.file_open('dis-tab')
1881 for k in self.conform.get_order('REGISTER'):
1882 reg = self.conform.use_item('REGISTER', k)
1883 if reg['pdu'] not in self.field: continue
1884 f = self.field[reg['pdu']]['ethname']
1885 pdu = self.eth_hf[f]['pdu']
1887 if (pdu['new']): new_prefix = 'new_'
1888 if (reg['rtype'] in ('NUM', 'STR')):
1890 if (reg['rtype'] == 'STR'):
1896 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1897 if (not pdu['hidden']):
1898 hnd = '%s_handle' % (asn2c(dis))
1900 hnd = 'find_dissector("%s")' % (dis)
1902 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1903 rport = self.value_get_eth(reg['rport'])
1904 fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1905 elif (reg['rtype'] in ('BER', 'PER')):
1906 roid = self.value_get_eth(reg['roid'])
1907 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1910 self.output.file_close(fx, discard=fempty)
1912 #--- eth_output_syn_reg -----------------------------------------------------
1913 def eth_output_syn_reg(self):
1914 fx = self.output.file_open('syn-reg')
1917 for k in self.conform.get_order('SYNTAX'):
1918 reg = self.conform.use_item('SYNTAX', k)
1920 fx.write(' /*--- Syntax registrations ---*/\n')
1922 fx.write(' register_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (k, self.eproto, reg['pdu']));
1924 self.output.file_close(fx, discard=fempty)
1926 #--- eth_output_tables -----------------------------------------------------
1927 def eth_output_tables(self):
1928 for num in list(self.conform.report.keys()):
1929 fx = self.output.file_open('table' + num)
1930 for rep in self.conform.report[num]:
1931 self.eth_output_table(fx, rep)
1932 self.output.file_close(fx)
1934 #--- eth_output_table -----------------------------------------------------
1935 def eth_output_table(self, fx, rep):
1936 def cmp_fn(a, b, cmp_flds, objs):
1937 if not cmp_flds: return 0
1944 res = int(obja[f]) - int(objb[f])
1946 res = cmp(obja[f], objb[f])
1949 if rep['type'] == 'HDR':
1953 var_list = var.split('.', 1)
1961 not_flds.append(f[1:])
1969 sort_flds.append(f[1:])
1974 if (cls in self.oassign_cls):
1975 for ident in self.oassign_cls[cls]:
1976 obj = self.get_obj_repr(ident, flds, not_flds)
1980 obj['_DICT'] = str(obj)
1982 objs_ord.append(ident)
1984 objs_ord.sort(cmp=partial(cmp_fn, cmp_flds=sort_flds, objs=objs))
1985 for ident in objs_ord:
1988 text = rep['text'] % obj
1990 raise sys.exc_info()[0]("%s:%s invalid key %s for information object %s of %s" % (rep['fn'], rep['lineno'], sys.exc_info()[1], ident, var))
1993 fx.write("/* Unknown or empty loop list %s */\n" % (var))
1995 fx.write(rep['text'])
1996 if rep['type'] == 'FTR':
1999 #--- dupl_report -----------------------------------------------------
2000 def dupl_report(self):
2002 tmplist = sorted(self.eth_type_dupl.keys())
2004 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
2006 for tt in self.eth_type_dupl[t]:
2007 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
2008 warnings.warn_explicit(msg, UserWarning, '', 0)
2010 tmplist = list(self.eth_hf_dupl.keys())
2013 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
2015 for tt in list(self.eth_hf_dupl[f].keys()):
2016 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
2017 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
2019 warnings.warn_explicit(msg, UserWarning, '', 0)
2021 #--- eth_do_output ------------------------------------------------------------
2022 def eth_do_output(self):
2024 print("\n# Assignments")
2025 for a in self.assign_ord:
2027 if (self.assign[a]['virt']): v = '*'
2029 print("\n# Value assignments")
2030 for a in self.vassign_ord:
2032 print("\n# Information object assignments")
2033 for a in self.oassign_ord:
2034 print(" %-12s (%s)" % (a, self.oassign[a].cls))
2036 print("\n# Imported Types")
2037 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2039 for t in self.type_imp:
2040 print("%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto']))
2041 print("\n# Imported Values")
2042 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2044 for t in self.value_imp:
2045 print("%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto']))
2046 print("\n# Imported Object Classes")
2047 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2049 for t in self.objectclass_imp:
2050 print("%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto']))
2051 print("\n# Exported Types")
2052 print("%-31s %s" % ("Wireshark type", "Export Flag"))
2054 for t in self.eth_export_ord:
2055 print("%-31s 0x%02X" % (t, self.eth_type[t]['export']))
2056 print("\n# Exported Values")
2057 print("%-40s %s" % ("Wireshark name", "Value"))
2059 for v in self.eth_vexport_ord:
2060 vv = self.eth_value[v]['value']
2061 if isinstance (vv, Value):
2062 vv = vv.to_str(self)
2063 print("%-40s %s" % (v, vv))
2064 print("\n# ASN.1 Object Classes")
2065 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2067 for t in self.objectclass_ord:
2068 print("%-40s " % (t))
2069 print("\n# ASN.1 Types")
2070 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type"))
2072 for t in self.type_ord:
2073 print("%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname']))
2074 print("\n# Wireshark Types")
2075 print("Wireshark type References (ASN.1 types)")
2077 for t in self.eth_type_ord:
2078 sys.stdout.write("%-31s %d" % (t, len(self.eth_type[t]['ref'])))
2079 print(', '.join(self.eth_type[t]['ref']))
2080 print("\n# ASN.1 Values")
2081 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value"))
2083 for v in self.value_ord:
2084 vv = self.value[v]['value']
2085 if isinstance (vv, Value):
2086 vv = vv.to_str(self)
2087 print("%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname']))
2088 #print "\n# Wireshark Values"
2089 #print "%-40s %s" % ("Wireshark name", "Value")
2091 #for v in self.eth_value_ord:
2092 # vv = self.eth_value[v]['value']
2093 # if isinstance (vv, Value):
2094 # vv = vv.to_str(self)
2095 # print "%-40s %s" % (v, vv)
2096 print("\n# ASN.1 Fields")
2097 print("ASN.1 unique name Wireshark name ASN.1 type")
2099 for f in (self.pdu_ord + self.field_ord):
2100 print("%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type']))
2101 print("\n# Wireshark Fields")
2102 print("Wireshark name Wireshark type References (ASN.1 fields)")
2104 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
2105 sys.stdout.write("%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])))
2106 print(', '.join(self.eth_hf[f]['ref']))
2107 #print "\n# Order after dependencies"
2108 #print '\n'.join(self.eth_type_ord1)
2109 print("\n# Cyclic dependencies")
2110 for c in self.eth_dep_cycle:
2111 print(' -> '.join(c))
2113 self.output.outnm = self.outnm_opt
2114 if (not self.output.outnm):
2115 self.output.outnm = self.proto
2116 self.output.outnm = self.output.outnm.replace('.', '-')
2117 if not self.justexpcnf:
2118 self.eth_output_hf()
2119 self.eth_output_ett()
2120 self.eth_output_types()
2121 self.eth_output_hf_arr()
2122 self.eth_output_ett_arr()
2123 self.eth_output_export()
2124 self.eth_output_val()
2125 self.eth_output_valexp()
2126 self.eth_output_dis_hnd()
2127 self.eth_output_dis_reg()
2128 self.eth_output_dis_tab()
2129 self.eth_output_syn_reg()
2130 self.eth_output_tables()
2132 self.eth_output_expcnf()
2134 def dbg_modules(self):
2136 sys.stdout.write("%-30s " % (m))
2137 dep = self.module[m][:]
2138 for i in range(len(dep)):
2139 if dep[i] not in self.module:
2140 dep[i] = '*' + dep[i]
2141 print(', '.join(dep))
2142 # end of print_mod()
2143 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module)
2144 print("\n# ASN.1 Moudules")
2145 print("Module name Dependency")
2148 for m in (self.module_ord):
2150 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
2152 print("\n# ASN.1 Moudules - in dependency order")
2153 print("Module name Dependency")
2158 print("\nCyclic dependencies:")
2159 for i in (list(range(len(mod_cyc)))):
2160 print("%02d: %s" % (i + 1, str(mod_cyc[i])))
2163 #--- EthCnf -------------------------------------------------------------------
2172 self.suppress_line = False
2173 self.include_path = []
2174 # Value name Default value Duplicity check Usage check
2175 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2176 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2177 self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2178 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2179 self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2180 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2181 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2182 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2183 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2184 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2185 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2186 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2187 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2188 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2189 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2190 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2191 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2192 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2193 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2194 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2195 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2196 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2197 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2199 for k in list(self.tblcfg.keys()) :
2203 def add_item(self, table, key, fn, lineno, **kw):
2204 if self.tblcfg[table]['chk_dup'] and key in self.table[table]:
2205 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2206 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
2207 UserWarning, fn, lineno)
2209 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2210 self.table[table][key].update(kw)
2211 self.order[table].append(key)
2213 def update_item(self, table, key, fn, lineno, **kw):
2214 if key not in self.table[table]:
2215 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2216 self.order[table].append(key)
2217 self.table[table][key][self.tblcfg[table]['val_nm']] = {}
2218 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
2220 def get_order(self, table):
2221 return self.order[table]
2223 def check_item(self, table, key):
2224 return key in self.table[table]
2226 def copy_item(self, table, dst_key, src_key):
2227 if (src_key in self.table[table]):
2228 self.table[table][dst_key] = self.table[table][src_key]
2230 def check_item_value(self, table, key, **kw):
2231 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key]
2233 def use_item(self, table, key, **kw):
2234 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
2235 if key not in self.table[table]: return vdflt
2236 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
2237 #print "use_item() - set used for %s %s" % (table, key)
2238 self.table[table][key]['used'] = True
2239 return self.table[table][key].get(vname, vdflt)
2241 def omit_assignment(self, type, ident, module):
2242 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
2244 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
2245 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2246 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
2247 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
2248 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
2251 def add_fn_line(self, name, ctx, line, fn, lineno):
2252 if name not in self.fn:
2253 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2254 if (self.fn[name][ctx]):
2255 self.fn[name][ctx]['text'] += line
2257 self.fn[name][ctx] = {'text' : line, 'used' : False,
2258 'fn' : fn, 'lineno' : lineno}
2259 def get_fn_presence(self, name):
2260 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2261 #if self.fn.has_key(name): print self.fn[name]
2262 return name in self.fn
2263 def get_fn_body_presence(self, name):
2264 return name in self.fn and self.fn[name]['FN_BODY']
2265 def get_fn_text(self, name, ctx):
2266 if (name not in self.fn):
2268 if (not self.fn[name][ctx]):
2270 self.fn[name][ctx]['used'] = True
2271 out = self.fn[name][ctx]['text']
2272 if (not self.suppress_line):
2273 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out);
2276 def add_pdu(self, par, is_new, fn, lineno):
2277 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2278 (reg, hidden) = (None, False)
2279 if (len(par) > 1): reg = par[1]
2280 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
2281 attr = {'new' : is_new, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False}
2282 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
2285 def add_syntax(self, par, fn, lineno):
2286 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
2287 if( (len(par) >=2)):
2290 name = '"'+par[0]+'"'
2291 attr = { 'pdu' : par[0] }
2292 self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno)
2295 def add_register(self, pdu, par, fn, lineno):
2296 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2297 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
2298 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
2299 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
2300 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
2301 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
2302 if ((len(par)-1) < pmin):
2303 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
2305 if ((len(par)-1) > pmax):
2306 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
2307 attr = {'pdu' : pdu, 'rtype' : rtype}
2308 if (rtype in ('NUM', 'STR')):
2309 attr['rtable'] = par[1]
2310 attr['rport'] = par[2]
2311 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
2312 elif (rtype in ('BER', 'PER')):
2313 attr['roid'] = par[1]
2314 attr['roidname'] = '""'
2316 attr['roidname'] = par[2]
2317 elif attr['roid'][0] != '"':
2318 attr['roidname'] = '"' + attr['roid'] + '"'
2319 rkey = '/'.join([rtype, attr['roid']])
2320 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
2322 def check_par(self, par, pmin, pmax, fn, lineno):
2323 for i in range(len(par)):
2327 if par[i][0] == '#':
2331 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2333 if (pmax >= 0) and (len(par) > pmax):
2334 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2339 def get_par(line, pmin, pmax, fn, lineno):
2340 par = line.split(None, pmax)
2341 par = self.check_par(par, pmin, pmax, fn, lineno)
2344 def get_par_nm(line, pmin, pmax, fn, lineno):
2346 par = line.split(None, pmax)
2349 for i in range(len(par)):
2350 if par[i][0] == '#':
2354 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2361 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2362 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2363 nmpar_end = re.compile(r'\s*$')
2364 result = nmpar_first.search(nmpar)
2367 k = result.group('attr')
2369 result = nmpar_next.search(nmpar, pos)
2374 p2 = nmpar_end.search(nmpar, pos).start()
2384 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2385 cdirective = re.compile(r'^\s*##')
2386 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2387 comment = re.compile(r'^\s*#[^.#]')
2388 empty = re.compile(r'^\s*$')
2391 default_flags = 0x00
2404 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import']
2408 if comment.search(line): continue
2409 result = directive.search(line)
2410 if result: # directive
2411 rep_result = report.search(result.group('name'))
2412 if result.group('name') == 'END_OF_CNF':
2414 elif result.group('name') == 'OPT':
2415 ctx = result.group('name')
2416 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2417 if not par: continue
2418 self.set_opt(par[0], par[1:], fn, lineno)
2420 elif result.group('name') in ('PDU', 'PDU_NEW', 'REGISTER', 'REGISTER_NEW',
2421 'MODULE', 'MODULE_IMPORT',
2422 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2423 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2424 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2425 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR', 'SYNTAX'):
2426 ctx = result.group('name')
2427 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2428 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2429 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2430 ctx = result.group('name')
2432 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2434 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2436 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2439 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2440 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2441 ctx = 'NO_OMIT_ASSGN'
2444 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2445 ctx = result.group('name')
2446 default_flags = EF_TYPE|EF_VALS
2447 if ctx == 'MODULE_EXPORTS':
2449 default_flags |= EF_MODULE
2450 if ctx == 'EXPORTS':
2451 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2453 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2454 if not par: continue
2456 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2457 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2458 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2459 elif (ctx == 'EXPORTS'): p = 0
2460 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2461 for i in range(p, len(par)):
2462 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2463 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2464 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2465 elif (par[i] == 'WS_DLL'): default_flags |= EF_WS_DLL
2466 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2467 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2468 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2469 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2470 ctx = result.group('name')
2471 default_flags = EF_ENUM
2472 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2473 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2474 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2475 for i in range(0, len(par)):
2476 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2477 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT
2478 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2479 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE
2480 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2481 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2482 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2483 elif result.group('name') == 'USE_VALS_EXT':
2484 ctx = result.group('name')
2485 default_flags = 0xFF
2486 elif result.group('name') == 'FN_HDR':
2488 if (ctx in ('FN_PARS',)) and name: minp = 0
2489 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2490 if (not par) and (minp > 0): continue
2491 ctx = result.group('name')
2492 if par: name = par[0]
2493 elif result.group('name') == 'FN_FTR':
2495 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0
2496 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2497 if (not par) and (minp > 0): continue
2498 ctx = result.group('name')
2499 if par: name = par[0]
2500 elif result.group('name') == 'FN_BODY':
2501 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2502 if not par: continue
2503 ctx = result.group('name')
2506 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2507 elif result.group('name') == 'FN_PARS':
2508 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2509 ctx = result.group('name')
2514 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2516 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2518 elif result.group('name') == 'CLASS':
2519 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2520 if not par: continue
2521 ctx = result.group('name')
2523 add_class_ident(name)
2524 if not name.split('$')[-1].isupper():
2525 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2526 UserWarning, fn, lineno)
2527 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2528 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2529 if not par: continue
2530 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
2531 elif rep_result: # Reports
2532 num = rep_result.group('num')
2533 type = rep_result.group('type')
2535 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2536 if not par: continue
2538 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
2539 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
2542 self.report.setdefault(num, []).append(rep)
2545 elif result.group('name') in ('INCLUDE', 'IMPORT') :
2546 is_imp = result.group('name') == 'IMPORT'
2547 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2549 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno)
2552 #print "Try include: %s" % (fname)
2553 if (not os.path.exists(fname)):
2554 fname = os.path.join(os.path.split(fn)[0], par[0])
2555 #print "Try include: %s" % (fname)
2557 while not os.path.exists(fname) and (i < len(self.include_path)):
2558 fname = os.path.join(self.include_path[i], par[0])
2559 #print "Try include: %s" % (fname)
2561 if (not os.path.exists(fname)):
2563 continue # just ignore
2565 fname = par[0] # report error
2566 fnew = open(fname, "r")
2567 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import})
2568 fn, f, lineno, is_import = par[0], fnew, 0, is_imp
2569 elif result.group('name') == 'END':
2572 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2575 if not empty.match(line):
2576 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2578 if empty.match(line): continue
2579 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2580 if not par: continue
2581 self.set_opt(par[0], par[1:], fn, lineno)
2582 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2583 if empty.match(line): continue
2584 if ctx == 'EXPORTS':
2585 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2587 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2588 if not par: continue
2589 flags = default_flags
2592 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2593 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2594 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2595 elif (ctx == 'EXPORTS'): p = 1
2596 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2597 for i in range(p, len(par)):
2598 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2599 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2600 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2601 elif (par[i] == 'WS_DLL'): flags |= EF_WS_DLL
2602 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2603 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2604 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2605 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2606 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2607 if empty.match(line): continue
2608 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2609 if not par: continue
2610 flags = default_flags
2611 for i in range(1, len(par)):
2612 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2613 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT
2614 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2615 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE
2616 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2617 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2618 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2619 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2620 elif ctx == 'USE_VALS_EXT':
2621 if empty.match(line): continue
2622 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2623 if not par: continue
2624 flags = default_flags
2625 self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno)
2626 elif ctx in ('PDU', 'PDU_NEW'):
2627 if empty.match(line): continue
2628 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2629 if not par: continue
2631 if (ctx == 'PDU_NEW'): is_new = True
2632 self.add_pdu(par[0:2], is_new, fn, lineno)
2634 self.add_register(par[0], par[2:5], fn, lineno)
2635 elif ctx in ('SYNTAX'):
2636 if empty.match(line): continue
2637 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2638 if not par: continue
2639 if not self.check_item('PDU', par[0]):
2640 self.add_pdu(par[0:1], False, fn, lineno)
2641 self.add_syntax(par, fn, lineno)
2642 elif ctx in ('REGISTER', 'REGISTER_NEW'):
2643 if empty.match(line): continue
2644 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2645 if not par: continue
2646 if not self.check_item('PDU', par[0]):
2648 if (ctx == 'REGISTER_NEW'): is_new = True
2649 self.add_pdu(par[0:1], is_new, fn, lineno)
2650 self.add_register(par[0], par[1:4], fn, lineno)
2651 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2652 if empty.match(line): continue
2653 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2654 if not par: continue
2655 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2656 elif ctx == 'IMPORT_TAG':
2657 if empty.match(line): continue
2658 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2659 if not par: continue
2660 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2661 elif ctx == 'OMIT_ASSIGNMENT':
2662 if empty.match(line): continue
2663 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2664 if not par: continue
2665 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2666 elif ctx == 'NO_OMIT_ASSGN':
2667 if empty.match(line): continue
2668 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2669 if not par: continue
2670 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2671 elif ctx == 'VIRTUAL_ASSGN':
2672 if empty.match(line): continue
2673 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2674 if not par: continue
2675 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2676 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2677 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2679 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2680 if not par[0][0].isupper():
2681 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2682 UserWarning, fn, lineno)
2683 elif ctx == 'SET_TYPE':
2684 if empty.match(line): continue
2685 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2686 if not par: continue
2687 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2688 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2689 if not par[1][0].isupper():
2690 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2691 UserWarning, fn, lineno)
2692 elif ctx == 'ASSIGN_VALUE_TO_TYPE':
2693 if empty.match(line): continue
2694 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2695 if not par: continue
2696 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno)
2697 elif ctx == 'TYPE_RENAME':
2698 if empty.match(line): continue
2699 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2700 if not par: continue
2701 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2702 if not par[1][0].isupper():
2703 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2704 UserWarning, fn, lineno)
2705 elif ctx == 'FIELD_RENAME':
2706 if empty.match(line): continue
2707 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2708 if not par: continue
2709 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2710 if not par[1][0].islower():
2711 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2712 UserWarning, fn, lineno)
2713 elif ctx == 'TF_RENAME':
2714 if empty.match(line): continue
2715 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2716 if not par: continue
2717 tmpu = par[1][0].upper() + par[1][1:]
2718 tmpl = par[1][0].lower() + par[1][1:]
2719 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2720 if not tmpu[0].isupper():
2721 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2722 UserWarning, fn, lineno)
2723 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2724 if not tmpl[0].islower():
2725 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2726 UserWarning, fn, lineno)
2727 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2728 if empty.match(line): continue
2729 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2730 if not par: continue
2731 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2732 elif ctx == 'FN_PARS':
2733 if empty.match(line): continue
2735 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2737 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2738 if not par: continue
2740 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2742 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2743 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2744 result = cdirective.search(line)
2745 if result: # directive
2746 line = '#' + line[result.end():]
2747 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2748 elif ctx == 'CLASS':
2749 if empty.match(line): continue
2750 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2751 if not par: continue
2752 if not set_type_to_class(name, par[0], par[1:]):
2753 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2754 UserWarning, fn, lineno)
2755 elif ctx == 'TABLE':
2756 self.report[name][-1]['text'] += line
2758 def set_opt(self, opt, par, fn, lineno):
2759 #print "set_opt: %s, %s" % (opt, par)
2761 par = self.check_par(par, 1, 1, fn, lineno)
2763 self.include_path.append(par[0])
2764 elif opt in ("-b", "BER", "CER", "DER"):
2765 par = self.check_par(par, 0, 0, fn, lineno)
2766 self.ectx.encoding = 'ber'
2767 elif opt in ("PER",):
2768 par = self.check_par(par, 0, 0, fn, lineno)
2769 self.ectx.encoding = 'per'
2770 elif opt in ("-p", "PROTO"):
2771 par = self.check_par(par, 1, 1, fn, lineno)
2773 self.ectx.proto_opt = par[0]
2774 self.ectx.merge_modules = True
2775 elif opt in ("ALIGNED",):
2776 par = self.check_par(par, 0, 0, fn, lineno)
2777 self.ectx.aligned = True
2778 elif opt in ("-u", "UNALIGNED"):
2779 par = self.check_par(par, 0, 0, fn, lineno)
2780 self.ectx.aligned = False
2781 elif opt in ("-d",):
2782 par = self.check_par(par, 1, 1, fn, lineno)
2784 self.ectx.dbgopt = par[0]
2785 elif opt in ("-e",):
2786 par = self.check_par(par, 0, 0, fn, lineno)
2787 self.ectx.expcnf = True
2788 elif opt in ("-S",):
2789 par = self.check_par(par, 0, 0, fn, lineno)
2790 self.ectx.merge_modules = True
2791 elif opt in ("GROUP_BY_PROT",):
2792 par = self.check_par(par, 0, 0, fn, lineno)
2793 self.ectx.group_by_prot = True
2794 elif opt in ("-o",):
2795 par = self.check_par(par, 1, 1, fn, lineno)
2797 self.ectx.outnm_opt = par[0]
2798 elif opt in ("-O",):
2799 par = self.check_par(par, 1, 1, fn, lineno)
2801 self.ectx.output.outdir = par[0]
2802 elif opt in ("-s",):
2803 par = self.check_par(par, 1, 1, fn, lineno)
2805 self.ectx.output.single_file = par[0]
2806 elif opt in ("-k",):
2807 par = self.check_par(par, 0, 0, fn, lineno)
2808 self.ectx.output.keep = True
2809 elif opt in ("-L",):
2810 par = self.check_par(par, 0, 0, fn, lineno)
2811 self.suppress_line = True
2812 elif opt in ("EMBEDDED_PDV_CB",):
2813 par = self.check_par(par, 1, 1, fn, lineno)
2815 self.ectx.default_embedded_pdv_cb = par[0]
2816 elif opt in ("EXTERNAL_TYPE_CB",):
2817 par = self.check_par(par, 1, 1, fn, lineno)
2819 self.ectx.default_external_type_cb = par[0]
2820 elif opt in ("-r",):
2821 par = self.check_par(par, 1, 1, fn, lineno)
2823 self.ectx.remove_prefix = par[0]
2825 warnings.warn_explicit("Unknown option %s" % (opt),
2826 UserWarning, fn, lineno)
2828 def dbg_print(self):
2829 print("\n# Conformance values")
2830 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value"))
2832 tbls = sorted(self.table.keys())
2834 keys = sorted(self.table[t].keys())
2836 print("%-15s %4s %-15s %-20s %s" % (
2837 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']])))
2839 def unused_report(self):
2840 tbls = sorted(self.table.keys())
2842 if not self.tblcfg[t]['chk_use']: continue
2843 keys = sorted(self.table[t].keys())
2845 if not self.table[t][k]['used']:
2846 warnings.warn_explicit("Unused %s for %s" % (t, k),
2847 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2848 fnms = list(self.fn.keys())
2851 keys = sorted(self.fn[f].keys())
2853 if not self.fn[f][k]: continue
2854 if not self.fn[f][k]['used']:
2855 warnings.warn_explicit("Unused %s for %s" % (k, f),
2856 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2858 #--- EthOut -------------------------------------------------------------------
2864 self.single_file = None
2865 self.created_files = {}
2866 self.created_files_ord = []
2869 def outcomment(self, ln, comment=None):
2871 return '%s %s\n' % (comment, ln)
2873 return '/* %-74s */\n' % (ln)
2875 def created_file_add(self, name, keep_anyway):
2876 name = os.path.normcase(os.path.abspath(name))
2877 if name not in self.created_files:
2878 self.created_files_ord.append(name)
2879 self.created_files[name] = keep_anyway
2881 self.created_files[name] = self.created_files[name] or keep_anyway
2883 def created_file_exists(self, name):
2884 name = os.path.normcase(os.path.abspath(name))
2885 return name in self.created_files
2887 #--- output_fname -------------------------------------------------------
2888 def output_fname(self, ftype, ext='c'):
2890 if not ext in ('cnf',):
2897 #--- file_open -------------------------------------------------------
2898 def file_open(self, ftype, ext='c'):
2899 fn = self.output_fname(ftype, ext=ext)
2900 if self.created_file_exists(fn):
2907 fx.write(self.fhdr(fn, comment = comment))
2909 if (not self.single_file and not self.created_file_exists(fn)):
2910 fx.write(self.fhdr(fn))
2911 if not self.ectx.merge_modules:
2914 if self.ectx.groups():
2916 if (len(self.ectx.modules) > 1):
2918 for (m, p) in self.ectx.modules:
2921 mstr += "Module %s" % (self.ectx.Module())
2922 mstr += " --- --- ---"
2923 fx.write(self.outcomment(mstr, comment))
2926 #--- file_close -------------------------------------------------------
2927 def file_close(self, fx, discard=False, keep_anyway=False):
2929 if discard and not self.created_file_exists(fx.name):
2932 self.created_file_add(fx.name, keep_anyway)
2933 #--- fhdr -------------------------------------------------------
2934 def fhdr(self, fn, comment=None):
2936 out += self.outcomment('Do not modify this file. Changes will be overwritten.', comment)
2937 out += self.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment)
2938 out += self.outcomment(os.path.basename(fn), comment)
2939 out += self.outcomment(' '.join(sys.argv), comment)
2941 # Make Windows path separator look like Unix path separator
2942 out = out.replace('\\', '/')
2943 # Change abolute paths to paths relative to asn1/<proto> subdir
2944 out = re.sub(r'(\s)/\S*(/tools/|/epan/)', r'\1../..\2', out)
2945 out = re.sub(r'(\s)/\S*/asn1/\S*?([\s/])', r'\1.\2', out)
2948 #--- dbg_print -------------------------------------------------------
2949 def dbg_print(self):
2950 print("\n# Output files")
2951 print("\n".join(self.created_files_ord))
2954 #--- make_single_file -------------------------------------------------------
2955 def make_single_file(self):
2956 if (not self.single_file): return
2957 in_nm = self.single_file + '.c'
2958 out_nm = os.path.join(self.outdir, self.output_fname(''))
2959 self.do_include(out_nm, in_nm)
2960 in_nm = self.single_file + '.h'
2961 if (os.path.exists(in_nm)):
2962 out_nm = os.path.join(self.outdir, self.output_fname('', ext='h'))
2963 self.do_include(out_nm, in_nm)
2965 for fn in self.created_files_ord:
2966 if not self.created_files[fn]:
2969 #--- do_include -------------------------------------------------------
2970 def do_include(self, out_nm, in_nm):
2971 def check_file(fn, fnlist):
2972 fnfull = os.path.normcase(os.path.abspath(fn))
2973 if (fnfull in fnlist and os.path.exists(fnfull)):
2974 return os.path.normpath(fn)
2976 fin = open(in_nm, "r")
2977 fout = open(out_nm, "w")
2978 fout.write(self.fhdr(out_nm))
2979 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
2981 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm)))
2983 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2988 cont_linenum = cont_linenum + 1;
2989 line = fin.readline()
2990 if (line == ''): break
2992 result = include.search(line)
2993 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2995 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2997 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2999 ifile = check_file(result.group('fname'), self.created_files)
3002 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
3003 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile)))
3004 finc = open(ifile, "r")
3005 fout.write(finc.read())
3007 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
3008 fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) )
3017 #--- Node ---------------------------------------------------------------------
3019 def __init__(self,*args, **kw):
3021 self.type = self.__class__.__name__
3023 assert (len(args) == 1)
3025 self.__dict__.update (kw)
3026 def str_child (self, key, child, depth):
3027 indent = " " * (2 * depth)
3028 keystr = indent + key + ": "
3029 if key == 'type': # already processed in str_depth
3031 if isinstance (child, Node): # ugh
3032 return keystr + "\n" + child.str_depth (depth+1)
3033 if isinstance(child, type ([])):
3036 if isinstance (x, Node):
3037 l.append (x.str_depth (depth+1))
3039 l.append (indent + " " + str(x) + "\n")
3040 return keystr + "[\n" + ''.join(l) + indent + "]\n"
3042 return keystr + str (child) + "\n"
3043 def str_depth (self, depth): # ugh
3044 indent = " " * (2 * depth)
3045 l = ["%s%s" % (indent, self.type)]
3046 l.append ("".join ([self.str_child (k_v[0], k_v[1], depth + 1) for k_v in list(self.__dict__.items ())]))
3047 return "\n".join (l)
3049 return "\n" + self.str_depth (0)
3050 def to_python (self, ctx):
3051 return self.str_depth (ctx.indent_lev)
3053 def eth_reg(self, ident, ectx):
3056 def fld_obj_repr(self, ectx):
3057 return "/* TO DO %s */" % (str(self))
3060 #--- ValueAssignment -------------------------------------------------------------
3061 class ValueAssignment (Node):
3062 def __init__(self,*args, **kw) :
3063 Node.__init__ (self,*args, **kw)
3065 def eth_reg(self, ident, ectx):
3066 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3067 ectx.eth_reg_vassign(self)
3068 ectx.eth_reg_value(self.ident, self.typ, self.val)
3070 #--- ObjectAssignment -------------------------------------------------------------
3071 class ObjectAssignment (Node):
3072 def __init__(self,*args, **kw) :
3073 Node.__init__ (self,*args, **kw)
3075 def __eq__(self, other):
3076 if self.cls != other.cls:
3078 if len(self.val) != len(other.val):
3080 for f in (list(self.val.keys())):
3081 if f not in other.val:
3083 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
3084 if not self.val[f].fld_obj_eq(other.val[f]):
3087 if str(self.val[f]) != str(other.val[f]):
3091 def eth_reg(self, ident, ectx):
3092 def make_virtual_type(cls, field, prefix):
3093 if isinstance(self.val, str): return
3094 if field in self.val and not isinstance(self.val[field], Type_Ref):
3095 vnm = prefix + '-' + self.ident
3096 virtual_tr = Type_Ref(val = vnm)
3098 self.val[field] = virtual_tr
3099 ectx.eth_reg_assign(vnm, t, virt=True)
3100 ectx.eth_reg_type(vnm, t)
3101 t.eth_reg_sub(vnm, ectx)
3102 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field):
3103 ectx.eth_reg_field(self.val[field].val, self.val[field].val, impl=self.val[field].HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', cls + '.' + field))
3105 # end of make_virtual_type()
3106 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3107 self.module = ectx.Module()
3108 ectx.eth_reg_oassign(self)
3109 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
3110 make_virtual_type(self.cls, '&Type', 'TYPE')
3111 if (self.cls == 'OPERATION'):
3112 make_virtual_type(self.cls, '&ArgumentType', 'ARG')
3113 make_virtual_type(self.cls, '&ResultType', 'RES')
3114 if (self.cls == 'ERROR'):
3115 make_virtual_type(self.cls, '&ParameterType', 'PAR')
3118 #--- Type ---------------------------------------------------------------------
3120 def __init__(self,*args, **kw) :
3124 self.named_list = None
3125 Node.__init__ (self,*args, **kw)
3128 if self.name is None :
3133 def HasConstraint(self):
3134 if self.constr is None :
3139 def HasSizeConstraint(self):
3140 return self.HasConstraint() and self.constr.IsSize()
3142 def HasValueConstraint(self):
3143 return self.HasConstraint() and self.constr.IsValue()
3145 def HasPermAlph(self):
3146 return self.HasConstraint() and self.constr.IsPermAlph()
3148 def HasContentsConstraint(self):
3149 return self.HasConstraint() and self.constr.IsContents()
3151 def HasOwnTag(self):
3152 return len(self.tags) > 0
3154 def HasImplicitTag(self, ectx):
3155 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
3157 def IndetermTag(self, ectx):
3160 def AddTag(self, tag):
3161 self.tags[0:0] = [tag]
3163 def GetTag(self, ectx):
3164 #print "GetTag(%s)\n" % self.name;
3165 if (self.HasOwnTag()):
3166 return self.tags[0].GetTag(ectx)
3168 return self.GetTTag(ectx)
3170 def GetTTag(self, ectx):
3171 print("#Unhandled GetTTag() in %s" % (self.type))
3172 print(self.str_depth(1))
3173 return ('BER_CLASS_unknown', 'TAG_unknown')
3175 def SetName(self, name):
3178 def AddConstraint(self, constr):
3179 if not self.HasConstraint():
3180 self.constr = constr
3182 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
3184 def eth_tname(self):
3185 return '#' + self.type + '_' + str(id(self))
3187 def eth_ftype(self, ectx):
3188 return ('FT_NONE', 'BASE_NONE')
3190 def eth_strings(self):
3193 def eth_omit_field(self):
3196 def eth_need_tree(self):
3199 def eth_has_vals(self):
3202 def eth_has_enum(self, tname, ectx):
3203 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
3205 def eth_need_pdu(self, ectx):
3208 def eth_named_bits(self):
3211 def eth_reg_sub(self, ident, ectx):
3214 def get_components(self, ectx):
3215 print("#Unhandled get_components() in %s" % (self.type))
3216 print(self.str_depth(1))
3219 def sel_req(self, sel, ectx):
3220 print("#Selection '%s' required for non-CHOICE type %s" % (sel, self.type))
3221 print(self.str_depth(1))
3223 def fld_obj_eq(self, other):
3224 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
3226 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
3227 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3229 if (ectx.NeedTags() and (len(self.tags) > tstrip)):
3231 for i in range(len(self.tags)-1, tstrip-1, -1):
3232 tagged_type = TaggedType(val=tagged_type, tstrip=i)
3233 tagged_type.AddTag(self.tags[i])
3234 if not tagflag: # 1st tagged level
3235 if self.IsNamed() and not selflag:
3236 tagged_type.SetName(self.name)
3237 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
3240 if ident and self.IsNamed() and not tagflag and not selflag:
3241 nm = ident + '/' + self.name
3244 elif self.IsNamed():
3246 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
3247 if not ident: # Assignment
3248 ectx.eth_reg_assign(nm, self)
3249 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx):
3250 ectx.eth_reg_type(nm, self)
3251 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
3252 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
3253 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
3254 if ectx.conform.check_item('SET_TYPE', nm):
3255 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
3257 ectx.eth_reg_type(nm, self) # new type
3259 elif ectx.conform.check_item('SET_TYPE', nm):
3260 trnm = ectx.conform.use_item('SET_TYPE', nm)
3261 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx):
3262 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints
3267 ectx.eth_reg_type(nm, self)
3269 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
3270 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
3271 ectx.eth_reg_assign(vnm, self, virt=True)
3272 ectx.eth_reg_type(vnm, self)
3273 self.eth_reg_sub(vnm, ectx)
3274 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
3275 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
3276 if ident and not tagflag and not self.eth_omit_field():
3277 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
3278 if ectx.conform.check_item('SET_TYPE', nm):
3279 virtual_tr.eth_reg_sub(nm, ectx)
3281 self.eth_reg_sub(nm, ectx)
3283 def eth_get_size_constr(self, ectx):
3284 (minv, maxv, ext) = ('MIN', 'MAX', False)
3285 if self.HasSizeConstraint():
3286 if self.constr.IsSize():
3287 (minv, maxv, ext) = self.constr.GetSize(ectx)
3288 if (self.constr.type == 'Intersection'):
3289 if self.constr.subtype[0].IsSize():
3290 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
3291 elif self.constr.subtype[1].IsSize():
3292 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
3293 if minv == 'MIN': minv = 'NO_BOUND'
3294 if maxv == 'MAX': maxv = 'NO_BOUND'
3295 if (ext): ext = 'TRUE'
3297 return (minv, maxv, ext)
3299 def eth_get_value_constr(self, ectx):
3300 (minv, maxv, ext) = ('MIN', 'MAX', False)
3301 if self.HasValueConstraint():
3302 (minv, maxv, ext) = self.constr.GetValue(ectx)
3303 if minv == 'MIN': minv = 'NO_BOUND'
3304 if maxv == 'MAX': maxv = 'NO_BOUND'
3305 if str(minv).isdigit():
3307 elif (str(minv)[0] == "-") and str(minv)[1:].isdigit():
3308 if (int(minv) == -(2**31)):
3310 elif (int(minv) < -(2**31)):
3311 minv = "G_GINT64_CONSTANT(%s)" % (str(minv))
3312 if str(maxv).isdigit():
3313 if (int(maxv) >= 2**32):
3314 maxv = "G_GUINT64_CONSTANT(%s)" % (str(maxv))
3317 if (ext): ext = 'TRUE'
3319 return (minv, maxv, ext)
3321 def eth_get_alphabet_constr(self, ectx):
3322 (alph, alphlen) = ('NULL', '0')
3323 if self.HasPermAlph():
3324 alph = self.constr.GetPermAlph(ectx)
3327 if (alph != 'NULL'):
3328 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
3329 alphlen = str(len(alph) - 2)
3331 alphlen = 'strlen(%s)' % (alph)
3332 return (alph, alphlen)
3334 def eth_type_vals(self, tname, ectx):
3335 if self.eth_has_vals():
3336 print("#Unhandled eth_type_vals('%s') in %s" % (tname, self.type))
3337 print(self.str_depth(1))
3340 def eth_type_enum(self, tname, ectx):
3341 if self.eth_has_enum(tname, ectx):
3342 print("#Unhandled eth_type_enum('%s') in %s" % (tname, self.type))
3343 print(self.str_depth(1))
3346 def eth_type_default_table(self, ectx, tname):
3349 def eth_type_default_body(self, ectx):
3350 print("#Unhandled eth_type_default_body() in %s" % (self.type))
3351 print(self.str_depth(1))
3354 def eth_type_default_pars(self, ectx, tname):
3361 'OFFSET' : 'offset',
3363 'HF_INDEX' : 'hf_index',
3365 'IMPLICIT_TAG' : 'implicit_tag',
3367 if (ectx.eth_type[tname]['tree']):
3368 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
3369 if (ectx.merge_modules):
3372 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
3375 def eth_type_fn(self, proto, tname, ectx):
3376 body = self.eth_type_default_body(ectx, tname)
3377 pars = self.eth_type_default_pars(ectx, tname)
3378 if ectx.conform.check_item('FN_PARS', tname):
3379 pars.update(ectx.conform.use_item('FN_PARS', tname))
3380 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
3381 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
3382 pars['DEFAULT_BODY'] = body
3384 for k in list(pars.keys()):
3386 pars[k] = pars[k] % pars
3387 except (ValueError,TypeError):
3388 raise sys.exc_info()[0]("%s\n%s" % (str(pars), sys.exc_info()[1]))
3390 out += self.eth_type_default_table(ectx, tname) % pars
3391 out += ectx.eth_type_fn_hdr(tname)
3392 out += ectx.eth_type_fn_body(tname, body, pars=pars)
3393 out += ectx.eth_type_fn_ftr(tname)
3396 #--- Value --------------------------------------------------------------------
3398 def __init__(self,*args, **kw) :
3400 Node.__init__ (self,*args, **kw)
3402 def SetName(self, name) :
3405 def to_str(self, ectx):
3406 return str(self.val)
3411 def fld_obj_repr(self, ectx):
3412 return self.to_str(ectx)
3414 #--- Value_Ref -----------------------------------------------------------------
3415 class Value_Ref (Value):
3416 def to_str(self, ectx):
3417 return asn2c(self.val)
3419 #--- ObjectClass ---------------------------------------------------------------------
3420 class ObjectClass (Node):
3421 def __init__(self,*args, **kw) :
3423 Node.__init__ (self,*args, **kw)
3425 def SetName(self, name):
3427 add_class_ident(self.name)
3429 def eth_reg(self, ident, ectx):
3430 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
3431 ectx.eth_reg_objectclass(self.name, self)
3433 #--- Class_Ref -----------------------------------------------------------------
3434 class Class_Ref (ObjectClass):
3437 #--- ObjectClassDefn ---------------------------------------------------------------------
3438 class ObjectClassDefn (ObjectClass):
3439 def reg_types(self):
3440 for fld in self.fields:
3441 repr = fld.fld_repr()
3442 set_type_to_class(self.name, repr[0], repr[1:])
3445 #--- Tag ---------------------------------------------------------------
3447 def to_python (self, ctx):
3448 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
3451 self.typ.to_python (ctx))
3452 def IsImplicit(self, ectx):
3453 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT')))
3455 def GetTag(self, ectx):
3457 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
3458 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
3459 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
3460 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
3461 return (tc, self.num)
3463 def eth_tname(self):
3465 if (self.cls == 'UNIVERSAL'): n = 'U'
3466 elif (self.cls == 'APPLICATION'): n = 'A'
3467 elif (self.cls == 'CONTEXT'): n = 'C'
3468 elif (self.cls == 'PRIVATE'): n = 'P'
3469 return n + str(self.num)
3471 #--- Constraint ---------------------------------------------------------------
3473 class Constraint (Node):
3474 def to_python (self, ctx):
3475 print("Ignoring constraint:", self.type)
3476 return self.subtype.typ.to_python (ctx)
3478 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
3480 def eth_tname(self):
3481 return '#' + self.type + '_' + str(id(self))
3484 return (self.type == 'Size' and self.subtype.IsValue()) \
3485 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
3487 def GetSize(self, ectx):
3488 (minv, maxv, ext) = ('MIN', 'MAX', False)
3490 if self.type == 'Size':
3491 (minv, maxv, ext) = self.subtype.GetValue(ectx)
3492 elif self.type == 'Intersection':
3493 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
3494 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
3495 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
3496 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
3497 return (minv, maxv, ext)
3500 return self.type == 'SingleValue' \
3501 or self.type == 'ValueRange' \
3502 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
3503 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
3505 def GetValue(self, ectx):
3506 (minv, maxv, ext) = ('MIN', 'MAX', False)
3508 if self.type == 'SingleValue':
3509 minv = ectx.value_get_eth(self.subtype)
3510 maxv = ectx.value_get_eth(self.subtype)
3511 ext = hasattr(self, 'ext') and self.ext
3512 elif self.type == 'ValueRange':
3513 minv = ectx.value_get_eth(self.subtype[0])
3514 maxv = ectx.value_get_eth(self.subtype[1])
3515 ext = hasattr(self, 'ext') and self.ext
3516 elif self.type == 'Intersection':
3517 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3518 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3519 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3520 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3521 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3522 v0 = self.subtype[0].GetValue(ectx)
3523 v1 = self.subtype[1].GetValue(ectx)
3524 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3525 elif self.type == 'Union':
3526 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3527 v0 = self.subtype[0].GetValue(ectx)
3528 v1 = self.subtype[1].GetValue(ectx)
3529 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3530 return (minv, maxv, ext)
3532 def IsAlphabet(self):
3533 return self.type == 'SingleValue' \
3534 or self.type == 'ValueRange' \
3535 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3536 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3538 def GetAlphabet(self, ectx):
3540 if self.IsAlphabet():
3541 if self.type == 'SingleValue':
3542 alph = ectx.value_get_eth(self.subtype)
3543 elif self.type == 'ValueRange':
3544 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3545 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3547 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3550 elif self.type == 'Union':
3551 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3552 a0 = self.subtype[0].GetAlphabet(ectx)
3553 a1 = self.subtype[1].GetAlphabet(ectx)
3554 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3555 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3556 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3558 alph = a0 + ' ' + a1
3561 def IsPermAlph(self):
3562 return self.type == 'From' and self.subtype.IsAlphabet() \
3563 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3565 def GetPermAlph(self, ectx):
3567 if self.IsPermAlph():
3568 if self.type == 'From':
3569 alph = self.subtype.GetAlphabet(ectx)
3570 elif self.type == 'Intersection':
3571 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3572 alph = self.subtype[0].GetPermAlph(ectx)
3573 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3574 alph = self.subtype[1].GetPermAlph(ectx)
3577 def IsContents(self):
3578 return self.type == 'Contents' \
3579 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3581 def GetContents(self, ectx):
3583 if self.IsContents():
3584 if self.type == 'Contents':
3585 if self.subtype.type == 'Type_Ref':
3586 contents = self.subtype.val
3587 elif self.type == 'Intersection':
3588 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3589 contents = self.subtype[0].GetContents(ectx)
3590 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3591 contents = self.subtype[1].GetContents(ectx)
3594 def IsNegativ(self):
3596 return isinstance(sval, str) and (sval[0] == '-')
3597 if self.type == 'SingleValue':
3598 return is_neg(self.subtype)
3599 elif self.type == 'ValueRange':
3600 if self.subtype[0] == 'MIN': return True
3601 return is_neg(self.subtype[0])
3604 def eth_constrname(self):
3606 if isinstance(val, Value_Ref):
3607 return asn2c(val.val)
3610 return 'M' + str(-int(val))
3612 return str(int(val))
3613 except (ValueError, TypeError):
3614 return asn2c(str(val))
3617 if hasattr(self, 'ext') and self.ext:
3619 if self.type == 'SingleValue':
3620 return int2str(self.subtype) + ext
3621 elif self.type == 'ValueRange':
3622 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3623 elif self.type == 'Size':
3624 return 'SIZE_' + self.subtype.eth_constrname() + ext
3626 if (not hasattr(self, 'constr_num')):
3629 self.constr_num = constr_cnt
3630 return 'CONSTR%03d%s' % (self.constr_num, ext)
3633 class Module (Node):
3634 def to_python (self, ctx):
3635 ctx.tag_def = self.tag_def.dfl_tag
3637 %s""" % (self.ident, self.body.to_python (ctx))
3640 return self.ident.val
3642 def get_proto(self, ectx):
3646 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
3649 def to_eth(self, ectx):
3650 ectx.tags_def = 'EXPLICIT' # default = explicit
3651 ectx.proto = self.get_proto(ectx)
3652 ectx.tag_def = self.tag_def.dfl_tag
3653 ectx.eth_reg_module(self)
3654 self.body.to_eth(ectx)
3656 class Module_Body (Node):
3657 def to_python (self, ctx):
3658 # XXX handle exports, imports.
3659 l = [x.to_python (ctx) for x in self.assign_list]
3660 l = [a for a in l if a != '']
3661 return "\n".join (l)
3663 def to_eth(self, ectx):
3665 ectx.eth_exports(self.exports)
3667 for i in self.imports:
3669 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3670 ectx.eth_module_dep_add(ectx.Module(), mod)
3671 for s in i.symbol_list:
3672 if isinstance(s, Type_Ref):
3673 ectx.eth_import_type(s.val, mod, proto)
3674 elif isinstance(s, Value_Ref):
3675 ectx.eth_import_value(s.val, mod, proto)
3676 elif isinstance(s, Class_Ref):
3677 ectx.eth_import_class(s.val, mod, proto)
3679 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
3680 warnings.warn_explicit(msg, UserWarning, '', 0)
3682 for a in self.assign_list:
3685 class Default_Tags (Node):
3686 def to_python (self, ctx): # not to be used directly
3689 # XXX should just calculate dependencies as we go along.
3690 def calc_dependencies (node, dict, trace = 0):
3691 if not hasattr (node, '__dict__'):
3692 if trace: print("#returning, node=", node)
3694 if isinstance (node, Type_Ref):
3696 if trace: print("#Setting", node.val)
3698 for (a, val) in list(node.__dict__.items ()):
3699 if trace: print("# Testing node ", node, "attr", a, " val", val)
3702 elif isinstance (val, Node):
3703 calc_dependencies (val, dict, trace)
3704 elif isinstance (val, type ([])):
3706 calc_dependencies (v, dict, trace)
3709 class Type_Assign (Node):
3710 def __init__ (self, *args, **kw):
3711 Node.__init__ (self, *args, **kw)
3712 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3713 to_test = self.val.typ
3716 if isinstance (to_test, SequenceType):
3717 to_test.sequence_name = self.name.name
3719 def to_python (self, ctx):
3721 calc_dependencies (self.val, dep_dict, 0)
3722 depend_list = list(dep_dict.keys ())
3723 return ctx.register_assignment (self.name.name,
3724 self.val.to_python (ctx),
3727 class PyQuote (Node):
3728 def to_python (self, ctx):
3729 return ctx.register_pyquote (self.val)
3731 #--- Type_Ref -----------------------------------------------------------------
3732 class Type_Ref (Type):
3733 def to_python (self, ctx):
3736 def eth_reg_sub(self, ident, ectx):
3737 ectx.eth_dep_add(ident, self.val)
3739 def eth_tname(self):
3740 if self.HasSizeConstraint():
3741 return asn2c(self.val) + '_' + self.constr.eth_constrname()
3743 return asn2c(self.val)
3745 def tr_need_own_fn(self, ectx):
3746 return ectx.Per() and self.HasSizeConstraint()
3748 def fld_obj_repr(self, ectx):
3751 def get_components(self, ectx):
3752 if self.val not in ectx.type or ectx.type[self.val]['import']:
3753 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3754 warnings.warn_explicit(msg, UserWarning, '', 0)
3757 return ectx.type[self.val]['val'].get_components(ectx)
3759 def GetTTag(self, ectx):
3760 #print "GetTTag(%s)\n" % self.val;
3761 if (ectx.type[self.val]['import']):
3762 if 'ttag' not in ectx.type[self.val]:
3763 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3764 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3765 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3766 warnings.warn_explicit(msg, UserWarning, '', 0)
3767 ttag = ('-1/*imported*/', '-1/*imported*/')
3768 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3769 return ectx.type[self.val]['ttag']
3771 return ectx.type[self.val]['val'].GetTag(ectx)
3773 def IndetermTag(self, ectx):
3774 if (ectx.type[self.val]['import']):
3777 return ectx.type[self.val]['val'].IndetermTag(ectx)
3779 def eth_type_default_pars(self, ectx, tname):
3781 pars = Type.eth_type_default_pars(self, ectx, tname)
3784 t = ectx.type[self.val]['ethname']
3785 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3786 pars['TYPE_REF_TNAME'] = t
3787 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3788 if self.HasSizeConstraint():
3789 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3792 def eth_type_default_body(self, ectx, tname):
3794 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3795 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3797 if self.HasSizeConstraint():
3798 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset',
3799 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3800 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3802 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3803 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3805 body = '#error Can not decode %s' % (tname)
3808 #--- SelectionType ------------------------------------------------------------
3809 class SelectionType (Type):
3810 def to_python (self, ctx):
3813 def sel_of_typeref(self):
3814 return self.typ.type == 'Type_Ref'
3816 def eth_reg_sub(self, ident, ectx):
3817 if not self.sel_of_typeref():
3820 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3821 ectx.eth_dep_add(ident, self.seltype)
3823 def eth_ftype(self, ectx):
3824 (ftype, display) = ('FT_NONE', 'BASE_NONE')
3825 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
3826 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
3827 return (ftype, display)
3829 def GetTTag(self, ectx):
3830 #print "GetTTag(%s)\n" % self.seltype;
3831 if (ectx.type[self.seltype]['import']):
3832 if 'ttag' not in ectx.type[self.seltype]:
3833 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3834 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3835 warnings.warn_explicit(msg, UserWarning, '', 0)
3836 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3837 return ectx.type[self.seltype]['ttag']
3839 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3841 def eth_type_default_pars(self, ectx, tname):
3842 pars = Type.eth_type_default_pars(self, ectx, tname)
3843 if self.sel_of_typeref():
3844 t = ectx.type[self.seltype]['ethname']
3845 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3846 pars['TYPE_REF_TNAME'] = t
3847 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3850 def eth_type_default_body(self, ectx, tname):
3851 if not self.sel_of_typeref():
3852 body = '#error Can not decode %s' % (tname)
3854 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3855 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3857 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3858 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3860 body = '#error Can not decode %s' % (tname)
3863 #--- TaggedType -----------------------------------------------------------------
3864 class TaggedType (Type):
3865 def eth_tname(self):
3867 for i in range(self.tstrip, len(self.val.tags)):
3868 tn += self.val.tags[i].eth_tname()
3870 tn += self.val.eth_tname()
3873 def eth_set_val_name(self, ident, val_name, ectx):
3874 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3875 self.val_name = val_name
3876 ectx.eth_dep_add(ident, self.val_name)
3878 def eth_reg_sub(self, ident, ectx):
3879 self.val_name = ident + '/' + UNTAG_TYPE_NAME
3880 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3882 def GetTTag(self, ectx):
3883 #print "GetTTag(%s)\n" % self.seltype;
3884 return self.GetTag(ectx)
3886 def eth_ftype(self, ectx):
3887 return self.val.eth_ftype(ectx)
3889 def eth_type_default_pars(self, ectx, tname):
3890 pars = Type.eth_type_default_pars(self, ectx, tname)
3891 t = ectx.type[self.val_name]['ethname']
3892 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3893 pars['TYPE_REF_TNAME'] = t
3894 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3895 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3896 if self.HasImplicitTag(ectx):
3897 pars['TAG_IMPL'] = 'TRUE'
3899 pars['TAG_IMPL'] = 'FALSE'
3902 def eth_type_default_body(self, ectx, tname):
3904 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3905 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3906 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3908 body = '#error Can not decode %s' % (tname)
3911 #--- SqType -----------------------------------------------------------
3912 class SqType (Type):
3913 def out_item(self, f, val, optional, ext, ectx):
3914 if (val.eth_omit_field()):
3915 t = ectx.type[val.ident]['ethname']
3916 fullname = ectx.dummy_eag_field
3918 ef = ectx.field[f]['ethname']
3919 t = ectx.eth_hf[ef]['ethtype']
3920 fullname = ectx.eth_hf[ef]['fullname']
3922 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3923 #print val.str_depth(1)
3926 opt = 'BER_FLAGS_OPTIONAL'
3927 if (not val.HasOwnTag()):
3928 if (opt): opt += '|'
3929 opt += 'BER_FLAGS_NOOWNTAG'
3930 elif (val.HasImplicitTag(ectx)):
3931 if (opt): opt += '|'
3932 opt += 'BER_FLAGS_IMPLTAG'
3933 if (val.IndetermTag(ectx)):
3934 if (opt): opt += '|'
3935 opt += 'BER_FLAGS_NOTCHKTAG'
3936 if (not opt): opt = '0'
3939 opt = 'ASN1_OPTIONAL'
3941 opt = 'ASN1_NOT_OPTIONAL'
3943 (tc, tn) = val.GetTag(ectx)
3944 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3945 % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t)
3947 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3948 % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t)
3953 #--- SeqType -----------------------------------------------------------
3954 class SeqType (SqType):
3956 def all_components(self):
3957 lst = self.elt_list[:]
3958 if hasattr(self, 'ext_list'):
3959 lst.extend(self.ext_list)
3960 if hasattr(self, 'elt_list2'):
3961 lst.extend(self.elt_list2)
3964 def need_components(self):
3965 lst = self.all_components()
3967 if e.type == 'components_of':
3971 def expand_components(self, ectx):
3972 while self.need_components():
3973 for i in range(len(self.elt_list)):
3974 if self.elt_list[i].type == 'components_of':
3975 comp = self.elt_list[i].typ.get_components(ectx)
3976 self.elt_list[i:i+1] = comp
3978 if hasattr(self, 'ext_list'):
3979 for i in range(len(self.ext_list)):
3980 if self.ext_list[i].type == 'components_of':
3981 comp = self.ext_list[i].typ.get_components(ectx)
3982 self.ext_list[i:i+1] = comp
3984 if hasattr(self, 'elt_list2'):
3985 for i in range(len(self.elt_list2)):
3986 if self.elt_list2[i].type == 'components_of':
3987 comp = self.elt_list2[i].typ.get_components(ectx)
3988 self.elt_list2[i:i+1] = comp
3991 def get_components(self, ectx):
3992 lst = self.elt_list[:]
3993 if hasattr(self, 'elt_list2'):
3994 lst.extend(self.elt_list2)
3997 def eth_reg_sub(self, ident, ectx, components_available=False):
3998 # check if autotag is required
4000 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4002 lst = self.all_components()
4003 for e in (self.elt_list):
4004 if e.val.HasOwnTag(): autotag = False; break;
4005 # expand COMPONENTS OF
4006 if self.need_components():
4007 if components_available:
4008 self.expand_components(ectx)
4010 ectx.eth_comp_req(ident)
4012 # extension addition groups
4013 if hasattr(self, 'ext_list'):
4014 if (ectx.Per()): # add names
4016 for e in (self.ext_list):
4017 if isinstance(e.val, ExtensionAdditionGroup):
4018 e.val.parent_ident = ident
4019 e.val.parent_tname = ectx.type[ident]['tname']
4021 e.val.SetName("eag_v%s" % (e.val.ver))
4023 e.val.SetName("eag_%d" % (eag_num))
4027 for e in (self.ext_list):
4028 if isinstance(e.val, ExtensionAdditionGroup):
4029 new_ext_list.extend(e.val.elt_list)
4031 new_ext_list.append(e)
4032 self.ext_list = new_ext_list
4036 for e in (self.elt_list):
4037 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4039 if autotag and hasattr(self, 'elt_list2'):
4040 for e in (self.elt_list2):
4041 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4043 if autotag and hasattr(self, 'ext_list'):
4044 for e in (self.ext_list):
4045 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4047 # register components
4048 for e in (self.elt_list):
4049 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4050 if hasattr(self, 'ext_list'):
4051 for e in (self.ext_list):
4052 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4053 if hasattr(self, 'elt_list2'):
4054 for e in (self.elt_list2):
4055 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4057 def eth_type_default_table(self, ectx, tname):
4058 #print "eth_type_default_table(tname='%s')" % (tname)
4059 fname = ectx.eth_type[tname]['ref'][0]
4060 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
4061 if hasattr(self, 'ext_list'):
4062 ext = 'ASN1_EXTENSION_ROOT'
4064 ext = 'ASN1_NO_EXTENSIONS'
4065 empty_ext_flag = '0'
4066 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0) and (not hasattr(self, 'elt_list2') or (len(self.elt_list2)==0)):
4067 empty_ext_flag = ext
4068 for e in (self.elt_list):
4069 f = fname + '/' + e.val.name
4070 table += self.out_item(f, e.val, e.optional, ext, ectx)
4071 if hasattr(self, 'ext_list'):
4072 for e in (self.ext_list):
4073 f = fname + '/' + e.val.name
4074 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4075 if hasattr(self, 'elt_list2'):
4076 for e in (self.elt_list2):
4077 f = fname + '/' + e.val.name
4078 table += self.out_item(f, e.val, e.optional, ext, ectx)
4080 table += " { NULL, 0, 0, 0, NULL }\n};\n"
4082 table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag)
4085 #--- SeqOfType -----------------------------------------------------------
4086 class SeqOfType (SqType):
4087 def eth_type_default_table(self, ectx, tname):
4088 #print "eth_type_default_table(tname='%s')" % (tname)
4089 fname = ectx.eth_type[tname]['ref'][0]
4090 if self.val.IsNamed ():
4091 f = fname + '/' + self.val.name
4093 f = fname + '/' + ITEM_FIELD_NAME
4094 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
4095 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
4099 #--- SequenceOfType -----------------------------------------------------------
4100 class SequenceOfType (SeqOfType):
4101 def to_python (self, ctx):
4102 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4103 # or '' + (1,) for optional
4105 if self.size_constr != None:
4106 print("#Ignoring size constraint:", self.size_constr.subtype)
4107 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
4108 self.val.to_python (ctx),
4111 def eth_reg_sub(self, ident, ectx):
4113 if not self.val.IsNamed ():
4114 itmnm += '/' + ITEM_FIELD_NAME
4115 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
4117 def eth_tname(self):
4118 if self.val.type != 'Type_Ref':
4119 return '#' + self.type + '_' + str(id(self))
4120 if not self.HasConstraint():
4121 return "SEQUENCE_OF_" + self.val.eth_tname()
4122 elif self.constr.IsSize():
4123 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4125 return '#' + self.type + '_' + str(id(self))
4127 def eth_ftype(self, ectx):
4128 return ('FT_UINT32', 'BASE_DEC')
4130 def eth_need_tree(self):
4133 def GetTTag(self, ectx):
4134 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4136 def eth_type_default_pars(self, ectx, tname):
4137 pars = Type.eth_type_default_pars(self, ectx, tname)
4138 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4139 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
4142 def eth_type_default_body(self, ectx, tname):
4144 if (ectx.constraints_check and self.HasSizeConstraint()):
4145 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4146 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4147 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4149 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4150 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4151 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4152 elif (ectx.Per() and not self.HasConstraint()):
4153 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4154 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4155 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4156 elif (ectx.Per() and self.constr.type == 'Size'):
4157 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4158 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4159 ('%(ETT_INDEX)s', '%(TABLE)s',),
4160 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
4162 body = '#error Can not decode %s' % (tname)
4166 #--- SetOfType ----------------------------------------------------------------
4167 class SetOfType (SeqOfType):
4168 def eth_reg_sub(self, ident, ectx):
4170 if not self.val.IsNamed ():
4171 itmnm += '/' + ITEM_FIELD_NAME
4172 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
4174 def eth_tname(self):
4175 if self.val.type != 'Type_Ref':
4176 return '#' + self.type + '_' + str(id(self))
4177 if not self.HasConstraint():
4178 return "SET_OF_" + self.val.eth_tname()
4179 elif self.constr.IsSize():
4180 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4182 return '#' + self.type + '_' + str(id(self))
4184 def eth_ftype(self, ectx):
4185 return ('FT_UINT32', 'BASE_DEC')
4187 def eth_need_tree(self):
4190 def GetTTag(self, ectx):
4191 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4193 def eth_type_default_pars(self, ectx, tname):
4194 pars = Type.eth_type_default_pars(self, ectx, tname)
4195 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4196 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
4199 def eth_type_default_body(self, ectx, tname):
4201 if (ectx.constraints_check and self.HasSizeConstraint()):
4202 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4203 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4204 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4206 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4207 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4208 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4209 elif (ectx.Per() and not self.HasConstraint()):
4210 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4211 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4212 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4213 elif (ectx.Per() and self.constr.type == 'Size'):
4214 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4215 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4216 ('%(ETT_INDEX)s', '%(TABLE)s',),
4217 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
4219 body = '#error Can not decode %s' % (tname)
4222 def mk_tag_str (ctx, cls, typ, num):
4224 # XXX should do conversion to int earlier!
4227 if typ == 'DEFAULT':
4229 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
4231 #--- SequenceType -------------------------------------------------------------
4232 class SequenceType (SeqType):
4233 def to_python (self, ctx):
4234 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4235 # or '' + (1,) for optional
4236 # XXX should also collect names for SEQUENCE inside SEQUENCE or
4237 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
4238 # from? for others, element or arm name would be fine)
4239 seq_name = getattr (self, 'sequence_name', None)
4240 if seq_name == None:
4243 seq_name = "'" + seq_name + "'"
4244 if 'ext_list' in self.__dict__:
4245 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
4246 self.elts_to_py (self.elt_list, ctx),
4247 self.elts_to_py (self.ext_list, ctx), seq_name)
4249 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
4250 self.elts_to_py (self.elt_list, ctx), seq_name)
4251 def elts_to_py (self, list, ctx):
4252 # we have elt_type, val= named_type, maybe default=, optional=
4253 # named_type node: either ident = or typ =
4254 # need to dismember these in order to generate Python output syntax.
4257 assert (e.type == 'elt_type')
4259 optflag = e.optional
4260 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
4261 assert (nt.type == 'named_type')
4264 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4265 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4266 nt.typ.tag.tag_typ,nt.typ.tag.num)
4270 return "('%s',%s,%s,%d)" % (identstr, tagstr,
4271 nt.typ.to_python (ctx), optflag)
4272 indentstr = ",\n" + ctx.spaces ()
4273 rv = indentstr.join ([elt_to_py (e) for e in list])
4277 def eth_need_tree(self):
4280 def GetTTag(self, ectx):
4281 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4283 def eth_type_default_pars(self, ectx, tname):
4284 pars = Type.eth_type_default_pars(self, ectx, tname)
4285 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4288 def eth_type_default_body(self, ectx, tname):
4290 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4291 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4292 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4294 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4295 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4296 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4298 body = '#error Can not decode %s' % (tname)
4301 #--- ExtensionAdditionGroup ---------------------------------------------------
4302 class ExtensionAdditionGroup (SeqType):
4303 def __init__(self,*args, **kw) :
4304 self.parent_ident = None
4305 self.parent_tname = None
4306 SeqType.__init__ (self,*args, **kw)
4308 def eth_omit_field(self):
4311 def eth_tname(self):
4312 if (self.parent_tname and self.IsNamed()):
4313 return self.parent_tname + "_" + self.name
4315 return SeqType.eth_tname(self)
4317 def eth_reg_sub(self, ident, ectx):
4318 ectx.eth_dummy_eag_field_required()
4319 ectx.eth_dep_add(self.parent_ident, ident)
4320 SeqType.eth_reg_sub(self, ident, ectx)
4322 def eth_type_default_pars(self, ectx, tname):
4323 pars = Type.eth_type_default_pars(self, ectx, tname)
4324 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4327 def eth_type_default_body(self, ectx, tname):
4329 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset',
4330 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
4332 body = '#error Can not decode %s' % (tname)
4336 #--- SetType ------------------------------------------------------------------
4337 class SetType (SeqType):
4339 def eth_need_tree(self):
4342 def GetTTag(self, ectx):
4343 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4345 def eth_type_default_pars(self, ectx, tname):
4346 pars = Type.eth_type_default_pars(self, ectx, tname)
4347 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4350 def eth_type_default_body(self, ectx, tname):
4352 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4353 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4354 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4356 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4357 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4358 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4360 body = '#error Can not decode %s' % (tname)
4363 #--- ChoiceType ---------------------------------------------------------------
4364 class ChoiceType (Type):
4365 def to_python (self, ctx):
4366 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4367 # or '' + (1,) for optional
4368 if 'ext_list' in self.__dict__:
4369 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
4370 self.elts_to_py (self.elt_list, ctx),
4371 self.elts_to_py (self.ext_list, ctx))
4373 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
4374 def elts_to_py (self, list, ctx):
4377 assert (nt.type == 'named_type')
4379 if hasattr (nt, 'ident'):
4382 if hasattr (nt.typ, 'val'):
4383 identstr = nt.typ.val # XXX, making up name
4384 elif hasattr (nt.typ, 'name'):
4385 identstr = nt.typ.name
4387 identstr = ctx.make_new_name ()
4389 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4390 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4391 nt.typ.tag.tag_typ,nt.typ.tag.num)
4395 return "('%s',%s,%s)" % (identstr, tagstr,
4396 nt.typ.to_python (ctx))
4397 indentstr = ",\n" + ctx.spaces ()
4398 rv = indentstr.join ([elt_to_py (e) for e in list])
4402 def eth_reg_sub(self, ident, ectx):
4403 #print "eth_reg_sub(ident='%s')" % (ident)
4404 # check if autotag is required
4406 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4408 for e in (self.elt_list):
4409 if e.HasOwnTag(): autotag = False; break;
4410 if autotag and hasattr(self, 'ext_list'):
4411 for e in (self.ext_list):
4412 if e.HasOwnTag(): autotag = False; break;
4416 for e in (self.elt_list):
4417 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4419 if autotag and hasattr(self, 'ext_list'):
4420 for e in (self.ext_list):
4421 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4423 for e in (self.elt_list):
4424 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4425 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4426 ectx.eth_sel_req(ident, e.name)
4427 if hasattr(self, 'ext_list'):
4428 for e in (self.ext_list):
4429 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4430 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4431 ectx.eth_sel_req(ident, e.name)
4433 def sel_item(self, ident, sel, ectx):
4434 lst = self.elt_list[:]
4435 if hasattr(self, 'ext_list'):
4436 lst.extend(self.ext_list)
4438 for e in (self.elt_list):
4439 if e.IsNamed() and (e.name == sel):
4443 print("#CHOICE %s does not contain item %s" % (ident, sel))
4446 def sel_req(self, ident, sel, ectx):
4447 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4448 ee = self.sel_item(ident, sel, ectx)
4450 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
4452 def eth_ftype(self, ectx):
4453 return ('FT_UINT32', 'BASE_DEC')
4455 def eth_ftype_sel(self, sel, ectx):
4456 ee = self.sel_item('', sel, ectx)
4458 return ee.eth_ftype(ectx)
4460 return ('FT_NONE', 'BASE_NONE')
4462 def eth_strings(self):
4465 def eth_need_tree(self):
4468 def eth_has_vals(self):
4471 def GetTTag(self, ectx):
4473 cls = 'BER_CLASS_ANY/*choice*/'
4474 #if hasattr(self, 'ext_list'):
4475 # lst.extend(self.ext_list)
4477 # cls = lst[0].GetTag(ectx)[0]
4479 # if (e.GetTag(ectx)[0] != cls):
4480 # cls = '-1/*choice*/'
4481 return (cls, '-1/*choice*/')
4483 def GetTTagSel(self, sel, ectx):
4484 ee = self.sel_item('', sel, ectx)
4486 return ee.GetTag(ectx)
4488 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4490 def IndetermTag(self, ectx):
4491 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4492 return not self.HasOwnTag()
4494 def detect_tagval(self, ectx):
4496 lst = self.elt_list[:]
4497 if hasattr(self, 'ext_list'):
4498 lst.extend(self.ext_list)
4499 if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()):
4500 t = lst[0].GetTag(ectx)[0]
4505 if (t == 'BER_CLASS_UNI'):
4508 if not ectx.Per() or e.HasOwnTag():
4509 tt = e.GetTag(ectx)[0]
4517 def get_vals(self, ectx):
4518 tagval = self.detect_tagval(ectx)
4521 for e in (self.elt_list):
4522 if (tagval): val = e.GetTag(ectx)[1]
4523 else: val = str(cnt)
4524 vals.append((val, e.name))
4526 if hasattr(self, 'ext_list'):
4527 for e in (self.ext_list):
4528 if (tagval): val = e.GetTag(ectx)[1]
4529 else: val = str(cnt)
4530 vals.append((val, e.name))
4534 def eth_type_vals(self, tname, ectx):
4536 vals = self.get_vals(ectx)
4537 out += ectx.eth_vals(tname, vals)
4540 def reg_enum_vals(self, tname, ectx):
4541 vals = self.get_vals(ectx)
4542 for (val, id) in vals:
4543 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4545 def eth_type_enum(self, tname, ectx):
4547 vals = self.get_vals(ectx)
4548 out += ectx.eth_enum(tname, vals)
4551 def eth_type_default_pars(self, ectx, tname):
4552 pars = Type.eth_type_default_pars(self, ectx, tname)
4553 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4556 def eth_type_default_table(self, ectx, tname):
4557 def out_item(val, e, ext, ectx):
4558 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
4560 vval = ectx.eth_enum_item(tname, e.name)
4563 f = fname + '/' + e.name
4564 ef = ectx.field[f]['ethname']
4565 t = ectx.eth_hf[ef]['ethtype']
4568 if (not e.HasOwnTag()):
4569 opt = 'BER_FLAGS_NOOWNTAG'
4570 elif (e.HasImplicitTag(ectx)):
4571 if (opt): opt += '|'
4572 opt += 'BER_FLAGS_IMPLTAG'
4573 if (not opt): opt = '0'
4575 (tc, tn) = e.GetTag(ectx)
4576 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4577 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
4579 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4580 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
4585 #print "eth_type_default_table(tname='%s')" % (tname)
4586 fname = ectx.eth_type[tname]['ref'][0]
4587 tagval = self.detect_tagval(ectx)
4588 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4590 if hasattr(self, 'ext_list'):
4591 ext = 'ASN1_EXTENSION_ROOT'
4593 ext = 'ASN1_NO_EXTENSIONS'
4594 empty_ext_flag = '0'
4595 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0):
4596 empty_ext_flag = ext
4597 for e in (self.elt_list):
4598 if (tagval): val = e.GetTag(ectx)[1]
4599 else: val = str(cnt)
4600 table += out_item(val, e, ext, ectx)
4602 if hasattr(self, 'ext_list'):
4603 for e in (self.ext_list):
4604 if (tagval): val = e.GetTag(ectx)[1]
4605 else: val = str(cnt)
4606 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4609 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4611 table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag)
4614 def eth_type_default_body(self, ectx, tname):
4616 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4617 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4618 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4621 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4622 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4623 ('%(ETT_INDEX)s', '%(TABLE)s',),
4626 body = '#error Can not decode %s' % (tname)
4629 #--- ChoiceValue ----------------------------------------------------
4630 class ChoiceValue (Value):
4631 def to_str(self, ectx):
4632 return self.val.to_str(ectx)
4634 def fld_obj_eq(self, other):
4635 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
4637 #--- EnumeratedType -----------------------------------------------------------
4638 class EnumeratedType (Type):
4639 def to_python (self, ctx):
4640 def strify_one (named_num):
4641 return "%s=%s" % (named_num.ident, named_num.val)
4642 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4644 def eth_ftype(self, ectx):
4645 return ('FT_UINT32', 'BASE_DEC')
4647 def eth_strings(self):
4650 def eth_has_vals(self):
4653 def GetTTag(self, ectx):
4654 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4656 def get_vals_etc(self, ectx):
4664 for e in (self.val):
4665 if e.type == 'NamedNumber':
4666 used[int(e.val)] = True
4667 for e in (self.val):
4668 if e.type == 'NamedNumber':
4671 while lastv in used:
4675 vals.append((val, e.ident))
4676 map_table.append(val)
4680 if self.ext is not None:
4681 for e in (self.ext):
4682 if e.type == 'NamedNumber':
4683 used[int(e.val)] = True
4684 for e in (self.ext):
4685 if e.type == 'NamedNumber':
4688 while lastv in used:
4692 vals.append((val, e.ident))
4693 map_table.append(val)
4698 for i in range(len(map_table)):
4699 need_map = need_map or (map_table[i] != i)
4702 return (vals, root_num, ext_num, map_table)
4704 def eth_type_vals(self, tname, ectx):
4706 vals = self.get_vals_etc(ectx)[0]
4707 out += ectx.eth_vals(tname, vals)
4710 def reg_enum_vals(self, tname, ectx):
4711 vals = self.get_vals_etc(ectx)[0]
4712 for (val, id) in vals:
4713 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4715 def eth_type_enum(self, tname, ectx):
4717 vals = self.get_vals_etc(ectx)[0]
4718 out += ectx.eth_enum(tname, vals)
4721 def eth_type_default_pars(self, ectx, tname):
4722 pars = Type.eth_type_default_pars(self, ectx, tname)
4723 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4724 if (self.ext != None):
4728 pars['ROOT_NUM'] = str(root_num)
4730 pars['EXT_NUM'] = str(ext_num)
4732 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4734 pars['TABLE'] = 'NULL'
4737 def eth_type_default_table(self, ectx, tname):
4738 if (not ectx.Per()): return ''
4739 map_table = self.get_vals_etc(ectx)[3]
4740 if (map_table == None): return ''
4741 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4742 table += ", ".join([str(v) for v in map_table])
4746 def eth_type_default_body(self, ectx, tname):
4748 if (ectx.constraints_check and self.HasValueConstraint()):
4749 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
4750 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4751 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4753 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4754 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4757 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4758 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4759 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4761 body = '#error Can not decode %s' % (tname)
4764 #--- EmbeddedPDVType -----------------------------------------------------------
4765 class EmbeddedPDVType (Type):
4766 def eth_tname(self):
4767 return 'EMBEDDED_PDV'
4769 def eth_ftype(self, ectx):
4770 return ('FT_NONE', 'BASE_NONE')
4772 def GetTTag(self, ectx):
4773 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4775 def eth_type_default_pars(self, ectx, tname):
4776 pars = Type.eth_type_default_pars(self, ectx, tname)
4777 if ectx.default_embedded_pdv_cb:
4778 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
4780 pars['TYPE_REF_FN'] = 'NULL'
4783 def eth_type_default_body(self, ectx, tname):
4785 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
4786 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4788 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
4789 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4791 body = '#error Can not decode %s' % (tname)
4794 #--- ExternalType -----------------------------------------------------------
4795 class ExternalType (Type):
4796 def eth_tname(self):
4799 def eth_ftype(self, ectx):
4800 return ('FT_NONE', 'BASE_NONE')
4802 def GetTTag(self, ectx):
4803 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4805 def eth_type_default_pars(self, ectx, tname):
4806 pars = Type.eth_type_default_pars(self, ectx, tname)
4807 if ectx.default_external_type_cb:
4808 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4810 pars['TYPE_REF_FN'] = 'NULL'
4813 def eth_type_default_body(self, ectx, tname):
4815 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4816 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4818 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4819 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4821 body = '#error Can not decode %s' % (tname)
4824 #--- OpenType -----------------------------------------------------------
4825 class OpenType (Type):
4826 def to_python (self, ctx):
4829 def single_type(self):
4830 if (self.HasConstraint() and
4831 self.constr.type == 'Type' and
4832 self.constr.subtype.type == 'Type_Ref'):
4833 return self.constr.subtype.val
4836 def eth_reg_sub(self, ident, ectx):
4837 t = self.single_type()
4839 ectx.eth_dep_add(ident, t)
4841 def eth_tname(self):
4842 t = self.single_type()
4844 return 'OpenType_' + t
4846 return Type.eth_tname(self)
4848 def eth_ftype(self, ectx):
4849 return ('FT_NONE', 'BASE_NONE')
4851 def GetTTag(self, ectx):
4852 return ('BER_CLASS_ANY', '0')
4854 def eth_type_default_pars(self, ectx, tname):
4855 pars = Type.eth_type_default_pars(self, ectx, tname)
4856 pars['FN_VARIANT'] = ectx.default_opentype_variant
4857 t = self.single_type()
4859 t = ectx.type[t]['ethname']
4860 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4861 pars['TYPE_REF_TNAME'] = t
4862 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4864 pars['TYPE_REF_FN'] = 'NULL'
4867 def eth_type_default_body(self, ectx, tname):
4869 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4870 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4872 body = '#error Can not decode %s' % (tname)
4875 #--- InstanceOfType -----------------------------------------------------------
4876 class InstanceOfType (Type):
4877 def eth_tname(self):
4878 return 'INSTANCE_OF'
4880 def eth_ftype(self, ectx):
4881 return ('FT_NONE', 'BASE_NONE')
4883 def GetTTag(self, ectx):
4884 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4886 def eth_type_default_pars(self, ectx, tname):
4887 pars = Type.eth_type_default_pars(self, ectx, tname)
4888 if ectx.default_external_type_cb:
4889 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4891 pars['TYPE_REF_FN'] = 'NULL'
4894 def eth_type_default_body(self, ectx, tname):
4896 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4897 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4899 body = '#error Can not decode %s' % (tname)
4901 body = '#error Can not decode %s' % (tname)
4904 #--- AnyType -----------------------------------------------------------
4905 class AnyType (Type):
4906 def to_python (self, ctx):
4909 def eth_ftype(self, ectx):
4910 return ('FT_NONE', 'BASE_NONE')
4912 def GetTTag(self, ectx):
4913 return ('BER_CLASS_ANY', '0')
4915 def eth_type_default_body(self, ectx, tname):
4916 body = '#error Can not decode %s' % (tname)
4919 class Literal (Node):
4920 def to_python (self, ctx):
4923 #--- NullType -----------------------------------------------------------------
4924 class NullType (Type):
4925 def to_python (self, ctx):
4928 def eth_tname(self):
4931 def GetTTag(self, ectx):
4932 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4934 def eth_type_default_body(self, ectx, tname):
4936 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4937 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4939 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4940 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4942 body = '#error Can not decode %s' % (tname)
4945 #--- NullValue ----------------------------------------------------
4946 class NullValue (Value):
4947 def to_str(self, ectx):
4950 #--- RealType -----------------------------------------------------------------
4951 class RealType (Type):
4952 def to_python (self, ctx):
4955 def eth_tname(self):
4958 def GetTTag(self, ectx):
4959 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4961 def eth_ftype(self, ectx):
4962 return ('FT_DOUBLE', 'BASE_NONE')
4964 def eth_type_default_body(self, ectx, tname):
4966 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4967 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4970 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4971 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4973 body = '#error Can not decode %s' % (tname)
4976 #--- BooleanType --------------------------------------------------------------
4977 class BooleanType (Type):
4978 def to_python (self, ctx):
4979 return 'asn1.BOOLEAN'
4981 def eth_tname(self):
4984 def GetTTag(self, ectx):
4985 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4987 def eth_ftype(self, ectx):
4988 return ('FT_BOOLEAN', 'BASE_NONE')
4990 def eth_type_default_body(self, ectx, tname):
4992 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4993 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
4995 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4996 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4998 body = '#error Can not decode %s' % (tname)
5001 #--- OctetStringType ----------------------------------------------------------
5002 class OctetStringType (Type):
5003 def to_python (self, ctx):
5004 return 'asn1.OCTSTRING'
5006 def eth_tname(self):
5007 if not self.HasConstraint():
5008 return 'OCTET_STRING'
5009 elif self.constr.type == 'Size':
5010 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
5012 return '#' + self.type + '_' + str(id(self))
5014 def eth_ftype(self, ectx):
5015 return ('FT_BYTES', 'BASE_NONE')
5017 def GetTTag(self, ectx):
5018 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
5020 def eth_need_pdu(self, ectx):
5022 if self.HasContentsConstraint():
5023 t = self.constr.GetContents(ectx)
5024 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5026 'new' : ectx.default_containing_variant == '_pdu_new' }
5029 def eth_type_default_pars(self, ectx, tname):
5030 pars = Type.eth_type_default_pars(self, ectx, tname)
5031 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5032 if self.HasContentsConstraint():
5033 pars['FN_VARIANT'] = ectx.default_containing_variant
5034 t = self.constr.GetContents(ectx)
5036 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5037 t = ectx.field[t]['ethname']
5038 pars['TYPE_REF_PROTO'] = ''
5039 pars['TYPE_REF_TNAME'] = t
5040 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5042 t = ectx.type[t]['ethname']
5043 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5044 pars['TYPE_REF_TNAME'] = t
5045 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5047 pars['TYPE_REF_FN'] = 'NULL'
5050 def eth_type_default_body(self, ectx, tname):
5052 if (ectx.constraints_check and self.HasSizeConstraint()):
5053 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret='offset',
5054 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5055 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5057 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5058 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5061 if self.HasContentsConstraint():
5062 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
5063 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5064 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
5066 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5067 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5068 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
5070 body = '#error Can not decode %s' % (tname)
5073 #--- CharacterStringType ------------------------------------------------------
5074 class CharacterStringType (Type):
5075 def eth_tname(self):
5076 if not self.HasConstraint():
5077 return self.eth_tsname()
5078 elif self.constr.type == 'Size':
5079 return self.eth_tsname() + '_' + self.constr.eth_constrname()
5081 return '#' + self.type + '_' + str(id(self))
5083 def eth_ftype(self, ectx):
5084 return ('FT_STRING', 'BASE_NONE')
5086 class RestrictedCharacterStringType (CharacterStringType):
5087 def to_python (self, ctx):
5088 return 'asn1.' + self.eth_tsname()
5090 def GetTTag(self, ectx):
5091 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
5093 def eth_type_default_pars(self, ectx, tname):
5094 pars = Type.eth_type_default_pars(self, ectx, tname)
5095 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5096 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
5097 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
5100 def eth_type_default_body(self, ectx, tname):
5102 if (ectx.constraints_check and self.HasSizeConstraint()):
5103 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret='offset',
5104 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5105 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5106 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5108 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
5109 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5110 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5112 elif (ectx.Per() and self.HasPermAlph()):
5113 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
5114 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5115 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
5118 if (self.eth_tsname() == 'GeneralString'):
5119 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5120 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5121 elif (self.eth_tsname() == 'GeneralizedTime'):
5122 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5123 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5124 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5125 elif (self.eth_tsname() == 'UTCTime'):
5126 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5127 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5128 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5130 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5131 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5132 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5134 body = '#error Can not decode %s' % (tname)
5137 class BMPStringType (RestrictedCharacterStringType):
5138 def eth_tsname(self):
5141 class GeneralStringType (RestrictedCharacterStringType):
5142 def eth_tsname(self):
5143 return 'GeneralString'
5145 class GraphicStringType (RestrictedCharacterStringType):
5146 def eth_tsname(self):
5147 return 'GraphicString'
5149 class IA5StringType (RestrictedCharacterStringType):
5150 def eth_tsname(self):
5153 class NumericStringType (RestrictedCharacterStringType):
5154 def eth_tsname(self):
5155 return 'NumericString'
5157 class PrintableStringType (RestrictedCharacterStringType):
5158 def eth_tsname(self):
5159 return 'PrintableString'
5161 class TeletexStringType (RestrictedCharacterStringType):
5162 def eth_tsname(self):
5163 return 'TeletexString'
5165 class T61StringType (RestrictedCharacterStringType):
5166 def eth_tsname(self):
5168 def GetTTag(self, ectx):
5169 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
5171 class UniversalStringType (RestrictedCharacterStringType):
5172 def eth_tsname(self):
5173 return 'UniversalString'
5175 class UTF8StringType (RestrictedCharacterStringType):
5176 def eth_tsname(self):
5179 class VideotexStringType (RestrictedCharacterStringType):
5180 def eth_tsname(self):
5181 return 'VideotexString'
5183 class VisibleStringType (RestrictedCharacterStringType):
5184 def eth_tsname(self):
5185 return 'VisibleString'
5187 class ISO646StringType (RestrictedCharacterStringType):
5188 def eth_tsname(self):
5189 return 'ISO646String'
5190 def GetTTag(self, ectx):
5191 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
5193 class UnrestrictedCharacterStringType (CharacterStringType):
5194 def to_python (self, ctx):
5195 return 'asn1.UnrestrictedCharacterString'
5196 def eth_tsname(self):
5197 return 'CHARACTER_STRING'
5199 #--- UsefulType ---------------------------------------------------------------
5200 class GeneralizedTime (RestrictedCharacterStringType):
5201 def eth_tsname(self):
5202 return 'GeneralizedTime'
5204 def eth_type_default_body(self, ectx, tname):
5206 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5207 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5210 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5212 class UTCTime (RestrictedCharacterStringType):
5213 def eth_tsname(self):
5216 def eth_type_default_body(self, ectx, tname):
5218 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5219 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5222 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5224 class ObjectDescriptor (RestrictedCharacterStringType):
5225 def eth_tsname(self):
5226 return 'ObjectDescriptor'
5228 def eth_type_default_body(self, ectx, tname):
5230 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5232 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
5233 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5235 body = '#error Can not decode %s' % (tname)
5238 #--- ObjectIdentifierType -----------------------------------------------------
5239 class ObjectIdentifierType (Type):
5240 def to_python (self, ctx):
5241 return 'asn1.OBJECT_IDENTIFIER'
5243 def eth_tname(self):
5244 return 'OBJECT_IDENTIFIER'
5246 def eth_ftype(self, ectx):
5247 return ('FT_OID', 'BASE_NONE')
5249 def GetTTag(self, ectx):
5250 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
5252 def eth_type_default_pars(self, ectx, tname):
5253 pars = Type.eth_type_default_pars(self, ectx, tname)
5254 pars['FN_VARIANT'] = ectx.default_oid_variant
5257 def eth_type_default_body(self, ectx, tname):
5259 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5260 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5262 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5263 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5265 body = '#error Can not decode %s' % (tname)
5268 #--- ObjectIdentifierValue ----------------------------------------------------
5269 class ObjectIdentifierValue (Value):
5270 def get_num(self, path, val):
5271 return str(oid_names.get(path + '/' + val, val))
5273 def to_str(self, ectx):
5278 for v in self.comp_list:
5279 if isinstance(v, Node) and (v.type == 'name_and_number'):
5284 vstr = self.get_num(path, v)
5285 if not first and not vstr.isdigit():
5286 vstr = ectx.value_get_val(vstr)
5291 out += ectx.value_get_eth(vstr) + '"'
5301 v = self.comp_list[0]
5302 if isinstance(v, Node) and (v.type == 'name_and_number'):
5307 vstr = self.get_num('', v)
5313 class NamedNumber(Node):
5314 def to_python (self, ctx):
5315 return "('%s',%s)" % (self.ident, self.val)
5317 class NamedNumListBase(Node):
5318 def to_python (self, ctx):
5319 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
5320 [x.to_python (ctx) for x in self.named_list]))
5322 #--- RelativeOIDType ----------------------------------------------------------
5323 class RelativeOIDType (Type):
5325 def eth_tname(self):
5326 return 'RELATIVE_OID'
5328 def eth_ftype(self, ectx):
5329 return ('FT_REL_OID', 'BASE_NONE')
5331 def GetTTag(self, ectx):
5332 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5334 def eth_type_default_pars(self, ectx, tname):
5335 pars = Type.eth_type_default_pars(self, ectx, tname)
5336 pars['FN_VARIANT'] = ectx.default_oid_variant
5339 def eth_type_default_body(self, ectx, tname):
5341 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5342 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5344 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5345 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5347 body = '#error Can not decode %s' % (tname)
5351 #--- IntegerType --------------------------------------------------------------
5352 class IntegerType (Type):
5353 def to_python (self, ctx):
5354 return "asn1.INTEGER_class ([%s])" % (",".join (
5355 [x.to_python (ctx) for x in self.named_list]))
5357 def add_named_value(self, ident, val):
5358 e = NamedNumber(ident = ident, val = val)
5359 if not self.named_list:
5360 self.named_list = []
5361 self.named_list.append(e)
5363 def eth_tname(self):
5365 return Type.eth_tname(self)
5366 if not self.HasConstraint():
5368 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
5369 return 'INTEGER' + '_' + self.constr.eth_constrname()
5371 return 'INTEGER' + '_' + self.constr.eth_tname()
5373 def GetTTag(self, ectx):
5374 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5377 def eth_ftype(self, ectx):
5378 if self.HasConstraint():
5379 if not self.constr.IsNegativ():
5380 return ('FT_UINT32', 'BASE_DEC')
5381 return ('FT_INT32', 'BASE_DEC')
5383 def eth_strings(self):
5384 if (self.named_list):
5389 def eth_has_vals(self):
5390 if (self.named_list):
5395 def get_vals(self, ectx):
5397 for e in (self.named_list):
5398 vals.append((int(e.val), e.ident))
5401 def eth_type_vals(self, tname, ectx):
5402 if not self.eth_has_vals(): return ''
5404 vals = self.get_vals(ectx)
5405 out += ectx.eth_vals(tname, vals)
5408 def reg_enum_vals(self, tname, ectx):
5409 vals = self.get_vals(ectx)
5410 for (val, id) in vals:
5411 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
5413 def eth_type_enum(self, tname, ectx):
5414 if not self.eth_has_enum(tname, ectx): return ''
5416 vals = self.get_vals(ectx)
5417 out += ectx.eth_enum(tname, vals)
5420 def eth_type_default_pars(self, ectx, tname):
5421 pars = Type.eth_type_default_pars(self, ectx, tname)
5422 if self.HasValueConstraint():
5423 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
5426 def eth_type_default_body(self, ectx, tname):
5428 if (ectx.constraints_check and self.HasValueConstraint()):
5429 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5430 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5431 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5433 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5434 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5436 elif (ectx.Per() and not self.HasValueConstraint()):
5437 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5438 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5439 elif (ectx.Per() and self.HasValueConstraint()):
5440 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5441 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5442 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5444 body = '#error Can not decode %s' % (tname)
5447 #--- BitStringType ------------------------------------------------------------
5448 class BitStringType (Type):
5449 def to_python (self, ctx):
5450 return "asn1.BITSTRING_class ([%s])" % (",".join (
5451 [x.to_python (ctx) for x in self.named_list]))
5453 def eth_tname(self):
5455 return Type.eth_tname(self)
5456 elif not self.HasConstraint():
5458 elif self.constr.IsSize():
5459 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
5461 return '#' + self.type + '_' + str(id(self))
5463 def GetTTag(self, ectx):
5464 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5466 def eth_ftype(self, ectx):
5467 return ('FT_BYTES', 'BASE_NONE')
5469 def eth_need_tree(self):
5470 return self.named_list
5472 def eth_need_pdu(self, ectx):
5474 if self.HasContentsConstraint():
5475 t = self.constr.GetContents(ectx)
5476 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5478 'new' : ectx.default_containing_variant == '_pdu_new' }
5481 def eth_named_bits(self):
5483 if (self.named_list):
5484 for e in (self.named_list):
5485 bits.append((int(e.val), e.ident))
5488 def eth_type_default_pars(self, ectx, tname):
5489 pars = Type.eth_type_default_pars(self, ectx, tname)
5490 pars['LEN_PTR'] = 'NULL'
5491 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5492 if 'ETT_INDEX' not in pars:
5493 pars['ETT_INDEX'] = '-1'
5494 pars['TABLE'] = 'NULL'
5495 if self.eth_named_bits():
5496 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5497 if self.HasContentsConstraint():
5498 pars['FN_VARIANT'] = ectx.default_containing_variant
5499 t = self.constr.GetContents(ectx)
5501 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5502 t = ectx.field[t]['ethname']
5503 pars['TYPE_REF_PROTO'] = ''
5504 pars['TYPE_REF_TNAME'] = t
5505 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5507 t = ectx.type[t]['ethname']
5508 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5509 pars['TYPE_REF_TNAME'] = t
5510 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5512 pars['TYPE_REF_FN'] = 'NULL'
5515 def eth_type_default_table(self, ectx, tname):
5516 #print "eth_type_default_table(tname='%s')" % (tname)
5518 bits = self.eth_named_bits()
5519 if (bits and ectx.Ber()):
5520 table = ectx.eth_bits(tname, bits)
5523 def eth_type_default_body(self, ectx, tname):
5525 if (ectx.constraints_check and self.HasSizeConstraint()):
5526 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret='offset',
5527 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5528 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5531 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
5532 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5533 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5536 if self.HasContentsConstraint():
5537 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
5538 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5539 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5541 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
5542 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5543 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s', '%(LEN_PTR)s'),))
5545 body = '#error Can not decode %s' % (tname)
5548 #--- BStringValue ------------------------------------------------------------
5567 class BStringValue (Value):
5568 def to_str(self, ectx):
5571 v += '0' * (8 - len(v) % 8)
5573 for i in (list(range(0, len(v), 4))):
5574 vv += bstring_tab[v[i:i+4]]
5577 #--- HStringValue ------------------------------------------------------------
5578 class HStringValue (Value):
5579 def to_str(self, ectx):
5581 vv += self.val[1:-2]
5584 return int(self.val[1:-2], 16)
5586 #--- FieldSpec ----------------------------------------------------------------
5587 class FieldSpec (Node):
5588 def __init__(self,*args, **kw) :
5590 Node.__init__ (self,*args, **kw)
5592 def SetName(self, name):
5596 return ['#UNSUPPORTED_' + self.type]
5600 repr.extend(self.get_repr())
5603 class TypeFieldSpec (FieldSpec):
5607 class FixedTypeValueFieldSpec (FieldSpec):
5609 if isinstance(self.typ, Type_Ref):
5610 repr = ['TypeReference', self.typ.val]
5612 repr = [self.typ.type]
5615 class VariableTypeValueFieldSpec (FieldSpec):
5617 return ['_' + self.type]
5619 class FixedTypeValueSetFieldSpec (FieldSpec):
5621 return ['_' + self.type]
5623 class ObjectFieldSpec (FieldSpec):
5625 return ['ClassReference', self.cls.val]
5627 class ObjectSetFieldSpec (FieldSpec):
5629 return ['ClassReference', self.cls.val]
5631 #==============================================================================
5633 def p_module_list_1 (t):
5634 'module_list : module_list ModuleDefinition'
5635 t[0] = t[1] + [t[2]]
5637 def p_module_list_2 (t):
5638 'module_list : ModuleDefinition'
5642 #--- ITU-T Recommendation X.680 -----------------------------------------------
5645 # 11 ASN.1 lexical items --------------------------------------------------------
5647 # 11.2 Type references
5649 'type_ref : UCASE_IDENT'
5650 t[0] = Type_Ref(val=t[1])
5653 def p_identifier (t):
5654 'identifier : LCASE_IDENT'
5657 # 11.4 Value references
5658 # cause reduce/reduce conflict
5659 #def p_valuereference (t):
5660 # 'valuereference : LCASE_IDENT'
5661 # t[0] = Value_Ref(val=t[1])
5663 # 11.5 Module references
5664 def p_modulereference (t):
5665 'modulereference : UCASE_IDENT'
5669 # 12 Module definition --------------------------------------------------------
5672 def p_ModuleDefinition (t):
5673 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5674 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7])
5676 def p_ModuleBegin (t):
5678 if t[-4].val == 'Remote-Operations-Information-Objects':
5681 def p_TagDefault_1 (t):
5682 '''TagDefault : EXPLICIT TAGS
5684 | AUTOMATIC TAGS '''
5685 t[0] = Default_Tags (dfl_tag = t[1])
5687 def p_TagDefault_2 (t):
5689 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5690 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
5692 def p_ModuleIdentifier_1 (t):
5693 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5694 t [0] = Node('module_ident', val = t[1], ident = t[2])
5696 def p_ModuleIdentifier_2 (t):
5697 'ModuleIdentifier : modulereference' # name, oid
5698 t [0] = Node('module_ident', val = t[1], ident = None)
5700 def p_DefinitiveIdentifier (t):
5701 'DefinitiveIdentifier : ObjectIdentifierValue'
5704 #def p_module_ref (t):
5705 # 'module_ref : UCASE_IDENT'
5708 def p_ModuleBody_1 (t):
5709 'ModuleBody : Exports Imports AssignmentList'
5710 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
5712 def p_ModuleBody_2 (t):
5714 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
5716 def p_Exports_1 (t):
5717 'Exports : EXPORTS syms_exported SEMICOLON'
5720 def p_Exports_2 (t):
5721 'Exports : EXPORTS ALL SEMICOLON'
5724 def p_Exports_3 (t):
5728 def p_syms_exported_1 (t):
5729 'syms_exported : exp_sym_list'
5732 def p_syms_exported_2 (t):
5736 def p_exp_sym_list_1 (t):
5737 'exp_sym_list : Symbol'
5740 def p_exp_sym_list_2 (t):
5741 'exp_sym_list : exp_sym_list COMMA Symbol'
5742 t[0] = t[1] + [t[3]]
5745 def p_Imports_1 (t):
5746 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5748 global lcase_ident_assigned
5749 lcase_ident_assigned = {}
5751 def p_importsbegin (t):
5753 global lcase_ident_assigned
5755 lcase_ident_assigned = {}
5756 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5758 def p_Imports_2 (t):
5762 def p_SymbolsImported_1(t):
5763 'SymbolsImported : '
5766 def p_SymbolsImported_2 (t):
5767 'SymbolsImported : SymbolsFromModuleList'
5770 def p_SymbolsFromModuleList_1 (t):
5771 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5772 t[0] = t[1] + [t[2]]
5774 def p_SymbolsFromModuleList_2 (t):
5775 'SymbolsFromModuleList : SymbolsFromModule'
5778 def p_SymbolsFromModule (t):
5779 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
5780 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
5781 for s in (t[0].symbol_list):
5782 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
5783 import_symbols_from_module(t[0].module, t[0].symbol_list)
5785 def import_symbols_from_module(module, symbol_list):
5786 if module.val == 'Remote-Operations-Information-Objects':
5787 for i in range(len(symbol_list)):
5789 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
5791 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5792 symbol_list[i] = Class_Ref (val = s.val)
5794 for i in range(len(symbol_list)):
5796 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)):
5797 import_class_from_module(module.val, s.val)
5798 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5799 symbol_list[i] = Class_Ref (val = s.val)
5801 def p_GlobalModuleReference (t):
5802 'GlobalModuleReference : modulereference AssignedIdentifier'
5803 t [0] = Node('module_ident', val = t[1], ident = t[2])
5805 def p_AssignedIdentifier_1 (t):
5806 'AssignedIdentifier : ObjectIdentifierValue'
5809 def p_AssignedIdentifier_2 (t):
5810 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5813 def p_AssignedIdentifier_3 (t):
5814 'AssignedIdentifier : '
5817 def p_SymbolList_1 (t):
5818 'SymbolList : Symbol'
5821 def p_SymbolList_2 (t):
5822 'SymbolList : SymbolList COMMA Symbol'
5823 t[0] = t[1] + [t[3]]
5826 '''Symbol : Reference
5827 | ParameterizedReference'''
5830 def p_Reference_1 (t):
5831 '''Reference : type_ref
5832 | objectclassreference '''
5835 def p_Reference_2 (t):
5836 '''Reference : LCASE_IDENT_ASSIGNED
5837 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5838 t[0] = Value_Ref(val=t[1])
5840 def p_AssignmentList_1 (t):
5841 'AssignmentList : AssignmentList Assignment'
5842 t[0] = t[1] + [t[2]]
5844 def p_AssignmentList_2 (t):
5845 'AssignmentList : Assignment SEMICOLON'
5848 def p_AssignmentList_3 (t):
5849 'AssignmentList : Assignment'
5852 def p_Assignment (t):
5853 '''Assignment : TypeAssignment
5855 | ValueSetTypeAssignment
5856 | ObjectClassAssignment
5858 | ObjectSetAssignment
5859 | ParameterizedAssignment
5864 # 13 Referencing type and value definitions -----------------------------------
5867 def p_DefinedType (t):
5868 '''DefinedType : ExternalTypeReference
5870 | ParameterizedType'''
5873 def p_DefinedValue_1(t):
5874 '''DefinedValue : ExternalValueReference'''
5877 def p_DefinedValue_2(t):
5878 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5879 t[0] = Value_Ref(val=t[1])
5882 def p_ExternalTypeReference (t):
5883 'ExternalTypeReference : modulereference DOT type_ref'
5884 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5886 def p_ExternalValueReference (t):
5887 'ExternalValueReference : modulereference DOT identifier'
5888 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5891 # 15 Assigning types and values -----------------------------------------------
5894 def p_TypeAssignment (t):
5895 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5900 def p_ValueAssignment (t):
5901 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
5902 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
5904 # only "simple" types are supported to simplify grammer
5905 def p_ValueType (t):
5906 '''ValueType : type_ref
5909 | ObjectIdentifierType
5916 def p_ValueSetTypeAssignment (t):
5917 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
5918 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
5922 'ValueSet : lbraceignore rbraceignore'
5926 # 16 Definition of types and values -------------------------------------------
5930 '''Type : BuiltinType
5932 | ConstrainedType'''
5936 def p_BuiltinType (t):
5937 '''BuiltinType : AnyType
5940 | CharacterStringType
5948 | ObjectClassFieldType
5949 | ObjectIdentifierType
5961 def p_ReferencedType (t):
5962 '''ReferencedType : DefinedType
5968 def p_NamedType (t):
5969 'NamedType : identifier Type'
5975 '''Value : BuiltinValue
5977 | ObjectClassFieldValue'''
5981 def p_BuiltinValue (t):
5982 '''BuiltinValue : BooleanValue
5985 | ObjectIdentifierValue
5990 | char_string''' # XXX we don't support {data} here
5994 def p_ReferencedValue (t):
5995 '''ReferencedValue : DefinedValue
5996 | ValueFromObject'''
6000 #def p_NamedValue (t):
6001 # 'NamedValue : identifier Value'
6002 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
6005 # 17 Notation for the boolean type --------------------------------------------
6008 def p_BooleanType (t):
6009 'BooleanType : BOOLEAN'
6010 t[0] = BooleanType ()
6013 def p_BooleanValue (t):
6014 '''BooleanValue : TRUE
6019 # 18 Notation for the integer type --------------------------------------------
6022 def p_IntegerType_1 (t):
6023 'IntegerType : INTEGER'
6024 t[0] = IntegerType (named_list = None)
6026 def p_IntegerType_2 (t):
6027 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
6028 t[0] = IntegerType(named_list = t[3])
6030 def p_NamedNumberList_1 (t):
6031 'NamedNumberList : NamedNumber'
6034 def p_NamedNumberList_2 (t):
6035 'NamedNumberList : NamedNumberList COMMA NamedNumber'
6036 t[0] = t[1] + [t[3]]
6038 def p_NamedNumber (t):
6039 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
6040 | identifier LPAREN DefinedValue RPAREN'''
6041 t[0] = NamedNumber(ident = t[1], val = t[3])
6043 def p_SignedNumber_1 (t):
6044 'SignedNumber : NUMBER'
6047 def p_SignedNumber_2 (t):
6048 'SignedNumber : MINUS NUMBER'
6052 def p_IntegerValue (t):
6053 'IntegerValue : SignedNumber'
6056 # 19 Notation for the enumerated type -----------------------------------------
6059 def p_EnumeratedType (t):
6060 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
6061 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
6063 def p_Enumerations_1 (t):
6064 'Enumerations : Enumeration'
6065 t[0] = { 'val' : t[1], 'ext' : None }
6067 def p_Enumerations_2 (t):
6068 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
6069 t[0] = { 'val' : t[1], 'ext' : [] }
6071 def p_Enumerations_3 (t):
6072 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
6073 t[0] = { 'val' : t[1], 'ext' : t[6] }
6075 def p_Enumeration_1 (t):
6076 'Enumeration : EnumerationItem'
6079 def p_Enumeration_2 (t):
6080 'Enumeration : Enumeration COMMA EnumerationItem'
6081 t[0] = t[1] + [t[3]]
6083 def p_EnumerationItem (t):
6084 '''EnumerationItem : Identifier
6088 def p_Identifier (t):
6089 'Identifier : identifier'
6090 t[0] = Node ('Identifier', ident = t[1])
6093 # 20 Notation for the real type -----------------------------------------------
6101 def p_RealValue (t):
6102 '''RealValue : REAL_NUMBER
6103 | SpecialRealValue'''
6106 def p_SpecialRealValue (t):
6107 '''SpecialRealValue : PLUS_INFINITY
6112 # 21 Notation for the bitstring type ------------------------------------------
6115 def p_BitStringType_1 (t):
6116 'BitStringType : BIT STRING'
6117 t[0] = BitStringType (named_list = None)
6119 def p_BitStringType_2 (t):
6120 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
6121 t[0] = BitStringType (named_list = t[4])
6123 def p_NamedBitList_1 (t):
6124 'NamedBitList : NamedBit'
6127 def p_NamedBitList_2 (t):
6128 'NamedBitList : NamedBitList COMMA NamedBit'
6129 t[0] = t[1] + [t[3]]
6132 '''NamedBit : identifier LPAREN NUMBER RPAREN
6133 | identifier LPAREN DefinedValue RPAREN'''
6134 t[0] = NamedNumber (ident = t[1], val = t[3])
6137 # 22 Notation for the octetstring type ----------------------------------------
6140 def p_OctetStringType (t):
6141 'OctetStringType : OCTET STRING'
6142 t[0] = OctetStringType ()
6145 # 23 Notation for the null type -----------------------------------------------
6153 def p_NullValue (t):
6158 # 24 Notation for sequence types ----------------------------------------------
6161 def p_SequenceType_1 (t):
6162 'SequenceType : SEQUENCE LBRACE RBRACE'
6163 t[0] = SequenceType (elt_list = [])
6165 def p_SequenceType_2 (t):
6166 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
6167 t[0] = SequenceType (elt_list = t[3]['elt_list'])
6168 if 'ext_list' in t[3]:
6169 t[0].ext_list = t[3]['ext_list']
6170 if 'elt_list2' in t[3]:
6171 t[0].elt_list2 = t[3]['elt_list2']
6173 def p_ExtensionAndException_1 (t):
6174 'ExtensionAndException : ELLIPSIS'
6177 def p_OptionalExtensionMarker_1 (t):
6178 'OptionalExtensionMarker : COMMA ELLIPSIS'
6181 def p_OptionalExtensionMarker_2 (t):
6182 'OptionalExtensionMarker : '
6185 def p_ComponentTypeLists_1 (t):
6186 'ComponentTypeLists : ComponentTypeList'
6187 t[0] = {'elt_list' : t[1]}
6189 def p_ComponentTypeLists_2 (t):
6190 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
6191 t[0] = {'elt_list' : t[1], 'ext_list' : []}
6193 def p_ComponentTypeLists_3 (t):
6194 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6195 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6197 def p_ComponentTypeLists_4 (t):
6198 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
6199 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
6201 def p_ComponentTypeLists_5 (t):
6202 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
6203 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
6205 def p_ComponentTypeLists_6 (t):
6206 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
6207 t[0] = {'elt_list' : [], 'ext_list' : []}
6209 def p_ComponentTypeLists_7 (t):
6210 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6211 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
6213 def p_ExtensionEndMarker (t):
6214 'ExtensionEndMarker : COMMA ELLIPSIS'
6217 def p_ExtensionAdditionList_1 (t):
6218 'ExtensionAdditionList : COMMA ExtensionAddition'
6221 def p_ExtensionAdditionList_2 (t):
6222 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
6223 t[0] = t[1] + [t[3]]
6225 def p_ExtensionAddition_1 (t):
6226 'ExtensionAddition : ExtensionAdditionGroup'
6227 t[0] = Node ('elt_type', val = t[1], optional = 0)
6229 def p_ExtensionAddition_2 (t):
6230 'ExtensionAddition : ComponentType'
6233 def p_ExtensionAdditionGroup (t):
6234 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
6235 t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3])
6237 def p_VersionNumber_1 (t):
6240 def p_VersionNumber_2 (t):
6241 'VersionNumber : NUMBER COLON'
6244 def p_ComponentTypeList_1 (t):
6245 'ComponentTypeList : ComponentType'
6248 def p_ComponentTypeList_2 (t):
6249 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
6250 t[0] = t[1] + [t[3]]
6252 def p_ComponentType_1 (t):
6253 'ComponentType : NamedType'
6254 t[0] = Node ('elt_type', val = t[1], optional = 0)
6256 def p_ComponentType_2 (t):
6257 'ComponentType : NamedType OPTIONAL'
6258 t[0] = Node ('elt_type', val = t[1], optional = 1)
6260 def p_ComponentType_3 (t):
6261 'ComponentType : NamedType DEFAULT DefaultValue'
6262 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
6264 def p_ComponentType_4 (t):
6265 'ComponentType : COMPONENTS OF Type'
6266 t[0] = Node ('components_of', typ = t[3])
6268 def p_DefaultValue_1 (t):
6269 '''DefaultValue : ReferencedValue
6277 | ObjectClassFieldValue'''
6280 def p_DefaultValue_2 (t):
6281 'DefaultValue : lbraceignore rbraceignore'
6285 def p_SequenceValue_1 (t):
6286 'SequenceValue : LBRACE RBRACE'
6290 #def p_SequenceValue_2 (t):
6291 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
6294 #def p_ComponentValueList_1 (t):
6295 # 'ComponentValueList : NamedValue'
6298 #def p_ComponentValueList_2 (t):
6299 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
6300 # t[0] = t[1] + [t[3]]
6303 # 25 Notation for sequence-of types -------------------------------------------
6306 def p_SequenceOfType (t):
6307 '''SequenceOfType : SEQUENCE OF Type
6308 | SEQUENCE OF NamedType'''
6309 t[0] = SequenceOfType (val = t[3], size_constr = None)
6312 # 26 Notation for set types ---------------------------------------------------
6315 def p_SetType_1 (t):
6316 'SetType : SET LBRACE RBRACE'
6317 t[0] = SetType (elt_list = [])
6319 def p_SetType_2 (t):
6320 'SetType : SET LBRACE ComponentTypeLists RBRACE'
6321 t[0] = SetType (elt_list = t[3]['elt_list'])
6322 if 'ext_list' in t[3]:
6323 t[0].ext_list = t[3]['ext_list']
6324 if 'elt_list2' in t[3]:
6325 t[0].elt_list2 = t[3]['elt_list2']
6328 # 27 Notation for set-of types ------------------------------------------------
6331 def p_SetOfType (t):
6332 '''SetOfType : SET OF Type
6333 | SET OF NamedType'''
6334 t[0] = SetOfType (val = t[3])
6336 # 28 Notation for choice types ------------------------------------------------
6339 def p_ChoiceType (t):
6340 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
6341 if 'ext_list' in t[3]:
6342 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
6344 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
6346 def p_AlternativeTypeLists_1 (t):
6347 'AlternativeTypeLists : AlternativeTypeList'
6348 t[0] = {'elt_list' : t[1]}
6350 def p_AlternativeTypeLists_2 (t):
6351 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
6352 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6354 def p_ExtensionAdditionAlternatives_1 (t):
6355 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
6358 def p_ExtensionAdditionAlternatives_2 (t):
6359 'ExtensionAdditionAlternatives : '
6362 def p_ExtensionAdditionAlternativesList_1 (t):
6363 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
6366 def p_ExtensionAdditionAlternativesList_2 (t):
6367 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
6370 def p_ExtensionAdditionAlternative_1 (t):
6371 'ExtensionAdditionAlternative : NamedType'
6374 def p_ExtensionAdditionAlternative_2 (t):
6375 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
6378 def p_ExtensionAdditionAlternativesGroup (t):
6379 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
6382 def p_AlternativeTypeList_1 (t):
6383 'AlternativeTypeList : NamedType'
6386 def p_AlternativeTypeList_2 (t):
6387 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
6388 t[0] = t[1] + [t[3]]
6391 def p_ChoiceValue_1 (t):
6392 '''ChoiceValue : identifier COLON Value
6393 | identifier COLON NullValue '''
6395 if not isinstance(val, Value):
6396 val = Value(val=val)
6397 t[0] = ChoiceValue (choice = t[1], val = val)
6399 # 29 Notation for selection types
6402 def p_SelectionType (t): #
6403 'SelectionType : identifier LT Type'
6404 t[0] = SelectionType (typ = t[3], sel = t[1])
6406 # 30 Notation for tagged types ------------------------------------------------
6409 def p_TaggedType_1 (t):
6410 'TaggedType : Tag Type'
6411 t[1].mode = 'default'
6415 def p_TaggedType_2 (t):
6416 '''TaggedType : Tag IMPLICIT Type
6417 | Tag EXPLICIT Type'''
6423 'Tag : LBRACK Class ClassNumber RBRACK'
6424 t[0] = Tag(cls = t[2], num = t[3])
6426 def p_ClassNumber_1 (t):
6427 'ClassNumber : number'
6430 def p_ClassNumber_2 (t):
6431 'ClassNumber : DefinedValue'
6435 '''Class : UNIVERSAL
6445 # 31 Notation for the object identifier type ----------------------------------
6448 def p_ObjectIdentifierType (t):
6449 'ObjectIdentifierType : OBJECT IDENTIFIER'
6450 t[0] = ObjectIdentifierType()
6453 def p_ObjectIdentifierValue (t):
6454 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6455 t[0] = ObjectIdentifierValue (comp_list=t[2])
6457 def p_oid_comp_list_1 (t):
6458 'oid_comp_list : oid_comp_list ObjIdComponents'
6459 t[0] = t[1] + [t[2]]
6461 def p_oid_comp_list_2 (t):
6462 'oid_comp_list : ObjIdComponents'
6465 def p_ObjIdComponents (t):
6466 '''ObjIdComponents : NameForm
6468 | NameAndNumberForm'''
6472 '''NameForm : LCASE_IDENT
6473 | LCASE_IDENT_ASSIGNED'''
6476 def p_NumberForm (t):
6477 '''NumberForm : NUMBER'''
6481 def p_NameAndNumberForm (t):
6482 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6483 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6484 t[0] = Node('name_and_number', ident = t[1], number = t[3])
6486 # 32 Notation for the relative object identifier type -------------------------
6489 def p_RelativeOIDType (t):
6490 'RelativeOIDType : RELATIVE_OID'
6491 t[0] = RelativeOIDType()
6493 # 33 Notation for the embedded-pdv type ---------------------------------------
6496 def p_EmbeddedPDVType (t):
6497 'EmbeddedPDVType : EMBEDDED PDV'
6498 t[0] = EmbeddedPDVType()
6500 # 34 Notation for the external type -------------------------------------------
6503 def p_ExternalType (t):
6504 'ExternalType : EXTERNAL'
6505 t[0] = ExternalType()
6507 # 36 Notation for character string types --------------------------------------
6510 def p_CharacterStringType (t):
6511 '''CharacterStringType : RestrictedCharacterStringType
6512 | UnrestrictedCharacterStringType'''
6516 # 37 Definition of restricted character string types --------------------------
6518 def p_RestrictedCharacterStringType_1 (t):
6519 'RestrictedCharacterStringType : BMPString'
6520 t[0] = BMPStringType ()
6521 def p_RestrictedCharacterStringType_2 (t):
6522 'RestrictedCharacterStringType : GeneralString'
6523 t[0] = GeneralStringType ()
6524 def p_RestrictedCharacterStringType_3 (t):
6525 'RestrictedCharacterStringType : GraphicString'
6526 t[0] = GraphicStringType ()
6527 def p_RestrictedCharacterStringType_4 (t):
6528 'RestrictedCharacterStringType : IA5String'
6529 t[0] = IA5StringType ()
6530 def p_RestrictedCharacterStringType_5 (t):
6531 'RestrictedCharacterStringType : ISO646String'
6532 t[0] = ISO646StringType ()
6533 def p_RestrictedCharacterStringType_6 (t):
6534 'RestrictedCharacterStringType : NumericString'
6535 t[0] = NumericStringType ()
6536 def p_RestrictedCharacterStringType_7 (t):
6537 'RestrictedCharacterStringType : PrintableString'
6538 t[0] = PrintableStringType ()
6539 def p_RestrictedCharacterStringType_8 (t):
6540 'RestrictedCharacterStringType : TeletexString'
6541 t[0] = TeletexStringType ()
6542 def p_RestrictedCharacterStringType_9 (t):
6543 'RestrictedCharacterStringType : T61String'
6544 t[0] = T61StringType ()
6545 def p_RestrictedCharacterStringType_10 (t):
6546 'RestrictedCharacterStringType : UniversalString'
6547 t[0] = UniversalStringType ()
6548 def p_RestrictedCharacterStringType_11 (t):
6549 'RestrictedCharacterStringType : UTF8String'
6550 t[0] = UTF8StringType ()
6551 def p_RestrictedCharacterStringType_12 (t):
6552 'RestrictedCharacterStringType : VideotexString'
6553 t[0] = VideotexStringType ()
6554 def p_RestrictedCharacterStringType_13 (t):
6555 'RestrictedCharacterStringType : VisibleString'
6556 t[0] = VisibleStringType ()
6559 # 40 Definition of unrestricted character string types ------------------------
6562 def p_UnrestrictedCharacterStringType (t):
6563 'UnrestrictedCharacterStringType : CHARACTER STRING'
6564 t[0] = UnrestrictedCharacterStringType ()
6567 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6569 # 42 Generalized time ---------------------------------------------------------
6571 def p_UsefulType_1 (t):
6572 'UsefulType : GeneralizedTime'
6573 t[0] = GeneralizedTime()
6575 # 43 Universal time -----------------------------------------------------------
6577 def p_UsefulType_2 (t):
6578 'UsefulType : UTCTime'
6581 # 44 The object descriptor type -----------------------------------------------
6583 def p_UsefulType_3 (t):
6584 'UsefulType : ObjectDescriptor'
6585 t[0] = ObjectDescriptor()
6588 # 45 Constrained types --------------------------------------------------------
6591 def p_ConstrainedType_1 (t):
6592 'ConstrainedType : Type Constraint'
6594 t[0].AddConstraint(t[2])
6596 def p_ConstrainedType_2 (t):
6597 'ConstrainedType : TypeWithConstraint'
6601 def p_TypeWithConstraint_1 (t):
6602 '''TypeWithConstraint : SET Constraint OF Type
6603 | SET SizeConstraint OF Type'''
6604 t[0] = SetOfType (val = t[4], constr = t[2])
6606 def p_TypeWithConstraint_2 (t):
6607 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6608 | SEQUENCE SizeConstraint OF Type'''
6609 t[0] = SequenceOfType (val = t[4], constr = t[2])
6611 def p_TypeWithConstraint_3 (t):
6612 '''TypeWithConstraint : SET Constraint OF NamedType
6613 | SET SizeConstraint OF NamedType'''
6614 t[0] = SetOfType (val = t[4], constr = t[2])
6616 def p_TypeWithConstraint_4 (t):
6617 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6618 | SEQUENCE SizeConstraint OF NamedType'''
6619 t[0] = SequenceOfType (val = t[4], constr = t[2])
6623 def p_Constraint (t):
6624 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6627 def p_ConstraintSpec (t):
6628 '''ConstraintSpec : ElementSetSpecs
6629 | GeneralConstraint'''
6632 # 46 Element set specification ------------------------------------------------
6635 def p_ElementSetSpecs_1 (t):
6636 'ElementSetSpecs : RootElementSetSpec'
6639 def p_ElementSetSpecs_2 (t):
6640 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6644 def p_ElementSetSpecs_3 (t):
6645 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6649 def p_RootElementSetSpec (t):
6650 'RootElementSetSpec : ElementSetSpec'
6653 def p_AdditionalElementSetSpec (t):
6654 'AdditionalElementSetSpec : ElementSetSpec'
6657 def p_ElementSetSpec (t):
6658 'ElementSetSpec : Unions'
6662 'Unions : Intersections'
6666 'Unions : UElems UnionMark Intersections'
6667 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
6673 def p_Intersections_1 (t):
6674 'Intersections : IntersectionElements'
6677 def p_Intersections_2 (t):
6678 'Intersections : IElems IntersectionMark IntersectionElements'
6679 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
6682 'IElems : Intersections'
6685 def p_IntersectionElements (t):
6686 'IntersectionElements : Elements'
6689 def p_UnionMark (t):
6693 def p_IntersectionMark (t):
6694 '''IntersectionMark : CIRCUMFLEX
6698 def p_Elements_1 (t):
6699 'Elements : SubtypeElements'
6702 def p_Elements_2 (t):
6703 'Elements : LPAREN ElementSetSpec RPAREN'
6706 # 47 Subtype elements ---------------------------------------------------------
6709 def p_SubtypeElements (t):
6710 '''SubtypeElements : SingleValue
6716 | InnerTypeConstraints
6717 | PatternConstraint'''
6722 def p_SingleValue (t):
6723 'SingleValue : Value'
6724 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
6726 # 47.3 Contained subtype
6728 def p_ContainedSubtype (t):
6729 'ContainedSubtype : Includes Type'
6730 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
6733 '''Includes : INCLUDES
6738 def p_ValueRange (t):
6739 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6740 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
6743 def p_LowerEndpoint_1 (t):
6744 'LowerEndpoint : LowerEndValue'
6747 def p_LowerEndpoint_2 (t):
6748 'LowerEndpoint : LowerEndValue LT'
6749 t[0] = t[1] # but not inclusive range
6751 def p_UpperEndpoint_1 (t):
6752 'UpperEndpoint : UpperEndValue'
6755 def p_UpperEndpoint_2 (t):
6756 'UpperEndpoint : LT UpperEndValue'
6757 t[0] = t[1] # but not inclusive range
6760 def p_LowerEndValue (t):
6761 '''LowerEndValue : Value
6765 def p_UpperEndValue (t):
6766 '''UpperEndValue : Value
6770 # 47.5 Size constraint
6772 def p_SizeConstraint (t):
6773 'SizeConstraint : SIZE Constraint'
6774 t[0] = Constraint (type = 'Size', subtype = t[2])
6776 # 47.6 Type constraint
6778 def p_TypeConstraint (t):
6779 'TypeConstraint : Type'
6780 t[0] = Constraint (type = 'Type', subtype = t[1])
6782 # 47.7 Permitted alphabet
6784 def p_PermittedAlphabet (t):
6785 'PermittedAlphabet : FROM Constraint'
6786 t[0] = Constraint (type = 'From', subtype = t[2])
6788 # 47.8 Inner subtyping
6790 def p_InnerTypeConstraints (t):
6791 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6792 | WITH COMPONENTS MultipleTypeConstraints'''
6793 pass # ignore PER invisible constraint
6796 def p_SingleTypeConstraint (t):
6797 'SingleTypeConstraint : Constraint'
6801 def p_MultipleTypeConstraints (t):
6802 '''MultipleTypeConstraints : FullSpecification
6803 | PartialSpecification'''
6806 def p_FullSpecification (t):
6807 'FullSpecification : LBRACE TypeConstraints RBRACE'
6810 def p_PartialSpecification (t):
6811 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6814 def p_TypeConstraints_1 (t):
6815 'TypeConstraints : named_constraint'
6818 def p_TypeConstraints_2 (t):
6819 'TypeConstraints : TypeConstraints COMMA named_constraint'
6820 t[0] = t[1] + [t[3]]
6822 def p_named_constraint_1 (t):
6823 'named_constraint : identifier constraint'
6824 return Node ('named_constraint', ident = t[1], constr = t[2])
6826 def p_named_constraint_2 (t):
6827 'named_constraint : constraint'
6828 return Node ('named_constraint', constr = t[1])
6830 def p_constraint (t):
6831 'constraint : value_constraint presence_constraint'
6832 t[0] = Node ('constraint', value = t[1], presence = t[2])
6834 def p_value_constraint_1 (t):
6835 'value_constraint : Constraint'
6838 def p_value_constraint_2 (t):
6839 'value_constraint : '
6842 def p_presence_constraint_1 (t):
6843 '''presence_constraint : PRESENT
6848 def p_presence_constraint_2 (t):
6849 '''presence_constraint : '''
6852 # 47.9 Pattern constraint
6854 def p_PatternConstraint (t):
6855 'PatternConstraint : PATTERN Value'
6856 t[0] = Constraint (type = 'Pattern', subtype = t[2])
6858 # 49 The exception identifier
6861 def p_ExceptionSpec_1 (t):
6862 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
6865 def p_ExceptionSpec_2 (t):
6869 def p_ExceptionIdentification (t):
6870 '''ExceptionIdentification : SignedNumber
6872 | Type COLON Value '''
6875 # /*-----------------------------------------------------------------------*/
6876 # /* Value Notation Productions */
6877 # /*-----------------------------------------------------------------------*/
6881 def p_binary_string (t):
6882 'binary_string : BSTRING'
6883 t[0] = BStringValue(val = t[1])
6885 def p_hex_string (t):
6886 'hex_string : HSTRING'
6887 t[0] = HStringValue(val = t[1])
6889 def p_char_string (t):
6890 'char_string : QSTRING'
6898 #--- ITU-T Recommendation X.208 -----------------------------------------------
6900 # 27 Notation for the any type ------------------------------------------------
6905 | ANY DEFINED BY identifier'''
6908 #--- ITU-T Recommendation X.681 -----------------------------------------------
6910 # 7 ASN.1 lexical items -------------------------------------------------------
6912 # 7.1 Information object class references
6914 def p_objectclassreference (t):
6915 'objectclassreference : CLASS_IDENT'
6916 t[0] = Class_Ref(val=t[1])
6918 # 7.2 Information object references
6920 def p_objectreference (t):
6921 'objectreference : LCASE_IDENT'
6924 # 7.3 Information object set references
6926 #def p_objectsetreference (t):
6927 # 'objectsetreference : UCASE_IDENT'
6930 # 7.4 Type field references
6931 # ucasefieldreference
6932 # 7.5 Value field references
6933 # lcasefieldreference
6934 # 7.6 Value set field references
6935 # ucasefieldreference
6936 # 7.7 Object field references
6937 # lcasefieldreference
6938 # 7.8 Object set field references
6939 # ucasefieldreference
6941 def p_ucasefieldreference (t):
6942 'ucasefieldreference : AMPERSAND UCASE_IDENT'
6945 def p_lcasefieldreference (t):
6946 'lcasefieldreference : AMPERSAND LCASE_IDENT'
6949 # 8 Referencing definitions
6952 def p_DefinedObjectClass (t):
6953 '''DefinedObjectClass : objectclassreference
6954 | UsefulObjectClassReference'''
6957 obj_class = t[0].val
6959 def p_DefinedObject (t):
6960 '''DefinedObject : objectreference'''
6964 def p_UsefulObjectClassReference (t):
6965 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6966 | ABSTRACT_SYNTAX'''
6967 t[0] = Class_Ref(val=t[1])
6969 # 9 Information object class definition and assignment
6972 def p_ObjectClassAssignment (t):
6973 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6974 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6977 if isinstance(t[0], ObjectClassDefn):
6981 def p_ObjectClass (t):
6982 '''ObjectClass : DefinedObjectClass
6984 | ParameterizedObjectClass '''
6988 def p_ObjectClassDefn (t):
6989 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
6990 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
6991 t[0] = ObjectClassDefn(fields = t[3])
6993 def p_FieldSpecs_1 (t):
6994 'FieldSpecs : FieldSpec'
6997 def p_FieldSpecs_2 (t):
6998 'FieldSpecs : FieldSpecs COMMA FieldSpec'
6999 t[0] = t[1] + [t[3]]
7001 def p_WithSyntaxSpec (t):
7002 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
7006 def p_FieldSpec (t):
7007 '''FieldSpec : TypeFieldSpec
7008 | FixedTypeValueFieldSpec
7009 | VariableTypeValueFieldSpec
7010 | FixedTypeValueSetFieldSpec
7012 | ObjectSetFieldSpec '''
7016 def p_TypeFieldSpec (t):
7017 '''TypeFieldSpec : ucasefieldreference
7018 | ucasefieldreference TypeOptionalitySpec '''
7019 t[0] = TypeFieldSpec()
7022 def p_TypeOptionalitySpec_1 (t):
7023 'TypeOptionalitySpec ::= OPTIONAL'
7026 def p_TypeOptionalitySpec_2 (t):
7027 'TypeOptionalitySpec ::= DEFAULT Type'
7031 def p_FixedTypeValueFieldSpec (t):
7032 '''FixedTypeValueFieldSpec : lcasefieldreference Type
7033 | lcasefieldreference Type UNIQUE
7034 | lcasefieldreference Type ValueOptionalitySpec
7035 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
7036 t[0] = FixedTypeValueFieldSpec(typ = t[2])
7039 def p_ValueOptionalitySpec_1 (t):
7040 'ValueOptionalitySpec ::= OPTIONAL'
7043 def p_ValueOptionalitySpec_2 (t):
7044 'ValueOptionalitySpec ::= DEFAULT Value'
7049 def p_VariableTypeValueFieldSpec (t):
7050 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
7051 | lcasefieldreference FieldName ValueOptionalitySpec '''
7052 t[0] = VariableTypeValueFieldSpec()
7056 def p_FixedTypeValueSetFieldSpec (t):
7057 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
7058 | ucasefieldreference Type ValueSetOptionalitySpec '''
7059 t[0] = FixedTypeValueSetFieldSpec()
7062 def p_ValueSetOptionalitySpec_1 (t):
7063 'ValueSetOptionalitySpec ::= OPTIONAL'
7066 def p_ValueSetOptionalitySpec_2 (t):
7067 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
7071 def p_ObjectFieldSpec (t):
7072 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
7073 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
7074 t[0] = ObjectFieldSpec(cls=t[2])
7079 def p_ObjectOptionalitySpec_1 (t):
7080 'ObjectOptionalitySpec ::= OPTIONAL'
7083 def p_ObjectOptionalitySpec_2 (t):
7084 'ObjectOptionalitySpec ::= DEFAULT Object'
7088 def p_ObjectSetFieldSpec (t):
7089 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
7090 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
7091 t[0] = ObjectSetFieldSpec(cls=t[2])
7094 def p_ObjectSetOptionalitySpec_1 (t):
7095 'ObjectSetOptionalitySpec ::= OPTIONAL'
7098 def p_ObjectSetOptionalitySpec_2 (t):
7099 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
7103 def p_PrimitiveFieldName (t):
7104 '''PrimitiveFieldName : ucasefieldreference
7105 | lcasefieldreference '''
7109 def p_FieldName_1 (t):
7110 'FieldName : PrimitiveFieldName'
7113 def p_FieldName_2 (t):
7114 'FieldName : FieldName DOT PrimitiveFieldName'
7115 t[0] = t[1] + '.' + t[3]
7117 # 11 Information object definition and assignment
7120 def p_ObjectAssignment (t):
7121 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
7122 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
7128 '''Object : DefinedObject
7130 | ParameterizedObject'''
7134 def p_ObjectDefn (t):
7135 'ObjectDefn : lbraceobject bodyobject rbraceobject'
7138 # {...} block of object definition
7139 def p_lbraceobject(t):
7140 'lbraceobject : braceobjectbegin LBRACE'
7143 def p_braceobjectbegin(t):
7144 'braceobjectbegin : '
7147 if set_class_syntax(obj_class):
7151 state = 'braceignore'
7152 lexer.push_state(state)
7154 def p_rbraceobject(t):
7155 'rbraceobject : braceobjectend RBRACE'
7158 def p_braceobjectend(t):
7162 set_class_syntax(None)
7164 def p_bodyobject_1 (t):
7168 def p_bodyobject_2 (t):
7169 'bodyobject : cls_syntax_list'
7172 def p_cls_syntax_list_1 (t):
7173 'cls_syntax_list : cls_syntax_list cls_syntax'
7177 def p_cls_syntax_list_2 (t):
7178 'cls_syntax_list : cls_syntax'
7182 def p_cls_syntax_1 (t):
7183 'cls_syntax : Type IDENTIFIED BY Value'
7184 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
7186 def p_cls_syntax_2 (t):
7187 'cls_syntax : HAS PROPERTY Value'
7188 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7191 def p_cls_syntax_3 (t):
7192 '''cls_syntax : ERRORS ObjectSet
7194 | RETURN RESULT BooleanValue
7195 | SYNCHRONOUS BooleanValue
7196 | INVOKE PRIORITY Value
7197 | RESULT_PRIORITY Value
7199 | ALWAYS RESPONDS BooleanValue
7200 | IDEMPOTENT BooleanValue '''
7201 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7203 def p_cls_syntax_4 (t):
7204 '''cls_syntax : ARGUMENT Type
7206 | PARAMETER Type '''
7207 t[0] = { get_class_fieled(t[1]) : t[2] }
7209 def p_cls_syntax_5 (t):
7210 'cls_syntax : CODE Value'
7211 fld = get_class_fieled(t[1]);
7212 t[0] = { fld : t[2] }
7213 if isinstance(t[2], ChoiceValue):
7214 fldt = fld + '.' + t[2].choice
7217 def p_cls_syntax_6 (t):
7218 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
7219 | RESULT Type OPTIONAL BooleanValue
7220 | PARAMETER Type OPTIONAL BooleanValue '''
7221 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
7223 # 12 Information object set definition and assignment
7226 def p_ObjectSetAssignment (t):
7227 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
7228 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
7231 def p_ObjectSet (t):
7232 'ObjectSet : lbraceignore rbraceignore'
7235 # 14 Notation for the object class field type ---------------------------------
7238 def p_ObjectClassFieldType (t):
7239 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
7240 t[0] = get_type_from_class(t[1], t[3])
7243 def p_ObjectClassFieldValue (t):
7244 '''ObjectClassFieldValue : OpenTypeFieldVal'''
7247 def p_OpenTypeFieldVal (t):
7248 '''OpenTypeFieldVal : Type COLON Value
7249 | NullType COLON NullValue'''
7253 # 15 Information from objects -------------------------------------------------
7257 def p_ValueFromObject (t):
7258 'ValueFromObject : LCASE_IDENT DOT FieldName'
7259 t[0] = t[1] + '.' + t[3]
7262 # Annex C - The instance-of type ----------------------------------------------
7265 def p_InstanceOfType (t):
7266 'InstanceOfType : INSTANCE OF DefinedObjectClass'
7267 t[0] = InstanceOfType()
7272 useful_object_class_types = {
7274 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
7275 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
7277 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
7278 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
7279 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
7282 object_class_types = { }
7284 object_class_typerefs = { }
7286 object_class_classrefs = { }
7289 class _VariableTypeValueFieldSpec (AnyType):
7292 class _FixedTypeValueSetFieldSpec (AnyType):
7295 class_types_creator = {
7296 'BooleanType' : lambda : BooleanType(),
7297 'IntegerType' : lambda : IntegerType(),
7298 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
7299 'OpenType' : lambda : OpenType(),
7301 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
7302 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
7308 'TYPE-IDENTIFIER' : {
7310 'IDENTIFIED' : 'IDENTIFIED',
7312 'IDENTIFIED BY' : '&id',
7314 'ABSTRACT-SYNTAX' : {
7316 'IDENTIFIED' : 'IDENTIFIED',
7318 'IDENTIFIED BY' : '&id',
7320 'PROPERTY' : 'PROPERTY',
7321 'HAS PROPERTY' : '&property',
7325 class_syntaxes_enabled = {
7326 'TYPE-IDENTIFIER' : True,
7327 'ABSTRACT-SYNTAX' : True,
7331 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
7332 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
7335 class_current_syntax = None
7337 def get_syntax_tokens(syntaxes):
7339 for s in (syntaxes):
7340 for k in (list(syntaxes[s].keys())):
7343 tokens[k] = tokens[k].replace('-', '_')
7344 return list(tokens.values())
7346 tokens = tokens + get_syntax_tokens(x681_syntaxes)
7348 def set_class_syntax(syntax):
7349 global class_syntaxes_enabled
7350 global class_current_syntax
7351 #print "set_class_syntax", syntax, class_current_syntax
7352 if class_syntaxes_enabled.get(syntax, False):
7353 class_current_syntax = syntax
7356 class_current_syntax = None
7359 def is_class_syntax(name):
7360 global class_syntaxes
7361 global class_current_syntax
7362 #print "is_class_syntax", name, class_current_syntax
7363 if not class_current_syntax:
7365 return name in class_syntaxes[class_current_syntax]
7367 def get_class_fieled(name):
7368 if not class_current_syntax:
7370 return class_syntaxes[class_current_syntax][name]
7372 def is_class_ident(name):
7373 return name in class_names
7375 def add_class_ident(name):
7376 #print "add_class_ident", name
7377 class_names[name] = name
7379 def get_type_from_class(cls, fld):
7380 flds = fld.split('.')
7381 if (isinstance(cls, Class_Ref)):
7382 key = cls.val + '.' + flds[0]
7384 key = cls + '.' + flds[0]
7386 if key in object_class_classrefs:
7387 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
7389 if key in object_class_typerefs:
7390 return Type_Ref(val=object_class_typerefs[key])
7392 creator = lambda : AnyType()
7393 creator = useful_object_class_types.get(key, creator)
7394 creator = object_class_types.get(key, creator)
7397 def set_type_to_class(cls, fld, pars):
7398 #print "set_type_to_class", cls, fld, pars
7399 key = cls + '.' + fld
7400 typename = 'OpenType'
7404 pars.append(typename)
7407 if (isinstance(pars[1], Class_Ref)):
7408 pars[1] = pars[1].val
7412 if key in object_class_types:
7413 msg = object_class_types[key]().type
7414 if key in object_class_typerefs:
7415 msg = "TypeReference " + object_class_typerefs[key]
7416 if key in object_class_classrefs:
7417 msg = "ClassReference " + object_class_classrefs[key]
7419 if msg == ' '.join(pars):
7423 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
7424 msg1 = "Already defined as '%s'" % (msg)
7425 raise CompError(msg0 + msg1)
7427 if (typename == 'ClassReference'):
7428 if not typeref: return False
7429 object_class_classrefs[key] = typeref
7432 if (typename == 'TypeReference'):
7433 if not typeref: return False
7434 object_class_typerefs[key] = typeref
7437 creator = class_types_creator.get(typename)
7439 object_class_types[key] = creator
7444 def import_class_from_module(mod, cls):
7445 add_class_ident(cls)
7446 mcls = "$%s$%s" % (mod, cls)
7447 for k in list(object_class_classrefs.keys()):
7448 kk = k.split('.', 1)
7450 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k]
7451 for k in list(object_class_typerefs.keys()):
7452 kk = k.split('.', 1)
7454 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k]
7455 for k in list(object_class_types.keys()):
7456 kk = k.split('.', 1)
7458 object_class_types[cls + '.' + kk[0]] = object_class_types[k]
7460 #--- ITU-T Recommendation X.682 -----------------------------------------------
7462 # 8 General constraint specification ------------------------------------------
7465 def p_GeneralConstraint (t):
7466 '''GeneralConstraint : UserDefinedConstraint
7468 | ContentsConstraint'''
7471 # 9 User-defined constraints --------------------------------------------------
7474 def p_UserDefinedConstraint (t):
7475 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7476 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
7478 def p_UserDefinedConstraintParameterList_1 (t):
7479 'UserDefinedConstraintParameterList : '
7482 def p_UserDefinedConstraintParameterList_2 (t):
7483 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7486 def p_UserDefinedConstraintParameterList_3 (t):
7487 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7488 t[0] = t[1] + [t[3]]
7491 def p_UserDefinedConstraintParameter (t):
7492 'UserDefinedConstraintParameter : Type'
7495 # 10 Table constraints, including component relation constraints --------------
7498 def p_TableConstraint (t):
7499 '''TableConstraint : SimpleTableConstraint
7500 | ComponentRelationConstraint'''
7501 t[0] = Constraint(type = 'Table', subtype = t[1])
7503 def p_SimpleTableConstraint (t):
7504 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7508 def p_ComponentRelationConstraint (t):
7509 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7510 t[0] = t[2] + str(t[5])
7512 def p_AtNotations_1 (t):
7513 'AtNotations : AtNotation'
7516 def p_AtNotations_2 (t):
7517 'AtNotations : AtNotations COMMA AtNotation'
7518 t[0] = t[1] + [t[3]]
7520 def p_AtNotation_1 (t):
7521 'AtNotation : AT ComponentIdList'
7524 def p_AtNotation_2 (t):
7525 'AtNotation : AT DOT Level ComponentIdList'
7526 t[0] = '@.' + t[3] + t[4]
7536 def p_ComponentIdList_1 (t):
7537 'ComponentIdList : LCASE_IDENT'
7540 def p_ComponentIdList_2 (t):
7541 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7542 t[0] = t[1] + '.' + t[3]
7544 # 11 Contents constraints -----------------------------------------------------
7547 def p_ContentsConstraint (t):
7548 'ContentsConstraint : CONTAINING type_ref'
7549 t[0] = Constraint(type = 'Contents', subtype = t[2])
7552 #--- ITU-T Recommendation X.683 -----------------------------------------------
7554 # 8 Parameterized assignments -------------------------------------------------
7557 def p_ParameterizedAssignment (t):
7558 '''ParameterizedAssignment : ParameterizedTypeAssignment
7559 | ParameterizedObjectClassAssignment
7560 | ParameterizedObjectAssignment
7561 | ParameterizedObjectSetAssignment'''
7565 def p_ParameterizedTypeAssignment (t):
7566 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7568 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
7570 def p_ParameterizedObjectClassAssignment (t):
7571 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7572 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7575 if isinstance(t[0], ObjectClassDefn):
7578 def p_ParameterizedObjectAssignment (t):
7579 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7580 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
7584 def p_ParameterizedObjectSetAssignment (t):
7585 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7586 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
7589 def p_ParameterList (t):
7590 'ParameterList : lbraceignore rbraceignore'
7592 #def p_ParameterList (t):
7593 # 'ParameterList : LBRACE Parameters RBRACE'
7596 #def p_Parameters_1 (t):
7597 # 'Parameters : Parameter'
7600 #def p_Parameters_2 (t):
7601 # 'Parameters : Parameters COMMA Parameter'
7602 # t[0] = t[1] + [t[3]]
7604 #def p_Parameter_1 (t):
7605 # 'Parameter : Type COLON Reference'
7606 # t[0] = [t[1], t[3]]
7608 #def p_Parameter_2 (t):
7609 # 'Parameter : Reference'
7613 # 9 Referencing parameterized definitions -------------------------------------
7616 def p_ParameterizedReference (t):
7617 'ParameterizedReference : Reference LBRACE RBRACE'
7622 def p_ParameterizedType (t):
7623 'ParameterizedType : type_ref ActualParameterList'
7628 def p_ParameterizedObjectClass (t):
7629 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7633 def p_ParameterizedObject (t):
7634 'ParameterizedObject : DefinedObject ActualParameterList'
7639 def p_ActualParameterList (t):
7640 'ActualParameterList : lbraceignore rbraceignore'
7642 #def p_ActualParameterList (t):
7643 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7646 #def p_ActualParameters_1 (t):
7647 # 'ActualParameters : ActualParameter'
7650 #def p_ActualParameters_2 (t):
7651 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7652 # t[0] = t[1] + [t[3]]
7654 #def p_ActualParameter (t):
7655 # '''ActualParameter : Type
7660 #--- ITU-T Recommendation X.880 -----------------------------------------------
7664 '&ArgumentType' : [],
7665 '&argumentTypeOptional' : [ 'BooleanType' ],
7666 '&returnResult' : [ 'BooleanType' ],
7668 '&resultTypeOptional' : [ 'BooleanType' ],
7669 '&Errors' : [ 'ClassReference', 'ERROR' ],
7670 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7671 '&synchronous' : [ 'BooleanType' ],
7672 '&idempotent' : [ 'BooleanType' ],
7673 '&alwaysReturns' : [ 'BooleanType' ],
7674 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7675 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7676 '&operationCode' : [ 'TypeReference', 'Code' ],
7679 '&ParameterType' : [],
7680 '¶meterTypeOptional' : [ 'BooleanType' ],
7681 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7682 '&errorCode' : [ 'TypeReference', 'Code' ],
7684 'OPERATION-PACKAGE' : {
7685 '&Both' : [ 'ClassReference', 'OPERATION' ],
7686 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7687 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7688 '&id' : [ 'ObjectIdentifierType' ],
7690 'CONNECTION-PACKAGE' : {
7691 '&bind' : [ 'ClassReference', 'OPERATION' ],
7692 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7693 '&responderCanUnbind' : [ 'BooleanType' ],
7694 '&unbindCanFail' : [ 'BooleanType' ],
7695 '&id' : [ 'ObjectIdentifierType' ],
7698 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7699 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7700 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7701 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7702 '&id' : [ 'ObjectIdentifierType' ],
7704 'ROS-OBJECT-CLASS' : {
7705 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7706 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7707 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7708 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7709 '&id' : [ 'ObjectIdentifierType' ],
7715 'ARGUMENT' : '&ArgumentType',
7716 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7717 'RESULT' : '&ResultType',
7718 'RESULT OPTIONAL' : '&resultTypeOptional',
7719 'RETURN' : 'RETURN',
7720 'RETURN RESULT' : '&returnResult',
7721 'ERRORS' : '&Errors',
7722 'LINKED' : '&Linked',
7723 'SYNCHRONOUS' : '&synchronous',
7724 'IDEMPOTENT' : '&idempotent',
7725 'ALWAYS' : 'ALWAYS',
7726 'RESPONDS' : 'RESPONDS',
7727 'ALWAYS RESPONDS' : '&alwaysReturns',
7728 'INVOKE' : 'INVOKE',
7729 'PRIORITY' : 'PRIORITY',
7730 'INVOKE PRIORITY' : '&InvokePriority',
7731 'RESULT-PRIORITY': '&ResultPriority',
7732 'CODE' : '&operationCode',
7735 'PARAMETER' : '&ParameterType',
7736 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
7737 'PRIORITY' : '&ErrorPriority',
7738 'CODE' : '&errorCode',
7740 # 'OPERATION-PACKAGE' : {
7742 # 'CONNECTION-PACKAGE' : {
7746 # 'ROS-OBJECT-CLASS' : {
7750 def x880_module_begin():
7751 #print "x880_module_begin()"
7752 for name in list(x880_classes.keys()):
7753 add_class_ident(name)
7755 def x880_import(name):
7756 if name in x880_syntaxes:
7757 class_syntaxes_enabled[name] = True
7758 class_syntaxes[name] = x880_syntaxes[name]
7759 if name in x880_classes:
7760 add_class_ident(name)
7761 for f in (list(x880_classes[name].keys())):
7762 set_type_to_class(name, f, x880_classes[name][f])
7764 tokens = tokens + get_syntax_tokens(x880_syntaxes)
7767 #def p_lbrace_oid(t):
7768 # 'lbrace_oid : brace_oid_begin LBRACE'
7771 #def p_brace_oid_begin(t):
7772 # 'brace_oid_begin : '
7776 #def p_rbrace_oid(t):
7777 # 'rbrace_oid : brace_oid_end RBRACE'
7780 #def p_brace_oid_end(t):
7781 # 'brace_oid_end : '
7785 # {...} block to be ignored
7786 def p_lbraceignore(t):
7787 'lbraceignore : braceignorebegin LBRACE'
7790 def p_braceignorebegin(t):
7791 'braceignorebegin : '
7794 lexer.push_state('braceignore')
7796 def p_rbraceignore(t):
7797 'rbraceignore : braceignoreend RBRACE'
7800 def p_braceignoreend(t):
7807 raise ParseError(t, input_file)
7810 '''pyquote : PYQUOTE'''
7811 t[0] = PyQuote (val = t[1])
7817 token = lexer.token ()
7823 def do_module (ast, defined_dict):
7824 assert (ast.type == 'Module')
7825 ctx = Ctx (defined_dict)
7826 print(ast.to_python (ctx))
7827 print(ctx.output_assignments ())
7828 print(ctx.output_pyquotes ())
7830 def eth_do_module (ast, ectx):
7831 assert (ast.type == 'Module')
7832 if ectx.dbg('s'): print(ast.str_depth(0))
7835 def testyacc(s, fn, defined_dict):
7836 ast = yacc.parse(s, debug=0)
7837 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
7838 print("""#!/usr/bin/env python
7839 # Auto-generated from %s at %s
7840 from PyZ3950 import asn1""" % (fn, time_str))
7842 eth_do_module (module, defined_dict)
7845 # Wireshark compiler
7848 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
7850 -b : BER (default is PER)
7851 -u : Unaligned (default is aligned)
7852 -p proto : Protocol name (implies -S). Default is module-name
7853 from input_file (renamed by #.MODULE if present)
7854 -o name : Output files name core (default is <proto>)
7855 -O dir : Output directory for dissector
7856 -c cnf_file : Conformance file
7857 -I path : Path for conformance file includes
7858 -e : Create conformance file for exported types
7859 -E : Just create conformance file for exported types
7860 -S : Single output for multiple modules
7861 -s template : Single file output (template is input file
7862 without .c/.h extension)
7863 -k : Keep intermediate files though single file output is used
7864 -L : Suppress #line directive from .cnf file
7865 -D dir : Directory for input_file(s) (default: '.')
7866 -C : Add check for SIZE constraints
7867 -r prefix : Remove the prefix from type names
7869 input_file(s) : Input ASN.1 file(s)
7871 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
7875 s - internal ASN.1 structure
7876 a - list of assignments
7878 c - conformance values
7879 m - list of compiled modules with dependency
7880 o - list of output files
7887 print("ASN.1 to Wireshark dissector compiler");
7889 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:");
7890 except getopt.GetoptError:
7891 eth_usage(); sys.exit(2)
7893 eth_usage(); sys.exit(2)
7898 ectx = EthCtx(conform, output)
7899 ectx.encoding = 'per'
7900 ectx.proto_opt = None
7902 ectx.tag_opt = False
7903 ectx.outnm_opt = None
7908 ectx.justexpcnf = False
7909 ectx.merge_modules = False
7910 ectx.group_by_prot = False
7911 ectx.conform.last_group = 0
7912 ectx.conform.suppress_line = False;
7913 ectx.output.outnm = None
7914 ectx.output.single_file = None
7915 ectx.constraints_check = False;
7917 if o in ("-h", "-?"):
7918 eth_usage(); sys.exit(2)
7922 ectx.conform.include_path.append(a)
7925 ectx.justexpcnf = True
7929 ectx.constraints_check = True
7931 warnings.warn("Command line option -X is obsolete and can be removed")
7933 warnings.warn("Command line option -T is obsolete and can be removed")
7936 ectx.conform.read(conf_to_read)
7939 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-X", "-T"):
7940 pass # already processed
7944 ectx.conform.set_opt(o, par, "commandline", 0)
7946 (ld, yd, pd) = (0, 0, 0);
7947 if ectx.dbg('l'): ld = 1
7948 if ectx.dbg('y'): yd = 1
7949 if ectx.dbg('p'): pd = 2
7950 lexer = lex.lex(debug=ld)
7951 yacc.yacc(method='LALR', debug=yd)
7952 g_conform = ectx.conform
7957 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn
7959 ast.extend(yacc.parse(f.read(), lexer=lexer, debug=pd))
7962 if (ectx.merge_modules): # common output for all module
7965 eth_do_module(module, ectx)
7967 ectx.eth_do_output()
7968 elif (ectx.groups()): # group by protocols/group
7971 if (ectx.group_by_prot): # group by protocols
7973 prot = module.get_proto(ectx)
7974 if prot not in pr2gr:
7975 pr2gr[prot] = len(groups)
7977 groups[pr2gr[prot]].append(module)
7978 else: # group by groups
7983 eth_do_module(module, ectx)
7985 ectx.eth_do_output()
7986 else: # output for each module
7989 eth_do_module(module, ectx)
7991 ectx.eth_do_output()
7997 ectx.conform.dbg_print()
7998 if not ectx.justexpcnf:
7999 ectx.conform.unused_report()
8002 ectx.output.dbg_print()
8003 ectx.output.make_single_file()
8009 if len (sys.argv) == 1:
8011 s = input ('Query: ')
8014 testfn (s, 'console', {})
8017 for fn in sys.argv [1:]:
8019 testfn (f.read (), fn, defined_dict)
8024 #--- BODY ---------------------------------------------------------------------
8026 if __name__ == '__main__':
8027 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
8032 #------------------------------------------------------------------------------
8034 # Editor modelines - http://www.wireshark.org/tools/modelines.html
8036 # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil
8037 # vi: set shiftwidth=4 tabstop=8 expandtab:
8038 # :indentSize=4:tabSize=8:noTabs=true: