5 # ASN.1 to Wireshark dissector compiler
6 # Copyright 2004 Tomas Kukosa
8 # SPDX-License-Identifier: MIT
11 """ASN.1 to Wireshark dissector compiler"""
14 # Compiler from ASN.1 specification to the Wireshark dissector
16 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
17 # https://www.pobox.com/~asl2/software/PyZ3950/
18 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
20 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
21 # https://www.dabeaz.com/ply/
24 # ITU-T Recommendation X.680 (07/2002),
25 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
27 # ITU-T Recommendation X.681 (07/2002),
28 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
30 # ITU-T Recommendation X.682 (07/2002),
31 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
33 # ITU-T Recommendation X.683 (07/2002),
34 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
36 # ITU-T Recommendation X.880 (07/1994),
37 # Information technology - Remote Operations: Concepts, model and notation
54 # Fallback: use lex.py and yacc from the tools directory within the
55 # Wireshark source tree if python-ply is not installed.
59 if sys
.version_info
[0] < 3:
60 from string
import maketrans
63 # OID name -> number conversion table
69 '0/recommendation' : 0,
98 '0/administration' : 2,
99 '0/network-operator' : 3,
100 '0/identified-organization' : 4,
101 '0/r-recommendation' : 5,
105 '1/registration-authority' : 1,
107 '1/identified-organization' : 3,
108 '/joint-iso-itu-t' : 2,
109 '/joint-iso-ccitt' : 2,
110 '2/presentation' : 0,
112 '2/association-control' : 2,
113 '2/reliable-transfer' : 3,
114 '2/remote-operations' : 4,
122 '2/osi-management' : 9,
123 '2/transaction-processing' : 10,
125 '2/distinguished-object-reference' : 11,
126 '2/reference-data-transfe' : 12,
127 '2/network-layer' : 13,
128 '2/network-layer-management' : 13,
129 '2/transport-layer' : 14,
130 '2/transport-layer-management' : 14,
131 '2/datalink-layer' : 15,
132 '2/datalink-layer-managemen' : 15,
133 '2/datalink-layer-management-information' : 15,
135 '2/registration-procedures' : 17,
136 '2/registration-procedure' : 17,
137 '2/physical-layer' : 18,
138 '2/physical-layer-management' : 18,
141 '2/generic-upper-layers-security' : 20,
143 '2/transport-layer-security-protocol' : 21,
144 '2/network-layer-security-protocol' : 22,
145 '2/international-organizations' : 23,
146 '2/internationalRA' : 23,
153 ITEM_FIELD_NAME
= '_item'
154 UNTAG_TYPE_NAME
= '_untag'
157 return id.replace('-', '_').replace('.', '_').replace('&', '_')
165 class LexError(Exception):
166 def __init__(self
, tok
, filename
=None):
168 self
.filename
= filename
169 self
.msg
= "Unexpected character %r" % (self
.tok
.value
[0])
170 Exception.__init
__(self
, self
.msg
)
172 return "%s:%d: %s" % (self
.filename
, self
.tok
.lineno
, self
.msg
)
176 class ParseError(Exception):
177 def __init__(self
, tok
, filename
=None):
179 self
.filename
= filename
180 self
.msg
= "Unexpected token %s(%r)" % (self
.tok
.type, self
.tok
.value
)
181 Exception.__init
__(self
, self
.msg
)
183 return "%s:%d: %s" % (self
.filename
, self
.tok
.lineno
, self
.msg
)
187 class DuplicateError(Exception):
188 def __init__(self
, type, ident
):
191 self
.msg
= "Duplicate %s for %s" % (self
.type, self
.ident
)
192 Exception.__init
__(self
, self
.msg
)
197 class CompError(Exception):
198 def __init__(self
, msg
):
200 Exception.__init
__(self
, self
.msg
)
207 ('braceignore','exclusive'),
211 ('left', 'UNION', 'BAR'),
212 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
214 # 11 ASN.1 lexical items
217 r
'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
218 r
'\.\.' : 'RANGE', # 11.17 Range separator
219 r
'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
220 r
'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
221 r
'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
222 # 11.26 Single character lexical items
237 #r"'" : 'APOSTROPHE',
240 r
'\!' : 'EXCLAMATION',
241 r
'\^' : 'CIRCUMFLEX',
246 # 11.27 Reserved words
248 # all keys in reserved_words must start w/ upper case
251 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
253 'APPLICATION' : 'APPLICATION',
254 'AUTOMATIC' : 'AUTOMATIC',
257 'BOOLEAN' : 'BOOLEAN',
259 'CHARACTER' : 'CHARACTER',
262 'COMPONENT' : 'COMPONENT',
263 'COMPONENTS' : 'COMPONENTS',
264 'CONSTRAINED' : 'CONSTRAINED',
265 'CONTAINING' : 'CONTAINING',
266 'DEFAULT' : 'DEFAULT',
267 'DEFINITIONS' : 'DEFINITIONS',
268 'EMBEDDED' : 'EMBEDDED',
269 # 'ENCODED' : 'ENCODED',
271 'ENUMERATED' : 'ENUMERATED',
272 # 'EXCEPT' : 'EXCEPT',
273 'EXPLICIT' : 'EXPLICIT',
274 'EXPORTS' : 'EXPORTS',
275 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
276 'EXTERNAL' : 'EXTERNAL',
279 'GeneralizedTime' : 'GeneralizedTime',
280 'IDENTIFIER' : 'IDENTIFIER',
281 'IMPLICIT' : 'IMPLICIT',
282 # 'IMPLIED' : 'IMPLIED',
283 'IMPORTS' : 'IMPORTS',
284 'INCLUDES' : 'INCLUDES',
285 'INSTANCE' : 'INSTANCE',
286 'INTEGER' : 'INTEGER',
287 'INTERSECTION' : 'INTERSECTION',
290 'MINUS-INFINITY' : 'MINUS_INFINITY',
293 'ObjectDescriptor' : 'ObjectDescriptor',
296 'OPTIONAL' : 'OPTIONAL',
297 'PATTERN' : 'PATTERN',
299 'PLUS-INFINITY' : 'PLUS_INFINITY',
300 'PRESENT' : 'PRESENT',
301 'PRIVATE' : 'PRIVATE',
303 'RELATIVE-OID' : 'RELATIVE_OID',
304 'SEQUENCE' : 'SEQUENCE',
308 'SUCCESSORS' : 'SUCCESSORS',
312 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
315 'UNIVERSAL' : 'UNIVERSAL',
316 'UTCTime' : 'UTCTime',
318 # X.208 obsolete but still used
320 'DEFINED' : 'DEFINED',
323 for k
in list(static_tokens
.keys()):
324 if static_tokens
[k
] is None:
325 static_tokens
[k
] = k
327 StringTypes
= ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
328 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
331 # Effective permitted-alphabet constraints are PER-visible only
332 # for the known-multiplier character string types (X.691 27.1)
334 # XXX: This should include BMPString (UCS2) and UniversalString (UCS4),
335 # but asn2wrs only supports the RestrictedCharacterStringValue
336 # notation of "cstring", but not that of "CharacterStringList",
337 # "Quadruple", or "Tuple" (See X.680 41.8), and packet-per.c does
338 # not support members of the permitted-alphabet being outside the
339 # ASCII range. We don't currently have any ASN.1 modules that need it,
341 KnownMultiplierStringTypes
= ('NumericString', 'PrintableString', 'IA5String',
342 'ISO646String', 'VisibleString')
344 for s
in StringTypes
:
345 reserved_words
[s
+ 'String'] = s
+ 'String'
347 tokens
= list(static_tokens
.values()) \
348 + list(reserved_words
.values()) \
349 + ['BSTRING', 'HSTRING', 'QSTRING',
350 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
351 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
354 cur_mod
= __import__ (__name__
) # XXX blech!
356 for (k
, v
) in list(static_tokens
.items ()):
357 cur_mod
.__dict
__['t_' + v
] = k
359 # 11.10 Binary strings
364 # 11.12 Hexadecimal strings
373 def t_UCASE_IDENT (t
):
374 r
"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
375 if (is_class_ident(t
.value
)): t
.type = 'CLASS_IDENT'
376 if (is_class_syntax(t
.value
)): t
.type = t
.value
377 t
.type = reserved_words
.get(t
.value
, t
.type)
380 lcase_ident_assigned
= {}
381 def t_LCASE_IDENT (t
):
382 r
"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
383 if (not in_oid
and (t
.value
in lcase_ident_assigned
)): t
.type = 'LCASE_IDENT_ASSIGNED'
387 def t_REAL_NUMBER (t
):
388 r
"[0-9]+\.[0-9]*(?!\.)"
397 pyquote_str
= 'PYQUOTE'
399 r
"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
400 if (t
.value
.find("\n") >= 0) : t
.lexer
.lineno
+= 1
401 if t
.value
[2:2+len (pyquote_str
)] == pyquote_str
:
402 t
.value
= t
.value
[2+len(pyquote_str
):]
403 t
.value
= t
.value
.lstrip ()
412 t
.lexer
.lineno
+= t
.value
.count("\n")
416 raise LexError(t
, input_file
)
418 # state 'braceignore'
420 def t_braceignore_lbrace(t
):
424 def t_braceignore_rbrace(t
):
427 # If closing brace, return token
428 if t
.lexer
.level
== 0:
432 def t_braceignore_QSTRING (t
):
434 t
.lexer
.lineno
+= t
.value
.count("\n")
436 def t_braceignore_COMMENT(t
):
437 r
"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
438 if (t
.value
.find("\n") >= 0) : t
.lexer
.lineno
+= 1
440 def t_braceignore_nonspace(t
):
441 r
'[^\s\{\}\"-]+|-(?!-)'
443 t_braceignore_ignore
= " \t\r"
445 def t_braceignore_NEWLINE(t
):
447 t
.lexer
.lineno
+= t
.value
.count("\n")
449 def t_braceignore_error(t
):
453 def __init__ (self
, defined_dict
, indent
= 0):
454 self
.tags_def
= 'EXPLICIT' # default = explicit
456 self
.assignments
= {}
457 self
.dependencies
= {}
459 self
.defined_dict
= defined_dict
462 return " " * (4 * self
.indent_lev
)
467 assert (self
.indent_lev
>= 0)
468 def register_assignment (self
, ident
, val
, dependencies
):
469 if ident
in self
.assignments
:
470 raise DuplicateError("assignment", ident
)
471 if ident
in self
.defined_dict
:
472 raise Exception("cross-module duplicates for %s" % ident
)
473 self
.defined_dict
[ident
] = 1
474 self
.assignments
[ident
] = val
475 self
.dependencies
[ident
] = dependencies
477 # return "#%s depends on %s" % (ident, str (dependencies))
478 def register_pyquote (self
, val
):
479 self
.pyquotes
.append (val
)
481 def output_assignments (self
):
484 assign_keys
= list(self
.assignments
.keys())
485 to_output_count
= len (assign_keys
)
488 for (ident
, val
) in list(self
.assignments
.items ()):
489 if ident
in already_output
:
492 for d
in self
.dependencies
[ident
]:
493 if ((d
not in already_output
) and
497 text_list
.append ("%s=%s" % (ident
,
498 self
.assignments
[ident
]))
499 already_output
[ident
] = 1
502 assert (to_output_count
>= 0)
504 if to_output_count
== 0:
506 # OK, we detected a cycle
508 for ident
in list(self
.assignments
.keys ()):
509 if ident
not in already_output
:
510 depend_list
= [d
for d
in self
.dependencies
[ident
] if d
in assign_keys
]
511 cycle_list
.append ("%s(%s)" % (ident
, ",".join (depend_list
)))
513 text_list
.append ("# Cycle XXX " + ",".join (cycle_list
))
514 for (ident
, val
) in list(self
.assignments
.items ()):
515 if ident
not in already_output
:
516 text_list
.append ("%s=%s" % (ident
, self
.assignments
[ident
]))
519 return "\n".join (text_list
)
520 def output_pyquotes (self
):
521 return "\n".join (self
.pyquotes
)
522 def make_new_name (self
):
524 return "_compiler_generated_name_%d" % (self
.name_ctr
,)
526 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
530 EF_WS_DLL
= 0x0010 # exported from shared library
539 #--- common dependency computation ---
540 # Input : list of items
541 # dictionary with lists of dependency
544 # Output : list of two outputs:
545 # [0] list of items in dependency
546 # [1] list of cycle dependency cycles
547 def dependency_compute(items
, dependency
, map_fn
= lambda t
: t
, ignore_fn
= lambda t
: False):
550 x
= {} # already emitted
551 #print '# Dependency computation'
554 #print 'Continue: %s : %s' % (t, (map_fn(t))
557 stackx
= {t
: dependency
.get(t
, [])[:]}
558 #print 'Push: %s : %s' % (t, str(stackx[t]))
560 if stackx
[stack
[-1]]: # has dependencies
561 d
= stackx
[stack
[-1]].pop(0)
562 if map_fn(d
) in x
or ignore_fn(d
):
564 if d
in stackx
: # cyclic dependency
567 c
= [d
] + c
[0:c
.index(d
)+1]
570 #print 'Cyclic: %s ' % (' -> '.join(c))
573 stackx
[d
] = dependency
.get(d
, [])[:]
574 #print 'Push: %s : %s' % (d, str(stackx[d]))
576 #print 'Pop: %s' % (stack[-1])
577 del stackx
[stack
[-1]]
578 e
= map_fn(stack
.pop())
581 #print 'Add: %s' % (e)
584 return (item_ord
, item_cyc
)
586 # Given a filename, return a relative path from the current directory
587 def relpath(filename
):
588 return os
.path
.relpath(filename
)
590 # Given a filename, return a relative path from epan/dissectors
591 def rel_dissector_path(filename
):
592 path_parts
= os
.path
.abspath(filename
).split(os
.sep
)
593 while (len(path_parts
) > 3 and path_parts
[0] != 'asn1'):
595 path_parts
.insert(0, '.')
596 return '/'.join(path_parts
)
599 #--- EthCtx -------------------------------------------------------------------
601 def __init__(self
, conform
, output
, indent
= 0):
602 self
.conform
= conform
604 self
.conform
.ectx
= self
605 self
.output
.ectx
= self
606 self
.encoding
= 'per'
608 self
.default_oid_variant
= ''
609 self
.default_opentype_variant
= ''
610 self
.default_containing_variant
= '_pdu_new'
611 self
.default_embedded_pdv_cb
= None
612 self
.default_external_type_cb
= None
613 self
.remove_prefix
= None
615 self
.emitted_pdu
= {}
618 self
.all_type_attr
= {}
622 def encp(self
): # encoding protocol
627 def Per(self
): return self
.encoding
== 'per'
628 def Ber(self
): return self
.encoding
== 'ber'
629 def Oer(self
): return self
.encoding
== 'oer'
630 def Aligned(self
): return self
.aligned
631 def Unaligned(self
): return not self
.aligned
632 def NeedTags(self
): return self
.tag_opt
or self
.Ber()
633 def NAPI(self
): return False # disable planned features
635 def Module(self
): # current module name
636 return self
.modules
[-1][0]
639 return self
.group_by_prot
or (self
.conform
.last_group
> 0)
642 if (self
.dbgopt
.find(d
) >= 0):
647 def value_max(self
, a
, b
):
648 if (a
== 'MAX') or (b
== 'MAX'): return 'MAX'
649 if a
== 'MIN': return b
650 if b
== 'MIN': return a
652 if (int(a
) > int(b
)):
656 except (ValueError, TypeError):
658 return "MAX((%s),(%s))" % (a
, b
)
660 def value_min(self
, a
, b
):
661 if (a
== 'MIN') or (b
== 'MIN'): return 'MIN'
662 if a
== 'MAX': return b
663 if b
== 'MAX': return a
665 if (int(a
) < int(b
)):
669 except (ValueError, TypeError):
671 return "MIN((%s),(%s))" % (a
, b
)
673 def value_get_eth(self
, val
):
674 if isinstance(val
, Value
):
675 return val
.to_str(self
)
677 if val
in self
.value
:
678 ethname
= self
.value
[val
]['ethname']
681 def value_get_val(self
, nm
):
684 if self
.value
[nm
]['import']:
685 v
= self
.get_val_from_all(nm
, self
.value
[nm
]['import'])
687 msg
= 'Need value of imported value identifier %s from %s (%s)' % (nm
, self
.value
[nm
]['import'], self
.value
[nm
]['proto'])
688 warnings
.warn_explicit(msg
, UserWarning, '', 0)
692 val
= self
.value
[nm
]['value']
693 if isinstance (val
, Value
):
694 val
= val
.to_str(self
)
696 msg
= 'Need value of unknown value identifier %s' % (nm
)
697 warnings
.warn_explicit(msg
, UserWarning, '', 0)
700 def eth_get_type_attr(self
, type):
701 #print "eth_get_type_attr(%s)" % (type)
703 while (not self
.type[type]['import']):
704 val
= self
.type[type]['val']
707 while (val
.type == 'TaggedType'):
709 ttype
+= '/' + UNTAG_TYPE_NAME
710 if (val
.type != 'Type_Ref'):
720 if (self
.type[t
]['import']):
721 attr
.update(self
.type[t
]['attr'])
722 attr
.update(self
.eth_get_type_attr_from_all(t
, self
.type[t
]['import']))
723 elif (self
.type[t
]['val'].type == 'SelectionType'):
724 val
= self
.type[t
]['val']
725 (ftype
, display
) = val
.eth_ftype(self
)
726 attr
.update({ 'TYPE' : ftype
, 'DISPLAY' : display
,
727 'STRINGS' : val
.eth_strings(), 'BITMASK' : '0' })
729 attr
.update(self
.type[t
]['attr'])
730 attr
.update(self
.eth_type
[self
.type[t
]['ethname']]['attr'])
731 if attr
['STRINGS'].startswith('VALS64(') and '|BASE_VAL64_STRING' not in attr
['DISPLAY']:
732 attr
['DISPLAY'] += '|BASE_VAL64_STRING'
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), 'module=', self.Module())
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
, mod
=None):
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 #print('DuplicateError: import=', self.type[ident]['import'], 'module=', self.Module())
948 raise DuplicateError("type", ident
)
950 self
.type[ident
] = { 'val' : val
, 'import' : None }
951 self
.type[ident
]['module'] = self
.Module()
952 self
.type[ident
]['proto'] = self
.proto
953 if len(ident
.split('/')) > 1:
954 self
.type[ident
]['tname'] = val
.eth_tname()
956 self
.type[ident
]['tname'] = asn2c(ident
)
958 mident
= "$%s$%s" % (mod
, ident
)
961 self
.type[ident
]['export'] = self
.conform
.use_item('EXPORTS', ident
)
962 self
.type[ident
]['enum'] = self
.conform
.use_item('MAKE_ENUM', ident
)
963 self
.type[ident
]['vals_ext'] = self
.conform
.use_item('USE_VALS_EXT', ident
)
964 self
.type[ident
]['user_def'] = self
.conform
.use_item('USER_DEFINED', ident
)
965 if mident
and self
.conform
.check_item('NO_EMIT', mident
) :
966 self
.type[ident
]['no_emit'] = self
.conform
.use_item('NO_EMIT', mident
)
968 self
.type[ident
]['no_emit'] = self
.conform
.use_item('NO_EMIT', ident
)
969 self
.type[ident
]['tname'] = self
.conform
.use_item('TYPE_RENAME', ident
, val_dflt
=self
.type[ident
]['tname'])
970 self
.type[ident
]['ethname'] = ''
971 if (val
.type == 'Type_Ref') or (val
.type == 'TaggedType') or (val
.type == 'SelectionType') :
972 self
.type[ident
]['attr'] = {}
974 (ftype
, display
) = val
.eth_ftype(self
)
975 self
.type[ident
]['attr'] = { 'TYPE' : ftype
, 'DISPLAY' : display
,
976 'STRINGS' : val
.eth_strings(), 'BITMASK' : '0' }
977 self
.type[ident
]['attr'].update(self
.conform
.use_item('TYPE_ATTR', ident
))
978 self
.type_ord
.append(ident
)
980 if (self
.conform
.check_item('PDU', ident
)):
981 self
.eth_reg_field(ident
, ident
, impl
=val
.HasImplicitTag(self
), pdu
=self
.conform
.use_item('PDU', ident
))
983 #--- eth_reg_objectclass ----------------------------------------------------------
984 def eth_reg_objectclass(self
, ident
, val
):
985 #print "eth_reg_objectclass(ident='%s')" % (ident)
986 if ident
in self
.objectclass
:
987 if self
.objectclass
[ident
]['import'] and (self
.objectclass
[ident
]['import'] == self
.Module()) :
988 # replace imported object class
989 del self
.objectclass
[ident
]
990 self
.objectclass_imp
.remove(ident
)
991 elif isinstance(self
.objectclass
[ident
]['val'], Class_Ref
) and \
992 isinstance(val
, Class_Ref
) and \
993 (self
.objectclass
[ident
]['val'].val
== val
.val
):
994 pass # ignore duplicated CLASS1 ::= CLASS2
996 raise DuplicateError("object class", ident
)
997 self
.objectclass
[ident
] = { 'import' : None, 'module' : self
.Module(), 'proto' : self
.proto
}
998 self
.objectclass
[ident
]['val'] = val
999 self
.objectclass
[ident
]['export'] = self
.conform
.use_item('EXPORTS', ident
)
1000 self
.objectclass_ord
.append(ident
)
1002 #--- eth_reg_value ----------------------------------------------------------
1003 def eth_reg_value(self
, ident
, type, value
, ethname
=None):
1004 #print "eth_reg_value(ident='%s')" % (ident)
1005 if ident
in self
.value
:
1006 if self
.value
[ident
]['import'] and (self
.value
[ident
]['import'] == self
.Module()) :
1007 # replace imported value
1008 del self
.value
[ident
]
1009 self
.value_imp
.remove(ident
)
1011 self
.value
[ident
]['ethname'] = ethname
1014 raise DuplicateError("value", ident
)
1015 self
.value
[ident
] = { 'import' : None, 'module' : self
.Module(), 'proto' : self
.proto
,
1016 'type' : type, 'value' : value
,
1018 self
.value
[ident
]['export'] = self
.conform
.use_item('EXPORTS', ident
)
1019 self
.value
[ident
]['ethname'] = ''
1020 if (ethname
): self
.value
[ident
]['ethname'] = ethname
1021 self
.value_ord
.append(ident
)
1023 #--- eth_reg_field ----------------------------------------------------------
1024 def eth_reg_field(self
, ident
, type, idx
='', parent
=None, impl
=False, pdu
=None):
1025 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
1026 if ident
in self
.field
:
1027 if pdu
and (type == self
.field
[ident
]['type']):
1028 pass # OK already created PDU
1030 raise DuplicateError("field", ident
)
1031 self
.field
[ident
] = {'type' : type, 'idx' : idx
, 'impl' : impl
, 'pdu' : pdu
,
1032 'modified' : '', 'attr' : {} }
1033 name
= ident
.split('/')[-1]
1034 if self
.remove_prefix
and name
.startswith(self
.remove_prefix
):
1035 name
= name
[len(self
.remove_prefix
):]
1037 if len(ident
.split('/')) > 1 and name
== ITEM_FIELD_NAME
: # Sequence/Set of type
1038 if len(self
.field
[ident
]['type'].split('/')) > 1:
1039 self
.field
[ident
]['attr']['NAME'] = '"%s item"' % ident
.split('/')[-2]
1040 self
.field
[ident
]['attr']['ABBREV'] = asn2c(ident
.split('/')[-2] + name
)
1042 self
.field
[ident
]['attr']['NAME'] = '"%s"' % self
.field
[ident
]['type']
1043 self
.field
[ident
]['attr']['ABBREV'] = asn2c(self
.field
[ident
]['type'])
1045 self
.field
[ident
]['attr']['NAME'] = '"%s"' % name
1046 self
.field
[ident
]['attr']['ABBREV'] = asn2c(name
)
1047 if self
.conform
.check_item('FIELD_ATTR', ident
):
1048 self
.field
[ident
]['modified'] = '#' + str(id(self
))
1049 self
.field
[ident
]['attr'].update(self
.conform
.use_item('FIELD_ATTR', ident
))
1051 self
.field
[ident
]['pdu']['export'] = (self
.conform
.use_item('EXPORTS', ident
+ '_PDU') != 0)
1052 self
.pdu_ord
.append(ident
)
1054 self
.field_ord
.append(ident
)
1056 self
.eth_dep_add(parent
, type)
1058 def eth_dummy_eag_field_required(self
):
1059 if (not self
.dummy_eag_field
):
1060 self
.dummy_eag_field
= 'eag_field'
1062 #--- eth_clean --------------------------------------------------------------
1063 def eth_clean(self
):
1064 self
.proto
= self
.proto_opt
1065 #--- ASN.1 tables ----------------
1067 self
.assign_ord
= []
1076 self
.sel_req_ord
= []
1077 self
.comp_req_ord
= []
1079 self
.vassign_ord
= []
1083 self
.objectclass
= {}
1084 self
.objectclass_ord
= []
1085 self
.objectclass_imp
= []
1087 self
.oassign_ord
= []
1088 self
.oassign_cls
= {}
1089 #--- Modules ------------
1091 self
.exports_all
= False
1095 #--- types -------------------
1097 self
.eth_type_ord
= []
1098 self
.eth_export_ord
= []
1099 self
.eth_type_dupl
= {}
1101 #--- value dependencies -------------------
1103 #--- values -------------------
1105 self
.eth_value_ord
= []
1106 #--- fields -------------------------
1108 self
.eth_hf_ord
= []
1109 self
.eth_hfpdu_ord
= []
1110 self
.eth_hf_dupl
= {}
1111 self
.dummy_eag_field
= None
1112 #--- type dependencies -------------------
1113 self
.eth_type_ord1
= []
1114 self
.eth_dep_cycle
= []
1115 self
.dep_cycle_eth_type
= {}
1116 #--- value dependencies and export -------------------
1117 self
.eth_value_ord1
= []
1118 self
.eth_vexport_ord
= []
1120 #--- eth_prepare ------------------------------------------------------------
1121 def eth_prepare(self
):
1122 self
.eproto
= asn2c(self
.proto
)
1124 #--- dummy types/fields for PDU registration ---
1126 if (self
.conform
.check_item('PDU', nm
)):
1127 self
.eth_reg_type('_dummy/'+nm
, NullType())
1128 self
.eth_reg_field(nm
, '_dummy/'+nm
, pdu
=self
.conform
.use_item('PDU', nm
))
1130 #--- required PDUs ----------------------------
1131 for t
in self
.type_ord
:
1132 pdu
= self
.type[t
]['val'].eth_need_pdu(self
)
1133 if not pdu
: continue
1136 pdu
['hidden'] = False
1137 pdu
['need_decl'] = True
1138 if f
not in self
.field
:
1139 self
.eth_reg_field(f
, f
, pdu
=pdu
)
1141 #--- values -> named values -------------------
1143 for v
in self
.value_ord
:
1144 if (self
.value
[v
]['type'].type == 'Type_Ref') or self
.conform
.check_item('ASSIGN_VALUE_TO_TYPE', v
):
1145 if self
.conform
.check_item('ASSIGN_VALUE_TO_TYPE', v
):
1146 tnm
= self
.conform
.use_item('ASSIGN_VALUE_TO_TYPE', v
)
1148 tnm
= self
.value
[v
]['type'].val
1149 if tnm
in self
.type \
1150 and not self
.type[tnm
]['import'] \
1151 and (self
.type[tnm
]['val'].type == 'IntegerType'):
1152 self
.type[tnm
]['val'].add_named_value(v
, self
.value
[v
]['value'])
1153 self
.value
[v
]['no_emit'] = True
1154 t_for_update
[tnm
] = True
1155 for t
in list(t_for_update
.keys()):
1156 self
.type[t
]['attr']['STRINGS'] = self
.type[t
]['val'].eth_strings()
1157 self
.type[t
]['attr'].update(self
.conform
.use_item('TYPE_ATTR', t
))
1159 #--- required components of ---------------------------
1160 #print "self.comp_req_ord = ", self.comp_req_ord
1161 for t
in self
.comp_req_ord
:
1162 self
.type[t
]['val'].eth_reg_sub(t
, self
, components_available
=True)
1164 #--- required selection types ---------------------------
1165 #print "self.sel_req_ord = ", self.sel_req_ord
1166 for t
in self
.sel_req_ord
:
1167 tt
= self
.sel_req
[t
]['typ']
1168 if tt
not in self
.type:
1169 self
.dummy_import_type(t
)
1170 elif self
.type[tt
]['import']:
1171 self
.eth_import_type(t
, self
.type[tt
]['import'], self
.type[tt
]['proto'])
1173 self
.type[tt
]['val'].sel_req(t
, self
.sel_req
[t
]['sel'], self
)
1175 #--- types -------------------
1176 for t
in self
.type_imp
: # imported types
1178 self
.eth_type
[nm
] = { 'import' : self
.type[t
]['import'],
1179 'proto' : asn2c(self
.type[t
]['proto']),
1180 'attr' : {}, 'ref' : []}
1181 self
.eth_type
[nm
]['attr'].update(self
.conform
.use_item('ETYPE_ATTR', nm
))
1182 self
.type[t
]['ethname'] = nm
1183 for t
in self
.type_ord
: # dummy import for missing type reference
1184 tp
= self
.type[t
]['val']
1185 #print "X : %s %s " % (t, tp.type)
1186 if isinstance(tp
, TaggedType
):
1187 #print "%s : %s " % (tp.type, t)
1189 if isinstance(tp
, Type_Ref
):
1190 #print "%s : %s ::= %s " % (tp.type, t, tp.val)
1191 if tp
.val
not in self
.type:
1192 self
.dummy_import_type(tp
.val
)
1193 for t
in self
.type_ord
:
1194 nm
= self
.type[t
]['tname']
1195 if ((nm
.find('#') >= 0) or
1196 ((len(t
.split('/'))>1) and
1197 (self
.conform
.get_fn_presence(t
) or self
.conform
.check_item('FN_PARS', t
) or
1198 self
.conform
.get_fn_presence('/'.join((t
,ITEM_FIELD_NAME
))) or self
.conform
.check_item('FN_PARS', '/'.join((t
,ITEM_FIELD_NAME
)))) and
1199 not self
.conform
.check_item('TYPE_RENAME', t
))):
1200 if len(t
.split('/')) == 2 and t
.split('/')[1] == ITEM_FIELD_NAME
: # Sequence of type at the 1st level
1201 nm
= t
.split('/')[0] + t
.split('/')[1]
1202 elif t
.split('/')[-1] == ITEM_FIELD_NAME
: # Sequence/Set of type at next levels
1203 nm
= 'T_' + self
.conform
.use_item('FIELD_RENAME', '/'.join(t
.split('/')[0:-1]), val_dflt
=t
.split('/')[-2]) + t
.split('/')[-1]
1204 elif t
.split('/')[-1] == UNTAG_TYPE_NAME
: # Untagged type
1205 nm
= self
.type['/'.join(t
.split('/')[0:-1])]['ethname'] + '_U'
1207 nm
= 'T_' + self
.conform
.use_item('FIELD_RENAME', t
, val_dflt
=t
.split('/')[-1])
1209 if nm
in self
.eth_type
:
1210 if nm
in self
.eth_type_dupl
:
1211 self
.eth_type_dupl
[nm
].append(t
)
1213 self
.eth_type_dupl
[nm
] = [self
.eth_type
[nm
]['ref'][0], t
]
1214 nm
+= '_%02d' % (len(self
.eth_type_dupl
[nm
])-1)
1215 if nm
in self
.eth_type
:
1216 self
.eth_type
[nm
]['ref'].append(t
)
1218 self
.eth_type_ord
.append(nm
)
1219 self
.eth_type
[nm
] = { 'import' : None, 'proto' : self
.eproto
, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
1220 'user_def' : EF_TYPE|EF_VALS
, 'no_emit' : EF_TYPE|EF_VALS
,
1221 'val' : self
.type[t
]['val'],
1222 'attr' : {}, 'ref' : [t
]}
1223 self
.type[t
]['ethname'] = nm
1224 if (not self
.eth_type
[nm
]['export'] and self
.type[t
]['export']): # new export
1225 self
.eth_export_ord
.append(nm
)
1226 self
.eth_type
[nm
]['export'] |
= self
.type[t
]['export']
1227 self
.eth_type
[nm
]['enum'] |
= self
.type[t
]['enum']
1228 self
.eth_type
[nm
]['vals_ext'] |
= self
.type[t
]['vals_ext']
1229 self
.eth_type
[nm
]['user_def'] &= self
.type[t
]['user_def']
1230 self
.eth_type
[nm
]['no_emit'] &= self
.type[t
]['no_emit']
1231 if self
.type[t
]['attr'].get('STRINGS') == '$$':
1232 use_ext
= self
.type[t
]['vals_ext']
1234 self
.eth_type
[nm
]['attr']['STRINGS'] = '&%s_ext' % (self
.eth_vals_nm(nm
))
1236 if self
.eth_type
[nm
]['val'].type == 'IntegerType' \
1237 and self
.eth_type
[nm
]['val'].HasConstraint() \
1238 and self
.eth_type
[nm
]['val'].constr
.Needs64b(self
):
1239 self
.eth_type
[nm
]['attr']['STRINGS'] = 'VALS64(%s)' % (self
.eth_vals_nm(nm
))
1241 self
.eth_type
[nm
]['attr']['STRINGS'] = 'VALS(%s)' % (self
.eth_vals_nm(nm
))
1242 self
.eth_type
[nm
]['attr'].update(self
.conform
.use_item('ETYPE_ATTR', nm
))
1243 for t
in self
.eth_type_ord
:
1244 bits
= self
.eth_type
[t
]['val'].eth_named_bits()
1246 for (val
, id) in bits
:
1247 self
.named_bit
.append({'name' : id, 'val' : val
,
1248 'ethname' : 'hf_%s_%s_%s' % (self
.eproto
, t
, asn2c(id)),
1249 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1251 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val
%8]})
1252 if self
.eth_type
[t
]['val'].eth_need_tree():
1253 self
.eth_type
[t
]['tree'] = "ett_%s_%s" % (self
.eth_type
[t
]['proto'], t
)
1255 self
.eth_type
[t
]['tree'] = None
1257 #--- register values from enums ------------
1258 for t
in self
.eth_type_ord
:
1259 if (self
.eth_type
[t
]['val'].eth_has_enum(t
, self
)):
1260 self
.eth_type
[t
]['val'].reg_enum_vals(t
, self
)
1262 #--- value dependencies -------------------
1263 for v
in self
.value_ord
:
1264 if isinstance (self
.value
[v
]['value'], Value
):
1265 dep
= self
.value
[v
]['value'].get_dep()
1267 dep
= self
.value
[v
]['value']
1268 if dep
and dep
in self
.value
:
1269 self
.value_dep
.setdefault(v
, []).append(dep
)
1271 #--- exports all necessary values
1272 for v
in self
.value_ord
:
1273 if not self
.value
[v
]['export']: continue
1274 deparr
= self
.value_dep
.get(v
, [])
1277 if not self
.value
[d
]['import']:
1278 if not self
.value
[d
]['export']:
1279 self
.value
[d
]['export'] = EF_TYPE
1280 deparr
.extend(self
.value_dep
.get(d
, []))
1282 #--- values -------------------
1283 for v
in self
.value_imp
:
1285 self
.eth_value
[nm
] = { 'import' : self
.value
[v
]['import'],
1286 'proto' : asn2c(self
.value
[v
]['proto']),
1288 self
.value
[v
]['ethname'] = nm
1289 for v
in self
.value_ord
:
1290 if (self
.value
[v
]['ethname']):
1292 if (self
.value
[v
]['no_emit']):
1295 self
.eth_value
[nm
] = { 'import' : None,
1296 'proto' : asn2c(self
.value
[v
]['proto']),
1297 'export' : self
.value
[v
]['export'], 'ref' : [v
] }
1298 self
.eth_value
[nm
]['value'] = self
.value
[v
]['value']
1299 self
.eth_value_ord
.append(nm
)
1300 self
.value
[v
]['ethname'] = nm
1302 #--- fields -------------------------
1303 for f
in (self
.pdu_ord
+ self
.field_ord
):
1304 if len(f
.split('/')) > 1 and f
.split('/')[-1] == ITEM_FIELD_NAME
: # Sequence/Set of type
1305 nm
= self
.conform
.use_item('FIELD_RENAME', '/'.join(f
.split('/')[0:-1]), val_dflt
=f
.split('/')[-2]) + f
.split('/')[-1]
1307 nm
= f
.split('/')[-1]
1308 nm
= self
.conform
.use_item('FIELD_RENAME', f
, val_dflt
=nm
)
1310 if (self
.field
[f
]['pdu']):
1312 if (not self
.merge_modules
or self
.field
[f
]['pdu']['export']):
1313 nm
= self
.eproto
+ '_' + nm
1314 t
= self
.field
[f
]['type']
1316 ethtype
= self
.type[t
]['ethname']
1317 else: # undefined type
1318 ethtype
= self
.dummy_import_type(t
)
1319 ethtypemod
= ethtype
+ self
.field
[f
]['modified']
1320 if nm
in self
.eth_hf
:
1321 if nm
in self
.eth_hf_dupl
:
1322 if ethtypemod
in self
.eth_hf_dupl
[nm
]:
1323 nm
= self
.eth_hf_dupl
[nm
][ethtypemod
]
1324 self
.eth_hf
[nm
]['ref'].append(f
)
1325 self
.field
[f
]['ethname'] = nm
1328 nmx
= nm
+ ('_%02d' % (len(self
.eth_hf_dupl
[nm
])))
1329 self
.eth_hf_dupl
[nm
][ethtype
] = nmx
1332 if (self
.eth_hf
[nm
]['ethtype']+self
.eth_hf
[nm
]['modified']) == ethtypemod
:
1333 self
.eth_hf
[nm
]['ref'].append(f
)
1334 self
.field
[f
]['ethname'] = nm
1338 self
.eth_hf_dupl
[nm
] = {self
.eth_hf
[nm
]['ethtype']+self
.eth_hf
[nm
]['modified'] : nm
, \
1341 if (self
.field
[f
]['pdu']):
1342 self
.eth_hfpdu_ord
.append(nm
)
1344 self
.eth_hf_ord
.append(nm
)
1345 fullname
= 'hf_%s_%s' % (self
.eproto
, nm
)
1346 attr
= self
.eth_get_type_attr(self
.field
[f
]['type']).copy()
1347 attr
.update(self
.field
[f
]['attr'])
1348 if (self
.NAPI() and 'NAME' in attr
):
1349 attr
['NAME'] += self
.field
[f
]['idx']
1350 attr
.update(self
.conform
.use_item('EFIELD_ATTR', nm
))
1351 use_vals_ext
= self
.eth_type
[ethtype
].get('vals_ext')
1353 attr
['DISPLAY'] += '|BASE_EXT_STRING'
1354 self
.eth_hf
[nm
] = {'fullname' : fullname
, 'pdu' : self
.field
[f
]['pdu'],
1355 'ethtype' : ethtype
, 'modified' : self
.field
[f
]['modified'],
1356 'attr' : attr
.copy(),
1358 self
.field
[f
]['ethname'] = nm
1359 if (self
.dummy_eag_field
):
1360 # Prepending "dummy_" avoids matching checkhf.pl.
1361 self
.dummy_eag_field
= 'dummy_hf_%s_%s' % (self
.eproto
, self
.dummy_eag_field
)
1362 #--- type dependencies -------------------
1363 (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'])
1365 while i
< len(self
.eth_dep_cycle
):
1366 t
= self
.type[self
.eth_dep_cycle
[i
][0]]['ethname']
1367 self
.dep_cycle_eth_type
.setdefault(t
, []).append(i
)
1370 #--- value dependencies and export -------------------
1371 for v
in self
.eth_value_ord
:
1372 if self
.eth_value
[v
]['export']:
1373 self
.eth_vexport_ord
.append(v
)
1375 self
.eth_value_ord1
.append(v
)
1377 #--- export tags, values, ... ---
1378 for t
in self
.exports
:
1379 if t
not in self
.type:
1381 if self
.type[t
]['import']:
1383 m
= self
.type[t
]['module']
1384 if not self
.Per() and not self
.Oer():
1385 if m
not in self
.all_tags
:
1386 self
.all_tags
[m
] = {}
1387 self
.all_tags
[m
][t
] = self
.type[t
]['val'].GetTTag(self
)
1388 if m
not in self
.all_type_attr
:
1389 self
.all_type_attr
[m
] = {}
1390 self
.all_type_attr
[m
][t
] = self
.eth_get_type_attr(t
).copy()
1391 for v
in self
.vexports
:
1392 if v
not in self
.value
:
1394 if self
.value
[v
]['import']:
1396 m
= self
.value
[v
]['module']
1397 if m
not in self
.all_vals
:
1398 self
.all_vals
[m
] = {}
1399 vv
= self
.value
[v
]['value']
1400 if isinstance (vv
, Value
):
1401 vv
= vv
.to_str(self
)
1402 self
.all_vals
[m
][v
] = vv
1404 #--- eth_vals_nm ------------------------------------------------------------
1405 def eth_vals_nm(self
, tname
):
1407 if (not self
.eth_type
[tname
]['export'] & EF_NO_PROT
):
1408 out
+= "%s_" % (self
.eproto
)
1409 out
+= "%s_vals" % (tname
)
1412 #--- eth_vals ---------------------------------------------------------------
1413 def eth_vals(self
, tname
, vals
):
1415 has_enum
= self
.eth_type
[tname
]['enum'] & EF_ENUM
1416 use_ext
= self
.eth_type
[tname
]['vals_ext']
1418 vals
.sort(key
=lambda vals_entry
: int(vals_entry
[0]))
1419 if (not self
.eth_type
[tname
]['export'] & EF_VALS
):
1421 if (self
.eth_type
[tname
]['export'] & EF_VALS
) and (self
.eth_type
[tname
]['export'] & EF_TABLE
):
1423 if self
.eth_type
[tname
]['val'].HasConstraint() and self
.eth_type
[tname
]['val'].constr
.Needs64b(self
) \
1424 and self
.eth_type
[tname
]['val'].type == 'IntegerType':
1425 out
+= "const val64_string %s[] = {\n" % (self
.eth_vals_nm(tname
))
1427 out
+= "const value_string %s[] = {\n" % (self
.eth_vals_nm(tname
))
1428 for (val
, id) in vals
:
1430 vval
= self
.eth_enum_item(tname
, id)
1433 out
+= ' { %3s, "%s" },\n' % (vval
, id)
1434 out
+= " { 0, NULL }\n};\n"
1436 out
+= "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self
.eth_vals_nm(tname
), self
.eth_vals_nm(tname
))
1439 #--- eth_enum_prefix ------------------------------------------------------------
1440 def eth_enum_prefix(self
, tname
, type=False):
1442 if (self
.eth_type
[tname
]['export'] & EF_ENUM
):
1443 no_prot
= self
.eth_type
[tname
]['export'] & EF_NO_PROT
1445 no_prot
= self
.eth_type
[tname
]['enum'] & EF_NO_PROT
1448 if ((not self
.eth_type
[tname
]['enum'] & EF_NO_TYPE
) or type):
1449 if (out
): out
+= '_'
1451 if (self
.eth_type
[tname
]['enum'] & EF_UCASE
):
1453 if (out
): out
+= '_'
1456 #--- eth_enum_nm ------------------------------------------------------------
1457 def eth_enum_nm(self
, tname
):
1458 out
= self
.eth_enum_prefix(tname
, type=True)
1462 #--- eth_enum_item ---------------------------------------------------------------
1463 def eth_enum_item(self
, tname
, ident
):
1464 out
= self
.eth_enum_prefix(tname
)
1466 if (self
.eth_type
[tname
]['enum'] & EF_UCASE
):
1470 #--- eth_enum ---------------------------------------------------------------
1471 def eth_enum(self
, tname
, vals
):
1473 if (self
.eth_type
[tname
]['enum'] & EF_DEFINE
):
1474 out
+= "/* enumerated values for %s */\n" % (tname
)
1475 for (val
, id) in vals
:
1476 out
+= '#define %-12s %3s\n' % (self
.eth_enum_item(tname
, id), val
)
1478 out
+= "typedef enum _%s {\n" % (self
.eth_enum_nm(tname
))
1480 for (val
, id) in vals
:
1481 if (first_line
== 1):
1485 out
+= ' %-12s = %3s' % (self
.eth_enum_item(tname
, id), val
)
1486 out
+= "\n} %s;\n" % (self
.eth_enum_nm(tname
))
1489 #--- eth_bits ---------------------------------------------------------------
1490 def eth_bits(self
, tname
, bits
):
1492 out
+= "static int * const "
1493 out
+= "%(TABLE)s[] = {\n"
1494 for (val
, id) in bits
:
1495 out
+= ' &hf_%s_%s_%s,\n' % (self
.eproto
, tname
, asn2c(id))
1496 out
+= " NULL\n};\n"
1499 #--- eth_type_fn_h ----------------------------------------------------------
1500 def eth_type_fn_h(self
, tname
):
1502 if (not self
.eth_type
[tname
]['export'] & EF_TYPE
):
1506 out
+= "dissect_%s_%s(bool 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
)
1507 elif (self
.Per() or self
.Oer()):
1508 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
)
1512 #--- eth_fn_call ------------------------------------------------------------
1513 def eth_fn_call(self
, fname
, ret
=None, indent
=2, par
=None):
1516 if (ret
== 'return'):
1522 for i
in range(len(par
)):
1523 if (i
>0): out
+= ind
* ' '
1524 out
+= ', '.join(par
[i
])
1525 if (i
<(len(par
)-1)): out
+= ',\n'
1529 def output_proto_root(self
):
1531 if self
.conform
.proto_root_name
:
1532 out
+= ' proto_item *prot_ti = proto_tree_add_item(tree, ' + self
.conform
.proto_root_name
+ ', tvb, 0, -1, ENC_NA);\n'
1533 out
+= ' proto_item_set_hidden(prot_ti);\n'
1536 #--- eth_type_fn_hdr --------------------------------------------------------
1537 def eth_type_fn_hdr(self
, tname
):
1539 if (not self
.eth_type
[tname
]['export'] & EF_TYPE
):
1543 out
+= "dissect_%s_%s(bool 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
)
1544 elif (self
.Per() or self
.Oer()):
1545 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
)
1546 #if self.conform.get_fn_presence(tname):
1547 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1549 if self
.conform
.check_item('PDU', tname
):
1550 out
+= self
.output_proto_root()
1553 if self
.eth_dep_cycle
:
1554 for cur_cycle
in self
.eth_dep_cycle
:
1555 t
= self
.type[cur_cycle
[0]]['ethname']
1557 cycle_funcs
= cur_cycle
1560 if len(cycle_funcs
) > 1:
1562 // {' -> '.join(cycle_funcs)}
1563 actx->pinfo->dissection_depth += {len(cycle_funcs) - 1};
1564 increment_dissection_depth(actx->pinfo);
1567 if self
.conform
.get_fn_presence(self
.eth_type
[tname
]['ref'][0]):
1568 out
+= self
.conform
.get_fn_text(self
.eth_type
[tname
]['ref'][0], 'FN_HDR')
1571 #--- eth_type_fn_ftr --------------------------------------------------------
1572 def eth_type_fn_ftr(self
, tname
):
1574 #if self.conform.get_fn_presence(tname):
1575 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1579 if self
.eth_dep_cycle
:
1580 for cur_cycle
in self
.eth_dep_cycle
:
1581 t
= self
.type[cur_cycle
[0]]['ethname']
1583 cycle_funcs
= cur_cycle
1586 if len(cycle_funcs
) > 1:
1588 actx->pinfo->dissection_depth -= {len(cycle_funcs) - 1};
1589 decrement_dissection_depth(actx->pinfo);
1592 if self
.conform
.get_fn_presence(self
.eth_type
[tname
]['ref'][0]):
1593 out
+= self
.conform
.get_fn_text(self
.eth_type
[tname
]['ref'][0], 'FN_FTR')
1594 out
+= " return offset;\n"
1598 #--- eth_type_fn_body -------------------------------------------------------
1599 def eth_type_fn_body(self
, tname
, body
, pars
=None):
1601 #if self.conform.get_fn_body_presence(tname):
1602 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1604 if self
.conform
.get_fn_body_presence(self
.eth_type
[tname
]['ref'][0]):
1605 out
= self
.conform
.get_fn_text(self
.eth_type
[tname
]['ref'][0], 'FN_BODY')
1613 #--- eth_out_pdu_decl ----------------------------------------------------------
1614 def eth_out_pdu_decl(self
, f
):
1615 #t = self.eth_hf[f]['ethtype']
1617 if (not self
.eth_hf
[f
]['pdu']['export']):
1620 out
+= 'dissect_'+f
+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n'
1623 #--- eth_output_hf ----------------------------------------------------------
1624 def eth_output_hf (self
):
1625 if not len(self
.eth_hf_ord
) and not len(self
.eth_hfpdu_ord
) and not len(self
.named_bit
): return
1626 fx
= self
.output
.file_open('hf')
1627 for f
in (self
.eth_hfpdu_ord
+ self
.eth_hf_ord
):
1628 fx
.write("%-50s/* %s */\n" % ("static int %s; " % (self
.eth_hf
[f
]['fullname']), self
.eth_hf
[f
]['ethtype']))
1629 if (self
.named_bit
):
1630 fx
.write('/* named bits */\n')
1631 for nb
in self
.named_bit
:
1632 fx
.write("static int %s;\n" % (nb
['ethname']))
1633 if (self
.dummy_eag_field
):
1634 fx
.write("static int %s; /* never registered */\n" % (self
.dummy_eag_field
))
1635 self
.output
.file_close(fx
)
1637 #--- eth_output_hf_arr ------------------------------------------------------
1638 def eth_output_hf_arr (self
):
1639 if not len(self
.eth_hf_ord
) and not len(self
.eth_hfpdu_ord
) and not len(self
.named_bit
): return
1640 fx
= self
.output
.file_open('hfarr')
1641 for f
in (self
.eth_hfpdu_ord
+ self
.eth_hf_ord
):
1642 t
= self
.eth_hf
[f
]['ethtype']
1643 if self
.remove_prefix
and t
.startswith(self
.remove_prefix
):
1644 t
= t
[len(self
.remove_prefix
):]
1645 name
=self
.eth_hf
[f
]['attr']['NAME']
1647 trantab
= maketrans("- ", "__")
1649 trantab
= str.maketrans("- ", "__")
1650 name
= name
.translate(trantab
)
1651 namelower
= name
.lower()
1652 tquoted_lower
= '"' + t
.lower() + '"'
1653 # Try to avoid giving blurbs that give no more info than the name
1654 if tquoted_lower
== namelower
or \
1656 tquoted_lower
.replace("t_", "") == namelower
:
1659 blurb
= '"%s"' % (t
)
1660 attr
= self
.eth_hf
[f
]['attr'].copy()
1661 if attr
['TYPE'] == 'FT_NONE':
1662 attr
['ABBREV'] = '"%s.%s_element"' % (self
.proto
, attr
['ABBREV'])
1664 attr
['ABBREV'] = '"%s.%s"' % (self
.proto
, attr
['ABBREV'])
1665 if 'BLURB' not in attr
:
1666 attr
['BLURB'] = blurb
1667 fx
.write(' { &%s,\n' % (self
.eth_hf
[f
]['fullname']))
1668 fx
.write(' { %(NAME)s, %(ABBREV)s,\n' % attr
)
1669 fx
.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr
)
1670 fx
.write(' %(BLURB)s, HFILL }},\n' % attr
)
1671 for nb
in self
.named_bit
:
1672 flt_str
= nb
['ethname']
1674 flt_str
= flt_str
[3:]
1675 flt_str
= flt_str
.replace('_' , '.')
1676 #print("filter string=%s" % (flt_str))
1677 fx
.write(' { &%s,\n' % (nb
['ethname']))
1678 fx
.write(' { "%s", "%s",\n' % (nb
['name'], flt_str
))
1679 fx
.write(' %s, %s, %s, %s,\n' % (nb
['ftype'], nb
['display'], nb
['strings'], nb
['bitmask']))
1680 fx
.write(' NULL, HFILL }},\n')
1681 self
.output
.file_close(fx
)
1683 #--- eth_output_ett ---------------------------------------------------------
1684 def eth_output_ett (self
):
1685 fx
= self
.output
.file_open('ett')
1687 #fx.write("static int ett_%s;\n" % (self.eproto))
1688 for t
in self
.eth_type_ord
:
1689 if self
.eth_type
[t
]['tree']:
1690 fx
.write("static int %s;\n" % (self
.eth_type
[t
]['tree']))
1692 self
.output
.file_close(fx
, discard
=fempty
)
1694 #--- eth_output_ett_arr -----------------------------------------------------
1695 def eth_output_ett_arr(self
):
1696 fx
= self
.output
.file_open('ettarr')
1698 #fx.write(" &ett_%s,\n" % (self.eproto))
1699 for t
in self
.eth_type_ord
:
1700 if self
.eth_type
[t
]['tree']:
1701 fx
.write(" &%s,\n" % (self
.eth_type
[t
]['tree']))
1703 self
.output
.file_close(fx
, discard
=fempty
)
1705 #--- eth_output_export ------------------------------------------------------
1706 def eth_output_export(self
):
1707 fx
= self
.output
.file_open('exp', ext
='h')
1708 for t
in self
.eth_export_ord
: # vals
1709 if (self
.eth_type
[t
]['export'] & EF_ENUM
) and self
.eth_type
[t
]['val'].eth_has_enum(t
, self
):
1710 fx
.write(self
.eth_type
[t
]['val'].eth_type_enum(t
, self
))
1711 if (self
.eth_type
[t
]['export'] & EF_VALS
) and self
.eth_type
[t
]['val'].eth_has_vals():
1712 if not self
.eth_type
[t
]['export'] & EF_TABLE
:
1713 if self
.eth_type
[t
]['export'] & EF_WS_DLL
:
1714 fx
.write("WS_DLL_PUBLIC ")
1717 if self
.eth_type
[t
]['val'].HasConstraint() and self
.eth_type
[t
]['val'].constr
.Needs64b(self
) \
1718 and self
.eth_type
[t
]['val'].type == 'IntegerType':
1719 fx
.write("const val64_string %s[];\n" % (self
.eth_vals_nm(t
)))
1721 fx
.write("const value_string %s[];\n" % (self
.eth_vals_nm(t
)))
1723 fx
.write(self
.eth_type
[t
]['val'].eth_type_vals(t
, self
))
1724 for t
in self
.eth_export_ord
: # functions
1725 if (self
.eth_type
[t
]['export'] & EF_TYPE
):
1726 if self
.eth_type
[t
]['export'] & EF_EXTERN
:
1727 if self
.eth_type
[t
]['export'] & EF_WS_DLL
:
1728 fx
.write("WS_DLL_PUBLIC ")
1731 fx
.write(self
.eth_type_fn_h(t
))
1732 for f
in self
.eth_hfpdu_ord
: # PDUs
1733 if (self
.eth_hf
[f
]['pdu'] and self
.eth_hf
[f
]['pdu']['export']):
1734 fx
.write(self
.eth_out_pdu_decl(f
))
1735 self
.output
.file_close(fx
)
1737 #--- eth_output_expcnf ------------------------------------------------------
1738 def eth_output_expcnf(self
):
1739 fx
= self
.output
.file_open('exp', ext
='cnf')
1740 fx
.write('#.MODULE\n')
1742 for (m
, p
) in self
.modules
:
1743 if (len(m
) > maxw
): maxw
= len(m
)
1744 for (m
, p
) in self
.modules
:
1745 fx
.write("%-*s %s\n" % (maxw
, m
, p
))
1746 fx
.write('#.END\n\n')
1747 for cls
in self
.objectclass_ord
:
1748 if self
.objectclass
[cls
]['export']:
1750 if self
.objectclass
[cls
]['export'] & EF_MODULE
:
1751 cnm
= "$%s$%s" % (self
.objectclass
[cls
]['module'], cnm
)
1752 fx
.write('#.CLASS %s\n' % (cnm
))
1754 for fld
in self
.objectclass
[cls
]['val'].fields
:
1755 w
= len(fld
.fld_repr()[0])
1756 if (w
> maxw
): maxw
= w
1757 for fld
in self
.objectclass
[cls
]['val'].fields
:
1758 repr = fld
.fld_repr()
1759 fx
.write('%-*s %s\n' % (maxw
, repr[0], ' '.join(repr[1:])))
1760 fx
.write('#.END\n\n')
1762 fx
.write('#.IMPORT_TAG\n')
1763 for t
in self
.eth_export_ord
: # tags
1764 if (self
.eth_type
[t
]['export'] & EF_TYPE
):
1765 fx
.write('%-24s ' % self
.eth_type
[t
]['ref'][0])
1766 fx
.write('%s %s\n' % self
.eth_type
[t
]['val'].GetTag(self
))
1767 fx
.write('#.END\n\n')
1768 fx
.write('#.TYPE_ATTR\n')
1769 for t
in self
.eth_export_ord
: # attributes
1770 if (self
.eth_type
[t
]['export'] & EF_TYPE
):
1771 tnm
= self
.eth_type
[t
]['ref'][0]
1772 if self
.eth_type
[t
]['export'] & EF_MODULE
:
1773 tnm
= "$%s$%s" % (self
.type[tnm
]['module'], tnm
)
1774 fx
.write('%-24s ' % tnm
)
1775 attr
= self
.eth_get_type_attr(self
.eth_type
[t
]['ref'][0]).copy()
1776 fx
.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr
)
1777 fx
.write('#.END\n\n')
1778 self
.output
.file_close(fx
, keep_anyway
=True)
1780 #--- eth_output_val ------------------------------------------------------
1781 def eth_output_val(self
):
1782 fx
= self
.output
.file_open('val', ext
='h')
1783 for v
in self
.eth_value_ord1
:
1784 vv
= self
.eth_value
[v
]['value']
1785 if isinstance (vv
, Value
):
1786 vv
= vv
.to_str(self
)
1787 fx
.write("#define %-30s %s\n" % (v
, vv
))
1788 for t
in self
.eth_type_ord1
:
1789 if self
.eth_type
[t
]['import']:
1791 if self
.eth_type
[t
]['val'].eth_has_enum(t
, self
) and not (self
.eth_type
[t
]['export'] & EF_ENUM
):
1792 fx
.write(self
.eth_type
[t
]['val'].eth_type_enum(t
, self
))
1793 self
.output
.file_close(fx
)
1795 #--- eth_output_valexp ------------------------------------------------------
1796 def eth_output_valexp(self
):
1797 if (not len(self
.eth_vexport_ord
)): return
1798 fx
= self
.output
.file_open('valexp', ext
='h')
1799 for v
in self
.eth_vexport_ord
:
1800 vv
= self
.eth_value
[v
]['value']
1801 if isinstance (vv
, Value
):
1802 vv
= vv
.to_str(self
)
1803 fx
.write("#define %-30s %s\n" % (v
, vv
))
1804 self
.output
.file_close(fx
)
1806 #--- eth_output_types -------------------------------------------------------
1807 def eth_output_types(self
):
1809 t
= self
.eth_hf
[f
]['ethtype']
1812 if (not self
.eth_hf
[f
]['pdu']['export']):
1815 out
+= 'dissect_'+f
+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n'
1816 out
+= self
.output_proto_root()
1818 out
+= ' int offset = 0;\n'
1822 if (self
.Aligned()):
1826 out
+= " asn1_ctx_t asn1_ctx;\n"
1827 out
+= self
.eth_fn_call('asn1_ctx_init', par
=(('&asn1_ctx', 'ASN1_ENC_PER', aligned
, 'pinfo'),))
1829 out
+= " asn1_ctx_t asn1_ctx;\n"
1830 out
+= self
.eth_fn_call('asn1_ctx_init', par
=(('&asn1_ctx', 'ASN1_ENC_BER', 'true', 'pinfo'),))
1831 par
=((impl
, 'tvb', off_par
,'&asn1_ctx', 'tree', self
.eth_hf
[f
]['fullname']),)
1833 par
=(('tvb', off_par
, '&asn1_ctx', 'tree', self
.eth_hf
[f
]['fullname']),)
1835 out
+= " asn1_ctx_t asn1_ctx;\n"
1836 out
+= self
.eth_fn_call('asn1_ctx_init', par
=(('&asn1_ctx', 'ASN1_ENC_OER', 'true', 'pinfo'),))
1837 par
=(('tvb', off_par
,'&asn1_ctx', 'tree', self
.eth_hf
[f
]['fullname']),)
1840 out
+= self
.eth_fn_call('dissect_%s_%s' % (self
.eth_type
[t
]['proto'], t
), ret
=ret_par
, par
=par
)
1842 out
+= ' offset += 7; offset >>= 3;\n'
1843 out
+= ' return offset;\n'
1847 fx
= self
.output
.file_open('fn')
1849 if (len(self
.eth_hfpdu_ord
)):
1851 for f
in self
.eth_hfpdu_ord
:
1852 if (self
.eth_hf
[f
]['pdu'] and self
.eth_hf
[f
]['pdu']['need_decl']):
1854 fx
.write('/*--- PDUs declarations ---*/\n')
1856 fx
.write(self
.eth_out_pdu_decl(f
))
1860 add_depth_define
= False
1861 if self
.eth_dep_cycle
:
1862 fx
.write('/*--- Cyclic dependencies ---*/\n\n')
1864 while i
< len(self
.eth_dep_cycle
):
1865 t
= self
.type[self
.eth_dep_cycle
[i
][0]]['ethname']
1866 if self
.dep_cycle_eth_type
[t
][0] != i
: i
+= 1; continue
1867 add_depth_define
= True
1868 fx
.write(''.join(['/* %s */\n' % ' -> '.join(self
.eth_dep_cycle
[i
]) for i
in self
.dep_cycle_eth_type
[t
]]))
1869 if not self
.eth_type
[t
]['export'] & EF_TYPE
:
1870 fx
.write(self
.eth_type_fn_h(t
))
1872 fx
.write('/*' + self
.eth_type_fn_h(t
).strip() + '*/\n')
1876 for t
in self
.eth_type_ord1
:
1877 if self
.eth_type
[t
]['import']:
1879 if self
.eth_type
[t
]['val'].eth_has_vals():
1880 if self
.eth_type
[t
]['no_emit'] & EF_VALS
:
1882 elif self
.eth_type
[t
]['user_def'] & EF_VALS
:
1883 if self
.eth_type
[t
]['val'].HasConstraint() and self
.eth_type
[t
]['val'].constr
.Needs64b(self
) \
1884 and self
.eth_type
[t
]['val'].type == 'IntegerType':
1885 fx
.write("extern const val64_string %s[];\n" % (self
.eth_vals_nm(t
)))
1887 fx
.write("extern const value_string %s[];\n" % (self
.eth_vals_nm(t
)))
1888 elif (self
.eth_type
[t
]['export'] & EF_VALS
) and (self
.eth_type
[t
]['export'] & EF_TABLE
):
1891 fx
.write(self
.eth_type
[t
]['val'].eth_type_vals(t
, self
))
1892 if self
.eth_type
[t
]['no_emit'] & EF_TYPE
:
1894 elif self
.eth_type
[t
]['user_def'] & EF_TYPE
:
1895 fx
.write(self
.eth_type_fn_h(t
))
1897 fx
.write(self
.eth_type
[t
]['val'].eth_type_fn(self
.eth_type
[t
]['proto'], t
, self
))
1899 if (len(self
.eth_hfpdu_ord
)):
1900 fx
.write('/*--- PDUs ---*/\n\n')
1901 for f
in self
.eth_hfpdu_ord
:
1902 if (self
.eth_hf
[f
]['pdu']):
1903 if (f
in self
.emitted_pdu
):
1904 fx
.write(" /* %s already emitted */\n" % (f
))
1906 fx
.write(out_pdu(f
))
1907 self
.emitted_pdu
[f
] = True
1909 fempty
= pos
== fx
.tell()
1910 self
.output
.file_close(fx
, discard
=fempty
)
1912 #--- eth_output_dis_hnd -----------------------------------------------------
1913 def eth_output_dis_hnd(self
):
1914 fx
= self
.output
.file_open('dis-hnd')
1916 for f
in self
.eth_hfpdu_ord
:
1917 pdu
= self
.eth_hf
[f
]['pdu']
1918 if (pdu
and pdu
['reg'] and not pdu
['hidden']):
1920 if (pdu
['reg'] != '.'):
1921 dis
+= '.' + pdu
['reg']
1922 fx
.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis
)))
1925 self
.output
.file_close(fx
, discard
=fempty
)
1927 #--- eth_output_dis_reg -----------------------------------------------------
1928 def eth_output_dis_reg(self
):
1929 fx
= self
.output
.file_open('dis-reg')
1931 for f
in self
.eth_hfpdu_ord
:
1932 pdu
= self
.eth_hf
[f
]['pdu']
1933 if (pdu
and pdu
['reg']):
1935 if (pdu
['new']): new_prefix
= 'new_'
1937 if (pdu
['reg'] != '.'): dis
+= '.' + pdu
['reg']
1938 fx
.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix
, dis
, f
, self
.eproto
))
1939 if (not pdu
['hidden']):
1940 fx
.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis
), dis
))
1943 self
.output
.file_close(fx
, discard
=fempty
)
1945 #--- eth_output_dis_tab -----------------------------------------------------
1946 def eth_output_dis_tab(self
):
1947 fx
= self
.output
.file_open('dis-tab')
1949 for k
in self
.conform
.get_order('REGISTER'):
1950 reg
= self
.conform
.use_item('REGISTER', k
)
1951 if reg
['pdu'] not in self
.field
: continue
1952 f
= self
.field
[reg
['pdu']]['ethname']
1953 pdu
= self
.eth_hf
[f
]['pdu']
1955 if (pdu
['new']): new_prefix
= 'new_'
1956 if (reg
['rtype'] in ('NUM', 'STR')):
1958 if (reg
['rtype'] == 'STR'):
1964 if (pdu
['reg'] != '.'): dis
+= '.' + pdu
['reg']
1965 if (not pdu
['hidden']):
1966 hnd
= '%s_handle' % (asn2c(dis
))
1968 hnd
= 'find_dissector("%s")' % (dis
)
1970 hnd
= '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix
, f
, self
.eproto
)
1971 rport
= self
.value_get_eth(reg
['rport'])
1972 fx
.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr
, reg
['rtable'], rport
, hnd
))
1973 elif (reg
['rtype'] in ('BER', 'PER', 'OER')):
1974 roid
= self
.value_get_eth(reg
['roid'])
1975 fx
.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix
, reg
['rtype'].lower(), roid
, f
, self
.eproto
, reg
['roidname']))
1978 self
.output
.file_close(fx
, discard
=fempty
)
1980 #--- eth_output_syn_reg -----------------------------------------------------
1981 def eth_output_syn_reg(self
):
1982 fx
= self
.output
.file_open('syn-reg')
1985 for k
in self
.conform
.get_order('SYNTAX'):
1986 reg
= self
.conform
.use_item('SYNTAX', k
)
1987 if reg
['pdu'] not in self
.field
: continue
1988 f
= self
.field
[reg
['pdu']]['ethname']
1989 pdu
= self
.eth_hf
[f
]['pdu']
1991 if (pdu
['new']): new_prefix
= 'new_'
1993 fx
.write(' /*--- Syntax registrations ---*/\n')
1995 fx
.write(' %sregister_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (new_prefix
, k
, self
.eproto
, reg
['pdu']))
1997 self
.output
.file_close(fx
, discard
=fempty
)
1999 #--- eth_output_tables -----------------------------------------------------
2000 def eth_output_tables(self
):
2001 for num
in list(self
.conform
.report
.keys()):
2002 fx
= self
.output
.file_open('table' + num
)
2003 for rep
in self
.conform
.report
[num
]:
2004 self
.eth_output_table(fx
, rep
)
2005 self
.output
.file_close(fx
)
2007 #--- eth_output_table -----------------------------------------------------
2008 def eth_output_table(self
, fx
, rep
):
2009 if rep
['type'] == 'HDR':
2013 var_list
= var
.split('.', 1)
2021 not_flds
.append(f
[1:])
2029 sort_flds
.append(f
[1:])
2034 if (cls
in self
.oassign_cls
):
2035 for ident
in self
.oassign_cls
[cls
]:
2036 obj
= self
.get_obj_repr(ident
, flds
, not_flds
)
2040 obj
['_DICT'] = str(obj
)
2042 objs_ord
.append(ident
)
2044 # Sort identifiers according to the matching object in objs.
2045 # The order is determined by sort_flds, keys prefixed by a
2046 # '#' are compared numerically.
2047 def obj_key_fn(name
):
2050 int(obj
[f
[1:]]) if f
[0] == '#' else obj
[f
]
2053 objs_ord
.sort(key
=obj_key_fn
)
2054 for ident
in objs_ord
:
2057 text
= rep
['text'] % obj
2059 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
))
2062 fx
.write("/* Unknown or empty loop list %s */\n" % (var
))
2064 fx
.write(rep
['text'])
2065 if rep
['type'] == 'FTR':
2068 #--- dupl_report -----------------------------------------------------
2069 def dupl_report(self
):
2073 tmplist
= sorted(self
.eth_type_dupl
.keys())
2075 msg
= "The same type names for different types. Explicit type renaming is recommended.\n"
2077 for tt
in self
.eth_type_dupl
[t
]:
2078 msg
+= " %-20s %s\n" % (self
.type[tt
]['ethname'], tt
)
2079 warnings
.warn_explicit(msg
, UserWarning, '', 0)
2081 tmplist
= list(self
.eth_hf_dupl
.keys())
2084 msg
= "The same field names for different types. Explicit field renaming is recommended.\n"
2086 for tt
in list(self
.eth_hf_dupl
[f
].keys()):
2087 msg
+= " %-20s %-20s " % (self
.eth_hf_dupl
[f
][tt
], tt
)
2088 msg
+= ", ".join(self
.eth_hf
[self
.eth_hf_dupl
[f
][tt
]]['ref'])
2090 warnings
.warn_explicit(msg
, UserWarning, '', 0)
2092 #--- eth_do_output ------------------------------------------------------------
2093 def eth_do_output(self
):
2095 print("\n# Assignments")
2096 for a
in self
.assign_ord
:
2098 if (self
.assign
[a
]['virt']): v
= '*'
2099 print('{} {}'.format(v
, a
))
2100 print("\n# Value assignments")
2101 for a
in self
.vassign_ord
:
2102 print(' {}'.format(a
))
2103 print("\n# Information object assignments")
2104 for a
in self
.oassign_ord
:
2105 print(" %-12s (%s)" % (a
, self
.oassign
[a
].cls
))
2107 print("\n# Imported Types")
2108 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2110 for t
in self
.type_imp
:
2111 print("%-40s %-24s %-24s" % (t
, self
.type[t
]['import'], self
.type[t
]['proto']))
2112 print("\n# Imported Values")
2113 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2115 for t
in self
.value_imp
:
2116 print("%-40s %-24s %-24s" % (t
, self
.value
[t
]['import'], self
.value
[t
]['proto']))
2117 print("\n# Imported Object Classes")
2118 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2120 for t
in self
.objectclass_imp
:
2121 print("%-40s %-24s %-24s" % (t
, self
.objectclass
[t
]['import'], self
.objectclass
[t
]['proto']))
2122 print("\n# Exported Types")
2123 print("%-31s %s" % ("Wireshark type", "Export Flag"))
2125 for t
in self
.eth_export_ord
:
2126 print("%-31s 0x%02X" % (t
, self
.eth_type
[t
]['export']))
2127 print("\n# Exported Values")
2128 print("%-40s %s" % ("Wireshark name", "Value"))
2130 for v
in self
.eth_vexport_ord
:
2131 vv
= self
.eth_value
[v
]['value']
2132 if isinstance (vv
, Value
):
2133 vv
= vv
.to_str(self
)
2134 print("%-40s %s" % (v
, vv
))
2135 print("\n# ASN.1 Object Classes")
2136 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2138 for t
in self
.objectclass_ord
:
2139 print("%-40s " % (t
))
2140 print("\n# ASN.1 Types")
2141 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type"))
2143 for t
in self
.type_ord
:
2144 print("%-49s %-24s %-24s" % (t
, self
.type[t
]['tname'], self
.type[t
]['ethname']))
2145 print("\n# Wireshark Types")
2146 print("Wireshark type References (ASN.1 types)")
2148 for t
in self
.eth_type_ord
:
2149 sys
.stdout
.write("%-31s %d" % (t
, len(self
.eth_type
[t
]['ref'])))
2150 print(', '.join(self
.eth_type
[t
]['ref']))
2151 print("\n# ASN.1 Values")
2152 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value"))
2154 for v
in self
.value_ord
:
2155 vv
= self
.value
[v
]['value']
2156 if isinstance (vv
, Value
):
2157 vv
= vv
.to_str(self
)
2158 print("%-40s %-18s %-20s %s" % (v
, self
.value
[v
]['type'].eth_tname(), vv
, self
.value
[v
]['ethname']))
2159 #print "\n# Wireshark Values"
2160 #print "%-40s %s" % ("Wireshark name", "Value")
2162 #for v in self.eth_value_ord:
2163 # vv = self.eth_value[v]['value']
2164 # if isinstance (vv, Value):
2165 # vv = vv.to_str(self)
2166 # print "%-40s %s" % (v, vv)
2167 print("\n# ASN.1 Fields")
2168 print("ASN.1 unique name Wireshark name ASN.1 type")
2170 for f
in (self
.pdu_ord
+ self
.field_ord
):
2171 print("%-40s %-20s %s" % (f
, self
.field
[f
]['ethname'], self
.field
[f
]['type']))
2172 print("\n# Wireshark Fields")
2173 print("Wireshark name Wireshark type References (ASN.1 fields)")
2175 for f
in (self
.eth_hfpdu_ord
+ self
.eth_hf_ord
):
2176 sys
.stdout
.write("%-30s %-20s %s" % (f
, self
.eth_hf
[f
]['ethtype'], len(self
.eth_hf
[f
]['ref'])))
2177 print(', '.join(self
.eth_hf
[f
]['ref']))
2178 #print "\n# Order after dependencies"
2179 #print '\n'.join(self.eth_type_ord1)
2180 print("\n# Cyclic dependencies")
2181 for c
in self
.eth_dep_cycle
:
2182 print(' -> '.join(c
))
2184 self
.output
.outnm
= self
.outnm_opt
2185 if (not self
.output
.outnm
):
2186 self
.output
.outnm
= self
.proto
2187 self
.output
.outnm
= self
.output
.outnm
.replace('.', '-')
2188 if not self
.justexpcnf
:
2189 self
.eth_output_hf()
2190 self
.eth_output_ett()
2191 self
.eth_output_types()
2192 self
.eth_output_hf_arr()
2193 self
.eth_output_ett_arr()
2194 self
.eth_output_export()
2195 self
.eth_output_val()
2196 self
.eth_output_valexp()
2197 self
.eth_output_dis_hnd()
2198 self
.eth_output_dis_reg()
2199 self
.eth_output_dis_tab()
2200 self
.eth_output_syn_reg()
2201 self
.eth_output_tables()
2203 self
.eth_output_expcnf()
2205 def dbg_modules(self
):
2207 sys
.stdout
.write("%-30s " % (m
))
2208 dep
= self
.module
[m
][:]
2209 for i
in range(len(dep
)):
2210 if dep
[i
] not in self
.module
:
2211 dep
[i
] = '*' + dep
[i
]
2212 print(', '.join(dep
))
2213 # end of print_mod()
2214 (mod_ord
, mod_cyc
) = dependency_compute(self
.module_ord
, self
.module
, ignore_fn
= lambda t
: t
not in self
.module
)
2215 print("\n# ASN.1 Modules")
2216 print("Module name Dependency")
2219 for m
in (self
.module_ord
):
2221 new_ord
= new_ord
or (self
.module_ord
.index(m
) != mod_ord
.index(m
))
2223 print("\n# ASN.1 Modules - in dependency order")
2224 print("Module name Dependency")
2229 print("\nCyclic dependencies:")
2230 for i
in (list(range(len(mod_cyc
)))):
2231 print("%02d: %s" % (i
+ 1, str(mod_cyc
[i
])))
2234 #--- EthCnf -------------------------------------------------------------------
2243 self
.suppress_line
= False
2244 self
.include_path
= []
2245 self
.proto_root_name
= None
2246 # Value name Default value Duplicity check Usage check
2247 self
.tblcfg
['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2248 self
.tblcfg
['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2249 self
.tblcfg
['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2250 self
.tblcfg
['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2251 self
.tblcfg
['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2252 self
.tblcfg
['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2253 self
.tblcfg
['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2254 self
.tblcfg
['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2255 self
.tblcfg
['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2256 self
.tblcfg
['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2257 self
.tblcfg
['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2258 self
.tblcfg
['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2259 self
.tblcfg
['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2260 self
.tblcfg
['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2261 self
.tblcfg
['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2262 self
.tblcfg
['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2263 self
.tblcfg
['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2264 self
.tblcfg
['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2265 self
.tblcfg
['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2266 self
.tblcfg
['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2267 self
.tblcfg
['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2268 self
.tblcfg
['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2269 self
.tblcfg
['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2271 for k
in list(self
.tblcfg
.keys()) :
2275 def add_item(self
, table
, key
, fn
, lineno
, **kw
):
2276 if self
.tblcfg
[table
]['chk_dup'] and key
in self
.table
[table
]:
2277 warnings
.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2278 (table
, key
, self
.table
[table
][key
]['fn'], self
.table
[table
][key
]['lineno']),
2279 UserWarning, fn
, lineno
)
2281 self
.table
[table
][key
] = {'fn' : fn
, 'lineno' : lineno
, 'used' : False}
2282 self
.table
[table
][key
].update(kw
)
2283 self
.order
[table
].append(key
)
2285 def update_item(self
, table
, key
, fn
, lineno
, **kw
):
2286 if key
not in self
.table
[table
]:
2287 self
.table
[table
][key
] = {'fn' : fn
, 'lineno' : lineno
, 'used' : False}
2288 self
.order
[table
].append(key
)
2289 self
.table
[table
][key
][self
.tblcfg
[table
]['val_nm']] = {}
2290 self
.table
[table
][key
][self
.tblcfg
[table
]['val_nm']].update(kw
[self
.tblcfg
[table
]['val_nm']])
2292 def get_order(self
, table
):
2293 return self
.order
[table
]
2295 def check_item(self
, table
, key
):
2296 return key
in self
.table
[table
]
2298 def copy_item(self
, table
, dst_key
, src_key
):
2299 if (src_key
in self
.table
[table
]):
2300 self
.table
[table
][dst_key
] = self
.table
[table
][src_key
]
2302 def check_item_value(self
, table
, key
, **kw
):
2303 return key
in self
.table
[table
] and kw
.get('val_nm', self
.tblcfg
[table
]['val_nm']) in self
.table
[table
][key
]
2305 def use_item(self
, table
, key
, **kw
):
2306 vdflt
= kw
.get('val_dflt', self
.tblcfg
[table
]['val_dflt'])
2307 if key
not in self
.table
[table
]: return vdflt
2308 vname
= kw
.get('val_nm', self
.tblcfg
[table
]['val_nm'])
2309 #print "use_item() - set used for %s %s" % (table, key)
2310 self
.table
[table
][key
]['used'] = True
2311 return self
.table
[table
][key
].get(vname
, vdflt
)
2313 def omit_assignment(self
, type, ident
, module
):
2314 if self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', ident
):
2316 if self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*') or \
2317 self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2318 self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*/'+module
) or \
2319 self
.ectx
.conform
.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module
):
2320 return self
.ectx
.conform
.use_item('NO_OMIT_ASSGN', ident
)
2323 def add_fn_line(self
, name
, ctx
, line
, fn
, lineno
):
2324 if name
not in self
.fn
:
2325 self
.fn
[name
] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2326 if (self
.fn
[name
][ctx
]):
2327 self
.fn
[name
][ctx
]['text'] += line
2329 self
.fn
[name
][ctx
] = {'text' : line
, 'used' : False,
2330 'fn' : fn
, 'lineno' : lineno
}
2331 def get_fn_presence(self
, name
):
2332 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2333 #if self.fn.has_key(name): print self.fn[name]
2334 return name
in self
.fn
2335 def get_fn_body_presence(self
, name
):
2336 return name
in self
.fn
and self
.fn
[name
]['FN_BODY']
2337 def get_fn_text(self
, name
, ctx
):
2338 if (name
not in self
.fn
):
2340 if (not self
.fn
[name
][ctx
]):
2342 self
.fn
[name
][ctx
]['used'] = True
2343 out
= self
.fn
[name
][ctx
]['text']
2344 if (not self
.suppress_line
):
2345 out
= '#line %u "%s"\n%s\n' % (self
.fn
[name
][ctx
]['lineno'], rel_dissector_path(self
.fn
[name
][ctx
]['fn']), out
)
2348 def add_pdu(self
, par
, fn
, lineno
):
2349 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2350 (reg
, hidden
) = (None, False)
2351 if (len(par
) > 1): reg
= par
[1]
2352 if (reg
and reg
[0]=='@'): (reg
, hidden
) = (reg
[1:], True)
2353 attr
= {'new' : False, 'reg' : reg
, 'hidden' : hidden
, 'need_decl' : False, 'export' : False}
2354 self
.add_item('PDU', par
[0], attr
=attr
, fn
=fn
, lineno
=lineno
)
2357 def add_syntax(self
, par
, fn
, lineno
):
2358 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
2359 if( (len(par
) >=2)):
2362 name
= '"'+par
[0]+'"'
2363 attr
= { 'pdu' : par
[0] }
2364 self
.add_item('SYNTAX', name
, attr
=attr
, fn
=fn
, lineno
=lineno
)
2367 def add_register(self
, pdu
, par
, fn
, lineno
):
2368 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2369 if (par
[0] in ('N', 'NUM')): rtype
= 'NUM'; (pmin
, pmax
) = (2, 2)
2370 elif (par
[0] in ('S', 'STR')): rtype
= 'STR'; (pmin
, pmax
) = (2, 2)
2371 elif (par
[0] in ('B', 'BER')): rtype
= 'BER'; (pmin
, pmax
) = (1, 2)
2372 elif (par
[0] in ('P', 'PER')): rtype
= 'PER'; (pmin
, pmax
) = (1, 2)
2373 elif (par
[0] in ('O', 'OER')): rtype
= 'OER'; (pmin
, pmax
) = (1, 2)
2374 else: warnings
.warn_explicit("Unknown registration type '%s'" % (par
[2]), UserWarning, fn
, lineno
); return
2375 if ((len(par
)-1) < pmin
):
2376 warnings
.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype
, pmin
), UserWarning, fn
, lineno
)
2378 if ((len(par
)-1) > pmax
):
2379 warnings
.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype
, pmax
), UserWarning, fn
, lineno
)
2380 attr
= {'pdu' : pdu
, 'rtype' : rtype
}
2381 if (rtype
in ('NUM', 'STR')):
2382 attr
['rtable'] = par
[1]
2383 attr
['rport'] = par
[2]
2384 rkey
= '/'.join([rtype
, attr
['rtable'], attr
['rport']])
2385 elif (rtype
in ('BER', 'PER', 'OER')):
2386 attr
['roid'] = par
[1]
2387 attr
['roidname'] = '""'
2389 attr
['roidname'] = par
[2]
2390 elif attr
['roid'][0] != '"':
2391 attr
['roidname'] = '"' + attr
['roid'] + '"'
2392 rkey
= '/'.join([rtype
, attr
['roid']])
2393 self
.add_item('REGISTER', rkey
, attr
=attr
, fn
=fn
, lineno
=lineno
)
2395 def check_par(self
, par
, pmin
, pmax
, fn
, lineno
):
2396 for i
in range(len(par
)):
2400 if par
[i
][0] == '#':
2404 warnings
.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin
), UserWarning, fn
, lineno
)
2406 if (pmax
>= 0) and (len(par
) > pmax
):
2407 warnings
.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax
), UserWarning, fn
, lineno
)
2412 def get_par(line
, pmin
, pmax
, fn
, lineno
):
2413 par
= line
.split(None, pmax
)
2414 par
= self
.check_par(par
, pmin
, pmax
, fn
, lineno
)
2417 def get_par_nm(line
, pmin
, pmax
, fn
, lineno
):
2419 par
= line
.split(None, pmax
)
2422 for i
in range(len(par
)):
2423 if par
[i
][0] == '#':
2427 warnings
.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin
), UserWarning, fn
, lineno
)
2434 nmpar_first
= re
.compile(r
'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2435 nmpar_next
= re
.compile(r
'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2436 nmpar_end
= re
.compile(r
'\s*$')
2437 result
= nmpar_first
.search(nmpar
)
2440 k
= result
.group('attr')
2442 result
= nmpar_next
.search(nmpar
, pos
)
2447 p2
= nmpar_end
.search(nmpar
, pos
).start()
2457 directive
= re
.compile(r
'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2458 cdirective
= re
.compile(r
'^\s*##')
2459 report
= re
.compile(r
'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2460 comment
= re
.compile(r
'^\s*#[^.#]')
2461 empty
= re
.compile(r
'^\s*$')
2464 default_flags
= 0x00
2477 fn
, f
, lineno
, is_import
= frec
['fn'], frec
['f'], frec
['lineno'], frec
['is_import']
2481 if comment
.search(line
): continue
2482 result
= directive
.search(line
)
2483 if result
: # directive
2484 rep_result
= report
.search(result
.group('name'))
2485 if result
.group('name') == 'END_OF_CNF':
2487 elif result
.group('name') == 'OPT':
2488 ctx
= result
.group('name')
2489 par
= get_par(line
[result
.end():], 0, -1, fn
=fn
, lineno
=lineno
)
2490 if not par
: continue
2491 self
.set_opt(par
[0], par
[1:], fn
, lineno
)
2493 elif result
.group('name') in ('PDU', 'REGISTER',
2494 'MODULE', 'MODULE_IMPORT',
2495 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2496 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2497 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2498 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR',
2500 ctx
= result
.group('name')
2501 elif result
.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2502 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2503 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2504 ctx
= result
.group('name')
2506 if ctx
in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2508 if ctx
in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2510 par
= get_par(line
[result
.end():], 0, 1, fn
=fn
, lineno
=lineno
)
2513 self
.add_item('OMIT_ASSIGNMENT', key
, omit
=True, fn
=fn
, lineno
=lineno
)
2514 if ctx
in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2515 ctx
= 'NO_OMIT_ASSGN'
2518 elif result
.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2519 ctx
= result
.group('name')
2520 default_flags
= EF_TYPE|EF_VALS
2521 if ctx
== 'MODULE_EXPORTS':
2523 default_flags |
= EF_MODULE
2524 if ctx
== 'EXPORTS':
2525 par
= get_par(line
[result
.end():], 0, 5, fn
=fn
, lineno
=lineno
)
2527 par
= get_par(line
[result
.end():], 0, 1, fn
=fn
, lineno
=lineno
)
2528 if not par
: continue
2530 if (par
[0] == 'WITH_VALS'): default_flags |
= EF_TYPE|EF_VALS
2531 elif (par
[0] == 'WITHOUT_VALS'): default_flags |
= EF_TYPE
; default_flags
&= ~EF_VALS
2532 elif (par
[0] == 'ONLY_VALS'): default_flags
&= ~EF_TYPE
; default_flags |
= EF_VALS
2533 elif (ctx
== 'EXPORTS'): p
= 0
2534 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[0]), UserWarning, fn
, lineno
)
2535 for i
in range(p
, len(par
)):
2536 if (par
[i
] == 'ONLY_ENUM'): default_flags
&= ~
(EF_TYPE|EF_VALS
); default_flags |
= EF_ENUM
2537 elif (par
[i
] == 'WITH_ENUM'): default_flags |
= EF_ENUM
2538 elif (par
[i
] == 'VALS_WITH_TABLE'): default_flags |
= EF_TABLE
2539 elif (par
[i
] == 'WS_DLL'): default_flags |
= EF_WS_DLL
2540 elif (par
[i
] == 'EXTERN'): default_flags |
= EF_EXTERN
2541 elif (par
[i
] == 'NO_PROT_PREFIX'): default_flags |
= EF_NO_PROT
2542 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2543 elif result
.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2544 ctx
= result
.group('name')
2545 default_flags
= EF_ENUM
2546 if ctx
== 'MAKE_ENUM': default_flags |
= EF_NO_PROT|EF_NO_TYPE
2547 if ctx
== 'MAKE_DEFINES': default_flags |
= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2548 par
= get_par(line
[result
.end():], 0, 3, fn
=fn
, lineno
=lineno
)
2549 for i
in range(0, len(par
)):
2550 if (par
[i
] == 'NO_PROT_PREFIX'): default_flags |
= EF_NO_PROT
2551 elif (par
[i
] == 'PROT_PREFIX'): default_flags
&= ~ EF_NO_PROT
2552 elif (par
[i
] == 'NO_TYPE_PREFIX'): default_flags |
= EF_NO_TYPE
2553 elif (par
[i
] == 'TYPE_PREFIX'): default_flags
&= ~ EF_NO_TYPE
2554 elif (par
[i
] == 'UPPER_CASE'): default_flags |
= EF_UCASE
2555 elif (par
[i
] == 'NO_UPPER_CASE'): default_flags
&= ~EF_UCASE
2556 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2557 elif result
.group('name') == 'USE_VALS_EXT':
2558 ctx
= result
.group('name')
2559 default_flags
= 0xFF
2560 elif result
.group('name') == 'FN_HDR':
2562 if (ctx
in ('FN_PARS',)) and name
: minp
= 0
2563 par
= get_par(line
[result
.end():], minp
, 1, fn
=fn
, lineno
=lineno
)
2564 if (not par
) and (minp
> 0): continue
2565 ctx
= result
.group('name')
2566 if par
: name
= par
[0]
2567 elif result
.group('name') == 'FN_FTR':
2569 if (ctx
in ('FN_PARS','FN_HDR')) and name
: minp
= 0
2570 par
= get_par(line
[result
.end():], minp
, 1, fn
=fn
, lineno
=lineno
)
2571 if (not par
) and (minp
> 0): continue
2572 ctx
= result
.group('name')
2573 if par
: name
= par
[0]
2574 elif result
.group('name') == 'FN_BODY':
2575 par
= get_par_nm(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2576 if not par
: continue
2577 ctx
= result
.group('name')
2580 self
.add_item('FN_PARS', name
, pars
=par
[1], fn
=fn
, lineno
=lineno
)
2581 elif result
.group('name') == 'FN_PARS':
2582 par
= get_par_nm(line
[result
.end():], 0, 1, fn
=fn
, lineno
=lineno
)
2583 ctx
= result
.group('name')
2588 self
.add_item(ctx
, name
, pars
={}, fn
=fn
, lineno
=lineno
)
2590 self
.add_item(ctx
, par
[0], pars
=par
[1], fn
=fn
, lineno
=lineno
)
2592 elif result
.group('name') == 'CLASS':
2593 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2594 if not par
: continue
2595 ctx
= result
.group('name')
2597 add_class_ident(name
)
2598 if not name
.split('$')[-1].isupper():
2599 warnings
.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name
),
2600 UserWarning, fn
, lineno
)
2601 elif result
.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2602 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2603 if not par
: continue
2604 self
.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids
={par
[0] : par
[0]}, fn
=fn
, lineno
=lineno
)
2605 elif rep_result
: # Reports
2606 num
= rep_result
.group('num')
2607 type = rep_result
.group('type')
2609 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2610 if not par
: continue
2612 par
= get_par(line
[result
.end():], 0, 0, fn
=fn
, lineno
=lineno
)
2613 rep
= { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn
, 'lineno' : lineno
}
2616 self
.report
.setdefault(num
, []).append(rep
)
2619 elif result
.group('name') in ('INCLUDE', 'IMPORT') :
2620 is_imp
= result
.group('name') == 'IMPORT'
2621 par
= get_par(line
[result
.end():], 1, 1, fn
=fn
, lineno
=lineno
)
2623 warnings
.warn_explicit("%s requires parameter" % (result
.group('name'),), UserWarning, fn
, lineno
)
2626 #print "Try include: %s" % (fname)
2627 if (not os
.path
.exists(fname
)):
2628 fname
= os
.path
.join(os
.path
.split(fn
)[0], par
[0])
2629 #print "Try include: %s" % (fname)
2631 while not os
.path
.exists(fname
) and (i
< len(self
.include_path
)):
2632 fname
= os
.path
.join(self
.include_path
[i
], par
[0])
2633 #print "Try include: %s" % (fname)
2635 if (not os
.path
.exists(fname
)):
2637 continue # just ignore
2639 fname
= par
[0] # report error
2640 fnew
= open(fname
, "r")
2641 stack
.append({'fn' : fn
, 'f' : f
, 'lineno' : lineno
, 'is_import' : is_import
})
2642 fn
, f
, lineno
, is_import
= par
[0], fnew
, 0, is_imp
2643 elif result
.group('name') == 'END':
2646 warnings
.warn_explicit("Unknown directive '%s'" % (result
.group('name')), UserWarning, fn
, lineno
)
2649 if not empty
.match(line
):
2650 warnings
.warn_explicit("Non-empty line in empty context", UserWarning, fn
, lineno
)
2652 if empty
.match(line
): continue
2653 par
= get_par(line
, 1, -1, fn
=fn
, lineno
=lineno
)
2654 if not par
: continue
2655 self
.set_opt(par
[0], par
[1:], fn
, lineno
)
2656 elif ctx
in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2657 if empty
.match(line
): continue
2658 if ctx
== 'EXPORTS':
2659 par
= get_par(line
, 1, 6, fn
=fn
, lineno
=lineno
)
2661 par
= get_par(line
, 1, 2, fn
=fn
, lineno
=lineno
)
2662 if not par
: continue
2663 flags
= default_flags
2666 if (par
[1] == 'WITH_VALS'): flags |
= EF_TYPE|EF_VALS
2667 elif (par
[1] == 'WITHOUT_VALS'): flags |
= EF_TYPE
; flags
&= ~EF_VALS
2668 elif (par
[1] == 'ONLY_VALS'): flags
&= ~EF_TYPE
; flags |
= EF_VALS
2669 elif (ctx
== 'EXPORTS'): p
= 1
2670 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[1]), UserWarning, fn
, lineno
)
2671 for i
in range(p
, len(par
)):
2672 if (par
[i
] == 'ONLY_ENUM'): flags
&= ~
(EF_TYPE|EF_VALS
); flags |
= EF_ENUM
2673 elif (par
[i
] == 'WITH_ENUM'): flags |
= EF_ENUM
2674 elif (par
[i
] == 'VALS_WITH_TABLE'): flags |
= EF_TABLE
2675 elif (par
[i
] == 'WS_DLL'): flags |
= EF_WS_DLL
2676 elif (par
[i
] == 'EXTERN'): flags |
= EF_EXTERN
2677 elif (par
[i
] == 'NO_PROT_PREFIX'): flags |
= EF_NO_PROT
2678 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2679 self
.add_item(ctx
, par
[0], flag
=flags
, fn
=fn
, lineno
=lineno
)
2680 elif ctx
in ('MAKE_ENUM', 'MAKE_DEFINES'):
2681 if empty
.match(line
): continue
2682 par
= get_par(line
, 1, 4, fn
=fn
, lineno
=lineno
)
2683 if not par
: continue
2684 flags
= default_flags
2685 for i
in range(1, len(par
)):
2686 if (par
[i
] == 'NO_PROT_PREFIX'): flags |
= EF_NO_PROT
2687 elif (par
[i
] == 'PROT_PREFIX'): flags
&= ~ EF_NO_PROT
2688 elif (par
[i
] == 'NO_TYPE_PREFIX'): flags |
= EF_NO_TYPE
2689 elif (par
[i
] == 'TYPE_PREFIX'): flags
&= ~ EF_NO_TYPE
2690 elif (par
[i
] == 'UPPER_CASE'): flags |
= EF_UCASE
2691 elif (par
[i
] == 'NO_UPPER_CASE'): flags
&= ~EF_UCASE
2692 else: warnings
.warn_explicit("Unknown parameter value '%s'" % (par
[i
]), UserWarning, fn
, lineno
)
2693 self
.add_item('MAKE_ENUM', par
[0], flag
=flags
, fn
=fn
, lineno
=lineno
)
2694 elif ctx
== 'USE_VALS_EXT':
2695 if empty
.match(line
): continue
2696 par
= get_par(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2697 if not par
: continue
2698 flags
= default_flags
2699 self
.add_item('USE_VALS_EXT', par
[0], flag
=flags
, fn
=fn
, lineno
=lineno
)
2701 if empty
.match(line
): continue
2702 par
= get_par(line
, 1, 5, fn
=fn
, lineno
=lineno
)
2703 if not par
: continue
2704 self
.add_pdu(par
[0:2], fn
, lineno
)
2706 self
.add_register(par
[0], par
[2:5], fn
, lineno
)
2707 elif ctx
== 'SYNTAX':
2708 if empty
.match(line
): continue
2709 par
= get_par(line
, 1, 2, fn
=fn
, lineno
=lineno
)
2710 if not par
: continue
2711 if not self
.check_item('PDU', par
[0]):
2712 self
.add_pdu(par
[0:1], fn
, lineno
)
2713 self
.add_syntax(par
, fn
, lineno
)
2714 elif ctx
== 'REGISTER':
2715 if empty
.match(line
): continue
2716 par
= get_par(line
, 3, 4, fn
=fn
, lineno
=lineno
)
2717 if not par
: continue
2718 if not self
.check_item('PDU', par
[0]):
2719 self
.add_pdu(par
[0:1], fn
, lineno
)
2720 self
.add_register(par
[0], par
[1:4], fn
, lineno
)
2721 elif ctx
in ('MODULE', 'MODULE_IMPORT'):
2722 if empty
.match(line
): continue
2723 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2724 if not par
: continue
2725 self
.add_item('MODULE', par
[0], proto
=par
[1], fn
=fn
, lineno
=lineno
)
2726 elif ctx
== 'IMPORT_TAG':
2727 if empty
.match(line
): continue
2728 par
= get_par(line
, 3, 3, fn
=fn
, lineno
=lineno
)
2729 if not par
: continue
2730 self
.add_item(ctx
, par
[0], ttag
=(par
[1], par
[2]), fn
=fn
, lineno
=lineno
)
2731 elif ctx
== 'OMIT_ASSIGNMENT':
2732 if empty
.match(line
): continue
2733 par
= get_par(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2734 if not par
: continue
2735 self
.add_item(ctx
, par
[0], omit
=True, fn
=fn
, lineno
=lineno
)
2736 elif ctx
== 'NO_OMIT_ASSGN':
2737 if empty
.match(line
): continue
2738 par
= get_par(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2739 if not par
: continue
2740 self
.add_item(ctx
, par
[0], omit
=False, fn
=fn
, lineno
=lineno
)
2741 elif ctx
== 'VIRTUAL_ASSGN':
2742 if empty
.match(line
): continue
2743 par
= get_par(line
, 2, -1, fn
=fn
, lineno
=lineno
)
2744 if not par
: continue
2745 if (len(par
[1].split('/')) > 1) and not self
.check_item('SET_TYPE', par
[1]):
2746 self
.add_item('SET_TYPE', par
[1], type=par
[0], fn
=fn
, lineno
=lineno
)
2747 self
.add_item('VIRTUAL_ASSGN', par
[1], name
=par
[0], fn
=fn
, lineno
=lineno
)
2749 self
.add_item('SET_TYPE', nm
, type=par
[0], fn
=fn
, lineno
=lineno
)
2750 if not par
[0][0].isupper():
2751 warnings
.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par
[0]),
2752 UserWarning, fn
, lineno
)
2753 elif ctx
== 'SET_TYPE':
2754 if empty
.match(line
): continue
2755 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2756 if not par
: continue
2757 if not self
.check_item('VIRTUAL_ASSGN', par
[0]):
2758 self
.add_item('SET_TYPE', par
[0], type=par
[1], fn
=fn
, lineno
=lineno
)
2759 if not par
[1][0].isupper():
2760 warnings
.warn_explicit("Set type should have uppercase name (%s)" % (par
[1]),
2761 UserWarning, fn
, lineno
)
2762 elif ctx
== 'ASSIGN_VALUE_TO_TYPE':
2763 if empty
.match(line
): continue
2764 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2765 if not par
: continue
2766 self
.add_item(ctx
, par
[0], name
=par
[1], fn
=fn
, lineno
=lineno
)
2767 elif ctx
== 'TYPE_RENAME':
2768 if empty
.match(line
): continue
2769 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2770 if not par
: continue
2771 self
.add_item('TYPE_RENAME', par
[0], eth_name
=par
[1], fn
=fn
, lineno
=lineno
)
2772 if not par
[1][0].isupper():
2773 warnings
.warn_explicit("Type should be renamed to uppercase name (%s)" % (par
[1]),
2774 UserWarning, fn
, lineno
)
2775 elif ctx
== 'FIELD_RENAME':
2776 if empty
.match(line
): continue
2777 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2778 if not par
: continue
2779 self
.add_item('FIELD_RENAME', par
[0], eth_name
=par
[1], fn
=fn
, lineno
=lineno
)
2780 if not par
[1][0].islower():
2781 warnings
.warn_explicit("Field should be renamed to lowercase name (%s)" % (par
[1]),
2782 UserWarning, fn
, lineno
)
2783 elif ctx
== 'TF_RENAME':
2784 if empty
.match(line
): continue
2785 par
= get_par(line
, 2, 2, fn
=fn
, lineno
=lineno
)
2786 if not par
: continue
2787 tmpu
= par
[1][0].upper() + par
[1][1:]
2788 tmpl
= par
[1][0].lower() + par
[1][1:]
2789 self
.add_item('TYPE_RENAME', par
[0], eth_name
=tmpu
, fn
=fn
, lineno
=lineno
)
2790 if not tmpu
[0].isupper():
2791 warnings
.warn_explicit("Type should be renamed to uppercase name (%s)" % (par
[1]),
2792 UserWarning, fn
, lineno
)
2793 self
.add_item('FIELD_RENAME', par
[0], eth_name
=tmpl
, fn
=fn
, lineno
=lineno
)
2794 if not tmpl
[0].islower():
2795 warnings
.warn_explicit("Field should be renamed to lowercase name (%s)" % (par
[1]),
2796 UserWarning, fn
, lineno
)
2797 elif ctx
in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2798 if empty
.match(line
): continue
2799 par
= get_par_nm(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2800 if not par
: continue
2801 self
.add_item(ctx
, par
[0], attr
=par
[1], fn
=fn
, lineno
=lineno
)
2802 elif ctx
== 'FN_PARS':
2803 if empty
.match(line
): continue
2805 par
= get_par_nm(line
, 0, 0, fn
=fn
, lineno
=lineno
)
2807 par
= get_par_nm(line
, 1, 1, fn
=fn
, lineno
=lineno
)
2808 if not par
: continue
2810 self
.update_item(ctx
, name
, pars
=par
[0], fn
=fn
, lineno
=lineno
)
2812 self
.add_item(ctx
, par
[0], pars
=par
[1], fn
=fn
, lineno
=lineno
)
2813 elif ctx
in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2814 result
= cdirective
.search(line
)
2815 if result
: # directive
2816 line
= '#' + line
[result
.end():]
2817 self
.add_fn_line(name
, ctx
, line
, fn
=fn
, lineno
=lineno
)
2818 elif ctx
== 'CLASS':
2819 if empty
.match(line
): continue
2820 par
= get_par(line
, 1, 3, fn
=fn
, lineno
=lineno
)
2821 if not par
: continue
2822 if not set_type_to_class(name
, par
[0], par
[1:]):
2823 warnings
.warn_explicit("Could not set type of class member %s.&%s to %s" % (name
, par
[0], par
[1]),
2824 UserWarning, fn
, lineno
)
2825 elif ctx
== 'TABLE':
2826 self
.report
[name
][-1]['text'] += line
2828 def set_opt(self
, opt
, par
, fn
, lineno
):
2829 #print("set_opt: %s, %s" % (opt, par))
2831 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2833 self
.include_path
.append(relpath(par
[0]))
2834 elif opt
in ("-b", "BER", "CER", "DER"):
2835 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2836 self
.ectx
.encoding
= 'ber'
2837 elif opt
in ("PER",):
2838 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2839 self
.ectx
.encoding
= 'per'
2840 elif opt
in ("OER",):
2841 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2842 self
.ectx
.encoding
= 'oer'
2843 elif opt
in ("-p", "PROTO"):
2844 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2846 self
.ectx
.proto_opt
= par
[0]
2847 self
.ectx
.merge_modules
= True
2848 elif opt
in ("ALIGNED",):
2849 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2850 self
.ectx
.aligned
= True
2851 elif opt
in ("-u", "UNALIGNED"):
2852 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2853 self
.ectx
.aligned
= False
2854 elif opt
in ("PROTO_ROOT_NAME"):
2855 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2857 self
.proto_root_name
= par
[0]
2858 elif opt
in ("-d",):
2859 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2861 self
.ectx
.dbgopt
= par
[0]
2862 elif opt
in ("-e",):
2863 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2864 self
.ectx
.expcnf
= True
2865 elif opt
in ("-S",):
2866 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2867 self
.ectx
.merge_modules
= True
2868 elif opt
in ("GROUP_BY_PROT",):
2869 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2870 self
.ectx
.group_by_prot
= True
2871 elif opt
in ("-o",):
2872 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2874 self
.ectx
.outnm_opt
= par
[0]
2875 elif opt
in ("-O",):
2876 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2878 self
.ectx
.output
.outdir
= relpath(par
[0])
2879 elif opt
in ("-s",):
2880 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2882 self
.ectx
.output
.single_file
= relpath(par
[0])
2883 elif opt
in ("-k",):
2884 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2885 self
.ectx
.output
.keep
= True
2886 elif opt
in ("-L",):
2887 par
= self
.check_par(par
, 0, 0, fn
, lineno
)
2888 self
.suppress_line
= True
2889 elif opt
in ("EMBEDDED_PDV_CB",):
2890 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2892 self
.ectx
.default_embedded_pdv_cb
= par
[0]
2893 elif opt
in ("EXTERNAL_TYPE_CB",):
2894 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2896 self
.ectx
.default_external_type_cb
= par
[0]
2897 elif opt
in ("-r",):
2898 par
= self
.check_par(par
, 1, 1, fn
, lineno
)
2900 self
.ectx
.remove_prefix
= par
[0]
2902 warnings
.warn_explicit("Unknown option %s" % (opt
),
2903 UserWarning, fn
, lineno
)
2905 def dbg_print(self
):
2906 print("\n# Conformance values")
2907 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value"))
2909 tbls
= sorted(self
.table
.keys())
2911 keys
= sorted(self
.table
[t
].keys())
2913 print("%-15s %4s %-15s %-20s %s" % (
2914 self
.table
[t
][k
]['fn'], self
.table
[t
][k
]['lineno'], t
, k
, str(self
.table
[t
][k
][self
.tblcfg
[t
]['val_nm']])))
2916 def unused_report(self
):
2917 tbls
= sorted(self
.table
.keys())
2919 if not self
.tblcfg
[t
]['chk_use']: continue
2920 keys
= sorted(self
.table
[t
].keys())
2922 if not self
.table
[t
][k
]['used']:
2923 warnings
.warn_explicit("Unused %s for %s" % (t
, k
),
2924 UserWarning, self
.table
[t
][k
]['fn'], self
.table
[t
][k
]['lineno'])
2925 fnms
= list(self
.fn
.keys())
2928 keys
= sorted(self
.fn
[f
].keys())
2930 if not self
.fn
[f
][k
]: continue
2931 if not self
.fn
[f
][k
]['used']:
2932 warnings
.warn_explicit("Unused %s for %s" % (k
, f
),
2933 UserWarning, self
.fn
[f
][k
]['fn'], self
.fn
[f
][k
]['lineno'])
2935 #--- EthOut -------------------------------------------------------------------
2941 self
.single_file
= None
2942 self
.created_files
= {}
2943 self
.created_files_ord
= []
2946 def outcomment(self
, ln
, comment
=None):
2948 return '%s %s\n' % (comment
, ln
)
2950 return '/* %-74s */\n' % (ln
)
2952 def created_file_add(self
, name
, keep_anyway
):
2953 name
= os
.path
.normcase(os
.path
.abspath(name
))
2954 if name
not in self
.created_files
:
2955 self
.created_files_ord
.append(name
)
2956 self
.created_files
[name
] = keep_anyway
2958 self
.created_files
[name
] = self
.created_files
[name
] or keep_anyway
2960 def created_file_exists(self
, name
):
2961 name
= os
.path
.normcase(os
.path
.abspath(name
))
2962 return name
in self
.created_files
2964 #--- output_fname -------------------------------------------------------
2965 def output_fname(self
, ftype
, ext
='c'):
2967 if ext
not in ('cnf',):
2974 #--- file_open -------------------------------------------------------
2975 def file_open(self
, ftype
, ext
='c'):
2976 fn
= self
.output_fname(ftype
, ext
=ext
)
2977 if self
.created_file_exists(fn
):
2984 fx
.write(self
.fhdr(fn
, comment
= comment
))
2986 if (not self
.single_file
and not self
.created_file_exists(fn
)):
2987 fx
.write(self
.fhdr(fn
))
2988 if not self
.ectx
.merge_modules
:
2991 if self
.ectx
.groups():
2993 if (len(self
.ectx
.modules
) > 1):
2995 for (m
, p
) in self
.ectx
.modules
:
2998 mstr
+= "Module %s" % (self
.ectx
.Module())
2999 mstr
+= " --- --- ---"
3000 fx
.write(self
.outcomment(mstr
, comment
))
3003 #--- file_close -------------------------------------------------------
3004 def file_close(self
, fx
, discard
=False, keep_anyway
=False):
3006 if discard
and not self
.created_file_exists(fx
.name
):
3009 self
.created_file_add(fx
.name
, keep_anyway
)
3010 #--- fhdr -------------------------------------------------------
3011 def fhdr(self
, fn
, comment
=None):
3013 out
+= self
.outcomment('Do not modify this file. Changes will be overwritten.', comment
)
3014 out
+= self
.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment
)
3015 out
+= self
.outcomment(os
.path
.basename(fn
), comment
)
3016 out
+= self
.outcomment(' '.join(['asn2wrs.py'] + sys
.argv
[1:]), comment
)
3018 # Make Windows path separator look like Unix path separator
3019 out
= out
.replace('\\', '/')
3020 # Change absolute paths and relative paths generated outside
3021 # source directory to paths relative to asn1/<proto> subdir.
3022 out
= re
.sub(r
'(\s)[./A-Z]\S*/dissectors\b', r
'\1../..', out
)
3023 out
= re
.sub(r
'(\s)[./A-Z]\S*/asn1/\S*?([\s/])', r
'\1.\2', out
)
3026 #--- dbg_print -------------------------------------------------------
3027 def dbg_print(self
):
3028 print("\n# Output files")
3029 print("\n".join(self
.created_files_ord
))
3032 #--- make_single_file -------------------------------------------------------
3033 def make_single_file(self
, suppress_line
):
3034 if (not self
.single_file
): return
3035 in_nm
= self
.single_file
+ '.c'
3036 out_nm
= os
.path
.join(self
.outdir
, self
.output_fname(''))
3037 self
.do_include(out_nm
, in_nm
, suppress_line
)
3038 in_nm
= self
.single_file
+ '.h'
3039 if (os
.path
.exists(in_nm
)):
3040 out_nm
= os
.path
.join(self
.outdir
, self
.output_fname('', ext
='h'))
3041 self
.do_include(out_nm
, in_nm
, suppress_line
)
3043 for fn
in self
.created_files_ord
:
3044 if not self
.created_files
[fn
]:
3047 #--- do_include -------------------------------------------------------
3048 def do_include(self
, out_nm
, in_nm
, suppress_line
):
3049 def check_file(fn
, fnlist
):
3050 fnfull
= os
.path
.normcase(os
.path
.abspath(fn
))
3051 if (fnfull
in fnlist
and os
.path
.exists(fnfull
)):
3052 return os
.path
.normpath(fn
)
3054 fin
= open(in_nm
, "r")
3055 fout
= open(out_nm
, "w")
3056 fout
.write(self
.fhdr(out_nm
))
3057 if (not suppress_line
):
3058 fout
.write('/* Input file: ' + os
.path
.basename(in_nm
) +' */\n')
3060 fout
.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm
)))
3062 include
= re
.compile(r
'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re
.IGNORECASE
)
3067 cont_linenum
= cont_linenum
+ 1
3068 line
= fin
.readline()
3069 if (line
== ''): break
3071 result
= include
.search(line
)
3072 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
3074 ifile
= check_file(os
.path
.join(os
.path
.split(in_nm
)[0], result
.group('fname')), self
.created_files
)
3076 ifile
= check_file(os
.path
.join(self
.outdir
, result
.group('fname')), self
.created_files
)
3078 ifile
= check_file(result
.group('fname'), self
.created_files
)
3080 if (not suppress_line
):
3082 fout
.write('/*--- Included file: ' + ifile
+ ' ---*/\n')
3083 fout
.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile
)))
3084 finc
= open(ifile
, "r")
3085 fout
.write(finc
.read())
3086 if (not suppress_line
):
3088 fout
.write('/*--- End of included file: ' + ifile
+ ' ---*/\n')
3089 fout
.write('#line %u "%s"\n' % (cont_linenum
+1, rel_dissector_path(in_nm
)) )
3098 #--- Node ---------------------------------------------------------------------
3100 def __init__(self
,*args
, **kw
):
3102 self
.type = self
.__class
__.__name
__
3104 assert (len(args
) == 1)
3106 self
.__dict
__.update (kw
)
3107 def str_child (self
, key
, child
, depth
):
3108 indent
= " " * (2 * depth
)
3109 keystr
= indent
+ key
+ ": "
3110 if key
== 'type': # already processed in str_depth
3112 if isinstance (child
, Node
): # ugh
3113 return keystr
+ "\n" + child
.str_depth (depth
+1)
3114 if isinstance(child
, type ([])):
3117 if isinstance (x
, Node
):
3118 l
.append (x
.str_depth (depth
+1))
3120 l
.append (indent
+ " " + str(x
) + "\n")
3121 return keystr
+ "[\n" + ''.join(l
) + indent
+ "]\n"
3123 return keystr
+ str (child
) + "\n"
3124 def str_depth (self
, depth
): # ugh
3125 indent
= " " * (2 * depth
)
3126 l
= ["%s%s" % (indent
, self
.type)]
3127 l
.append ("".join ([self
.str_child (k_v
[0], k_v
[1], depth
+ 1) for k_v
in list(self
.__dict
__.items ())]))
3128 return "\n".join (l
)
3130 return "\n" + self
.str_depth (0)
3131 def to_python (self
, ctx
):
3132 return self
.str_depth (ctx
.indent_lev
)
3134 def eth_reg(self
, ident
, ectx
):
3137 def fld_obj_repr(self
, ectx
):
3138 return "/* TO DO %s */" % (str(self
))
3141 #--- ValueAssignment -------------------------------------------------------------
3142 class ValueAssignment (Node
):
3143 def __init__(self
,*args
, **kw
) :
3144 Node
.__init
__ (self
,*args
, **kw
)
3146 def eth_reg(self
, ident
, ectx
):
3147 if ectx
.conform
.omit_assignment('V', self
.ident
, ectx
.Module()): return # Assignment to omit
3148 ectx
.eth_reg_vassign(self
)
3149 ectx
.eth_reg_value(self
.ident
, self
.typ
, self
.val
)
3151 #--- ObjectAssignment -------------------------------------------------------------
3152 class ObjectAssignment (Node
):
3153 def __init__(self
,*args
, **kw
) :
3154 Node
.__init
__ (self
,*args
, **kw
)
3156 def __eq__(self
, other
):
3157 if self
.cls
!= other
.cls
:
3159 if len(self
.val
) != len(other
.val
):
3161 for f
in (list(self
.val
.keys())):
3162 if f
not in other
.val
:
3164 if isinstance(self
.val
[f
], Node
) and isinstance(other
.val
[f
], Node
):
3165 if not self
.val
[f
].fld_obj_eq(other
.val
[f
]):
3168 if str(self
.val
[f
]) != str(other
.val
[f
]):
3172 def eth_reg(self
, ident
, ectx
):
3173 def make_virtual_type(cls
, field
, prefix
):
3174 if isinstance(self
.val
, str): return
3175 if field
in self
.val
and not isinstance(self
.val
[field
], Type_Ref
):
3176 vnm
= prefix
+ '-' + self
.ident
3177 virtual_tr
= Type_Ref(val
= vnm
)
3179 self
.val
[field
] = virtual_tr
3180 ectx
.eth_reg_assign(vnm
, t
, virt
=True)
3181 ectx
.eth_reg_type(vnm
, t
)
3182 t
.eth_reg_sub(vnm
, ectx
)
3183 if field
in self
.val
and ectx
.conform
.check_item('PDU', cls
+ '.' + field
):
3184 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
))
3186 # end of make_virtual_type()
3187 if ectx
.conform
.omit_assignment('V', self
.ident
, ectx
.Module()): return # Assignment to omit
3188 self
.module
= ectx
.Module()
3189 ectx
.eth_reg_oassign(self
)
3190 if (self
.cls
== 'TYPE-IDENTIFIER') or (self
.cls
== 'ABSTRACT-SYNTAX'):
3191 make_virtual_type(self
.cls
, '&Type', 'TYPE')
3192 if (self
.cls
== 'OPERATION'):
3193 make_virtual_type(self
.cls
, '&ArgumentType', 'ARG')
3194 make_virtual_type(self
.cls
, '&ResultType', 'RES')
3195 if (self
.cls
== 'ERROR'):
3196 make_virtual_type(self
.cls
, '&ParameterType', 'PAR')
3199 #--- Type ---------------------------------------------------------------------
3201 def __init__(self
,*args
, **kw
) :
3205 self
.named_list
= None
3206 Node
.__init
__ (self
,*args
, **kw
)
3209 if self
.name
is None :
3214 def HasConstraint(self
):
3215 if self
.constr
is None :
3220 def HasSizeConstraint(self
):
3221 return self
.HasConstraint() and self
.constr
.IsSize()
3223 def HasValueConstraint(self
):
3224 return self
.HasConstraint() and self
.constr
.IsValue()
3226 def HasPermAlph(self
):
3227 return self
.HasConstraint() and self
.constr
.IsPermAlph()
3229 def HasContentsConstraint(self
):
3230 return self
.HasConstraint() and self
.constr
.IsContents()
3232 def HasOwnTag(self
):
3233 return len(self
.tags
) > 0
3235 def HasImplicitTag(self
, ectx
):
3236 return (self
.HasOwnTag() and self
.tags
[0].IsImplicit(ectx
))
3238 def IndetermTag(self
, ectx
):
3241 def AddTag(self
, tag
):
3242 self
.tags
[0:0] = [tag
]
3244 def GetTag(self
, ectx
):
3245 #print "GetTag(%s)\n" % self.name;
3246 if (self
.HasOwnTag()):
3247 return self
.tags
[0].GetTag(ectx
)
3249 return self
.GetTTag(ectx
)
3251 def GetTTag(self
, ectx
):
3252 print("#Unhandled GetTTag() in %s" % (self
.type))
3253 print(self
.str_depth(1))
3254 return ('BER_CLASS_unknown', 'TAG_unknown')
3256 def SetName(self
, name
):
3259 def AddConstraint(self
, constr
):
3260 if not self
.HasConstraint():
3261 self
.constr
= constr
3263 self
.constr
= Constraint(type = 'Intersection', subtype
= [self
.constr
, constr
])
3265 def eth_tname(self
):
3266 return '#' + self
.type + '_' + str(id(self
))
3268 def eth_ftype(self
, ectx
):
3269 return ('FT_NONE', 'BASE_NONE')
3271 def eth_strings(self
):
3274 def eth_omit_field(self
):
3277 def eth_need_tree(self
):
3280 def eth_has_vals(self
):
3283 def eth_has_enum(self
, tname
, ectx
):
3284 return self
.eth_has_vals() and (ectx
.eth_type
[tname
]['enum'] & EF_ENUM
)
3286 def eth_need_pdu(self
, ectx
):
3289 def eth_named_bits(self
):
3292 def eth_reg_sub(self
, ident
, ectx
):
3295 def get_components(self
, ectx
):
3296 print("#Unhandled get_components() in %s" % (self
.type))
3297 print(self
.str_depth(1))
3300 def sel_req(self
, sel
, ectx
):
3301 print("#Selection '%s' required for non-CHOICE type %s" % (sel
, self
.type))
3302 print(self
.str_depth(1))
3304 def fld_obj_eq(self
, other
):
3305 return isinstance(other
, Type
) and (self
.eth_tname() == other
.eth_tname())
3307 def eth_reg(self
, ident
, ectx
, tstrip
=0, tagflag
=False, selflag
=False, idx
='', parent
=None):
3308 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3310 if (ectx
.NeedTags() and (len(self
.tags
) > tstrip
)):
3312 for i
in range(len(self
.tags
)-1, tstrip
-1, -1):
3313 tagged_type
= TaggedType(val
=tagged_type
, tstrip
=i
)
3314 tagged_type
.AddTag(self
.tags
[i
])
3315 if not tagflag
: # 1st tagged level
3316 if self
.IsNamed() and not selflag
:
3317 tagged_type
.SetName(self
.name
)
3318 tagged_type
.eth_reg(ident
, ectx
, tstrip
=1, tagflag
=tagflag
, idx
=idx
, parent
=parent
)
3321 if ident
and self
.IsNamed() and not tagflag
and not selflag
:
3322 nm
= ident
+ '/' + self
.name
3325 elif self
.IsNamed():
3327 if not ident
and ectx
.conform
.omit_assignment('T', nm
, ectx
.Module()): return # Assignment to omit
3328 if not ident
: # Assignment
3329 ectx
.eth_reg_assign(nm
, self
)
3330 if self
.type == 'Type_Ref' and not self
.tr_need_own_fn(ectx
):
3331 ectx
.eth_reg_type(nm
, self
)
3332 virtual_tr
= Type_Ref(val
=ectx
.conform
.use_item('SET_TYPE', nm
))
3333 if (self
.type == 'Type_Ref') or ectx
.conform
.check_item('SET_TYPE', nm
):
3334 if ident
and (ectx
.conform
.check_item('TYPE_RENAME', nm
) or ectx
.conform
.get_fn_presence(nm
) or selflag
):
3335 if ectx
.conform
.check_item('SET_TYPE', nm
):
3336 ectx
.eth_reg_type(nm
, virtual_tr
) # dummy Type Reference
3338 ectx
.eth_reg_type(nm
, self
) # new type
3340 elif ectx
.conform
.check_item('SET_TYPE', nm
):
3341 trnm
= ectx
.conform
.use_item('SET_TYPE', nm
)
3342 elif (self
.type == 'Type_Ref') and self
.tr_need_own_fn(ectx
):
3343 ectx
.eth_reg_type(nm
, self
) # need own function, e.g. for constraints
3348 ectx
.eth_reg_type(nm
, self
, mod
= ectx
.Module())
3350 if ectx
.conform
.check_item('VIRTUAL_ASSGN', nm
):
3351 vnm
= ectx
.conform
.use_item('VIRTUAL_ASSGN', nm
)
3352 ectx
.eth_reg_assign(vnm
, self
, virt
=True)
3353 ectx
.eth_reg_type(vnm
, self
)
3354 self
.eth_reg_sub(vnm
, ectx
)
3355 if parent
and (ectx
.type[parent
]['val'].type == 'TaggedType'):
3356 ectx
.type[parent
]['val'].eth_set_val_name(parent
, trnm
, ectx
)
3357 if ident
and not tagflag
and not self
.eth_omit_field():
3358 ectx
.eth_reg_field(nm
, trnm
, idx
=idx
, parent
=parent
, impl
=self
.HasImplicitTag(ectx
))
3359 if ectx
.conform
.check_item('SET_TYPE', nm
):
3360 virtual_tr
.eth_reg_sub(nm
, ectx
)
3362 self
.eth_reg_sub(nm
, ectx
)
3364 def eth_get_size_constr(self
, ectx
):
3365 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3366 if self
.HasSizeConstraint():
3367 if self
.constr
.IsSize():
3368 (minv
, maxv
, ext
) = self
.constr
.GetSize(ectx
)
3369 if (self
.constr
.type == 'Intersection'):
3370 if self
.constr
.subtype
[0].IsSize():
3371 (minv
, maxv
, ext
) = self
.constr
.subtype
[0].GetSize(ectx
)
3372 elif self
.constr
.subtype
[1].IsSize():
3373 (minv
, maxv
, ext
) = self
.constr
.subtype
[1].GetSize(ectx
)
3374 if minv
== 'MIN': minv
= 'NO_BOUND'
3375 if maxv
== 'MAX': maxv
= 'NO_BOUND'
3376 if (ext
): ext
= 'true'
3378 return (minv
, maxv
, ext
)
3380 def eth_get_value_constr(self
, ectx
, named_list
=[]):
3381 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3382 if self
.HasValueConstraint():
3383 # If this is a subclass (Type_Ref), we may have passed in the
3384 # NamedNumberList of the parent class. Otherwise use our own,
3386 named_list
= named_list
or self
.named_list
3387 (minv
, maxv
, ext
) = self
.constr
.GetValue(ectx
, named_list
)
3388 if minv
== 'MIN': minv
= 'NO_BOUND'
3389 if maxv
== 'MAX': maxv
= 'NO_BOUND'
3390 if str(minv
).isdigit():
3392 elif (str(minv
)[0] == "-") and str(minv
)[1:].isdigit():
3393 if (int(minv
) == -(2**31)):
3395 elif (int(minv
) < -(2**31)):
3396 minv
= "INT64_C(%s)" % (str(minv
))
3397 if str(maxv
).isdigit():
3398 if (int(maxv
) >= 2**32):
3399 maxv
= "UINT64_C(%s)" % (str(maxv
))
3402 if (ext
): ext
= 'true'
3404 return (minv
, maxv
, ext
)
3406 def eth_get_alphabet_constr(self
, ectx
):
3407 (alph
, alphlen
) = ('NULL', '0')
3408 if self
.HasPermAlph():
3409 alph
= self
.constr
.GetPermAlph(ectx
)
3412 if (alph
!= 'NULL'):
3413 if (((alph
[0] + alph
[-1]) == '""') and (not alph
.count('"', 1, -1))):
3414 alphlen
= str(len(alph
) - 2)
3416 alphlen
= 'strlen(%s)' % (alph
)
3417 return (alph
, alphlen
)
3419 def eth_type_vals(self
, tname
, ectx
):
3420 if self
.eth_has_vals():
3421 print("#Unhandled eth_type_vals('%s') in %s" % (tname
, self
.type))
3422 print(self
.str_depth(1))
3425 def eth_type_enum(self
, tname
, ectx
):
3426 if self
.eth_has_enum(tname
, ectx
):
3427 print("#Unhandled eth_type_enum('%s') in %s" % (tname
, self
.type))
3428 print(self
.str_depth(1))
3431 def eth_type_default_table(self
, ectx
, tname
):
3434 def eth_type_default_body(self
, ectx
, tname
):
3435 print("#Unhandled eth_type_default_body('%s') in %s" % (tname
, self
.type))
3436 print(self
.str_depth(1))
3439 def eth_type_default_pars(self
, ectx
, tname
):
3446 'OFFSET' : 'offset',
3448 'HF_INDEX' : 'hf_index',
3450 'IMPLICIT_TAG' : 'implicit_tag',
3452 if (ectx
.eth_type
[tname
]['tree']):
3453 pars
['ETT_INDEX'] = ectx
.eth_type
[tname
]['tree']
3454 if (ectx
.merge_modules
):
3457 pars
['PROTOP'] = ectx
.eth_type
[tname
]['proto'] + '_'
3460 def eth_type_fn(self
, proto
, tname
, ectx
):
3461 body
= self
.eth_type_default_body(ectx
, tname
)
3462 pars
= self
.eth_type_default_pars(ectx
, tname
)
3463 if ectx
.conform
.check_item('FN_PARS', tname
):
3464 pars
.update(ectx
.conform
.use_item('FN_PARS', tname
))
3465 elif ectx
.conform
.check_item('FN_PARS', ectx
.eth_type
[tname
]['ref'][0]):
3466 pars
.update(ectx
.conform
.use_item('FN_PARS', ectx
.eth_type
[tname
]['ref'][0]))
3467 pars
['DEFAULT_BODY'] = body
3469 for k
in list(pars
.keys()):
3471 pars
[k
] = pars
[k
] % pars
3472 except (ValueError,TypeError):
3473 raise sys
.exc_info()[0]("%s\n%s" % (str(pars
), sys
.exc_info()[1]))
3475 out
+= self
.eth_type_default_table(ectx
, tname
) % pars
3476 out
+= ectx
.eth_type_fn_hdr(tname
)
3477 out
+= ectx
.eth_type_fn_body(tname
, body
, pars
=pars
)
3478 out
+= ectx
.eth_type_fn_ftr(tname
)
3481 #--- Value --------------------------------------------------------------------
3483 def __init__(self
,*args
, **kw
) :
3485 Node
.__init
__ (self
,*args
, **kw
)
3487 def SetName(self
, name
) :
3490 def to_str(self
, ectx
):
3491 return str(self
.val
)
3496 def fld_obj_repr(self
, ectx
):
3497 return self
.to_str(ectx
)
3499 #--- Value_Ref -----------------------------------------------------------------
3500 class Value_Ref (Value
):
3501 def to_str(self
, ectx
):
3502 return asn2c(self
.val
)
3504 #--- ObjectClass ---------------------------------------------------------------------
3505 class ObjectClass (Node
):
3506 def __init__(self
,*args
, **kw
) :
3508 Node
.__init
__ (self
,*args
, **kw
)
3510 def SetName(self
, name
):
3512 add_class_ident(self
.name
)
3514 def eth_reg(self
, ident
, ectx
):
3515 if ectx
.conform
.omit_assignment('C', self
.name
, ectx
.Module()): return # Assignment to omit
3516 ectx
.eth_reg_objectclass(self
.name
, self
)
3518 #--- Class_Ref -----------------------------------------------------------------
3519 class Class_Ref (ObjectClass
):
3522 #--- ObjectClassDefn ---------------------------------------------------------------------
3523 class ObjectClassDefn (ObjectClass
):
3524 def reg_types(self
):
3525 for fld
in self
.fields
:
3526 repr = fld
.fld_repr()
3527 set_type_to_class(self
.name
, repr[0], repr[1:])
3530 #--- Tag ---------------------------------------------------------------
3532 def to_python (self
, ctx
):
3533 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx
, self
.tag
.cls
,
3536 self
.typ
.to_python (ctx
))
3537 def IsImplicit(self
, ectx
):
3538 return ((self
.mode
== 'IMPLICIT') or ((self
.mode
== 'default') and (ectx
.tag_def
!= 'EXPLICIT')))
3540 def GetTag(self
, ectx
):
3542 if (self
.cls
== 'UNIVERSAL'): tc
= 'BER_CLASS_UNI'
3543 elif (self
.cls
== 'APPLICATION'): tc
= 'BER_CLASS_APP'
3544 elif (self
.cls
== 'CONTEXT'): tc
= 'BER_CLASS_CON'
3545 elif (self
.cls
== 'PRIVATE'): tc
= 'BER_CLASS_PRI'
3546 return (tc
, self
.num
)
3548 def eth_tname(self
):
3550 if (self
.cls
== 'UNIVERSAL'): n
= 'U'
3551 elif (self
.cls
== 'APPLICATION'): n
= 'A'
3552 elif (self
.cls
== 'CONTEXT'): n
= 'C'
3553 elif (self
.cls
== 'PRIVATE'): n
= 'P'
3554 return n
+ str(self
.num
)
3556 #--- Constraint ---------------------------------------------------------------
3558 class Constraint (Node
):
3559 def to_python (self
, ctx
):
3560 print("Ignoring constraint:", self
.type)
3561 return self
.subtype
.typ
.to_python (ctx
)
3563 return "Constraint: type=%s, subtype=%s" % (self
.type, self
.subtype
)
3565 def eth_tname(self
):
3566 return '#' + self
.type + '_' + str(id(self
))
3569 return (self
.type == 'Size' and self
.subtype
.IsValue()) \
3570 or (self
.type == 'Intersection' and (self
.subtype
[0].IsSize() or self
.subtype
[1].IsSize())) \
3572 def GetSize(self
, ectx
):
3573 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3575 if self
.type == 'Size':
3576 (minv
, maxv
, ext
) = self
.subtype
.GetValue(ectx
)
3577 ext
= ext
or (hasattr(self
, 'ext') and self
.ext
)
3578 elif self
.type == 'Intersection':
3579 if self
.subtype
[0].IsSize() and not self
.subtype
[1].IsSize():
3580 (minv
, maxv
, ext
) = self
.subtype
[0].GetSize(ectx
)
3581 elif not self
.subtype
[0].IsSize() and self
.subtype
[1].IsSize():
3582 (minv
, maxv
, ext
) = self
.subtype
[1].GetSize(ectx
)
3583 return (minv
, maxv
, ext
)
3586 return self
.type == 'SingleValue' \
3587 or self
.type == 'ValueRange' \
3588 or (self
.type == 'Intersection' and (self
.subtype
[0].IsValue() or self
.subtype
[1].IsValue())) \
3589 or (self
.type == 'Union' and (self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue()))
3591 def GetValue(self
, ectx
, named_list
=[]):
3592 (minv
, maxv
, ext
) = ('MIN', 'MAX', False)
3594 if self
.type == 'SingleValue':
3595 minv
= ectx
.value_get_eth(self
.subtype
)
3597 minv
= next((e
.val
for e
in named_list
if minv
== e
.ident
), minv
)
3599 # named_list is not an iterable, e.g. None
3602 ext
= hasattr(self
, 'ext') and self
.ext
3603 elif self
.type == 'ValueRange':
3604 minv
= ectx
.value_get_eth(self
.subtype
[0])
3605 maxv
= ectx
.value_get_eth(self
.subtype
[1])
3607 minv
= next((e
.val
for e
in named_list
if minv
== e
.ident
), minv
)
3608 maxv
= next((e
.val
for e
in named_list
if maxv
== e
.ident
), maxv
)
3610 # named_list is not an iterable
3612 ext
= hasattr(self
, 'ext') and self
.ext
3613 elif self
.type == 'Intersection':
3614 if self
.subtype
[0].IsValue() and not self
.subtype
[1].IsValue():
3615 (minv
, maxv
, ext
) = self
.subtype
[0].GetValue(ectx
, named_list
)
3616 elif not self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue():
3617 (minv
, maxv
, ext
) = self
.subtype
[1].GetValue(ectx
, named_list
)
3618 elif self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue():
3619 v0
= self
.subtype
[0].GetValue(ectx
, named_list
)
3620 v1
= self
.subtype
[1].GetValue(ectx
, named_list
)
3621 (minv
, maxv
, ext
) = (ectx
.value_max(v0
[0],v1
[0]), ectx
.value_min(v0
[1],v1
[1]), v0
[2] and v1
[2])
3622 elif self
.type == 'Union':
3623 if self
.subtype
[0].IsValue() and self
.subtype
[1].IsValue():
3624 v0
= self
.subtype
[0].GetValue(ectx
, named_list
)
3625 v1
= self
.subtype
[1].GetValue(ectx
, named_list
)
3626 (minv
, maxv
, ext
) = (ectx
.value_min(v0
[0],v1
[0]), ectx
.value_max(v0
[1],v1
[1]), hasattr(self
, 'ext') and self
.ext
)
3627 return (minv
, maxv
, ext
)
3629 def IsAlphabet(self
):
3630 return self
.type == 'SingleValue' \
3631 or self
.type == 'ValueRange' \
3632 or (self
.type == 'Intersection' and (self
.subtype
[0].IsAlphabet() or self
.subtype
[1].IsAlphabet())) \
3633 or (self
.type == 'Union' and (self
.subtype
[0].IsAlphabet() and self
.subtype
[1].IsAlphabet()))
3635 def GetAlphabet(self
, ectx
):
3637 if self
.IsAlphabet():
3638 if self
.type == 'SingleValue':
3639 alph
= ectx
.value_get_eth(self
.subtype
)
3640 elif self
.type == 'ValueRange':
3641 if ((len(self
.subtype
[0]) == 3) and ((self
.subtype
[0][0] + self
.subtype
[0][-1]) == '""') \
3642 and (len(self
.subtype
[1]) == 3) and ((self
.subtype
[1][0] + self
.subtype
[1][-1]) == '""')):
3644 for c
in range(ord(self
.subtype
[0][1]), ord(self
.subtype
[1][1]) + 1):
3647 elif self
.type == 'Union':
3648 if self
.subtype
[0].IsAlphabet() and self
.subtype
[1].IsAlphabet():
3649 a0
= self
.subtype
[0].GetAlphabet(ectx
)
3650 a1
= self
.subtype
[1].GetAlphabet(ectx
)
3651 if (((a0
[0] + a0
[-1]) == '""') and not a0
.count('"', 1, -1) \
3652 and ((a1
[0] + a1
[-1]) == '""') and not a1
.count('"', 1, -1)):
3653 alph
= '"' + a0
[1:-1] + a1
[1:-1] + '"'
3655 alph
= a0
+ ' ' + a1
3658 def IsPermAlph(self
):
3659 return self
.type == 'From' and self
.subtype
.IsAlphabet() \
3660 or (self
.type == 'Intersection' and (self
.subtype
[0].IsPermAlph() or self
.subtype
[1].IsPermAlph())) \
3662 def GetPermAlph(self
, ectx
):
3664 if self
.IsPermAlph():
3665 if self
.type == 'From':
3666 alph
= self
.subtype
.GetAlphabet(ectx
)
3667 elif self
.type == 'Intersection':
3668 if self
.subtype
[0].IsPermAlph() and not self
.subtype
[1].IsPermAlph():
3669 alph
= self
.subtype
[0].GetPermAlph(ectx
)
3670 elif not self
.subtype
[0].IsPermAlph() and self
.subtype
[1].IsPermAlph():
3671 alph
= self
.subtype
[1].GetPermAlph(ectx
)
3674 def IsContents(self
):
3675 return self
.type == 'Contents' \
3676 or (self
.type == 'Intersection' and (self
.subtype
[0].IsContents() or self
.subtype
[1].IsContents())) \
3678 def GetContents(self
, ectx
):
3680 if self
.IsContents():
3681 if self
.type == 'Contents':
3682 if self
.subtype
.type == 'Type_Ref':
3683 contents
= self
.subtype
.val
3684 elif self
.type == 'Intersection':
3685 if self
.subtype
[0].IsContents() and not self
.subtype
[1].IsContents():
3686 contents
= self
.subtype
[0].GetContents(ectx
)
3687 elif not self
.subtype
[0].IsContents() and self
.subtype
[1].IsContents():
3688 contents
= self
.subtype
[1].GetContents(ectx
)
3691 def IsNegativ(self
):
3693 return isinstance(sval
, str) and (sval
[0] == '-')
3694 if self
.type == 'SingleValue':
3695 return is_neg(self
.subtype
)
3696 elif self
.type == 'ValueRange':
3697 if self
.subtype
[0] == 'MIN': return True
3698 return is_neg(self
.subtype
[0])
3701 def eth_constrname(self
):
3703 if isinstance(val
, Value_Ref
):
3704 return asn2c(val
.val
)
3707 return 'M' + str(-int(val
))
3709 return str(int(val
))
3710 except (ValueError, TypeError):
3711 return asn2c(str(val
))
3714 if hasattr(self
, 'ext') and self
.ext
:
3716 if self
.type == 'SingleValue':
3717 return int2str(self
.subtype
) + ext
3718 elif self
.type == 'ValueRange':
3719 return int2str(self
.subtype
[0]) + '_' + int2str(self
.subtype
[1]) + ext
3720 elif self
.type == 'Size':
3721 return 'SIZE_' + self
.subtype
.eth_constrname() + ext
3723 if (not hasattr(self
, 'constr_num')):
3726 self
.constr_num
= constr_cnt
3727 return 'CONSTR%03d%s' % (self
.constr_num
, ext
)
3729 def Needs64b(self
, ectx
):
3730 (minv
, maxv
, ext
) = self
.GetValue(ectx
)
3731 if ((str(minv
).isdigit() or ((str(minv
)[0] == "-") and str(minv
)[1:].isdigit())) \
3732 and (str(maxv
).isdigit() or ((str(maxv
)[0] == "-") and str(maxv
)[1:].isdigit())) \
3733 and ((abs(int(maxv
) - int(minv
)) >= 2**32) or (int(minv
) < -2**31) or (int(maxv
) >= 2**32))) \
3734 or (maxv
== 'MAX') or (minv
== 'MIN'):
3738 class Module (Node
):
3739 def to_python (self
, ctx
):
3740 ctx
.tag_def
= self
.tag_def
.dfl_tag
3742 %s""" % (self
.ident
, self
.body
.to_python (ctx
))
3745 return self
.ident
.val
3747 def get_proto(self
, ectx
):
3751 prot
= ectx
.conform
.use_item('MODULE', self
.get_name(), val_dflt
=self
.get_name())
3754 def to_eth(self
, ectx
):
3755 ectx
.tags_def
= 'EXPLICIT' # default = explicit
3756 ectx
.proto
= self
.get_proto(ectx
)
3757 ectx
.tag_def
= self
.tag_def
.dfl_tag
3758 ectx
.eth_reg_module(self
)
3759 self
.body
.to_eth(ectx
)
3761 class Module_Body (Node
):
3762 def to_python (self
, ctx
):
3763 # XXX handle exports, imports.
3764 list = [x
.to_python (ctx
) for x
in self
.assign_list
]
3765 list = [a
for a
in list if a
!= '']
3766 return "\n".join(list)
3768 def to_eth(self
, ectx
):
3770 ectx
.eth_exports(self
.exports
)
3772 for i
in self
.imports
:
3774 proto
= ectx
.conform
.use_item('MODULE', mod
, val_dflt
=mod
)
3775 ectx
.eth_module_dep_add(ectx
.Module(), mod
)
3776 for s
in i
.symbol_list
:
3777 if isinstance(s
, Type_Ref
):
3778 ectx
.eth_import_type(s
.val
, mod
, proto
)
3779 elif isinstance(s
, Value_Ref
):
3780 ectx
.eth_import_value(s
.val
, mod
, proto
)
3781 elif isinstance(s
, Class_Ref
):
3782 ectx
.eth_import_class(s
.val
, mod
, proto
)
3784 msg
= 'Unknown kind of imported symbol %s from %s' % (str(s
), mod
)
3785 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3787 for a
in self
.assign_list
:
3790 class Default_Tags (Node
):
3791 def to_python (self
, ctx
): # not to be used directly
3794 # XXX should just calculate dependencies as we go along.
3795 def calc_dependencies (node
, dict, trace
= 0):
3796 if not hasattr (node
, '__dict__'):
3797 if trace
: print("#returning, node=", node
)
3799 if isinstance (node
, Type_Ref
):
3801 if trace
: print("#Setting", node
.val
)
3803 for (a
, val
) in list(node
.__dict
__.items ()):
3804 if trace
: print("# Testing node ", node
, "attr", a
, " val", val
)
3807 elif isinstance (val
, Node
):
3808 calc_dependencies (val
, dict, trace
)
3809 elif isinstance (val
, type ([])):
3811 calc_dependencies (v
, dict, trace
)
3814 class Type_Assign (Node
):
3815 def __init__ (self
, *args
, **kw
):
3816 Node
.__init
__ (self
, *args
, **kw
)
3817 if isinstance (self
.val
, Tag
): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3818 to_test
= self
.val
.typ
3821 if isinstance (to_test
, SequenceType
):
3822 to_test
.sequence_name
= self
.name
.name
3824 def to_python (self
, ctx
):
3826 calc_dependencies (self
.val
, dep_dict
, 0)
3827 depend_list
= list(dep_dict
.keys ())
3828 return ctx
.register_assignment (self
.name
.name
,
3829 self
.val
.to_python (ctx
),
3832 class PyQuote (Node
):
3833 def to_python (self
, ctx
):
3834 return ctx
.register_pyquote (self
.val
)
3836 #--- Type_Ref -----------------------------------------------------------------
3837 class Type_Ref (Type
):
3838 def to_python (self
, ctx
):
3841 def eth_reg_sub(self
, ident
, ectx
):
3842 ectx
.eth_dep_add(ident
, self
.val
)
3844 def eth_tname(self
):
3845 if self
.HasSizeConstraint() or self
.HasValueConstraint():
3846 return asn2c(self
.val
) + '_' + self
.constr
.eth_constrname()
3848 return asn2c(self
.val
)
3850 def tr_need_own_fn(self
, ectx
):
3851 return (ectx
.Per() or ectx
.Oer()) and (self
.HasSizeConstraint() or self
.HasValueConstraint())
3853 def fld_obj_repr(self
, ectx
):
3856 def get_components(self
, ectx
):
3857 if self
.val
not in ectx
.type or ectx
.type[self
.val
]['import']:
3858 msg
= "Can not get COMPONENTS OF %s which is imported type" % (self
.val
)
3859 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3862 return ectx
.type[self
.val
]['val'].get_components(ectx
)
3864 def GetTTag(self
, ectx
):
3865 #print "GetTTag(%s)\n" % self.val;
3866 if (ectx
.type[self
.val
]['import']):
3867 if 'ttag' not in ectx
.type[self
.val
]:
3868 ttag
= ectx
.get_ttag_from_all(self
.val
, ectx
.type[self
.val
]['import'])
3869 if not ttag
and not ectx
.conform
.check_item('IMPORT_TAG', self
.val
):
3870 msg
= 'Missing tag information for imported type %s from %s (%s)' % (self
.val
, ectx
.type[self
.val
]['import'], ectx
.type[self
.val
]['proto'])
3871 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3872 ttag
= ('-1/*imported*/', '-1/*imported*/')
3873 ectx
.type[self
.val
]['ttag'] = ectx
.conform
.use_item('IMPORT_TAG', self
.val
, val_dflt
=ttag
)
3874 return ectx
.type[self
.val
]['ttag']
3876 return ectx
.type[self
.val
]['val'].GetTag(ectx
)
3878 def IndetermTag(self
, ectx
):
3879 if (ectx
.type[self
.val
]['import']):
3882 return ectx
.type[self
.val
]['val'].IndetermTag(ectx
)
3884 def eth_get_value_constr(self
, ectx
):
3885 # NamedNumberList of the parent type
3886 named_list
= ectx
.type[self
.val
]['val'].named_list
3887 return super(Type_Ref
, self
).eth_get_value_constr(ectx
, named_list
)
3889 def eth_type_default_pars(self
, ectx
, tname
):
3891 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
3894 t
= ectx
.type[self
.val
]['ethname']
3895 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
3896 pars
['TYPE_REF_TNAME'] = t
3897 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3898 if self
.HasSizeConstraint():
3899 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
3900 elif self
.HasValueConstraint():
3901 # We ought to enforce X.680 51.4.2 - 'All values in the "ValueRange"
3902 # are required to be in the root of the parent type' by examining
3903 # MIN_VAL and MAX_VAL of the parent type.
3904 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_value_constr(ectx
)
3907 def eth_type_default_body(self
, ectx
, tname
):
3909 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3910 par
=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3911 elif (ectx
.Per() or ectx
.Oer()):
3912 if self
.HasSizeConstraint():
3913 body
= ectx
.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret
='offset',
3914 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3915 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3916 elif self
.HasValueConstraint() and isinstance(ectx
.type[self
.val
]['val'], IntegerType
):
3917 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret
='offset',
3918 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
3919 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
3921 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3922 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3924 body
= '#error Can not decode %s' % (tname
)
3927 #--- SelectionType ------------------------------------------------------------
3928 class SelectionType (Type
):
3929 def to_python (self
, ctx
):
3932 def sel_of_typeref(self
):
3933 return self
.typ
.type == 'Type_Ref'
3935 def eth_reg_sub(self
, ident
, ectx
):
3936 if not self
.sel_of_typeref():
3939 self
.seltype
= ectx
.eth_sel_req(self
.typ
.val
, self
.sel
)
3940 ectx
.eth_dep_add(ident
, self
.seltype
)
3942 def eth_ftype(self
, ectx
):
3943 (ftype
, display
) = ('FT_NONE', 'BASE_NONE')
3944 if self
.sel_of_typeref() and not ectx
.type[self
.seltype
]['import']:
3945 (ftype
, display
) = ectx
.type[self
.typ
.val
]['val'].eth_ftype_sel(self
.sel
, ectx
)
3946 return (ftype
, display
)
3948 def GetTTag(self
, ectx
):
3949 #print "GetTTag(%s)\n" % self.seltype;
3950 if (ectx
.type[self
.seltype
]['import']):
3951 if 'ttag' not in ectx
.type[self
.seltype
]:
3952 if not ectx
.conform
.check_item('IMPORT_TAG', self
.seltype
):
3953 msg
= 'Missing tag information for imported type %s from %s (%s)' % (self
.seltype
, ectx
.type[self
.seltype
]['import'], ectx
.type[self
.seltype
]['proto'])
3954 warnings
.warn_explicit(msg
, UserWarning, '', 0)
3955 ectx
.type[self
.seltype
]['ttag'] = ectx
.conform
.use_item('IMPORT_TAG', self
.seltype
, val_dflt
=('-1 /*imported*/', '-1 /*imported*/'))
3956 return ectx
.type[self
.seltype
]['ttag']
3958 return ectx
.type[self
.typ
.val
]['val'].GetTTagSel(self
.sel
, ectx
)
3960 def eth_type_default_pars(self
, ectx
, tname
):
3961 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
3962 if self
.sel_of_typeref():
3963 t
= ectx
.type[self
.seltype
]['ethname']
3964 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
3965 pars
['TYPE_REF_TNAME'] = t
3966 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3969 def eth_type_default_body(self
, ectx
, tname
):
3970 if not self
.sel_of_typeref():
3971 body
= '#error Can not decode %s' % (tname
)
3973 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3974 par
=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3975 elif (ectx
.Per() or ectx
.Oer()):
3976 body
= ectx
.eth_fn_call('%(TYPE_REF_FN)s', ret
='offset',
3977 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3979 body
= '#error Can not decode %s' % (tname
)
3982 #--- TaggedType -----------------------------------------------------------------
3983 class TaggedType (Type
):
3984 def eth_tname(self
):
3986 for i
in range(self
.tstrip
, len(self
.val
.tags
)):
3987 tn
+= self
.val
.tags
[i
].eth_tname()
3989 tn
+= self
.val
.eth_tname()
3992 def eth_set_val_name(self
, ident
, val_name
, ectx
):
3993 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3994 self
.val_name
= val_name
3995 ectx
.eth_dep_add(ident
, self
.val_name
)
3997 def eth_reg_sub(self
, ident
, ectx
):
3998 self
.val_name
= ident
+ '/' + UNTAG_TYPE_NAME
3999 self
.val
.eth_reg(self
.val_name
, ectx
, tstrip
=self
.tstrip
+1, tagflag
=True, parent
=ident
)
4001 def GetTTag(self
, ectx
):
4002 #print "GetTTag(%s)\n" % self.seltype;
4003 return self
.GetTag(ectx
)
4005 def eth_ftype(self
, ectx
):
4006 return self
.val
.eth_ftype(ectx
)
4008 def eth_type_default_pars(self
, ectx
, tname
):
4009 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4010 t
= ectx
.type[self
.val_name
]['ethname']
4011 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
4012 pars
['TYPE_REF_TNAME'] = t
4013 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4014 (pars
['TAG_CLS'], pars
['TAG_TAG']) = self
.GetTag(ectx
)
4015 if self
.HasImplicitTag(ectx
):
4016 pars
['TAG_IMPL'] = 'true'
4018 pars
['TAG_IMPL'] = 'false'
4021 def eth_type_default_body(self
, ectx
, tname
):
4023 body
= ectx
.eth_fn_call('dissect_%(ER)s_tagged_type', ret
='offset',
4024 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4025 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
4027 body
= '#error Can not decode tagged_type %s' % (tname
)
4030 #--- SqType -----------------------------------------------------------
4031 class SqType (Type
):
4032 def out_item(self
, f
, val
, optional
, ext
, ectx
):
4033 if (val
.eth_omit_field()):
4034 t
= ectx
.type[val
.ident
]['ethname']
4035 fullname
= ectx
.dummy_eag_field
4037 ef
= ectx
.field
[f
]['ethname']
4038 t
= ectx
.eth_hf
[ef
]['ethtype']
4039 fullname
= ectx
.eth_hf
[ef
]['fullname']
4041 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
4042 #print val.str_depth(1)
4045 opt
= 'BER_FLAGS_OPTIONAL'
4046 if (not val
.HasOwnTag()):
4047 if (opt
): opt
+= '|'
4048 opt
+= 'BER_FLAGS_NOOWNTAG'
4049 elif (val
.HasImplicitTag(ectx
)):
4050 if (opt
): opt
+= '|'
4051 opt
+= 'BER_FLAGS_IMPLTAG'
4052 if (val
.IndetermTag(ectx
)):
4053 if (opt
): opt
+= '|'
4054 opt
+= 'BER_FLAGS_NOTCHKTAG'
4055 if (not opt
): opt
= '0'
4058 opt
= 'ASN1_OPTIONAL'
4060 opt
= 'ASN1_NOT_OPTIONAL'
4062 (tc
, tn
) = val
.GetTag(ectx
)
4063 out
= ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4064 % ('&'+fullname
, tc
, tn
, opt
, ectx
.eth_type
[t
]['proto'], t
)
4065 elif (ectx
.Per() or ectx
.Oer()):
4066 out
= ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
4067 % ('&'+fullname
, ext
, opt
, ectx
.eth_type
[t
]['proto'], t
)
4072 #--- SeqType -----------------------------------------------------------
4073 class SeqType (SqType
):
4075 def all_components(self
):
4076 lst
= self
.elt_list
[:]
4077 if hasattr(self
, 'ext_list'):
4078 lst
.extend(self
.ext_list
)
4079 if hasattr(self
, 'elt_list2'):
4080 lst
.extend(self
.elt_list2
)
4083 def need_components(self
):
4084 lst
= self
.all_components()
4086 if e
.type == 'components_of':
4090 def expand_components(self
, ectx
):
4091 while self
.need_components():
4092 for i
in range(len(self
.elt_list
)):
4093 if self
.elt_list
[i
].type == 'components_of':
4094 comp
= self
.elt_list
[i
].typ
.get_components(ectx
)
4095 self
.elt_list
[i
:i
+1] = comp
4097 if hasattr(self
, 'ext_list'):
4098 for i
in range(len(self
.ext_list
)):
4099 if self
.ext_list
[i
].type == 'components_of':
4100 comp
= self
.ext_list
[i
].typ
.get_components(ectx
)
4101 self
.ext_list
[i
:i
+1] = comp
4103 if hasattr(self
, 'elt_list2'):
4104 for i
in range(len(self
.elt_list2
)):
4105 if self
.elt_list2
[i
].type == 'components_of':
4106 comp
= self
.elt_list2
[i
].typ
.get_components(ectx
)
4107 self
.elt_list2
[i
:i
+1] = comp
4110 def get_components(self
, ectx
):
4111 lst
= self
.elt_list
[:]
4112 if hasattr(self
, 'elt_list2'):
4113 lst
.extend(self
.elt_list2
)
4116 def eth_reg_sub(self
, ident
, ectx
, components_available
=False):
4117 # check if autotag is required
4119 if (ectx
.NeedTags() and (ectx
.tag_def
== 'AUTOMATIC')):
4121 lst
= self
.all_components()
4122 for e
in (self
.elt_list
):
4123 if e
.val
.HasOwnTag(): autotag
= False
4125 # expand COMPONENTS OF
4126 if self
.need_components():
4127 if components_available
:
4128 self
.expand_components(ectx
)
4130 ectx
.eth_comp_req(ident
)
4132 # extension addition groups
4133 if hasattr(self
, 'ext_list'):
4134 if (ectx
.Per() or ectx
.Oer()): # add names
4136 for e
in (self
.ext_list
):
4137 if isinstance(e
.val
, ExtensionAdditionGroup
):
4138 e
.val
.parent_ident
= ident
4139 e
.val
.parent_tname
= ectx
.type[ident
]['tname']
4141 e
.val
.SetName("eag_v%s" % (e
.val
.ver
))
4143 e
.val
.SetName("eag_%d" % (eag_num
))
4147 for e
in (self
.ext_list
):
4148 if isinstance(e
.val
, ExtensionAdditionGroup
):
4149 new_ext_list
.extend(e
.val
.elt_list
)
4151 new_ext_list
.append(e
)
4152 self
.ext_list
= new_ext_list
4156 for e
in (self
.elt_list
):
4157 e
.val
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4159 if autotag
and hasattr(self
, 'elt_list2'):
4160 for e
in (self
.elt_list2
):
4161 e
.val
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4163 if autotag
and hasattr(self
, 'ext_list'):
4164 for e
in (self
.ext_list
):
4165 e
.val
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4167 # register components
4168 for e
in (self
.elt_list
):
4169 e
.val
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4170 if hasattr(self
, 'ext_list'):
4171 for e
in (self
.ext_list
):
4172 e
.val
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4173 if hasattr(self
, 'elt_list2'):
4174 for e
in (self
.elt_list2
):
4175 e
.val
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4177 def eth_type_default_table(self
, ectx
, tname
):
4178 #print ("eth_type_default_table(tname='%s')" % (tname))
4179 fname
= ectx
.eth_type
[tname
]['ref'][0]
4180 table
= "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
4181 if hasattr(self
, 'ext_list'):
4182 ext
= 'ASN1_EXTENSION_ROOT'
4184 ext
= 'ASN1_NO_EXTENSIONS'
4185 empty_ext_flag
= '0'
4186 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)):
4187 empty_ext_flag
= ext
4188 for e
in (self
.elt_list
):
4189 f
= fname
+ '/' + e
.val
.name
4190 table
+= self
.out_item(f
, e
.val
, e
.optional
, ext
, ectx
)
4191 if hasattr(self
, 'ext_list'):
4192 for e
in (self
.ext_list
):
4193 f
= fname
+ '/' + e
.val
.name
4194 table
+= self
.out_item(f
, e
.val
, e
.optional
, 'ASN1_NOT_EXTENSION_ROOT', ectx
)
4195 if hasattr(self
, 'elt_list2'):
4196 for e
in (self
.elt_list2
):
4197 f
= fname
+ '/' + e
.val
.name
4198 table
+= self
.out_item(f
, e
.val
, e
.optional
, ext
, ectx
)
4200 table
+= " { NULL, 0, 0, 0, NULL }\n};\n"
4202 table
+= " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag
)
4205 #--- SeqOfType -----------------------------------------------------------
4206 class SeqOfType (SqType
):
4207 def eth_type_default_table(self
, ectx
, tname
):
4208 #print "eth_type_default_table(tname='%s')" % (tname)
4209 fname
= ectx
.eth_type
[tname
]['ref'][0]
4210 if self
.val
.IsNamed ():
4211 f
= fname
+ '/' + self
.val
.name
4213 f
= fname
+ '/' + ITEM_FIELD_NAME
4214 table
= "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
4215 table
+= self
.out_item(f
, self
.val
, False, 'ASN1_NO_EXTENSIONS', ectx
)
4219 #--- SequenceOfType -----------------------------------------------------------
4220 class SequenceOfType (SeqOfType
):
4221 def to_python (self
, ctx
):
4222 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4223 # or '' + (1,) for optional
4225 if self
.size_constr
is not None:
4226 print("#Ignoring size constraint:", self
.size_constr
.subtype
)
4227 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx
.spaces (),
4228 self
.val
.to_python (ctx
),
4231 def eth_reg_sub(self
, ident
, ectx
):
4233 if not self
.val
.IsNamed ():
4234 itmnm
+= '/' + ITEM_FIELD_NAME
4235 self
.val
.eth_reg(itmnm
, ectx
, tstrip
=1, idx
='[##]', parent
=ident
)
4237 def eth_tname(self
):
4238 if self
.val
.type != 'Type_Ref':
4239 return '#' + self
.type + '_' + str(id(self
))
4240 if not self
.HasConstraint():
4241 return "SEQUENCE_OF_" + self
.val
.eth_tname()
4242 elif self
.constr
.IsSize():
4243 return 'SEQUENCE_' + self
.constr
.eth_constrname() + '_OF_' + self
.val
.eth_tname()
4245 return '#' + self
.type + '_' + str(id(self
))
4247 def eth_ftype(self
, ectx
):
4248 return ('FT_UINT32', 'BASE_DEC')
4250 def eth_need_tree(self
):
4253 def GetTTag(self
, ectx
):
4254 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4256 def eth_type_default_pars(self
, ectx
, tname
):
4257 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4258 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
4259 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
4262 def eth_type_default_body(self
, ectx
, tname
):
4264 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
4265 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret
='offset',
4266 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4267 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4269 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence_of', ret
='offset',
4270 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4271 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4272 elif ((ectx
.Per() or ectx
.Oer()) and not self
.HasConstraint()):
4273 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence_of', ret
='offset',
4274 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4275 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4276 elif ((ectx
.Per() or ectx
.Oer()) and self
.constr
.type == 'Size'):
4277 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret
='offset',
4278 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4279 ('%(ETT_INDEX)s', '%(TABLE)s',),
4280 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
4282 body
= '#error Can not decode SequenceOfType %s' % (tname
)
4286 #--- SetOfType ----------------------------------------------------------------
4287 class SetOfType (SeqOfType
):
4288 def eth_reg_sub(self
, ident
, ectx
):
4290 if not self
.val
.IsNamed ():
4291 itmnm
+= '/' + ITEM_FIELD_NAME
4292 self
.val
.eth_reg(itmnm
, ectx
, tstrip
=1, idx
='(##)', parent
=ident
)
4294 def eth_tname(self
):
4295 if self
.val
.type != 'Type_Ref':
4296 return '#' + self
.type + '_' + str(id(self
))
4297 if not self
.HasConstraint():
4298 return "SET_OF_" + self
.val
.eth_tname()
4299 elif self
.constr
.IsSize():
4300 return 'SET_' + self
.constr
.eth_constrname() + '_OF_' + self
.val
.eth_tname()
4302 return '#' + self
.type + '_' + str(id(self
))
4304 def eth_ftype(self
, ectx
):
4305 return ('FT_UINT32', 'BASE_DEC')
4307 def eth_need_tree(self
):
4310 def GetTTag(self
, ectx
):
4311 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4313 def eth_type_default_pars(self
, ectx
, tname
):
4314 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4315 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
4316 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
4319 def eth_type_default_body(self
, ectx
, tname
):
4321 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
4322 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret
='offset',
4323 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4324 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4326 body
= ectx
.eth_fn_call('dissect_%(ER)s_set_of', ret
='offset',
4327 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4328 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4329 elif (ectx
.Per() and not self
.HasConstraint()):
4330 body
= ectx
.eth_fn_call('dissect_%(ER)s_set_of', ret
='offset',
4331 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4332 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4333 elif (ectx
.Per() and self
.constr
.type == 'Size'):
4334 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret
='offset',
4335 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4336 ('%(ETT_INDEX)s', '%(TABLE)s',),
4337 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
4339 body
= '#error Can not decode SetOfType %s' % (tname
)
4342 def mk_tag_str (ctx
, cls
, typ
, num
):
4344 # XXX should do conversion to int earlier!
4347 if typ
== 'DEFAULT':
4349 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ
, val
, cls
) # XXX still ned
4351 #--- SequenceType -------------------------------------------------------------
4352 class SequenceType (SeqType
):
4353 def to_python (self
, ctx
):
4354 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4355 # or '' + (1,) for optional
4356 # XXX should also collect names for SEQUENCE inside SEQUENCE or
4357 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
4358 # from? for others, element or arm name would be fine)
4359 seq_name
= getattr (self
, 'sequence_name', None)
4360 if seq_name
is None:
4363 seq_name
= "'" + seq_name
+ "'"
4364 if 'ext_list' in self
.__dict
__:
4365 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx
.spaces (),
4366 self
.elts_to_py (self
.elt_list
, ctx
),
4367 self
.elts_to_py (self
.ext_list
, ctx
), seq_name
)
4369 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx
.spaces (),
4370 self
.elts_to_py (self
.elt_list
, ctx
), seq_name
)
4371 def elts_to_py (self
, list, ctx
):
4372 # we have elt_type, val= named_type, maybe default=, optional=
4373 # named_type node: either ident = or typ =
4374 # need to dismember these in order to generate Python output syntax.
4377 assert (e
.type == 'elt_type')
4379 optflag
= e
.optional
4380 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
4381 assert (nt
.type == 'named_type')
4384 if hasattr (nt
.typ
, 'type') and nt
.typ
.type == 'tag': # ugh
4385 tagstr
= mk_tag_str (ctx
,nt
.typ
.tag
.cls
,
4386 nt
.typ
.tag
.tag_typ
,nt
.typ
.tag
.num
)
4390 return "('%s',%s,%s,%d)" % (identstr
, tagstr
,
4391 nt
.typ
.to_python (ctx
), optflag
)
4392 indentstr
= ",\n" + ctx
.spaces ()
4393 rv
= indentstr
.join ([elt_to_py (e
) for e
in list])
4397 def eth_need_tree(self
):
4400 def GetTTag(self
, ectx
):
4401 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4403 def eth_type_default_pars(self
, ectx
, tname
):
4404 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4405 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4408 def eth_type_default_body(self
, ectx
, tname
):
4410 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence', ret
='offset',
4411 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4412 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4413 elif (ectx
.Per() or ectx
.Oer()):
4414 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence', ret
='offset',
4415 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4416 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4418 body
= '#error Can not decode SequenceType %s' % (tname
)
4421 #--- ExtensionAdditionGroup ---------------------------------------------------
4422 class ExtensionAdditionGroup (SeqType
):
4423 def __init__(self
,*args
, **kw
) :
4424 self
.parent_ident
= None
4425 self
.parent_tname
= None
4426 SeqType
.__init
__ (self
,*args
, **kw
)
4428 def eth_omit_field(self
):
4431 def eth_tname(self
):
4432 if (self
.parent_tname
and self
.IsNamed()):
4433 return self
.parent_tname
+ "_" + self
.name
4435 return SeqType
.eth_tname(self
)
4437 def eth_reg_sub(self
, ident
, ectx
):
4438 ectx
.eth_dummy_eag_field_required()
4439 ectx
.eth_dep_add(self
.parent_ident
, ident
)
4440 SeqType
.eth_reg_sub(self
, ident
, ectx
)
4442 def eth_type_default_pars(self
, ectx
, tname
):
4443 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4444 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4447 def eth_type_default_body(self
, ectx
, tname
):
4449 body
= ectx
.eth_fn_call('dissect_%(ER)s_sequence_eag', ret
='offset',
4450 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
4452 body
= '#error Can not decode ExtensionAdditionGroup %s' % (tname
)
4456 #--- SetType ------------------------------------------------------------------
4457 class SetType (SeqType
):
4459 def eth_need_tree(self
):
4462 def GetTTag(self
, ectx
):
4463 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4465 def eth_type_default_pars(self
, ectx
, tname
):
4466 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4467 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4470 def eth_type_default_body(self
, ectx
, tname
):
4472 body
= ectx
.eth_fn_call('dissect_%(ER)s_set', ret
='offset',
4473 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4474 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4476 body
= ectx
.eth_fn_call('dissect_%(ER)s_set', ret
='offset',
4477 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4478 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4480 body
= '#error Can not decode SetType %s' % (tname
)
4483 #--- ChoiceType ---------------------------------------------------------------
4484 class ChoiceType (Type
):
4485 def to_python (self
, ctx
):
4486 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4487 # or '' + (1,) for optional
4488 if 'ext_list' in self
.__dict
__:
4489 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx
.spaces (),
4490 self
.elts_to_py (self
.elt_list
, ctx
),
4491 self
.elts_to_py (self
.ext_list
, ctx
))
4493 return "%sasn1.CHOICE ([%s])" % (ctx
.spaces (), self
.elts_to_py (self
.elt_list
, ctx
))
4494 def elts_to_py (self
, list, ctx
):
4497 assert (nt
.type == 'named_type')
4499 if hasattr (nt
, 'ident'):
4502 if hasattr (nt
.typ
, 'val'):
4503 identstr
= nt
.typ
.val
# XXX, making up name
4504 elif hasattr (nt
.typ
, 'name'):
4505 identstr
= nt
.typ
.name
4507 identstr
= ctx
.make_new_name ()
4509 if hasattr (nt
.typ
, 'type') and nt
.typ
.type == 'tag': # ugh
4510 tagstr
= mk_tag_str (ctx
,nt
.typ
.tag
.cls
,
4511 nt
.typ
.tag
.tag_typ
,nt
.typ
.tag
.num
)
4515 return "('%s',%s,%s)" % (identstr
, tagstr
,
4516 nt
.typ
.to_python (ctx
))
4517 indentstr
= ",\n" + ctx
.spaces ()
4518 rv
= indentstr
.join ([elt_to_py (e
) for e
in list])
4522 def eth_reg_sub(self
, ident
, ectx
):
4523 #print "eth_reg_sub(ident='%s')" % (ident)
4524 # check if autotag is required
4526 if (ectx
.NeedTags() and (ectx
.tag_def
== 'AUTOMATIC')):
4528 for e
in (self
.elt_list
):
4529 if e
.HasOwnTag(): autotag
= False; break
4530 if autotag
and hasattr(self
, 'ext_list'):
4531 for e
in (self
.ext_list
):
4532 if e
.HasOwnTag(): autotag
= False; break
4536 for e
in (self
.elt_list
):
4537 e
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4539 if autotag
and hasattr(self
, 'ext_list'):
4540 for e
in (self
.ext_list
):
4541 e
.AddTag(Tag(cls
= 'CONTEXT', num
= str(atag
), mode
= 'IMPLICIT'))
4543 for e
in (self
.elt_list
):
4544 e
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4545 if ectx
.conform
.check_item('EXPORTS', ident
+ '.' + e
.name
):
4546 ectx
.eth_sel_req(ident
, e
.name
)
4547 if hasattr(self
, 'ext_list'):
4548 for e
in (self
.ext_list
):
4549 e
.eth_reg(ident
, ectx
, tstrip
=1, parent
=ident
)
4550 if ectx
.conform
.check_item('EXPORTS', ident
+ '.' + e
.name
):
4551 ectx
.eth_sel_req(ident
, e
.name
)
4553 def sel_item(self
, ident
, sel
, ectx
):
4554 lst
= self
.elt_list
[:]
4555 if hasattr(self
, 'ext_list'):
4556 lst
.extend(self
.ext_list
)
4558 for e
in (self
.elt_list
):
4559 if e
.IsNamed() and (e
.name
== sel
):
4563 print("#CHOICE %s does not contain item %s" % (ident
, sel
))
4566 def sel_req(self
, ident
, sel
, ectx
):
4567 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4568 ee
= self
.sel_item(ident
, sel
, ectx
)
4570 ee
.eth_reg(ident
, ectx
, tstrip
=0, selflag
=True)
4572 def eth_ftype(self
, ectx
):
4573 return ('FT_UINT32', 'BASE_DEC')
4575 def eth_ftype_sel(self
, sel
, ectx
):
4576 ee
= self
.sel_item('', sel
, ectx
)
4578 return ee
.eth_ftype(ectx
)
4580 return ('FT_NONE', 'BASE_NONE')
4582 def eth_strings(self
):
4585 def eth_need_tree(self
):
4588 def eth_has_vals(self
):
4591 def GetTTag(self
, ectx
):
4593 cls
= 'BER_CLASS_ANY/*choice*/'
4594 #if hasattr(self, 'ext_list'):
4595 # lst.extend(self.ext_list)
4597 # cls = lst[0].GetTag(ectx)[0]
4599 # if (e.GetTag(ectx)[0] != cls):
4600 # cls = '-1/*choice*/'
4601 return (cls
, '-1/*choice*/')
4603 def GetTTagSel(self
, sel
, ectx
):
4604 ee
= self
.sel_item('', sel
, ectx
)
4606 return ee
.GetTag(ectx
)
4608 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4610 def IndetermTag(self
, ectx
):
4611 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4612 return not self
.HasOwnTag()
4614 def detect_tagval(self
, ectx
):
4615 '''Returns True if the tag numbers are used as the tree values.
4616 Returns False if we assign our own tree values for each choice.
4619 lst
= self
.elt_list
[:]
4620 if hasattr(self
, 'ext_list'):
4621 lst
.extend(self
.ext_list
)
4622 if (len(lst
) > 0) and (not (ectx
.Per() or ectx
.Oer()) or lst
[0].HasOwnTag()):
4623 t
= lst
[0].GetTag(ectx
)[0]
4628 if (t
== 'BER_CLASS_UNI'):
4629 # Don't use universal tags
4631 if t
== 'BER_CLASS_ANY/*choice*/':
4632 # Don't use -1 tags that refer to another level of CHOICE
4635 if not (ectx
.Per() or ectx
.Oer()) or e
.HasOwnTag():
4636 tt
= e
.GetTag(ectx
)[0]
4644 def get_vals(self
, ectx
):
4645 tagval
= self
.detect_tagval(ectx
)
4648 for e
in (self
.elt_list
):
4649 if (tagval
): val
= e
.GetTag(ectx
)[1]
4650 else: val
= str(cnt
)
4651 vals
.append((val
, e
.name
))
4653 if hasattr(self
, 'ext_list'):
4654 for e
in (self
.ext_list
):
4655 if (tagval
): val
= e
.GetTag(ectx
)[1]
4656 else: val
= str(cnt
)
4657 vals
.append((val
, e
.name
))
4661 def eth_type_vals(self
, tname
, ectx
):
4663 vals
= self
.get_vals(ectx
)
4664 out
+= ectx
.eth_vals(tname
, vals
)
4667 def reg_enum_vals(self
, tname
, ectx
):
4668 vals
= self
.get_vals(ectx
)
4669 for (val
, id) in vals
:
4670 ectx
.eth_reg_value(id, self
, val
, ethname
=ectx
.eth_enum_item(tname
, id))
4672 def eth_type_enum(self
, tname
, ectx
):
4674 vals
= self
.get_vals(ectx
)
4675 out
+= ectx
.eth_enum(tname
, vals
)
4678 def eth_type_default_pars(self
, ectx
, tname
):
4679 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4680 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4683 def eth_type_default_table(self
, ectx
, tname
):
4684 def out_item(val
, e
, ext
, ectx
):
4685 has_enum
= ectx
.eth_type
[tname
]['enum'] & EF_ENUM
4687 vval
= ectx
.eth_enum_item(tname
, e
.name
)
4690 f
= fname
+ '/' + e
.name
4691 ef
= ectx
.field
[f
]['ethname']
4692 t
= ectx
.eth_hf
[ef
]['ethtype']
4695 if (not e
.HasOwnTag()):
4696 opt
= 'BER_FLAGS_NOOWNTAG'
4697 elif (e
.HasImplicitTag(ectx
)):
4698 if (opt
): opt
+= '|'
4699 opt
+= 'BER_FLAGS_IMPLTAG'
4700 if (not opt
): opt
= '0'
4702 (tc
, tn
) = e
.GetTag(ectx
)
4703 out
= ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4704 % (vval
, '&'+ectx
.eth_hf
[ef
]['fullname'], tc
, tn
, opt
, ectx
.eth_type
[t
]['proto'], t
)
4705 elif (ectx
.Per() or ectx
.Oer()):
4706 out
= ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4707 % (vval
, '&'+ectx
.eth_hf
[ef
]['fullname'], ext
, ectx
.eth_type
[t
]['proto'], t
)
4712 #print "eth_type_default_table(tname='%s')" % (tname)
4713 fname
= ectx
.eth_type
[tname
]['ref'][0]
4714 tagval
= self
.detect_tagval(ectx
)
4715 table
= "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4717 if hasattr(self
, 'ext_list'):
4718 ext
= 'ASN1_EXTENSION_ROOT'
4720 ext
= 'ASN1_NO_EXTENSIONS'
4721 empty_ext_flag
= '0'
4722 if (len(self
.elt_list
)==0) and hasattr(self
, 'ext_list') and (len(self
.ext_list
)==0):
4723 empty_ext_flag
= ext
4724 for e
in (self
.elt_list
):
4725 if (tagval
): val
= e
.GetTag(ectx
)[1]
4726 else: val
= str(cnt
)
4727 table
+= out_item(val
, e
, ext
, ectx
)
4729 if hasattr(self
, 'ext_list'):
4730 for e
in (self
.ext_list
):
4731 if (tagval
): val
= e
.GetTag(ectx
)[1]
4732 else: val
= str(cnt
)
4733 table
+= out_item(val
, e
, 'ASN1_NOT_EXTENSION_ROOT', ectx
)
4736 table
+= " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4738 table
+= " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag
)
4741 def eth_type_default_body(self
, ectx
, tname
):
4743 body
= ectx
.eth_fn_call('dissect_%(ER)s_choice', ret
='offset',
4744 par
=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4745 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4747 elif (ectx
.Per() or ectx
.Oer()):
4748 body
= ectx
.eth_fn_call('dissect_%(ER)s_choice', ret
='offset',
4749 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4750 ('%(ETT_INDEX)s', '%(TABLE)s',),
4753 body
= '#error Can not decode ChoiceType %s' % (tname
)
4756 #--- ChoiceValue ----------------------------------------------------
4757 class ChoiceValue (Value
):
4758 def to_str(self
, ectx
):
4759 return self
.val
.to_str(ectx
)
4761 def fld_obj_eq(self
, other
):
4762 return isinstance(other
, ChoiceValue
) and (self
.choice
== other
.choice
) and (str(self
.val
.val
) == str(other
.val
.val
))
4764 #--- EnumeratedType -----------------------------------------------------------
4765 class EnumeratedType (Type
):
4766 def to_python (self
, ctx
):
4767 def strify_one (named_num
):
4768 return "%s=%s" % (named_num
.ident
, named_num
.val
)
4769 return "asn1.ENUM(%s)" % ",".join (map (strify_one
, self
.val
))
4771 def eth_ftype(self
, ectx
):
4772 return ('FT_UINT32', 'BASE_DEC')
4774 def eth_strings(self
):
4777 def eth_has_vals(self
):
4780 def GetTTag(self
, ectx
):
4781 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4783 def get_vals_etc(self
, ectx
):
4791 for e
in (self
.val
):
4792 if e
.type == 'NamedNumber':
4793 used
[int(e
.val
)] = True
4794 for e
in (self
.val
):
4795 if e
.type == 'NamedNumber':
4798 while lastv
in used
:
4802 vals
.append((val
, e
.ident
))
4803 map_table
.append(val
)
4807 if self
.ext
is not None:
4808 for e
in (self
.ext
):
4809 if e
.type == 'NamedNumber':
4810 used
[int(e
.val
)] = True
4811 for e
in (self
.ext
):
4812 if e
.type == 'NamedNumber':
4815 while lastv
in used
:
4819 vals
.append((val
, e
.ident
))
4820 map_table
.append(val
)
4825 for i
in range(len(map_table
)):
4826 need_map
= need_map
or (map_table
[i
] != i
)
4829 return (vals
, root_num
, ext_num
, map_table
)
4831 def eth_type_vals(self
, tname
, ectx
):
4833 vals
= self
.get_vals_etc(ectx
)[0]
4834 out
+= ectx
.eth_vals(tname
, vals
)
4837 def reg_enum_vals(self
, tname
, ectx
):
4838 vals
= self
.get_vals_etc(ectx
)[0]
4839 for (val
, id) in vals
:
4840 ectx
.eth_reg_value(id, self
, val
, ethname
=ectx
.eth_enum_item(tname
, id))
4842 def eth_type_enum(self
, tname
, ectx
):
4844 vals
= self
.get_vals_etc(ectx
)[0]
4845 out
+= ectx
.eth_enum(tname
, vals
)
4848 def eth_type_default_pars(self
, ectx
, tname
):
4849 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4850 (root_num
, ext_num
, map_table
) = self
.get_vals_etc(ectx
)[1:]
4851 if self
.ext
is not None:
4855 pars
['ROOT_NUM'] = str(root_num
)
4857 pars
['EXT_NUM'] = str(ext_num
)
4859 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4861 pars
['TABLE'] = 'NULL'
4864 def eth_type_default_table(self
, ectx
, tname
):
4865 if (not ectx
.Per() and not ectx
.Oer()): return ''
4866 map_table
= self
.get_vals_etc(ectx
)[3]
4867 if map_table
is None: return ''
4868 table
= "static uint32_t %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4869 table
+= ", ".join([str(v
) for v
in map_table
])
4873 def eth_type_default_body(self
, ectx
, tname
):
4875 if (ectx
.constraints_check
and self
.HasValueConstraint()):
4876 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer', ret
='offset',
4877 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4878 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4880 body
= ectx
.eth_fn_call('dissect_%(ER)s_integer', ret
='offset',
4881 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4883 elif (ectx
.Per() or ectx
.Oer()):
4884 body
= ectx
.eth_fn_call('dissect_%(ER)s_enumerated', ret
='offset',
4885 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4886 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4888 body
= '#error Can not decode EnumeratedType %s' % (tname
)
4891 #--- EmbeddedPDVType -----------------------------------------------------------
4892 class EmbeddedPDVType (Type
):
4893 def eth_tname(self
):
4894 return 'EMBEDDED_PDV'
4896 def eth_ftype(self
, ectx
):
4897 return ('FT_NONE', 'BASE_NONE')
4899 def GetTTag(self
, ectx
):
4900 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4902 def eth_type_default_pars(self
, ectx
, tname
):
4903 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4904 if ectx
.default_embedded_pdv_cb
:
4905 pars
['TYPE_REF_FN'] = ectx
.default_embedded_pdv_cb
4907 pars
['TYPE_REF_FN'] = 'NULL'
4910 def eth_type_default_body(self
, ectx
, tname
):
4912 body
= ectx
.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret
='offset',
4913 par
=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4915 body
= ectx
.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret
='offset',
4916 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4918 body
= '#error Can not decode EmbeddedPDVType %s' % (tname
)
4921 #--- ExternalType -----------------------------------------------------------
4922 class ExternalType (Type
):
4923 def eth_tname(self
):
4926 def eth_ftype(self
, ectx
):
4927 return ('FT_NONE', 'BASE_NONE')
4929 def GetTTag(self
, ectx
):
4930 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4932 def eth_type_default_pars(self
, ectx
, tname
):
4933 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4934 if ectx
.default_external_type_cb
:
4935 pars
['TYPE_REF_FN'] = ectx
.default_external_type_cb
4937 pars
['TYPE_REF_FN'] = 'NULL'
4940 def eth_type_default_body(self
, ectx
, tname
):
4942 body
= ectx
.eth_fn_call('dissect_%(ER)s_external_type', ret
='offset',
4943 par
=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4945 body
= ectx
.eth_fn_call('dissect_%(ER)s_external_type', ret
='offset',
4946 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4948 body
= '#error Can not decode ExternalType %s' % (tname
)
4951 #--- OpenType -----------------------------------------------------------
4952 class OpenType (Type
):
4953 def to_python (self
, ctx
):
4956 def single_type(self
):
4957 if (self
.HasConstraint() and
4958 self
.constr
.type == 'Type' and
4959 self
.constr
.subtype
.type == 'Type_Ref'):
4960 return self
.constr
.subtype
.val
4963 def eth_reg_sub(self
, ident
, ectx
):
4964 t
= self
.single_type()
4966 ectx
.eth_dep_add(ident
, t
)
4968 def eth_tname(self
):
4969 t
= self
.single_type()
4971 return 'OpenType_' + t
4973 return Type
.eth_tname(self
)
4975 def eth_ftype(self
, ectx
):
4976 return ('FT_NONE', 'BASE_NONE')
4978 def GetTTag(self
, ectx
):
4979 return ('BER_CLASS_ANY', '0')
4981 def eth_type_default_pars(self
, ectx
, tname
):
4982 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
4983 pars
['FN_VARIANT'] = ectx
.default_opentype_variant
4984 t
= self
.single_type()
4986 t
= ectx
.type[t
]['ethname']
4987 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
4988 pars
['TYPE_REF_TNAME'] = t
4989 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4991 pars
['TYPE_REF_FN'] = 'NULL'
4994 def eth_type_default_body(self
, ectx
, tname
):
4995 if (ectx
.Per() or ectx
.Oer()):
4996 body
= ectx
.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret
='offset',
4997 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4999 body
= '#error Can not decode OpenType %s' % (tname
)
5002 #--- InstanceOfType -----------------------------------------------------------
5003 class InstanceOfType (Type
):
5004 def eth_tname(self
):
5005 return 'INSTANCE_OF'
5007 def eth_ftype(self
, ectx
):
5008 return ('FT_NONE', 'BASE_NONE')
5010 def GetTTag(self
, ectx
):
5011 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
5013 def eth_type_default_pars(self
, ectx
, tname
):
5014 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5015 if ectx
.default_external_type_cb
:
5016 pars
['TYPE_REF_FN'] = ectx
.default_external_type_cb
5018 pars
['TYPE_REF_FN'] = 'NULL'
5021 def eth_type_default_body(self
, ectx
, tname
):
5023 body
= ectx
.eth_fn_call('dissect_%(ER)s_external_type', ret
='offset',
5024 par
=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
5026 body
= '#error Can not decode %s' % (tname
)
5029 #--- AnyType -----------------------------------------------------------
5030 class AnyType (Type
):
5031 def to_python (self
, ctx
):
5034 def eth_ftype(self
, ectx
):
5035 return ('FT_NONE', 'BASE_NONE')
5037 def GetTTag(self
, ectx
):
5038 return ('BER_CLASS_ANY', '0')
5040 def eth_type_default_body(self
, ectx
, tname
):
5041 body
= '#error Can not decode %s' % (tname
)
5044 class Literal (Node
):
5045 def to_python (self
, ctx
):
5048 #--- NullType -----------------------------------------------------------------
5049 class NullType (Type
):
5050 def to_python (self
, ctx
):
5053 def eth_tname(self
):
5056 def GetTTag(self
, ectx
):
5057 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
5059 def eth_type_default_body(self
, ectx
, tname
):
5061 body
= ectx
.eth_fn_call('dissect_%(ER)s_null', ret
='offset',
5062 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5063 elif (ectx
.Per() or ectx
.Oer()):
5064 body
= ectx
.eth_fn_call('dissect_%(ER)s_null', ret
='offset',
5065 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5067 body
= '#error Can not decode %s' % (tname
)
5070 #--- NullValue ----------------------------------------------------
5071 class NullValue (Value
):
5072 def to_str(self
, ectx
):
5075 #--- RealType -----------------------------------------------------------------
5076 class RealType (Type
):
5077 def to_python (self
, ctx
):
5080 def eth_tname(self
):
5083 def GetTTag(self
, ectx
):
5084 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
5086 def eth_ftype(self
, ectx
):
5087 return ('FT_DOUBLE', 'BASE_NONE')
5089 def eth_type_default_body(self
, ectx
, tname
):
5091 body
= ectx
.eth_fn_call('dissect_%(ER)s_real', ret
='offset',
5092 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5095 body
= ectx
.eth_fn_call('dissect_%(ER)s_real', ret
='offset',
5096 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5098 body
= '#error Can not decode %s' % (tname
)
5101 #--- BooleanType --------------------------------------------------------------
5102 class BooleanType (Type
):
5103 def to_python (self
, ctx
):
5104 return 'asn1.BOOLEAN'
5106 def eth_tname(self
):
5109 def GetTTag(self
, ectx
):
5110 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
5112 def eth_ftype(self
, ectx
):
5113 return ('FT_BOOLEAN', 'BASE_NONE')
5115 def eth_type_default_body(self
, ectx
, tname
):
5117 body
= ectx
.eth_fn_call('dissect_%(ER)s_boolean', ret
='offset',
5118 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5120 body
= ectx
.eth_fn_call('dissect_%(ER)s_boolean', ret
='offset',
5121 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5123 body
= ectx
.eth_fn_call('dissect_%(ER)s_boolean', ret
='offset',
5124 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5126 body
= '#error Can not decode %s' % (tname
)
5129 #--- OctetStringType ----------------------------------------------------------
5130 class OctetStringType (Type
):
5131 def to_python (self
, ctx
):
5132 return 'asn1.OCTSTRING'
5134 def eth_tname(self
):
5135 if not self
.HasConstraint():
5136 return 'OCTET_STRING'
5137 elif self
.constr
.type == 'Size':
5138 return 'OCTET_STRING' + '_' + self
.constr
.eth_constrname()
5140 return '#' + self
.type + '_' + str(id(self
))
5142 def eth_ftype(self
, ectx
):
5143 return ('FT_BYTES', 'BASE_NONE')
5145 def GetTTag(self
, ectx
):
5146 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
5148 def eth_need_pdu(self
, ectx
):
5150 if self
.HasContentsConstraint():
5151 t
= self
.constr
.GetContents(ectx
)
5152 if t
and (ectx
.default_containing_variant
in ('_pdu', '_pdu_new')):
5154 'new' : ectx
.default_containing_variant
== '_pdu_new' }
5157 def eth_type_default_pars(self
, ectx
, tname
):
5158 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5159 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
5160 if self
.HasContentsConstraint():
5161 pars
['FN_VARIANT'] = ectx
.default_containing_variant
5162 t
= self
.constr
.GetContents(ectx
)
5164 if pars
['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5165 t
= ectx
.field
[t
]['ethname']
5166 pars
['TYPE_REF_PROTO'] = ''
5167 pars
['TYPE_REF_TNAME'] = t
5168 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5170 t
= ectx
.type[t
]['ethname']
5171 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
5172 pars
['TYPE_REF_TNAME'] = t
5173 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5175 pars
['TYPE_REF_FN'] = 'NULL'
5178 def eth_type_default_body(self
, ectx
, tname
):
5180 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
5181 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret
='offset',
5182 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5183 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5185 body
= ectx
.eth_fn_call('dissect_%(ER)s_octet_string', ret
='offset',
5186 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5188 elif (ectx
.Per() or ectx
.Oer()):
5189 if self
.HasContentsConstraint():
5190 body
= ectx
.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret
='offset',
5191 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5192 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
5194 body
= ectx
.eth_fn_call('dissect_%(ER)s_octet_string', ret
='offset',
5195 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5196 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
5198 body
= '#error Can not decode %s' % (tname
)
5201 #--- CharacterStringType ------------------------------------------------------
5202 class CharacterStringType (Type
):
5203 def eth_tname(self
):
5204 if not self
.HasConstraint():
5205 return self
.eth_tsname()
5206 elif self
.constr
.type == 'Size':
5207 return self
.eth_tsname() + '_' + self
.constr
.eth_constrname()
5209 return '#' + self
.type + '_' + str(id(self
))
5211 def eth_ftype(self
, ectx
):
5212 return ('FT_STRING', 'BASE_NONE')
5214 class RestrictedCharacterStringType (CharacterStringType
):
5215 def to_python (self
, ctx
):
5216 return 'asn1.' + self
.eth_tsname()
5218 def GetTTag(self
, ectx
):
5219 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self
.eth_tsname())
5221 def eth_type_default_pars(self
, ectx
, tname
):
5222 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5223 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
5224 (pars
['STRING_TYPE'], pars
['STRING_TAG']) = (self
.eth_tsname(), self
.GetTTag(ectx
)[1])
5225 (pars
['ALPHABET'], pars
['ALPHABET_LEN']) = self
.eth_get_alphabet_constr(ectx
)
5228 def eth_type_default_body(self
, ectx
, tname
):
5230 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
5231 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret
='offset',
5232 par
=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5233 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5234 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5236 body
= ectx
.eth_fn_call('dissect_%(ER)s_restricted_string', ret
='offset',
5237 par
=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5238 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5240 elif (ectx
.Per() and self
.HasPermAlph() and self
.eth_tsname() in KnownMultiplierStringTypes
):
5241 # XXX: If there is a permitted alphabet but it is extensible,
5242 # then the permitted-alphabet is not PER-visible and should be
5243 # ignored. (X.691 9.3.10, 9.3.18) We don't handle extensible
5244 # permitted-alphabets.
5245 body
= ectx
.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret
='offset',
5246 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5247 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
5250 if (self
.eth_tsname() == 'GeneralString'):
5251 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5252 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5253 elif (self
.eth_tsname() == 'GeneralizedTime' or self
.eth_tsname() == 'UTCTime'):
5254 body
= ectx
.eth_fn_call('dissect_%(ER)s_VisibleString', ret
='offset',
5255 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5256 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s'),
5258 elif (self
.eth_tsname() in KnownMultiplierStringTypes
):
5259 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5260 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5261 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s'),
5264 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5265 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5266 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5268 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5269 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5270 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5272 body
= '#error Can not decode %s' % (tname
)
5275 class BMPStringType (RestrictedCharacterStringType
):
5276 def eth_tsname(self
):
5279 class GeneralStringType (RestrictedCharacterStringType
):
5280 def eth_tsname(self
):
5281 return 'GeneralString'
5283 class GraphicStringType (RestrictedCharacterStringType
):
5284 def eth_tsname(self
):
5285 return 'GraphicString'
5287 class IA5StringType (RestrictedCharacterStringType
):
5288 def eth_tsname(self
):
5291 class NumericStringType (RestrictedCharacterStringType
):
5292 def eth_tsname(self
):
5293 return 'NumericString'
5295 class PrintableStringType (RestrictedCharacterStringType
):
5296 def eth_tsname(self
):
5297 return 'PrintableString'
5299 class TeletexStringType (RestrictedCharacterStringType
):
5300 def eth_tsname(self
):
5301 return 'TeletexString'
5303 class T61StringType (RestrictedCharacterStringType
):
5304 def eth_tsname(self
):
5306 def GetTTag(self
, ectx
):
5307 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
5309 class UniversalStringType (RestrictedCharacterStringType
):
5310 def eth_tsname(self
):
5311 return 'UniversalString'
5313 class UTF8StringType (RestrictedCharacterStringType
):
5314 def eth_tsname(self
):
5317 class VideotexStringType (RestrictedCharacterStringType
):
5318 def eth_tsname(self
):
5319 return 'VideotexString'
5321 class VisibleStringType (RestrictedCharacterStringType
):
5322 def eth_tsname(self
):
5323 return 'VisibleString'
5325 class ISO646StringType (RestrictedCharacterStringType
):
5326 def eth_tsname(self
):
5327 return 'ISO646String'
5328 def GetTTag(self
, ectx
):
5329 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
5331 class UnrestrictedCharacterStringType (CharacterStringType
):
5332 def to_python (self
, ctx
):
5333 return 'asn1.UnrestrictedCharacterString'
5334 def eth_tsname(self
):
5335 return 'CHARACTER_STRING'
5337 #--- UsefulType ---------------------------------------------------------------
5338 class GeneralizedTime (RestrictedCharacterStringType
):
5339 def eth_tsname(self
):
5340 return 'GeneralizedTime'
5342 def eth_ftype(self
, ectx
):
5344 return ('FT_ABSOLUTE_TIME', 'ABSOLUTE_TIME_LOCAL')
5346 return ('FT_STRING', 'BASE_NONE')
5348 def eth_type_default_body(self
, ectx
, tname
):
5350 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5351 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5354 return RestrictedCharacterStringType
.eth_type_default_body(self
, ectx
, tname
)
5356 class UTCTime (RestrictedCharacterStringType
):
5357 def eth_tsname(self
):
5360 def eth_type_default_body(self
, ectx
, tname
):
5362 body
= ectx
.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret
='offset',
5363 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', 'NULL', 'NULL'),))
5366 return RestrictedCharacterStringType
.eth_type_default_body(self
, ectx
, tname
)
5368 class ObjectDescriptor (RestrictedCharacterStringType
):
5369 def eth_tsname(self
):
5370 return 'ObjectDescriptor'
5372 def eth_type_default_body(self
, ectx
, tname
):
5374 body
= RestrictedCharacterStringType
.eth_type_default_body(self
, ectx
, tname
)
5376 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_descriptor', ret
='offset',
5377 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5379 body
= '#error Can not decode %s' % (tname
)
5382 #--- ObjectIdentifierType -----------------------------------------------------
5383 class ObjectIdentifierType (Type
):
5384 def to_python (self
, ctx
):
5385 return 'asn1.OBJECT_IDENTIFIER'
5387 def eth_tname(self
):
5388 return 'OBJECT_IDENTIFIER'
5390 def eth_ftype(self
, ectx
):
5391 return ('FT_OID', 'BASE_NONE')
5393 def GetTTag(self
, ectx
):
5394 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
5396 def eth_type_default_pars(self
, ectx
, tname
):
5397 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5398 pars
['FN_VARIANT'] = ectx
.default_oid_variant
5401 def eth_type_default_body(self
, ectx
, tname
):
5403 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret
='offset',
5404 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5406 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret
='offset',
5407 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5409 body
= ectx
.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret
='offset',
5410 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5412 body
= '#error Can not decode %s' % (tname
)
5415 #--- ObjectIdentifierValue ----------------------------------------------------
5416 class ObjectIdentifierValue (Value
):
5417 def get_num(self
, path
, val
):
5418 return str(oid_names
.get(path
+ '/' + val
, val
))
5420 def to_str(self
, ectx
):
5425 for v
in self
.comp_list
:
5426 if isinstance(v
, Node
) and (v
.type == 'name_and_number'):
5431 vstr
= self
.get_num(path
, v
)
5432 if not first
and not vstr
.isdigit():
5433 vstr
= ectx
.value_get_val(vstr
)
5438 out
+= ectx
.value_get_eth(vstr
) + '"'
5448 v
= self
.comp_list
[0]
5449 if isinstance(v
, Node
) and (v
.type == 'name_and_number'):
5454 vstr
= self
.get_num('', v
)
5460 class NamedNumber(Node
):
5461 def to_python (self
, ctx
):
5462 return "('%s',%s)" % (self
.ident
, self
.val
)
5463 def __lt__(self
, other
):
5464 return int(self
.val
) < int(other
.val
)
5466 class NamedNumListBase(Node
):
5467 def to_python (self
, ctx
):
5468 return "asn1.%s_class ([%s])" % (self
.asn1_typ
,",".join (
5469 [x
.to_python (ctx
) for x
in self
.named_list
]))
5471 #--- RelativeOIDType ----------------------------------------------------------
5472 class RelativeOIDType (Type
):
5474 def eth_tname(self
):
5475 return 'RELATIVE_OID'
5477 def eth_ftype(self
, ectx
):
5478 return ('FT_REL_OID', 'BASE_NONE')
5480 def GetTTag(self
, ectx
):
5481 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5483 def eth_type_default_pars(self
, ectx
, tname
):
5484 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5485 pars
['FN_VARIANT'] = ectx
.default_oid_variant
5488 def eth_type_default_body(self
, ectx
, tname
):
5490 body
= ectx
.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret
='offset',
5491 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5493 body
= ectx
.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret
='offset',
5494 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5496 body
= '#error Can not decode relative_oid %s' % (tname
)
5500 #--- IntegerType --------------------------------------------------------------
5501 class IntegerType (Type
):
5502 def to_python (self
, ctx
):
5503 return "asn1.INTEGER_class ([%s])" % (",".join (
5504 [x
.to_python (ctx
) for x
in self
.named_list
]))
5506 def add_named_value(self
, ident
, val
):
5507 e
= NamedNumber(ident
= ident
, val
= val
)
5508 if not self
.named_list
:
5509 self
.named_list
= []
5510 self
.named_list
.append(e
)
5512 def eth_tname(self
):
5514 return Type
.eth_tname(self
)
5515 if not self
.HasConstraint():
5517 elif self
.constr
.type == 'SingleValue' or self
.constr
.type == 'ValueRange':
5518 return 'INTEGER' + '_' + self
.constr
.eth_constrname()
5520 return 'INTEGER' + '_' + self
.constr
.eth_tname()
5522 def GetTTag(self
, ectx
):
5523 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5526 def eth_ftype(self
, ectx
):
5527 if self
.HasConstraint():
5528 if not self
.constr
.IsNegativ():
5529 if self
.constr
.Needs64b(ectx
):
5530 return ('FT_UINT64', 'BASE_DEC')
5532 return ('FT_UINT32', 'BASE_DEC')
5533 if self
.constr
.Needs64b(ectx
):
5534 return ('FT_INT64', 'BASE_DEC')
5535 return ('FT_INT32', 'BASE_DEC')
5537 def eth_strings(self
):
5538 if (self
.named_list
):
5543 def eth_has_vals(self
):
5544 if (self
.named_list
):
5549 def get_vals(self
, ectx
):
5551 for e
in (self
.named_list
):
5552 vals
.append((int(e
.val
), e
.ident
))
5555 def eth_type_vals(self
, tname
, ectx
):
5556 if not self
.eth_has_vals(): return ''
5558 vals
= self
.get_vals(ectx
)
5559 out
+= ectx
.eth_vals(tname
, vals
)
5562 def reg_enum_vals(self
, tname
, ectx
):
5563 vals
= self
.get_vals(ectx
)
5564 for (val
, id) in vals
:
5565 ectx
.eth_reg_value(id, self
, val
, ethname
=ectx
.eth_enum_item(tname
, id))
5567 def eth_type_enum(self
, tname
, ectx
):
5568 if not self
.eth_has_enum(tname
, ectx
): return ''
5570 vals
= self
.get_vals(ectx
)
5571 out
+= ectx
.eth_enum(tname
, vals
)
5574 def eth_type_default_pars(self
, ectx
, tname
):
5575 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5576 if self
.HasValueConstraint():
5577 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_value_constr(ectx
)
5578 if (pars
['FN_VARIANT'] == '') and self
.constr
.Needs64b(ectx
):
5579 if ectx
.Ber(): pars
['FN_VARIANT'] = '64'
5581 if (ectx
.Oer() and pars
['MAX_VAL'] == 'NO_BOUND'):
5582 pars
['FN_VARIANT'] = '_64b_no_ub'
5584 pars
['FN_VARIANT'] = '_64b'
5587 def eth_type_default_body(self
, ectx
, tname
):
5589 if (ectx
.constraints_check
and self
.HasValueConstraint()):
5590 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret
='offset',
5591 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5592 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5594 body
= ectx
.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret
='offset',
5595 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5597 elif (ectx
.Per() or ectx
.Oer()):
5598 if (self
.HasValueConstraint()):
5599 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret
='offset',
5600 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5601 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5603 body
= ectx
.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret
='offset',
5604 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5606 body
= '#error Can not decode %s' % (tname
)
5609 #--- BitStringType ------------------------------------------------------------
5610 class BitStringType (Type
):
5611 def to_python (self
, ctx
):
5612 return "asn1.BITSTRING_class ([%s])" % (",".join (
5613 [x
.to_python (ctx
) for x
in self
.named_list
]))
5615 def eth_tname(self
):
5617 return Type
.eth_tname(self
)
5618 elif not self
.HasConstraint():
5620 elif self
.constr
.IsSize():
5621 return 'BIT_STRING' + '_' + self
.constr
.eth_constrname()
5623 return '#' + self
.type + '_' + str(id(self
))
5625 def GetTTag(self
, ectx
):
5626 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5628 def eth_ftype(self
, ectx
):
5629 return ('FT_BYTES', 'BASE_NONE')
5631 def eth_need_tree(self
):
5632 return self
.named_list
5634 def eth_need_pdu(self
, ectx
):
5636 if self
.HasContentsConstraint():
5637 t
= self
.constr
.GetContents(ectx
)
5638 if t
and (ectx
.default_containing_variant
in ('_pdu', '_pdu_new')):
5640 'new' : ectx
.default_containing_variant
== '_pdu_new' }
5643 def sortNamedBits(self
):
5644 return self
.named_list
.val
5646 def eth_named_bits(self
):
5648 if (self
.named_list
):
5649 sorted_list
= self
.named_list
5652 for e
in (sorted_list
):
5653 # Fill the table with "spare_bit" for "un named bits"
5654 if (int(e
.val
) != 0) and (expected_bit_no
!= int(e
.val
)):
5655 while ( expected_bit_no
< int(e
.val
)):
5656 bits
.append((expected_bit_no
, ("spare_bit%u" % (expected_bit_no
))))
5657 expected_bit_no
= expected_bit_no
+ 1
5658 #print ("Adding named bits to list %s bit no %d" % (e.ident, int (e.val)))
5659 bits
.append((int(e
.val
), e
.ident
))
5660 expected_bit_no
= int(e
.val
) + 1
5663 def eth_type_default_pars(self
, ectx
, tname
):
5664 pars
= Type
.eth_type_default_pars(self
, ectx
, tname
)
5665 pars
['LEN_PTR'] = 'NULL'
5666 (pars
['MIN_VAL'], pars
['MAX_VAL'], pars
['EXT']) = self
.eth_get_size_constr(ectx
)
5667 if 'ETT_INDEX' not in pars
:
5668 pars
['ETT_INDEX'] = '-1'
5669 pars
['TABLE'] = 'NULL'
5670 if self
.eth_named_bits():
5671 pars
['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5672 if self
.HasContentsConstraint():
5673 pars
['FN_VARIANT'] = ectx
.default_containing_variant
5674 t
= self
.constr
.GetContents(ectx
)
5676 if pars
['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5677 t
= ectx
.field
[t
]['ethname']
5678 pars
['TYPE_REF_PROTO'] = ''
5679 pars
['TYPE_REF_TNAME'] = t
5680 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5682 t
= ectx
.type[t
]['ethname']
5683 pars
['TYPE_REF_PROTO'] = ectx
.eth_type
[t
]['proto']
5684 pars
['TYPE_REF_TNAME'] = t
5685 pars
['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5687 pars
['TYPE_REF_FN'] = 'NULL'
5690 def eth_type_default_table(self
, ectx
, tname
):
5691 #print ("eth_type_default_table(tname='%s')" % (tname))
5693 bits
= self
.eth_named_bits()
5695 table
= ectx
.eth_bits(tname
, bits
)
5698 def eth_type_default_body(self
, ectx
, tname
):
5699 bits
= self
.eth_named_bits()
5701 if (ectx
.constraints_check
and self
.HasSizeConstraint()):
5702 body
= ectx
.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret
='offset',
5703 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5704 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%s' % len(bits
),'%(HF_INDEX)s', '%(ETT_INDEX)s',),
5707 body
= ectx
.eth_fn_call('dissect_%(ER)s_bitstring', ret
='offset',
5708 par
=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5709 ('%(TABLE)s', '%s' % len(bits
), '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5711 elif (ectx
.Per() or ectx
.Oer()):
5712 if self
.HasContentsConstraint():
5713 body
= ectx
.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret
='offset',
5714 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5715 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5717 body
= ectx
.eth_fn_call('dissect_%(ER)s_bit_string', ret
='offset',
5718 par
=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5719 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s','%(TABLE)s', '%s' % len(bits
), '%(VAL_PTR)s', '%(LEN_PTR)s'),))
5721 body
= '#error Can not decode %s' % (tname
)
5724 #--- BStringValue ------------------------------------------------------------
5743 class BStringValue (Value
):
5744 def to_str(self
, ectx
):
5747 v
+= '0' * (8 - len(v
) % 8)
5749 for i
in (list(range(0, len(v
), 4))):
5750 vv
+= bstring_tab
[v
[i
:i
+4]]
5753 #--- HStringValue ------------------------------------------------------------
5754 class HStringValue (Value
):
5755 def to_str(self
, ectx
):
5757 vv
+= self
.val
[1:-2]
5760 return int(self
.val
[1:-2], 16)
5762 #--- FieldSpec ----------------------------------------------------------------
5763 class FieldSpec (Node
):
5764 def __init__(self
,*args
, **kw
) :
5766 Node
.__init
__ (self
,*args
, **kw
)
5768 def SetName(self
, name
):
5772 return ['#UNSUPPORTED_' + self
.type]
5776 repr.extend(self
.get_repr())
5779 class TypeFieldSpec (FieldSpec
):
5783 class FixedTypeValueFieldSpec (FieldSpec
):
5785 if isinstance(self
.typ
, Type_Ref
):
5786 repr = ['TypeReference', self
.typ
.val
]
5788 repr = [self
.typ
.type]
5791 class VariableTypeValueFieldSpec (FieldSpec
):
5793 return ['_' + self
.type]
5795 class FixedTypeValueSetFieldSpec (FieldSpec
):
5797 return ['_' + self
.type]
5799 class ObjectFieldSpec (FieldSpec
):
5801 return ['ClassReference', self
.cls
.val
]
5803 class ObjectSetFieldSpec (FieldSpec
):
5805 return ['ClassReference', self
.cls
.val
]
5807 #==============================================================================
5809 def p_module_list_1 (t
):
5810 'module_list : module_list ModuleDefinition'
5811 t
[0] = t
[1] + [t
[2]]
5813 def p_module_list_2 (t
):
5814 'module_list : ModuleDefinition'
5818 #--- ITU-T Recommendation X.680 -----------------------------------------------
5821 # 11 ASN.1 lexical items --------------------------------------------------------
5823 # 11.2 Type references
5825 'type_ref : UCASE_IDENT'
5826 t
[0] = Type_Ref(val
=t
[1])
5829 def p_identifier (t
):
5830 'identifier : LCASE_IDENT'
5833 # 11.4 Value references
5834 # cause reduce/reduce conflict
5835 #def p_valuereference (t):
5836 # 'valuereference : LCASE_IDENT'
5837 # t[0] = Value_Ref(val=t[1])
5839 # 11.5 Module references
5840 def p_modulereference (t
):
5841 'modulereference : UCASE_IDENT'
5845 # 12 Module definition --------------------------------------------------------
5848 def p_ModuleDefinition (t
):
5849 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5850 t
[0] = Module (ident
= t
[1], tag_def
= t
[3], body
= t
[7])
5852 def p_ModuleBegin (t
):
5854 if t
[-4].val
== 'Remote-Operations-Information-Objects':
5857 def p_TagDefault_1 (t
):
5858 '''TagDefault : EXPLICIT TAGS
5860 | AUTOMATIC TAGS '''
5861 t
[0] = Default_Tags (dfl_tag
= t
[1])
5863 def p_TagDefault_2 (t
):
5865 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5866 t
[0] = Default_Tags (dfl_tag
= 'EXPLICIT')
5868 def p_ModuleIdentifier_1 (t
):
5869 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5870 t
[0] = Node('module_ident', val
= t
[1], ident
= t
[2])
5872 def p_ModuleIdentifier_2 (t
):
5873 'ModuleIdentifier : modulereference' # name, oid
5874 t
[0] = Node('module_ident', val
= t
[1], ident
= None)
5876 def p_DefinitiveIdentifier (t
):
5877 'DefinitiveIdentifier : ObjectIdentifierValue'
5880 #def p_module_ref (t):
5881 # 'module_ref : UCASE_IDENT'
5884 def p_ModuleBody_1 (t
):
5885 'ModuleBody : Exports Imports AssignmentList'
5886 t
[0] = Module_Body (exports
= t
[1], imports
= t
[2], assign_list
= t
[3])
5888 def p_ModuleBody_2 (t
):
5890 t
[0] = Node ('module_body', exports
= [], imports
= [], assign_list
= [])
5892 def p_Exports_1 (t
):
5893 'Exports : EXPORTS syms_exported SEMICOLON'
5896 def p_Exports_2 (t
):
5897 'Exports : EXPORTS ALL SEMICOLON'
5900 def p_Exports_3 (t
):
5904 def p_syms_exported_1 (t
):
5905 'syms_exported : exp_sym_list'
5908 def p_syms_exported_2 (t
):
5912 def p_exp_sym_list_1 (t
):
5913 'exp_sym_list : Symbol'
5916 def p_exp_sym_list_2 (t
):
5917 'exp_sym_list : exp_sym_list COMMA Symbol'
5918 t
[0] = t
[1] + [t
[3]]
5921 def p_Imports_1 (t
):
5922 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5924 global lcase_ident_assigned
5925 lcase_ident_assigned
= {}
5927 def p_importsbegin (t
):
5929 global lcase_ident_assigned
5931 lcase_ident_assigned
= {}
5932 lcase_ident_assigned
.update(g_conform
.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5934 def p_Imports_2 (t
):
5938 def p_SymbolsImported_1(t
):
5939 'SymbolsImported : '
5942 def p_SymbolsImported_2 (t
):
5943 'SymbolsImported : SymbolsFromModuleList'
5946 def p_SymbolsFromModuleList_1 (t
):
5947 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5948 t
[0] = t
[1] + [t
[2]]
5950 def p_SymbolsFromModuleList_2 (t
):
5951 'SymbolsFromModuleList : SymbolsFromModule'
5954 def p_SymbolsFromModule (t
):
5955 '''SymbolsFromModule : SymbolList FROM GlobalModuleReference
5956 | SymbolList FROM GlobalModuleReference WITH SUCCESSORS'''
5957 t
[0] = Node ('SymbolList', symbol_list
= t
[1], module
= t
[3])
5958 for s
in (t
[0].symbol_list
):
5959 if (isinstance(s
, Value_Ref
)): lcase_ident_assigned
[s
.val
] = t
[3]
5960 import_symbols_from_module(t
[0].module
, t
[0].symbol_list
)
5962 def import_symbols_from_module(module
, symbol_list
):
5963 if module
.val
== 'Remote-Operations-Information-Objects':
5964 for i
in range(len(symbol_list
)):
5966 if isinstance(s
, Type_Ref
) or isinstance(s
, Class_Ref
):
5968 if isinstance(s
, Type_Ref
) and is_class_ident(s
.val
):
5969 symbol_list
[i
] = Class_Ref (val
= s
.val
)
5971 for i
in range(len(symbol_list
)):
5973 if isinstance(s
, Type_Ref
) and is_class_ident("$%s$%s" % (module
.val
, s
.val
)):
5974 import_class_from_module(module
.val
, s
.val
)
5975 if isinstance(s
, Type_Ref
) and is_class_ident(s
.val
):
5976 symbol_list
[i
] = Class_Ref (val
= s
.val
)
5978 def p_GlobalModuleReference (t
):
5979 'GlobalModuleReference : modulereference AssignedIdentifier'
5980 t
[0] = Node('module_ident', val
= t
[1], ident
= t
[2])
5982 def p_AssignedIdentifier_1 (t
):
5983 'AssignedIdentifier : ObjectIdentifierValue'
5986 def p_AssignedIdentifier_2 (t
):
5987 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5990 def p_AssignedIdentifier_3 (t
):
5991 'AssignedIdentifier : '
5994 def p_SymbolList_1 (t
):
5995 'SymbolList : Symbol'
5998 def p_SymbolList_2 (t
):
5999 'SymbolList : SymbolList COMMA Symbol'
6000 t
[0] = t
[1] + [t
[3]]
6003 '''Symbol : Reference
6004 | ParameterizedReference'''
6007 def p_Reference_1 (t
):
6008 '''Reference : type_ref
6009 | objectclassreference '''
6012 def p_Reference_2 (t
):
6013 '''Reference : LCASE_IDENT_ASSIGNED
6014 | identifier ''' # instead of valuereference which causes reduce/reduce conflict
6015 t
[0] = Value_Ref(val
=t
[1])
6017 def p_AssignmentList_1 (t
):
6018 'AssignmentList : AssignmentList Assignment'
6019 t
[0] = t
[1] + [t
[2]]
6021 def p_AssignmentList_2 (t
):
6022 'AssignmentList : Assignment SEMICOLON'
6025 def p_AssignmentList_3 (t
):
6026 'AssignmentList : Assignment'
6029 def p_Assignment (t
):
6030 '''Assignment : TypeAssignment
6032 | ValueSetTypeAssignment
6033 | ObjectClassAssignment
6035 | ObjectSetAssignment
6036 | ParameterizedAssignment
6041 # 13 Referencing type and value definitions -----------------------------------
6044 def p_DefinedType (t
):
6045 '''DefinedType : ExternalTypeReference
6047 | ParameterizedType'''
6050 def p_DefinedValue_1(t
):
6051 '''DefinedValue : ExternalValueReference'''
6054 def p_DefinedValue_2(t
):
6055 '''DefinedValue : identifier ''' # instead of valuereference which causes reduce/reduce conflict
6056 t
[0] = Value_Ref(val
=t
[1])
6059 def p_ExternalTypeReference (t
):
6060 'ExternalTypeReference : modulereference DOT type_ref'
6061 t
[0] = Node ('ExternalTypeReference', module
= t
[1], typ
= t
[3])
6063 def p_ExternalValueReference (t
):
6064 'ExternalValueReference : modulereference DOT identifier'
6065 t
[0] = Node ('ExternalValueReference', module
= t
[1], ident
= t
[3])
6068 # 15 Assigning types and values -----------------------------------------------
6071 def p_TypeAssignment (t
):
6072 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
6077 def p_ValueAssignment (t
):
6078 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
6079 t
[0] = ValueAssignment(ident
= t
[1], typ
= t
[2], val
= t
[4])
6081 # only "simple" types are supported to simplify grammar
6082 def p_ValueType (t
):
6083 '''ValueType : type_ref
6086 | ObjectIdentifierType
6093 def p_ValueSetTypeAssignment (t
):
6094 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
6095 t
[0] = Node('ValueSetTypeAssignment', name
=t
[1], typ
=t
[2], val
=t
[4])
6099 'ValueSet : lbraceignore rbraceignore'
6103 # 16 Definition of types and values -------------------------------------------
6107 '''Type : BuiltinType
6109 | ConstrainedType'''
6113 def p_BuiltinType (t
):
6114 '''BuiltinType : AnyType
6117 | CharacterStringType
6125 | ObjectClassFieldType
6126 | ObjectIdentifierType
6138 def p_ReferencedType (t
):
6139 '''ReferencedType : DefinedType
6145 def p_NamedType (t
):
6146 'NamedType : identifier Type'
6152 '''Value : BuiltinValue
6154 | ObjectClassFieldValue'''
6158 def p_BuiltinValue (t
):
6159 '''BuiltinValue : BooleanValue
6162 | ObjectIdentifierValue
6167 | char_string''' # XXX we don't support {data} here
6171 def p_ReferencedValue (t
):
6172 '''ReferencedValue : DefinedValue
6173 | ValueFromObject'''
6177 #def p_NamedValue (t):
6178 # 'NamedValue : identifier Value'
6179 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
6182 # 17 Notation for the boolean type --------------------------------------------
6185 def p_BooleanType (t
):
6186 'BooleanType : BOOLEAN'
6187 t
[0] = BooleanType ()
6190 def p_BooleanValue (t
):
6191 '''BooleanValue : TRUE
6196 # 18 Notation for the integer type --------------------------------------------
6199 def p_IntegerType_1 (t
):
6200 'IntegerType : INTEGER'
6201 t
[0] = IntegerType (named_list
= None)
6203 def p_IntegerType_2 (t
):
6204 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
6205 t
[0] = IntegerType(named_list
= t
[3])
6207 def p_NamedNumberList_1 (t
):
6208 'NamedNumberList : NamedNumber'
6211 def p_NamedNumberList_2 (t
):
6212 'NamedNumberList : NamedNumberList COMMA NamedNumber'
6213 t
[0] = t
[1] + [t
[3]]
6215 def p_NamedNumber (t
):
6216 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
6217 | identifier LPAREN DefinedValue RPAREN'''
6218 t
[0] = NamedNumber(ident
= t
[1], val
= t
[3])
6220 def p_SignedNumber_1 (t
):
6221 'SignedNumber : NUMBER'
6224 def p_SignedNumber_2 (t
):
6225 'SignedNumber : MINUS NUMBER'
6229 def p_IntegerValue (t
):
6230 'IntegerValue : SignedNumber'
6233 # 19 Notation for the enumerated type -----------------------------------------
6236 def p_EnumeratedType (t
):
6237 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
6238 t
[0] = EnumeratedType (val
= t
[3]['val'], ext
= t
[3]['ext'])
6240 def p_Enumerations_1 (t
):
6241 'Enumerations : Enumeration'
6242 t
[0] = { 'val' : t
[1], 'ext' : None }
6244 def p_Enumerations_2 (t
):
6245 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
6246 t
[0] = { 'val' : t
[1], 'ext' : [] }
6248 def p_Enumerations_3 (t
):
6249 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
6250 t
[0] = { 'val' : t
[1], 'ext' : t
[6] }
6252 def p_Enumeration_1 (t
):
6253 'Enumeration : EnumerationItem'
6256 def p_Enumeration_2 (t
):
6257 'Enumeration : Enumeration COMMA EnumerationItem'
6258 t
[0] = t
[1] + [t
[3]]
6260 def p_EnumerationItem (t
):
6261 '''EnumerationItem : Identifier
6265 def p_Identifier (t
):
6266 'Identifier : identifier'
6267 t
[0] = Node ('Identifier', ident
= t
[1])
6270 # 20 Notation for the real type -----------------------------------------------
6278 def p_RealValue (t
):
6279 '''RealValue : REAL_NUMBER
6280 | SpecialRealValue'''
6283 def p_SpecialRealValue (t
):
6284 '''SpecialRealValue : PLUS_INFINITY
6289 # 21 Notation for the bitstring type ------------------------------------------
6292 def p_BitStringType_1 (t
):
6293 'BitStringType : BIT STRING'
6294 t
[0] = BitStringType (named_list
= None)
6296 def p_BitStringType_2 (t
):
6297 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
6298 t
[0] = BitStringType (named_list
= t
[4])
6300 def p_NamedBitList_1 (t
):
6301 'NamedBitList : NamedBit'
6304 def p_NamedBitList_2 (t
):
6305 'NamedBitList : NamedBitList COMMA NamedBit'
6306 t
[0] = t
[1] + [t
[3]]
6309 '''NamedBit : identifier LPAREN NUMBER RPAREN
6310 | identifier LPAREN DefinedValue RPAREN'''
6311 t
[0] = NamedNumber (ident
= t
[1], val
= t
[3])
6314 # 22 Notation for the octetstring type ----------------------------------------
6317 def p_OctetStringType (t
):
6318 'OctetStringType : OCTET STRING'
6319 t
[0] = OctetStringType ()
6322 # 23 Notation for the null type -----------------------------------------------
6330 def p_NullValue (t
):
6335 # 24 Notation for sequence types ----------------------------------------------
6338 def p_SequenceType_1 (t
):
6339 'SequenceType : SEQUENCE LBRACE RBRACE'
6340 t
[0] = SequenceType (elt_list
= [])
6342 def p_SequenceType_2 (t
):
6343 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
6344 t
[0] = SequenceType (elt_list
= t
[3]['elt_list'])
6345 if 'ext_list' in t
[3]:
6346 t
[0].ext_list
= t
[3]['ext_list']
6347 if 'elt_list2' in t
[3]:
6348 t
[0].elt_list2
= t
[3]['elt_list2']
6350 def p_ExtensionAndException_1 (t
):
6351 'ExtensionAndException : ELLIPSIS'
6354 def p_OptionalExtensionMarker_1 (t
):
6355 'OptionalExtensionMarker : COMMA ELLIPSIS'
6358 def p_OptionalExtensionMarker_2 (t
):
6359 'OptionalExtensionMarker : '
6362 def p_ComponentTypeLists_1 (t
):
6363 'ComponentTypeLists : ComponentTypeList'
6364 t
[0] = {'elt_list' : t
[1]}
6366 def p_ComponentTypeLists_2 (t
):
6367 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
6368 t
[0] = {'elt_list' : t
[1], 'ext_list' : []}
6370 def p_ComponentTypeLists_3 (t
):
6371 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6372 t
[0] = {'elt_list' : t
[1], 'ext_list' : t
[4]}
6374 def p_ComponentTypeLists_4 (t
):
6375 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
6376 t
[0] = {'elt_list' : t
[1], 'ext_list' : [], 'elt_list2' : t
[6]}
6378 def p_ComponentTypeLists_5 (t
):
6379 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
6380 t
[0] = {'elt_list' : t
[1], 'ext_list' : t
[4], 'elt_list2' : t
[7]}
6382 def p_ComponentTypeLists_6 (t
):
6383 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
6384 t
[0] = {'elt_list' : [], 'ext_list' : []}
6386 def p_ComponentTypeLists_7 (t
):
6387 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6388 t
[0] = {'elt_list' : [], 'ext_list' : t
[2]}
6390 def p_ExtensionEndMarker (t
):
6391 'ExtensionEndMarker : COMMA ELLIPSIS'
6394 def p_ExtensionAdditionList_1 (t
):
6395 'ExtensionAdditionList : COMMA ExtensionAddition'
6398 def p_ExtensionAdditionList_2 (t
):
6399 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
6400 t
[0] = t
[1] + [t
[3]]
6402 def p_ExtensionAddition_1 (t
):
6403 'ExtensionAddition : ExtensionAdditionGroup'
6404 t
[0] = Node ('elt_type', val
= t
[1], optional
= 0)
6406 def p_ExtensionAddition_2 (t
):
6407 'ExtensionAddition : ComponentType'
6410 def p_ExtensionAdditionGroup (t
):
6411 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
6412 t
[0] = ExtensionAdditionGroup (ver
= t
[2], elt_list
= t
[3])
6414 def p_VersionNumber_1 (t
):
6417 def p_VersionNumber_2 (t
):
6418 'VersionNumber : NUMBER COLON'
6421 def p_ComponentTypeList_1 (t
):
6422 'ComponentTypeList : ComponentType'
6425 def p_ComponentTypeList_2 (t
):
6426 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
6427 t
[0] = t
[1] + [t
[3]]
6429 def p_ComponentType_1 (t
):
6430 'ComponentType : NamedType'
6431 t
[0] = Node ('elt_type', val
= t
[1], optional
= 0)
6433 def p_ComponentType_2 (t
):
6434 'ComponentType : NamedType OPTIONAL'
6435 t
[0] = Node ('elt_type', val
= t
[1], optional
= 1)
6437 def p_ComponentType_3 (t
):
6438 'ComponentType : NamedType DEFAULT DefaultValue'
6439 t
[0] = Node ('elt_type', val
= t
[1], optional
= 1, default
= t
[3])
6441 def p_ComponentType_4 (t
):
6442 'ComponentType : COMPONENTS OF Type'
6443 t
[0] = Node ('components_of', typ
= t
[3])
6445 def p_DefaultValue_1 (t
):
6446 '''DefaultValue : ReferencedValue
6454 | ObjectClassFieldValue'''
6457 def p_DefaultValue_2 (t
):
6458 'DefaultValue : lbraceignore rbraceignore'
6462 def p_SequenceValue_1 (t
):
6463 'SequenceValue : LBRACE RBRACE'
6467 #def p_SequenceValue_2 (t):
6468 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
6471 #def p_ComponentValueList_1 (t):
6472 # 'ComponentValueList : NamedValue'
6475 #def p_ComponentValueList_2 (t):
6476 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
6477 # t[0] = t[1] + [t[3]]
6480 # 25 Notation for sequence-of types -------------------------------------------
6483 def p_SequenceOfType (t
):
6484 '''SequenceOfType : SEQUENCE OF Type
6485 | SEQUENCE OF NamedType'''
6486 t
[0] = SequenceOfType (val
= t
[3], size_constr
= None)
6489 # 26 Notation for set types ---------------------------------------------------
6492 def p_SetType_1 (t
):
6493 'SetType : SET LBRACE RBRACE'
6494 t
[0] = SetType (elt_list
= [])
6496 def p_SetType_2 (t
):
6497 'SetType : SET LBRACE ComponentTypeLists RBRACE'
6498 t
[0] = SetType (elt_list
= t
[3]['elt_list'])
6499 if 'ext_list' in t
[3]:
6500 t
[0].ext_list
= t
[3]['ext_list']
6501 if 'elt_list2' in t
[3]:
6502 t
[0].elt_list2
= t
[3]['elt_list2']
6505 # 27 Notation for set-of types ------------------------------------------------
6508 def p_SetOfType (t
):
6509 '''SetOfType : SET OF Type
6510 | SET OF NamedType'''
6511 t
[0] = SetOfType (val
= t
[3])
6513 # 28 Notation for choice types ------------------------------------------------
6516 def p_ChoiceType (t
):
6517 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
6518 if 'ext_list' in t
[3]:
6519 t
[0] = ChoiceType (elt_list
= t
[3]['elt_list'], ext_list
= t
[3]['ext_list'])
6521 t
[0] = ChoiceType (elt_list
= t
[3]['elt_list'])
6523 def p_AlternativeTypeLists_1 (t
):
6524 'AlternativeTypeLists : AlternativeTypeList'
6525 t
[0] = {'elt_list' : t
[1]}
6527 def p_AlternativeTypeLists_2 (t
):
6528 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
6529 t
[0] = {'elt_list' : t
[1], 'ext_list' : t
[4]}
6531 def p_ExtensionAdditionAlternatives_1 (t
):
6532 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
6535 def p_ExtensionAdditionAlternatives_2 (t
):
6536 'ExtensionAdditionAlternatives : '
6539 def p_ExtensionAdditionAlternativesList_1 (t
):
6540 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
6543 def p_ExtensionAdditionAlternativesList_2 (t
):
6544 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
6547 def p_ExtensionAdditionAlternative_1 (t
):
6548 'ExtensionAdditionAlternative : NamedType'
6551 def p_ExtensionAdditionAlternative_2 (t
):
6552 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
6555 def p_ExtensionAdditionAlternativesGroup (t
):
6556 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
6559 def p_AlternativeTypeList_1 (t
):
6560 'AlternativeTypeList : NamedType'
6563 def p_AlternativeTypeList_2 (t
):
6564 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
6565 t
[0] = t
[1] + [t
[3]]
6568 def p_ChoiceValue_1 (t
):
6569 '''ChoiceValue : identifier COLON Value
6570 | identifier COLON NullValue '''
6572 if not isinstance(val
, Value
):
6573 val
= Value(val
=val
)
6574 t
[0] = ChoiceValue (choice
= t
[1], val
= val
)
6576 # 29 Notation for selection types
6579 def p_SelectionType (t
): #
6580 'SelectionType : identifier LT Type'
6581 t
[0] = SelectionType (typ
= t
[3], sel
= t
[1])
6583 # 30 Notation for tagged types ------------------------------------------------
6586 def p_TaggedType_1 (t
):
6587 'TaggedType : Tag Type'
6588 t
[1].mode
= 'default'
6592 def p_TaggedType_2 (t
):
6593 '''TaggedType : Tag IMPLICIT Type
6594 | Tag EXPLICIT Type'''
6600 'Tag : LBRACK Class ClassNumber RBRACK'
6601 t
[0] = Tag(cls
= t
[2], num
= t
[3])
6603 def p_ClassNumber_1 (t
):
6604 'ClassNumber : number'
6607 def p_ClassNumber_2 (t
):
6608 'ClassNumber : DefinedValue'
6612 '''Class : UNIVERSAL
6622 # 31 Notation for the object identifier type ----------------------------------
6625 def p_ObjectIdentifierType (t
):
6626 'ObjectIdentifierType : OBJECT IDENTIFIER'
6627 t
[0] = ObjectIdentifierType()
6630 def p_ObjectIdentifierValue (t
):
6631 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6632 t
[0] = ObjectIdentifierValue (comp_list
=t
[2])
6634 def p_oid_comp_list_1 (t
):
6635 'oid_comp_list : oid_comp_list ObjIdComponents'
6636 t
[0] = t
[1] + [t
[2]]
6638 def p_oid_comp_list_2 (t
):
6639 'oid_comp_list : ObjIdComponents'
6642 def p_ObjIdComponents (t
):
6643 '''ObjIdComponents : NameForm
6645 | NameAndNumberForm'''
6649 '''NameForm : LCASE_IDENT
6650 | LCASE_IDENT_ASSIGNED'''
6653 def p_NumberForm (t
):
6654 '''NumberForm : NUMBER'''
6658 def p_NameAndNumberForm (t
):
6659 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6660 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6661 t
[0] = Node('name_and_number', ident
= t
[1], number
= t
[3])
6663 # 32 Notation for the relative object identifier type -------------------------
6666 def p_RelativeOIDType (t
):
6667 'RelativeOIDType : RELATIVE_OID'
6668 t
[0] = RelativeOIDType()
6670 # 33 Notation for the embedded-pdv type ---------------------------------------
6673 def p_EmbeddedPDVType (t
):
6674 'EmbeddedPDVType : EMBEDDED PDV'
6675 t
[0] = EmbeddedPDVType()
6677 # 34 Notation for the external type -------------------------------------------
6680 def p_ExternalType (t
):
6681 'ExternalType : EXTERNAL'
6682 t
[0] = ExternalType()
6684 # 36 Notation for character string types --------------------------------------
6687 def p_CharacterStringType (t
):
6688 '''CharacterStringType : RestrictedCharacterStringType
6689 | UnrestrictedCharacterStringType'''
6693 # 37 Definition of restricted character string types --------------------------
6695 def p_RestrictedCharacterStringType_1 (t
):
6696 'RestrictedCharacterStringType : BMPString'
6697 t
[0] = BMPStringType ()
6698 def p_RestrictedCharacterStringType_2 (t
):
6699 'RestrictedCharacterStringType : GeneralString'
6700 t
[0] = GeneralStringType ()
6701 def p_RestrictedCharacterStringType_3 (t
):
6702 'RestrictedCharacterStringType : GraphicString'
6703 t
[0] = GraphicStringType ()
6704 def p_RestrictedCharacterStringType_4 (t
):
6705 'RestrictedCharacterStringType : IA5String'
6706 t
[0] = IA5StringType ()
6707 def p_RestrictedCharacterStringType_5 (t
):
6708 'RestrictedCharacterStringType : ISO646String'
6709 t
[0] = ISO646StringType ()
6710 def p_RestrictedCharacterStringType_6 (t
):
6711 'RestrictedCharacterStringType : NumericString'
6712 t
[0] = NumericStringType ()
6713 def p_RestrictedCharacterStringType_7 (t
):
6714 'RestrictedCharacterStringType : PrintableString'
6715 t
[0] = PrintableStringType ()
6716 def p_RestrictedCharacterStringType_8 (t
):
6717 'RestrictedCharacterStringType : TeletexString'
6718 t
[0] = TeletexStringType ()
6719 def p_RestrictedCharacterStringType_9 (t
):
6720 'RestrictedCharacterStringType : T61String'
6721 t
[0] = T61StringType ()
6722 def p_RestrictedCharacterStringType_10 (t
):
6723 'RestrictedCharacterStringType : UniversalString'
6724 t
[0] = UniversalStringType ()
6725 def p_RestrictedCharacterStringType_11 (t
):
6726 'RestrictedCharacterStringType : UTF8String'
6727 t
[0] = UTF8StringType ()
6728 def p_RestrictedCharacterStringType_12 (t
):
6729 'RestrictedCharacterStringType : VideotexString'
6730 t
[0] = VideotexStringType ()
6731 def p_RestrictedCharacterStringType_13 (t
):
6732 'RestrictedCharacterStringType : VisibleString'
6733 t
[0] = VisibleStringType ()
6736 # 40 Definition of unrestricted character string types ------------------------
6739 def p_UnrestrictedCharacterStringType (t
):
6740 'UnrestrictedCharacterStringType : CHARACTER STRING'
6741 t
[0] = UnrestrictedCharacterStringType ()
6744 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6746 # 42 Generalized time ---------------------------------------------------------
6748 def p_UsefulType_1 (t
):
6749 'UsefulType : GeneralizedTime'
6750 t
[0] = GeneralizedTime()
6752 # 43 Universal time -----------------------------------------------------------
6754 def p_UsefulType_2 (t
):
6755 'UsefulType : UTCTime'
6758 # 44 The object descriptor type -----------------------------------------------
6760 def p_UsefulType_3 (t
):
6761 'UsefulType : ObjectDescriptor'
6762 t
[0] = ObjectDescriptor()
6765 # 45 Constrained types --------------------------------------------------------
6768 def p_ConstrainedType_1 (t
):
6769 'ConstrainedType : Type Constraint'
6771 t
[0].AddConstraint(t
[2])
6773 def p_ConstrainedType_2 (t
):
6774 'ConstrainedType : TypeWithConstraint'
6778 def p_TypeWithConstraint_1 (t
):
6779 '''TypeWithConstraint : SET Constraint OF Type
6780 | SET SizeConstraint OF Type'''
6781 t
[0] = SetOfType (val
= t
[4], constr
= t
[2])
6783 def p_TypeWithConstraint_2 (t
):
6784 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6785 | SEQUENCE SizeConstraint OF Type'''
6786 t
[0] = SequenceOfType (val
= t
[4], constr
= t
[2])
6788 def p_TypeWithConstraint_3 (t
):
6789 '''TypeWithConstraint : SET Constraint OF NamedType
6790 | SET SizeConstraint OF NamedType'''
6791 t
[0] = SetOfType (val
= t
[4], constr
= t
[2])
6793 def p_TypeWithConstraint_4 (t
):
6794 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6795 | SEQUENCE SizeConstraint OF NamedType'''
6796 t
[0] = SequenceOfType (val
= t
[4], constr
= t
[2])
6800 def p_Constraint (t
):
6801 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6804 def p_ConstraintSpec (t
):
6805 '''ConstraintSpec : ElementSetSpecs
6806 | GeneralConstraint'''
6809 # 46 Element set specification ------------------------------------------------
6812 def p_ElementSetSpecs_1 (t
):
6813 'ElementSetSpecs : RootElementSetSpec'
6816 def p_ElementSetSpecs_2 (t
):
6817 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6821 def p_ElementSetSpecs_3 (t
):
6822 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6826 def p_RootElementSetSpec (t
):
6827 'RootElementSetSpec : ElementSetSpec'
6830 def p_AdditionalElementSetSpec (t
):
6831 'AdditionalElementSetSpec : ElementSetSpec'
6834 def p_ElementSetSpec (t
):
6835 'ElementSetSpec : Unions'
6839 'Unions : Intersections'
6843 'Unions : UElems UnionMark Intersections'
6844 # Constraints currently ignored become None, e.g. InnerTypeConstraints
6845 # (WITH COMPONENT[S]). Don't add them to a Union.
6851 t
[0] = Constraint(type = 'Union', subtype
= [t
[1], t
[3]])
6857 def p_Intersections_1 (t
):
6858 'Intersections : IntersectionElements'
6861 def p_Intersections_2 (t
):
6862 'Intersections : IElems IntersectionMark IntersectionElements'
6863 t
[0] = Constraint(type = 'Intersection', subtype
= [t
[1], t
[3]])
6866 'IElems : Intersections'
6869 def p_IntersectionElements (t
):
6870 'IntersectionElements : Elements'
6873 def p_UnionMark (t
):
6877 def p_IntersectionMark (t
):
6878 '''IntersectionMark : CIRCUMFLEX
6882 def p_Elements_1 (t
):
6883 'Elements : SubtypeElements'
6886 def p_Elements_2 (t
):
6887 'Elements : LPAREN ElementSetSpec RPAREN'
6890 # 47 Subtype elements ---------------------------------------------------------
6893 def p_SubtypeElements (t
):
6894 '''SubtypeElements : SingleValue
6900 | InnerTypeConstraints
6901 | PatternConstraint'''
6906 def p_SingleValue (t
):
6907 'SingleValue : Value'
6908 t
[0] = Constraint(type = 'SingleValue', subtype
= t
[1])
6910 # 47.3 Contained subtype
6912 def p_ContainedSubtype (t
):
6913 'ContainedSubtype : Includes Type'
6914 t
[0] = Constraint(type = 'ContainedSubtype', subtype
= t
[2])
6917 '''Includes : INCLUDES
6922 def p_ValueRange (t
):
6923 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6924 t
[0] = Constraint(type = 'ValueRange', subtype
= [t
[1], t
[3]])
6927 def p_LowerEndpoint_1 (t
):
6928 'LowerEndpoint : LowerEndValue'
6931 def p_LowerEndpoint_2 (t
):
6932 'LowerEndpoint : LowerEndValue LT'
6933 t
[0] = t
[1] # but not inclusive range
6935 def p_UpperEndpoint_1 (t
):
6936 'UpperEndpoint : UpperEndValue'
6939 def p_UpperEndpoint_2 (t
):
6940 'UpperEndpoint : LT UpperEndValue'
6941 t
[0] = t
[1] # but not inclusive range
6944 def p_LowerEndValue (t
):
6945 '''LowerEndValue : Value
6949 def p_UpperEndValue (t
):
6950 '''UpperEndValue : Value
6954 # 47.5 Size constraint
6956 def p_SizeConstraint (t
):
6957 'SizeConstraint : SIZE Constraint'
6958 t
[0] = Constraint (type = 'Size', subtype
= t
[2])
6960 # 47.6 Type constraint
6962 def p_TypeConstraint (t
):
6963 'TypeConstraint : Type'
6964 t
[0] = Constraint (type = 'Type', subtype
= t
[1])
6966 # 47.7 Permitted alphabet
6968 def p_PermittedAlphabet (t
):
6969 'PermittedAlphabet : FROM Constraint'
6970 t
[0] = Constraint (type = 'From', subtype
= t
[2])
6972 # 47.8 Inner subtyping
6974 def p_InnerTypeConstraints (t
):
6975 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6976 | WITH COMPONENTS MultipleTypeConstraints'''
6977 pass # ignore PER invisible constraint
6980 def p_SingleTypeConstraint (t
):
6981 'SingleTypeConstraint : Constraint'
6985 def p_MultipleTypeConstraints (t
):
6986 '''MultipleTypeConstraints : FullSpecification
6987 | PartialSpecification'''
6990 def p_FullSpecification (t
):
6991 'FullSpecification : LBRACE TypeConstraints RBRACE'
6994 def p_PartialSpecification (t
):
6995 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6998 def p_TypeConstraints_1 (t
):
6999 'TypeConstraints : named_constraint'
7002 def p_TypeConstraints_2 (t
):
7003 'TypeConstraints : TypeConstraints COMMA named_constraint'
7004 t
[0] = t
[1] + [t
[3]]
7006 def p_named_constraint_1 (t
):
7007 'named_constraint : identifier constraint'
7008 return Node ('named_constraint', ident
= t
[1], constr
= t
[2])
7010 def p_named_constraint_2 (t
):
7011 'named_constraint : constraint'
7012 return Node ('named_constraint', constr
= t
[1])
7014 def p_constraint (t
):
7015 'constraint : value_constraint presence_constraint'
7016 t
[0] = Node ('constraint', value
= t
[1], presence
= t
[2])
7018 def p_value_constraint_1 (t
):
7019 'value_constraint : Constraint'
7022 def p_value_constraint_2 (t
):
7023 'value_constraint : '
7026 def p_presence_constraint_1 (t
):
7027 '''presence_constraint : PRESENT
7032 def p_presence_constraint_2 (t
):
7033 '''presence_constraint : '''
7036 # 47.9 Pattern constraint
7038 def p_PatternConstraint (t
):
7039 'PatternConstraint : PATTERN Value'
7040 t
[0] = Constraint (type = 'Pattern', subtype
= t
[2])
7042 # 49 The exception identifier
7045 def p_ExceptionSpec_1 (t
):
7046 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
7049 def p_ExceptionSpec_2 (t
):
7053 def p_ExceptionIdentification (t
):
7054 '''ExceptionIdentification : SignedNumber
7056 | Type COLON Value '''
7059 # /*-----------------------------------------------------------------------*/
7060 # /* Value Notation Productions */
7061 # /*-----------------------------------------------------------------------*/
7065 def p_binary_string (t
):
7066 'binary_string : BSTRING'
7067 t
[0] = BStringValue(val
= t
[1])
7069 def p_hex_string (t
):
7070 'hex_string : HSTRING'
7071 t
[0] = HStringValue(val
= t
[1])
7073 def p_char_string (t
):
7074 'char_string : QSTRING'
7082 #--- ITU-T Recommendation X.208 -----------------------------------------------
7084 # 27 Notation for the any type ------------------------------------------------
7089 | ANY DEFINED BY identifier'''
7092 #--- ITU-T Recommendation X.681 -----------------------------------------------
7094 # 7 ASN.1 lexical items -------------------------------------------------------
7096 # 7.1 Information object class references
7098 def p_objectclassreference (t
):
7099 'objectclassreference : CLASS_IDENT'
7100 t
[0] = Class_Ref(val
=t
[1])
7102 # 7.2 Information object references
7104 def p_objectreference (t
):
7105 'objectreference : LCASE_IDENT'
7108 # 7.3 Information object set references
7110 #def p_objectsetreference (t):
7111 # 'objectsetreference : UCASE_IDENT'
7114 # 7.4 Type field references
7115 # ucasefieldreference
7116 # 7.5 Value field references
7117 # lcasefieldreference
7118 # 7.6 Value set field references
7119 # ucasefieldreference
7120 # 7.7 Object field references
7121 # lcasefieldreference
7122 # 7.8 Object set field references
7123 # ucasefieldreference
7125 def p_ucasefieldreference (t
):
7126 'ucasefieldreference : AMPERSAND UCASE_IDENT'
7129 def p_lcasefieldreference (t
):
7130 'lcasefieldreference : AMPERSAND LCASE_IDENT'
7133 # 8 Referencing definitions
7136 def p_DefinedObjectClass (t
):
7137 '''DefinedObjectClass : objectclassreference
7138 | UsefulObjectClassReference'''
7141 obj_class
= t
[0].val
7143 def p_DefinedObject (t
):
7144 '''DefinedObject : objectreference'''
7148 def p_UsefulObjectClassReference (t
):
7149 '''UsefulObjectClassReference : TYPE_IDENTIFIER
7150 | ABSTRACT_SYNTAX'''
7151 t
[0] = Class_Ref(val
=t
[1])
7153 # 9 Information object class definition and assignment
7156 def p_ObjectClassAssignment (t
):
7157 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
7158 | UCASE_IDENT ASSIGNMENT ObjectClass'''
7161 if isinstance(t
[0], ObjectClassDefn
):
7165 def p_ObjectClass (t
):
7166 '''ObjectClass : DefinedObjectClass
7168 | ParameterizedObjectClass '''
7172 def p_ObjectClassDefn (t
):
7173 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
7174 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
7175 t
[0] = ObjectClassDefn(fields
= t
[3])
7177 def p_FieldSpecs_1 (t
):
7178 'FieldSpecs : FieldSpec'
7181 def p_FieldSpecs_2 (t
):
7182 'FieldSpecs : FieldSpecs COMMA FieldSpec'
7183 t
[0] = t
[1] + [t
[3]]
7185 def p_WithSyntaxSpec (t
):
7186 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
7190 def p_FieldSpec (t
):
7191 '''FieldSpec : TypeFieldSpec
7192 | FixedTypeValueFieldSpec
7193 | VariableTypeValueFieldSpec
7194 | FixedTypeValueSetFieldSpec
7196 | ObjectSetFieldSpec '''
7200 def p_TypeFieldSpec (t
):
7201 '''TypeFieldSpec : ucasefieldreference
7202 | ucasefieldreference TypeOptionalitySpec '''
7203 t
[0] = TypeFieldSpec()
7206 def p_TypeOptionalitySpec_1 (t
):
7207 'TypeOptionalitySpec ::= OPTIONAL'
7210 def p_TypeOptionalitySpec_2 (t
):
7211 'TypeOptionalitySpec ::= DEFAULT Type'
7215 def p_FixedTypeValueFieldSpec (t
):
7216 '''FixedTypeValueFieldSpec : lcasefieldreference Type
7217 | lcasefieldreference Type UNIQUE
7218 | lcasefieldreference Type ValueOptionalitySpec
7219 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
7220 t
[0] = FixedTypeValueFieldSpec(typ
= t
[2])
7223 def p_ValueOptionalitySpec_1 (t
):
7224 'ValueOptionalitySpec ::= OPTIONAL'
7227 def p_ValueOptionalitySpec_2 (t
):
7228 'ValueOptionalitySpec ::= DEFAULT Value'
7233 def p_VariableTypeValueFieldSpec (t
):
7234 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
7235 | lcasefieldreference FieldName ValueOptionalitySpec '''
7236 t
[0] = VariableTypeValueFieldSpec()
7240 def p_FixedTypeValueSetFieldSpec (t
):
7241 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
7242 | ucasefieldreference Type ValueSetOptionalitySpec '''
7243 t
[0] = FixedTypeValueSetFieldSpec()
7246 def p_ValueSetOptionalitySpec_1 (t
):
7247 'ValueSetOptionalitySpec ::= OPTIONAL'
7250 def p_ValueSetOptionalitySpec_2 (t
):
7251 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
7255 def p_ObjectFieldSpec (t
):
7256 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
7257 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
7258 t
[0] = ObjectFieldSpec(cls
=t
[2])
7263 def p_ObjectOptionalitySpec_1 (t
):
7264 'ObjectOptionalitySpec ::= OPTIONAL'
7267 def p_ObjectOptionalitySpec_2 (t
):
7268 'ObjectOptionalitySpec ::= DEFAULT Object'
7272 def p_ObjectSetFieldSpec (t
):
7273 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
7274 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
7275 t
[0] = ObjectSetFieldSpec(cls
=t
[2])
7278 def p_ObjectSetOptionalitySpec_1 (t
):
7279 'ObjectSetOptionalitySpec ::= OPTIONAL'
7282 def p_ObjectSetOptionalitySpec_2 (t
):
7283 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
7287 def p_PrimitiveFieldName (t
):
7288 '''PrimitiveFieldName : ucasefieldreference
7289 | lcasefieldreference '''
7293 def p_FieldName_1 (t
):
7294 'FieldName : PrimitiveFieldName'
7297 def p_FieldName_2 (t
):
7298 'FieldName : FieldName DOT PrimitiveFieldName'
7299 t
[0] = t
[1] + '.' + t
[3]
7301 # 11 Information object definition and assignment
7304 def p_ObjectAssignment (t
):
7305 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
7306 t
[0] = ObjectAssignment (ident
= t
[1], cls
=t
[2].val
, val
=t
[4])
7312 '''Object : DefinedObject
7314 | ParameterizedObject'''
7318 def p_ObjectDefn (t
):
7319 'ObjectDefn : lbraceobject bodyobject rbraceobject'
7322 # {...} block of object definition
7323 def p_lbraceobject(t
):
7324 'lbraceobject : braceobjectbegin LBRACE'
7327 def p_braceobjectbegin(t
):
7328 'braceobjectbegin : '
7331 if set_class_syntax(obj_class
):
7335 state
= 'braceignore'
7336 lexer
.push_state(state
)
7338 def p_rbraceobject(t
):
7339 'rbraceobject : braceobjectend RBRACE'
7342 def p_braceobjectend(t
):
7346 set_class_syntax(None)
7348 def p_bodyobject_1 (t
):
7352 def p_bodyobject_2 (t
):
7353 'bodyobject : cls_syntax_list'
7356 def p_cls_syntax_list_1 (t
):
7357 'cls_syntax_list : cls_syntax_list cls_syntax'
7361 def p_cls_syntax_list_2 (t
):
7362 'cls_syntax_list : cls_syntax'
7366 def p_cls_syntax_1 (t
):
7367 'cls_syntax : Type IDENTIFIED BY Value'
7368 t
[0] = { get_class_field(' ') : t
[1], get_class_field(' '.join((t
[2], t
[3]))) : t
[4] }
7370 def p_cls_syntax_2 (t
):
7371 'cls_syntax : HAS PROPERTY Value'
7372 t
[0] = { get_class_field(' '.join(t
[1:-1])) : t
[-1:][0] }
7375 def p_cls_syntax_3 (t
):
7376 '''cls_syntax : ERRORS ObjectSet
7378 | RETURN RESULT BooleanValue
7379 | SYNCHRONOUS BooleanValue
7380 | INVOKE PRIORITY Value
7381 | RESULT_PRIORITY Value
7383 | ALWAYS RESPONDS BooleanValue
7384 | IDEMPOTENT BooleanValue '''
7385 t
[0] = { get_class_field(' '.join(t
[1:-1])) : t
[-1:][0] }
7387 def p_cls_syntax_4 (t
):
7388 '''cls_syntax : ARGUMENT Type
7390 | PARAMETER Type '''
7391 t
[0] = { get_class_field(t
[1]) : t
[2] }
7393 def p_cls_syntax_5 (t
):
7394 'cls_syntax : CODE Value'
7395 fld
= get_class_field(t
[1])
7396 t
[0] = { fld
: t
[2] }
7397 if isinstance(t
[2], ChoiceValue
):
7398 fldt
= fld
+ '.' + t
[2].choice
7401 def p_cls_syntax_6 (t
):
7402 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
7403 | RESULT Type OPTIONAL BooleanValue
7404 | PARAMETER Type OPTIONAL BooleanValue '''
7405 t
[0] = { get_class_field(t
[1]) : t
[2], get_class_field(' '.join((t
[1], t
[3]))) : t
[4] }
7407 # 12 Information object set definition and assignment
7410 def p_ObjectSetAssignment (t
):
7411 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
7412 t
[0] = Node('ObjectSetAssignment', name
=t
[1], cls
=t
[2], val
=t
[4])
7415 def p_ObjectSet (t
):
7416 'ObjectSet : lbraceignore rbraceignore'
7419 # 14 Notation for the object class field type ---------------------------------
7422 def p_ObjectClassFieldType (t
):
7423 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
7424 t
[0] = get_type_from_class(t
[1], t
[3])
7427 def p_ObjectClassFieldValue (t
):
7428 '''ObjectClassFieldValue : OpenTypeFieldVal'''
7431 def p_OpenTypeFieldVal (t
):
7432 '''OpenTypeFieldVal : Type COLON Value
7433 | NullType COLON NullValue'''
7437 # 15 Information from objects -------------------------------------------------
7441 def p_ValueFromObject (t
):
7442 'ValueFromObject : LCASE_IDENT DOT FieldName'
7443 t
[0] = t
[1] + '.' + t
[3]
7446 # Annex C - The instance-of type ----------------------------------------------
7449 def p_InstanceOfType (t
):
7450 'InstanceOfType : INSTANCE OF DefinedObjectClass'
7451 t
[0] = InstanceOfType()
7456 useful_object_class_types
= {
7458 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
7459 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
7461 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
7462 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
7463 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
7466 object_class_types
= { }
7468 object_class_typerefs
= { }
7470 object_class_classrefs
= { }
7473 class _VariableTypeValueFieldSpec (AnyType
):
7476 class _FixedTypeValueSetFieldSpec (AnyType
):
7479 class_types_creator
= {
7480 'BooleanType' : lambda : BooleanType(),
7481 'IntegerType' : lambda : IntegerType(),
7482 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
7483 'OpenType' : lambda : OpenType(),
7485 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
7486 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
7492 'TYPE-IDENTIFIER' : {
7494 'IDENTIFIED' : 'IDENTIFIED',
7496 'IDENTIFIED BY' : '&id',
7498 'ABSTRACT-SYNTAX' : {
7500 'IDENTIFIED' : 'IDENTIFIED',
7502 'IDENTIFIED BY' : '&id',
7504 'PROPERTY' : 'PROPERTY',
7505 'HAS PROPERTY' : '&property',
7509 class_syntaxes_enabled
= {
7510 'TYPE-IDENTIFIER' : True,
7511 'ABSTRACT-SYNTAX' : True,
7515 'TYPE-IDENTIFIER' : x681_syntaxes
['TYPE-IDENTIFIER'],
7516 'ABSTRACT-SYNTAX' : x681_syntaxes
['ABSTRACT-SYNTAX'],
7519 class_current_syntax
= None
7521 def get_syntax_tokens(syntaxes
):
7523 for s
in (syntaxes
):
7524 for k
in (list(syntaxes
[s
].keys())):
7527 tokens
[k
] = tokens
[k
].replace('-', '_')
7528 return list(tokens
.values())
7530 tokens
= tokens
+ get_syntax_tokens(x681_syntaxes
)
7532 def set_class_syntax(syntax
):
7533 global class_syntaxes_enabled
7534 global class_current_syntax
7535 #print "set_class_syntax", syntax, class_current_syntax
7536 if class_syntaxes_enabled
.get(syntax
, False):
7537 class_current_syntax
= syntax
7540 class_current_syntax
= None
7543 def is_class_syntax(name
):
7544 global class_syntaxes
7545 global class_current_syntax
7546 #print "is_class_syntax", name, class_current_syntax
7547 if not class_current_syntax
:
7549 return name
in class_syntaxes
[class_current_syntax
]
7551 def get_class_field(name
):
7552 if not class_current_syntax
:
7554 return class_syntaxes
[class_current_syntax
][name
]
7556 def is_class_ident(name
):
7557 return name
in class_names
7559 def add_class_ident(name
):
7560 #print "add_class_ident", name
7561 class_names
[name
] = name
7563 def get_type_from_class(cls
, fld
):
7564 flds
= fld
.split('.')
7565 if (isinstance(cls
, Class_Ref
)):
7566 key
= cls
.val
+ '.' + flds
[0]
7568 key
= cls
+ '.' + flds
[0]
7570 if key
in object_class_classrefs
:
7571 return get_type_from_class(object_class_classrefs
[key
], '.'.join(flds
[1:]))
7573 if key
in object_class_typerefs
:
7574 return Type_Ref(val
=object_class_typerefs
[key
])
7576 creator
= lambda : AnyType()
7577 creator
= useful_object_class_types
.get(key
, creator
)
7578 creator
= object_class_types
.get(key
, creator
)
7581 def set_type_to_class(cls
, fld
, pars
):
7582 #print "set_type_to_class", cls, fld, pars
7583 key
= cls
+ '.' + fld
7584 typename
= 'OpenType'
7588 pars
.append(typename
)
7591 if (isinstance(pars
[1], Class_Ref
)):
7592 pars
[1] = pars
[1].val
7596 if key
in object_class_types
:
7597 msg
= object_class_types
[key
]().type
7598 if key
in object_class_typerefs
:
7599 msg
= "TypeReference " + object_class_typerefs
[key
]
7600 if key
in object_class_classrefs
:
7601 msg
= "ClassReference " + object_class_classrefs
[key
]
7603 if msg
== ' '.join(pars
):
7607 msg0
= "Can not define CLASS field %s as '%s'\n" % (key
, ' '.join(pars
))
7608 msg1
= "Already defined as '%s'" % (msg
)
7609 raise CompError(msg0
+ msg1
)
7611 if (typename
== 'ClassReference'):
7612 if not typeref
: return False
7613 object_class_classrefs
[key
] = typeref
7616 if (typename
== 'TypeReference'):
7617 if not typeref
: return False
7618 object_class_typerefs
[key
] = typeref
7621 creator
= class_types_creator
.get(typename
)
7623 object_class_types
[key
] = creator
7628 def import_class_from_module(mod
, cls
):
7629 add_class_ident(cls
)
7630 mcls
= "$%s$%s" % (mod
, cls
)
7631 for k
in list(object_class_classrefs
.keys()):
7632 kk
= k
.split('.', 1)
7634 object_class_classrefs
[cls
+ '.' + kk
[0]] = object_class_classrefs
[k
]
7635 for k
in list(object_class_typerefs
.keys()):
7636 kk
= k
.split('.', 1)
7638 object_class_typerefs
[cls
+ '.' + kk
[0]] = object_class_typerefs
[k
]
7639 for k
in list(object_class_types
.keys()):
7640 kk
= k
.split('.', 1)
7642 object_class_types
[cls
+ '.' + kk
[0]] = object_class_types
[k
]
7644 #--- ITU-T Recommendation X.682 -----------------------------------------------
7646 # 8 General constraint specification ------------------------------------------
7649 def p_GeneralConstraint (t
):
7650 '''GeneralConstraint : UserDefinedConstraint
7652 | ContentsConstraint'''
7655 # 9 User-defined constraints --------------------------------------------------
7658 def p_UserDefinedConstraint (t
):
7659 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7660 t
[0] = Constraint(type = 'UserDefined', subtype
= t
[4])
7662 def p_UserDefinedConstraintParameterList_1 (t
):
7663 'UserDefinedConstraintParameterList : '
7666 def p_UserDefinedConstraintParameterList_2 (t
):
7667 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7670 def p_UserDefinedConstraintParameterList_3 (t
):
7671 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7672 t
[0] = t
[1] + [t
[3]]
7675 def p_UserDefinedConstraintParameter (t
):
7676 'UserDefinedConstraintParameter : Type'
7679 # 10 Table constraints, including component relation constraints --------------
7682 def p_TableConstraint (t
):
7683 '''TableConstraint : SimpleTableConstraint
7684 | ComponentRelationConstraint'''
7685 t
[0] = Constraint(type = 'Table', subtype
= t
[1])
7687 def p_SimpleTableConstraint (t
):
7688 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7692 def p_ComponentRelationConstraint (t
):
7693 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7694 t
[0] = t
[2] + str(t
[5])
7696 def p_AtNotations_1 (t
):
7697 'AtNotations : AtNotation'
7700 def p_AtNotations_2 (t
):
7701 'AtNotations : AtNotations COMMA AtNotation'
7702 t
[0] = t
[1] + [t
[3]]
7704 def p_AtNotation_1 (t
):
7705 'AtNotation : AT ComponentIdList'
7708 def p_AtNotation_2 (t
):
7709 'AtNotation : AT DOT Level ComponentIdList'
7710 t
[0] = '@.' + t
[3] + t
[4]
7720 def p_ComponentIdList_1 (t
):
7721 'ComponentIdList : LCASE_IDENT'
7724 def p_ComponentIdList_2 (t
):
7725 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7726 t
[0] = t
[1] + '.' + t
[3]
7728 # 11 Contents constraints -----------------------------------------------------
7731 def p_ContentsConstraint (t
):
7732 'ContentsConstraint : CONTAINING type_ref'
7733 t
[0] = Constraint(type = 'Contents', subtype
= t
[2])
7736 #--- ITU-T Recommendation X.683 -----------------------------------------------
7738 # 8 Parameterized assignments -------------------------------------------------
7741 def p_ParameterizedAssignment (t
):
7742 '''ParameterizedAssignment : ParameterizedTypeAssignment
7743 | ParameterizedObjectClassAssignment
7744 | ParameterizedObjectAssignment
7745 | ParameterizedObjectSetAssignment'''
7749 def p_ParameterizedTypeAssignment (t
):
7750 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7752 t
[0].SetName(t
[1]) # t[0].SetName(t[1] + 'xxx')
7754 def p_ParameterizedObjectClassAssignment (t
):
7755 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7756 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7759 if isinstance(t
[0], ObjectClassDefn
):
7762 def p_ParameterizedObjectAssignment (t
):
7763 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7764 t
[0] = ObjectAssignment (ident
= t
[1], cls
=t
[3].val
, val
=t
[5])
7768 def p_ParameterizedObjectSetAssignment (t
):
7769 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7770 t
[0] = Node('ObjectSetAssignment', name
=t
[1], cls
=t
[3].val
, val
=t
[5])
7773 def p_ParameterList (t
):
7774 'ParameterList : lbraceignore rbraceignore'
7776 #def p_ParameterList (t):
7777 # 'ParameterList : LBRACE Parameters RBRACE'
7780 #def p_Parameters_1 (t):
7781 # 'Parameters : Parameter'
7784 #def p_Parameters_2 (t):
7785 # 'Parameters : Parameters COMMA Parameter'
7786 # t[0] = t[1] + [t[3]]
7788 #def p_Parameter_1 (t):
7789 # 'Parameter : Type COLON Reference'
7790 # t[0] = [t[1], t[3]]
7792 #def p_Parameter_2 (t):
7793 # 'Parameter : Reference'
7797 # 9 Referencing parameterized definitions -------------------------------------
7800 def p_ParameterizedReference (t
):
7801 'ParameterizedReference : Reference LBRACE RBRACE'
7806 def p_ParameterizedType (t
):
7807 'ParameterizedType : type_ref ActualParameterList'
7812 def p_ParameterizedObjectClass (t
):
7813 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7817 def p_ParameterizedObject (t
):
7818 'ParameterizedObject : DefinedObject ActualParameterList'
7823 def p_ActualParameterList (t
):
7824 'ActualParameterList : lbraceignore rbraceignore'
7826 #def p_ActualParameterList (t):
7827 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7830 #def p_ActualParameters_1 (t):
7831 # 'ActualParameters : ActualParameter'
7834 #def p_ActualParameters_2 (t):
7835 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7836 # t[0] = t[1] + [t[3]]
7838 #def p_ActualParameter (t):
7839 # '''ActualParameter : Type
7844 #--- ITU-T Recommendation X.880 -----------------------------------------------
7848 '&ArgumentType' : [],
7849 '&argumentTypeOptional' : [ 'BooleanType' ],
7850 '&returnResult' : [ 'BooleanType' ],
7852 '&resultTypeOptional' : [ 'BooleanType' ],
7853 '&Errors' : [ 'ClassReference', 'ERROR' ],
7854 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7855 '&synchronous' : [ 'BooleanType' ],
7856 '&idempotent' : [ 'BooleanType' ],
7857 '&alwaysReturns' : [ 'BooleanType' ],
7858 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7859 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7860 '&operationCode' : [ 'TypeReference', 'Code' ],
7863 '&ParameterType' : [],
7864 '¶meterTypeOptional' : [ 'BooleanType' ],
7865 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7866 '&errorCode' : [ 'TypeReference', 'Code' ],
7868 'OPERATION-PACKAGE' : {
7869 '&Both' : [ 'ClassReference', 'OPERATION' ],
7870 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7871 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7872 '&id' : [ 'ObjectIdentifierType' ],
7874 'CONNECTION-PACKAGE' : {
7875 '&bind' : [ 'ClassReference', 'OPERATION' ],
7876 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7877 '&responderCanUnbind' : [ 'BooleanType' ],
7878 '&unbindCanFail' : [ 'BooleanType' ],
7879 '&id' : [ 'ObjectIdentifierType' ],
7882 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7883 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7884 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7885 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7886 '&id' : [ 'ObjectIdentifierType' ],
7888 'ROS-OBJECT-CLASS' : {
7889 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7890 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7891 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7892 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7893 '&id' : [ 'ObjectIdentifierType' ],
7899 'ARGUMENT' : '&ArgumentType',
7900 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7901 'RESULT' : '&ResultType',
7902 'RESULT OPTIONAL' : '&resultTypeOptional',
7903 'RETURN' : 'RETURN',
7904 'RETURN RESULT' : '&returnResult',
7905 'ERRORS' : '&Errors',
7906 'LINKED' : '&Linked',
7907 'SYNCHRONOUS' : '&synchronous',
7908 'IDEMPOTENT' : '&idempotent',
7909 'ALWAYS' : 'ALWAYS',
7910 'RESPONDS' : 'RESPONDS',
7911 'ALWAYS RESPONDS' : '&alwaysReturns',
7912 'INVOKE' : 'INVOKE',
7913 'PRIORITY' : 'PRIORITY',
7914 'INVOKE PRIORITY' : '&InvokePriority',
7915 'RESULT-PRIORITY': '&ResultPriority',
7916 'CODE' : '&operationCode',
7919 'PARAMETER' : '&ParameterType',
7920 'PARAMETER OPTIONAL' : '¶meterTypeOptional',
7921 'PRIORITY' : '&ErrorPriority',
7922 'CODE' : '&errorCode',
7924 # 'OPERATION-PACKAGE' : {
7926 # 'CONNECTION-PACKAGE' : {
7930 # 'ROS-OBJECT-CLASS' : {
7934 def x880_module_begin():
7935 #print "x880_module_begin()"
7936 for name
in list(x880_classes
.keys()):
7937 add_class_ident(name
)
7939 def x880_import(name
):
7940 if name
in x880_syntaxes
:
7941 class_syntaxes_enabled
[name
] = True
7942 class_syntaxes
[name
] = x880_syntaxes
[name
]
7943 if name
in x880_classes
:
7944 add_class_ident(name
)
7945 for f
in (list(x880_classes
[name
].keys())):
7946 set_type_to_class(name
, f
, x880_classes
[name
][f
])
7948 tokens
= tokens
+ get_syntax_tokens(x880_syntaxes
)
7951 #def p_lbrace_oid(t):
7952 # 'lbrace_oid : brace_oid_begin LBRACE'
7955 #def p_brace_oid_begin(t):
7956 # 'brace_oid_begin : '
7960 #def p_rbrace_oid(t):
7961 # 'rbrace_oid : brace_oid_end RBRACE'
7964 #def p_brace_oid_end(t):
7965 # 'brace_oid_end : '
7969 # {...} block to be ignored
7970 def p_lbraceignore(t
):
7971 'lbraceignore : braceignorebegin LBRACE'
7974 def p_braceignorebegin(t
):
7975 'braceignorebegin : '
7978 lexer
.push_state('braceignore')
7980 def p_rbraceignore(t
):
7981 'rbraceignore : braceignoreend RBRACE'
7984 def p_braceignoreend(t
):
7991 raise ParseError(t
, input_file
)
7994 '''pyquote : PYQUOTE'''
7995 t
[0] = PyQuote (val
= t
[1])
8001 token
= lexer
.token ()
8007 def do_module (ast
, defined_dict
):
8008 assert (ast
.type == 'Module')
8009 ctx
= Ctx (defined_dict
)
8010 print(ast
.to_python (ctx
))
8011 print(ctx
.output_assignments ())
8012 print(ctx
.output_pyquotes ())
8014 def eth_do_module (ast
, ectx
):
8015 assert (ast
.type == 'Module')
8016 if ectx
.dbg('s'): print(ast
.str_depth(0))
8019 def testyacc(s
, fn
, defined_dict
):
8020 ast
= yacc
.parse(s
, debug
=0)
8021 time_str
= time
.strftime("%a, %d %b %Y %H:%M:%S +0000", time
.gmtime())
8022 print("""#!/usr/bin/env python
8023 # Auto-generated from %s at %s
8024 from PyZ3950 import asn1""" % (fn
, time_str
))
8026 eth_do_module (module
, defined_dict
)
8029 # Wireshark compiler
8032 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
8034 -b : BER (default is PER)
8035 -u : Unaligned (default is aligned)
8036 -p proto : Protocol name (implies -S). Default is module-name
8037 from input_file (renamed by #.MODULE if present)
8038 -o name : Output files name core (default is <proto>)
8039 -O dir : Output directory for dissector
8040 -c cnf_file : Conformance file
8041 -I path : Path for conformance file includes
8042 -e : Create conformance file for exported types
8043 -E : Just create conformance file for exported types
8044 -S : Single output for multiple modules
8045 -s template : Single file output (template is input file
8046 without .c/.h extension)
8047 -k : Keep intermediate files though single file output is used
8048 -L : Suppress #line directive from .cnf file
8049 -D dir : Directory for input_file(s) (default: '.')
8050 -C : Add check for SIZE constraints
8051 -r prefix : Remove the prefix from type names
8053 input_file(s) : Input ASN.1 file(s)
8055 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
8059 s - internal ASN.1 structure
8060 a - list of assignments
8062 c - conformance values
8063 m - list of compiled modules with dependency
8064 o - list of output files
8068 ## Used to preparse C style comments
8069 ## https://github.com/eerimoq/asn1tools/blob/master/asn1tools/parser.py#L231
8071 def ignore_comments(string
):
8072 """Ignore comments in given string by replacing them with spaces. This
8073 reduces the parsing time by roughly a factor of two.
8078 (mo
.start(), mo
.group(0))
8079 for mo
in re
.finditer(r
'(/\*|\*/|\n)', string
)
8084 multi_line_comment_depth
= 0
8086 non_comment_offset
= 0
8089 for offset
, kind
in comments
:
8090 if multi_line_comment_depth
> 0:
8092 multi_line_comment_depth
+= 1
8094 multi_line_comment_depth
-= 1
8096 if multi_line_comment_depth
== 0:
8098 chunks
.append(' ' * (offset
- start_offset
))
8099 non_comment_offset
= offset
8102 non_comment_offset
= offset
8104 multi_line_comment_depth
= 1
8105 start_offset
= offset
8106 chunks
.append(string
[non_comment_offset
:start_offset
])
8108 chunks
.append(string
[non_comment_offset
:])
8110 return ''.join(chunks
)
8119 opts
, args
= getopt
.getopt(sys
.argv
[1:], "h?d:D:buXp:qFTo:O:c:I:eESs:kLCr:")
8120 except getopt
.GetoptError
:
8121 eth_usage(); sys
.exit(2)
8123 eth_usage(); sys
.exit(2)
8128 ectx
= EthCtx(conform
, output
)
8129 ectx
.encoding
= 'per'
8130 ectx
.proto_opt
= None
8132 ectx
.tag_opt
= False
8133 ectx
.outnm_opt
= None
8138 ectx
.justexpcnf
= False
8139 ectx
.merge_modules
= False
8140 ectx
.group_by_prot
= False
8141 ectx
.conform
.last_group
= 0
8142 ectx
.conform
.suppress_line
= False
8143 ectx
.output
.outnm
= None
8144 ectx
.output
.single_file
= None
8145 ectx
.constraints_check
= False
8147 if o
in ("-h", "-?"):
8148 eth_usage(); sys
.exit(2)
8150 conf_to_read
= relpath(a
)
8152 ectx
.conform
.include_path
.append(relpath(a
))
8155 ectx
.justexpcnf
= True
8157 ectx
.srcdir
= relpath(a
)
8159 ectx
.constraints_check
= True
8161 ectx
.conform
.suppress_line
= True
8165 warnings
.warn("Command line option -X is obsolete and can be removed")
8167 warnings
.warn("Command line option -T is obsolete and can be removed")
8170 print("ASN.1 to Wireshark dissector compiler")
8173 ectx
.conform
.read(conf_to_read
)
8176 if o
in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-q", "-X", "-T"):
8177 pass # already processed
8181 ectx
.conform
.set_opt(o
, par
, "commandline", 0)
8183 (ld
, yd
, pd
) = (0, 0, 0)
8184 if ectx
.dbg('l'): ld
= 1
8185 if ectx
.dbg('y'): yd
= 1
8186 if ectx
.dbg('p'): pd
= 2
8187 lexer
= lex
.lex(debug
=ld
)
8188 parser
= yacc
.yacc(method
='LALR', debug
=yd
, outputdir
='.')
8189 parser
.defaulted_states
= {}
8190 g_conform
= ectx
.conform
8195 if (ectx
.srcdir
): fn
= ectx
.srcdir
+ '/' + fn
8196 # Read ASN.1 definition, trying one of the common encodings.
8197 data
= open(fn
, "rb").read()
8199 data
= data
.decode('utf-8')
8200 except UnicodeDecodeError:
8201 warnings
.warn_explicit(f
"Decoding {fn} as UTF-8 failed.", UnicodeWarning
, '', 0)
8203 # Py2 compat, name.translate in eth_output_hf_arr fails with unicode
8204 if not isinstance(data
, str):
8205 data
= data
.encode('utf-8')
8206 data
= ignore_comments(data
)
8207 ast
.extend(yacc
.parse(data
, lexer
=lexer
, debug
=pd
))
8209 if (ectx
.merge_modules
): # common output for all module
8212 eth_do_module(module
, ectx
)
8214 ectx
.eth_do_output()
8215 elif (ectx
.groups()): # group by protocols/group
8218 if (ectx
.group_by_prot
): # group by protocols
8220 prot
= module
.get_proto(ectx
)
8221 if prot
not in pr2gr
:
8222 pr2gr
[prot
] = len(groups
)
8224 groups
[pr2gr
[prot
]].append(module
)
8225 else: # group by groups
8230 eth_do_module(module
, ectx
)
8232 ectx
.eth_do_output()
8233 else: # output for each module
8236 eth_do_module(module
, ectx
)
8238 ectx
.eth_do_output()
8244 ectx
.conform
.dbg_print()
8245 if not ectx
.justexpcnf
:
8246 ectx
.conform
.unused_report()
8249 ectx
.output
.dbg_print()
8250 ectx
.output
.make_single_file(ectx
.conform
.suppress_line
)
8255 if sys
.version_info
[0] < 3:
8256 print("This requires Python 3")
8260 if len (sys
.argv
) == 1:
8262 s
= eval(input ('Query: '))
8265 testfn (s
, 'console', {})
8268 for fn
in sys
.argv
[1:]:
8270 testfn (f
.read (), fn
, defined_dict
)
8275 #--- BODY ---------------------------------------------------------------------
8277 if __name__
== '__main__':
8278 if (os
.path
.splitext(os
.path
.basename(sys
.argv
[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
8283 #------------------------------------------------------------------------------
8285 # Editor modelines - https://www.wireshark.org/tools/modelines.html
8287 # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil
8288 # vi: set shiftwidth=4 tabstop=8 expandtab:
8289 # :indentSize=4:tabSize=8:noTabs=true: