'2/upu' : 40,
}
+ITEM_FIELD_NAME = '_item'
+UNTAG_TYPE_NAME = '_untag'
+
def asn2c(id):
return id.replace('-', '_').replace('.', '_').replace('&', '_')
r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
r'\.\.' : 'RANGE', # 11.17 Range separator
r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
- #r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
- #r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
+ r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
+ r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
# 11.26 Single character lexical items
r'\{' : 'LBRACE',
r'\}' : 'RBRACE',
if ident in self.assignments:
raise DuplicateError("assignment", ident)
if ident in self.defined_dict:
- raise "cross-module duplicates for " + ident
+ raise Exception("cross-module duplicates for %s" % ident)
self.defined_dict [ident] = 1
self.assignments[ident] = val
self.dependencies [ident] = dependencies
x[e] = True
return (item_ord, item_cyc)
+# Given a filename, return a relative path from epan/dissectors
+def rel_dissector_path(filename):
+ path_parts = os.path.abspath(filename).split(os.sep)
+ while (len(path_parts) > 3 and path_parts[0] != 'asn1'):
+ path_parts.pop(0)
+ path_parts.insert(0, '..')
+ path_parts.insert(0, '..')
+ return '/'.join(path_parts)
+
+
#--- EthCtx -------------------------------------------------------------------
class EthCtx:
def __init__(self, conform, output, indent = 0):
self.default_containing_variant = '_pdu_new'
self.default_embedded_pdv_cb = None
self.default_external_type_cb = None
+ self.remove_prefix = None
self.srcdir = None
self.emitted_pdu = {}
self.module = {}
def Ber(self): return self.encoding == 'ber'
def Aligned(self): return self.aligned
def Unaligned(self): return not self.aligned
- def Tag(self): return self.tag_opt or self.Ber()
+ def NeedTags(self): return self.tag_opt or self.Ber()
def NAPI(self): return False # disable planned features
def Module(self): # current module name
ttype = type
while (val.type == 'TaggedType'):
val = val.val
- ttype += '/_untag'
+ ttype += '/' + UNTAG_TYPE_NAME
if (val.type != 'Type_Ref'):
if (type != ttype):
types.append(ttype)
def dummy_import_type(self, ident):
# dummy imported
if ident in self.type:
- raise "Try to dummy import for existing type :" + ident
+ raise Exception("Try to dummy import for existing type :%s" % ident)
ethtype = asn2c(ident)
self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
'ethname' : ethtype }
self.type_imp.remove(ident)
else:
raise DuplicateError("type", ident)
+ val.ident = ident
self.type[ident] = { 'val' : val, 'import' : None }
self.type[ident]['module'] = self.Module()
self.type[ident]['proto'] = self.proto
self.type[ident]['tname'] = asn2c(ident)
self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
+ self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident)
self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
'modified' : '', 'attr' : {} }
name = ident.split('/')[-1]
- if len(ident.split('/')) > 1 and name == '_item': # Sequence/Set of type
+ if self.remove_prefix and name.startswith(self.remove_prefix):
+ name = name[len(self.remove_prefix):]
+
+ if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type
if len(self.field[ident]['type'].split('/')) > 1:
self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2]
self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
if parent:
self.eth_dep_add(parent, type)
+ def eth_dummy_eag_field_required(self):
+ if (not self.dummy_eag_field):
+ self.dummy_eag_field = 'dummy_eag_field'
+
#--- eth_clean --------------------------------------------------------------
def eth_clean(self):
self.proto = self.proto_opt;
self.eth_hf_ord = []
self.eth_hfpdu_ord = []
self.eth_hf_dupl = {}
+ self.dummy_eag_field = None
#--- type dependencies -------------------
self.eth_type_ord1 = []
self.eth_dep_cycle = []
self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
#--- types -------------------
- for t in self.type_imp:
+ for t in self.type_imp: # imported types
nm = asn2c(t)
self.eth_type[nm] = { 'import' : self.type[t]['import'],
'proto' : asn2c(self.type[t]['proto']),
'attr' : {}, 'ref' : []}
self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
self.type[t]['ethname'] = nm
+ for t in self.type_ord: # dummy import for missing type reference
+ tp = self.type[t]['val']
+ #print "X : %s %s " % (t, tp.type)
+ if isinstance(tp, TaggedType):
+ #print "%s : %s " % (tp.type, t)
+ tp = tp.val
+ if isinstance(tp, Type_Ref):
+ #print "%s : %s ::= %s " % (tp.type, t, tp.val)
+ if tp.val not in self.type:
+ self.dummy_import_type(tp.val)
for t in self.type_ord:
nm = self.type[t]['tname']
if ((nm.find('#') >= 0) or
((len(t.split('/'))>1) and
(self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
- self.conform.get_fn_presence('/'.join((t,'_item'))) or self.conform.check_item('FN_PARS', '/'.join((t,'_item')))) and
+ self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and
not self.conform.check_item('TYPE_RENAME', t))):
- if len(t.split('/')) == 2 and t.split('/')[1] == '_item': # Sequence of type at the 1st level
+ if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level
nm = t.split('/')[0] + t.split('/')[1]
- elif t.split('/')[-1] == '_item': # Sequence/Set of type at next levels
+ elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels
nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
- elif t.split('/')[-1] == '_untag': # Untagged type
+ elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type
nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
else:
nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
self.eth_type[nm]['ref'].append(t)
else:
self.eth_type_ord.append(nm)
- self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0,
+ self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
'val' : self.type[t]['val'],
'attr' : {}, 'ref' : [t]}
self.eth_export_ord.append(nm)
self.eth_type[nm]['export'] |= self.type[t]['export']
self.eth_type[nm]['enum'] |= self.type[t]['enum']
+ self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext']
self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
if self.type[t]['attr'].get('STRINGS') == '$$':
- self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
+ use_ext = self.type[t]['vals_ext']
+ if (use_ext):
+ self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm))
+ else:
+ self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
for t in self.eth_type_ord:
bits = self.eth_type[t]['val'].eth_named_bits()
#--- fields -------------------------
for f in (self.pdu_ord + self.field_ord):
- if len(f.split('/')) > 1 and f.split('/')[-1] == '_item': # Sequence/Set of type
+ if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type
nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
else:
nm = f.split('/')[-1]
if (self.NAPI() and 'NAME' in attr):
attr['NAME'] += self.field[f]['idx']
attr.update(self.conform.use_item('EFIELD_ATTR', nm))
+ use_vals_ext = self.eth_type[ethtype].get('vals_ext')
+ if (use_vals_ext):
+ attr['DISPLAY'] += '|BASE_EXT_STRING'
self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
'attr' : attr.copy(),
'ref' : [f]}
self.field[f]['ethname'] = nm
+ if (self.dummy_eag_field):
+ self.dummy_eag_field = 'hf_%s_%s' % (self.eproto, self.dummy_eag_field)
#--- type dependencies -------------------
(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'])
i = 0
def eth_vals(self, tname, vals):
out = ""
has_enum = self.eth_type[tname]['enum'] & EF_ENUM
+ use_ext = self.eth_type[tname]['vals_ext']
+ if (use_ext):
+ vals.sort(key=lambda vals_entry: int(vals_entry[0]))
if (not self.eth_type[tname]['export'] & EF_VALS):
out += 'static '
if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
vval = val
out += ' { %3s, "%s" },\n' % (vval, id)
out += " { 0, NULL }\n};\n"
+ if (use_ext):
+ out += "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self.eth_vals_nm(tname), self.eth_vals_nm(tname))
return out
#--- eth_enum_prefix ------------------------------------------------------------
fx.write('/* named bits */\n')
for nb in self.named_bit:
fx.write("static int %s = -1;\n" % (nb['ethname']))
+ if (self.dummy_eag_field):
+ fx.write("static int %s = -1; /* never registered */ \n" % (self.dummy_eag_field))
self.output.file_close(fx)
#--- eth_output_hf_arr ------------------------------------------------------
fx = self.output.file_open('hfarr')
for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
t = self.eth_hf[f]['ethtype']
+ if self.remove_prefix and t.startswith(self.remove_prefix):
+ t = t[len(self.remove_prefix):]
name=self.eth_hf[f]['attr']['NAME']
trantab=maketrans("- ", "__")
name=name.translate(trantab)
#--- eth_output_export ------------------------------------------------------
def eth_output_export(self):
- if (not len(self.eth_export_ord)): return
fx = self.output.file_open('exp', ext='h')
for t in self.eth_export_ord: # vals
if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
if (pdu['new']): new_prefix = 'new_'
if (reg['rtype'] in ('NUM', 'STR')):
rstr = ''
- if (reg['rtype'] == 'STR'): rstr = '_string'
+ if (reg['rtype'] == 'STR'):
+ rstr = 'string'
+ else:
+ rstr = 'uint'
if (pdu['reg']):
dis = self.proto
if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
else:
hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
rport = self.value_get_eth(reg['rport'])
- fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
+ fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
elif (reg['rtype'] in ('BER', 'PER')):
roid = self.value_get_eth(reg['roid'])
fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
fx.write('\n')
self.output.file_close(fx, discard=fempty)
+ #--- eth_output_syn_reg -----------------------------------------------------
+ def eth_output_syn_reg(self):
+ fx = self.output.file_open('syn-reg')
+ fempty = True
+ first_decl = True
+ for k in self.conform.get_order('SYNTAX'):
+ reg = self.conform.use_item('SYNTAX', k)
+ if first_decl:
+ fx.write(' /*--- Syntax registrations ---*/\n')
+ first_decl = False
+ fx.write(' register_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (k, self.eproto, reg['pdu']));
+ fempty=False
+ self.output.file_close(fx, discard=fempty)
+
#--- eth_output_table -----------------------------------------------------
def eth_output_table(self):
for num in list(self.conform.report.keys()):
self.eth_output_dis_hnd()
self.eth_output_dis_reg()
self.eth_output_dis_tab()
+ self.eth_output_syn_reg()
self.eth_output_table()
if self.expcnf:
self.eth_output_expcnf()
# Value name Default value Duplicity check Usage check
self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
+ self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
self.fn[name][ctx]['used'] = True
out = self.fn[name][ctx]['text']
if (not self.suppress_line):
- out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], os.path.basename(self.fn[name][ctx]['fn']), out);
+ out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out);
return out
def add_pdu(self, par, is_new, fn, lineno):
self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
return
+ def add_syntax(self, par, fn, lineno):
+ #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
+ if( (len(par) >=2)):
+ name = par[1]
+ else:
+ name = '"'+par[0]+'"'
+ attr = { 'pdu' : par[0] }
+ self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno)
+ return
+
def add_register(self, pdu, par, fn, lineno):
#print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
- 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
+ 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR', 'SYNTAX'):
ctx = result.group('name')
elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
+ elif result.group('name') == 'USE_VALS_EXT':
+ ctx = result.group('name')
+ default_flags = 0xFF
elif result.group('name') == 'FN_HDR':
minp = 1
if (ctx in ('FN_PARS',)) and name: minp = 0
elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
+ elif ctx == 'USE_VALS_EXT':
+ if empty.match(line): continue
+ par = get_par(line, 1, 1, fn=fn, lineno=lineno)
+ if not par: continue
+ flags = default_flags
+ self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno)
elif ctx in ('PDU', 'PDU_NEW'):
if empty.match(line): continue
par = get_par(line, 1, 5, fn=fn, lineno=lineno)
self.add_pdu(par[0:2], is_new, fn, lineno)
if (len(par)>=3):
self.add_register(par[0], par[2:5], fn, lineno)
+ elif ctx in ('SYNTAX'):
+ if empty.match(line): continue
+ par = get_par(line, 1, 2, fn=fn, lineno=lineno)
+ if not par: continue
+ if not self.check_item('PDU', par[0]):
+ self.add_pdu(par[0:1], False, fn, lineno)
+ self.add_syntax(par, fn, lineno)
elif ctx in ('REGISTER', 'REGISTER_NEW'):
if empty.match(line): continue
par = get_par(line, 3, 4, fn=fn, lineno=lineno)
par = self.check_par(par, 1, 1, fn, lineno)
if not par: return
self.ectx.default_external_type_cb = par[0]
+ elif opt in ("-r",):
+ par = self.check_par(par, 1, 1, fn, lineno)
+ if not par: return
+ self.ectx.remove_prefix = par[0]
else:
warnings.warn_explicit("Unknown option %s" % (opt),
UserWarning, fn, lineno)
fn += '-' + ftype
fn += '.' + ext
return fn
- #--- output_fullname -------------------------------------------------------
- def output_fullname(self, ftype, ext='c'):
- return os.path.join(self.outdir, self.output_fname(ftype, ext=ext))
#--- file_open -------------------------------------------------------
def file_open(self, ftype, ext='c'):
- fn = self.output_fullname(ftype, ext=ext)
+ fn = self.output_fname(ftype, ext=ext)
if self.created_file_exists(fn):
fx = file(fn, 'a')
else:
def make_single_file(self):
if (not self.single_file): return
in_nm = self.single_file + '.c'
- out_nm = self.output_fullname('')
+ out_nm = os.path.join(self.outdir, self.output_fname(''))
self.do_include(out_nm, in_nm)
in_nm = self.single_file + '.h'
if (os.path.exists(in_nm)):
- out_nm = self.output_fullname('', ext='h')
+ out_nm = os.path.join(self.outdir, self.output_fname('', ext='h'))
self.do_include(out_nm, in_nm)
if (not self.keep):
for fn in self.created_files_ord:
fout.write(self.fhdr(out_nm))
fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
fout.write('\n')
- fout.write('#line %u "%s"\n' % (1, os.path.basename(in_nm)))
+ fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm)))
include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
if (ifile):
fout.write('\n')
fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
- fout.write('#line %u "%s"\n' % (1, os.path.basename(ifile)))
+ fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile)))
finc = file(ifile, "r")
fout.write(finc.read())
fout.write('\n')
fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
- fout.write('#line %u "%s"\n' % (cont_linenum+1, os.path.basename(in_nm)) )
+ fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) )
finc.close()
else:
fout.write(line)
def fld_obj_repr(self, ectx):
return "/* TO DO %s */" % (str(self))
+
#--- ValueAssignment -------------------------------------------------------------
class ValueAssignment (Node):
def __init__(self,*args, **kw) :
def eth_strings(self):
return 'NULL'
+ def eth_omit_field(self):
+ return False
+
def eth_need_tree(self):
return False
def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
#print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
#print " ", self
- if (ectx.Tag() and (len(self.tags) > tstrip)):
+ if (ectx.NeedTags() and (len(self.tags) > tstrip)):
tagged_type = self
for i in range(len(self.tags)-1, tstrip-1, -1):
tagged_type = TaggedType(val=tagged_type, tstrip=i)
self.eth_reg_sub(vnm, ectx)
if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
- if ident and not tagflag:
+ if ident and not tagflag and not self.eth_omit_field():
ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
if ectx.conform.check_item('SET_TYPE', nm):
virtual_tr.eth_reg_sub(nm, ectx)
for k in list(pars.keys()):
try:
pars[k] = pars[k] % pars
- except (TypeError):
+ except (ValueError,TypeError):
raise sys.exc_info()[0], "%s\n%s" % (str(pars), sys.exc_info()[1])
out = '\n'
out += self.eth_type_default_table(ectx, tname) % pars
self.tag.num),
self.typ.to_python (ctx))
def IsImplicit(self, ectx):
- return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def == 'IMPLICIT')))
+ return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT')))
def GetTag(self, ectx):
tc = ''
return n + str(self.num)
#--- Constraint ---------------------------------------------------------------
+constr_cnt = 0
class Constraint (Node):
def to_python (self, ctx):
print "Ignoring constraint:", self.type
if (int(val) < 0):
return 'M' + str(-int(val))
else:
- return str(val)
+ return str(int(val))
except (ValueError, TypeError):
return asn2c(str(val))
elif self.type == 'Size':
return 'SIZE_' + self.subtype.eth_constrname() + ext
else:
- return 'CONSTR' + str(id(self)) + ext
+ if (not hasattr(self, 'constr_num')):
+ global constr_cnt
+ constr_cnt += 1
+ self.constr_num = constr_cnt
+ return 'CONSTR%03d%s' % (self.constr_num, ext)
class Module (Node):
ectx.eth_dep_add(ident, self.val_name)
def eth_reg_sub(self, ident, ectx):
- self.val_name = ident + '/' + '_untag'
+ self.val_name = ident + '/' + UNTAG_TYPE_NAME
self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
def GetTTag(self, ectx):
#--- SqType -----------------------------------------------------------
class SqType (Type):
def out_item(self, f, val, optional, ext, ectx):
- ef = ectx.field[f]['ethname']
- t = ectx.eth_hf[ef]['ethtype']
- efd = ef
- if (ectx.Ber() and ectx.field[f]['impl']):
- efd += '_impl'
+ if (val.eth_omit_field()):
+ t = ectx.type[val.ident]['ethname']
+ fullname = ectx.dummy_eag_field
+ else:
+ ef = ectx.field[f]['ethname']
+ t = ectx.eth_hf[ef]['ethtype']
+ fullname = ectx.eth_hf[ef]['fullname']
if (ectx.Ber()):
#print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
#print val.str_depth(1)
if (ectx.Ber()):
(tc, tn) = val.GetTag(ectx)
out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
- % ('&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
+ % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t)
elif (ectx.Per()):
out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
- % ('&'+ectx.eth_hf[ef]['fullname'], ext, opt, ectx.eth_type[t]['proto'], t)
+ % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t)
else:
out = ''
return out
#--- SeqType -----------------------------------------------------------
class SeqType (SqType):
- def need_components(self):
+ def all_components(self):
lst = self.elt_list[:]
if hasattr(self, 'ext_list'):
lst.extend(self.ext_list)
if hasattr(self, 'elt_list2'):
lst.extend(self.elt_list2)
+ return lst
+
+ def need_components(self):
+ lst = self.all_components()
for e in (lst):
if e.type == 'components_of':
return True
lst.extend(self.elt_list2)
return lst
+ def eth_reg_sub(self, ident, ectx, components_available=False):
+ # check if autotag is required
+ autotag = False
+ if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
+ autotag = True
+ lst = self.all_components()
+ for e in (self.elt_list):
+ if e.val.HasOwnTag(): autotag = False; break;
+ # expand COMPONENTS OF
+ if self.need_components():
+ if components_available:
+ self.expand_components(ectx)
+ else:
+ ectx.eth_comp_req(ident)
+ return
+ # extension addition groups
+ if hasattr(self, 'ext_list'):
+ if (ectx.Per()): # add names
+ eag_num = 1
+ for e in (self.ext_list):
+ if isinstance(e.val, ExtensionAdditionGroup):
+ e.val.parent_ident = ident
+ e.val.parent_tname = ectx.type[ident]['tname']
+ if (e.val.ver):
+ e.val.SetName("eag_v%s" % (e.val.ver))
+ else:
+ e.val.SetName("eag_%d" % (eag_num))
+ eag_num += 1;
+ else: # expand
+ new_ext_list = []
+ for e in (self.ext_list):
+ if isinstance(e.val, ExtensionAdditionGroup):
+ new_ext_list.extend(e.val.elt_list)
+ else:
+ new_ext_list.append(e)
+ self.ext_list = new_ext_list
+ # do autotag
+ if autotag:
+ atag = 0
+ for e in (self.elt_list):
+ e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
+ atag += 1
+ if autotag and hasattr(self, 'elt_list2'):
+ for e in (self.elt_list2):
+ e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
+ atag += 1
+ if autotag and hasattr(self, 'ext_list'):
+ for e in (self.ext_list):
+ e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
+ atag += 1
+ # register components
+ for e in (self.elt_list):
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ if hasattr(self, 'ext_list'):
+ for e in (self.ext_list):
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ if hasattr(self, 'elt_list2'):
+ for e in (self.elt_list2):
+ e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
+
def eth_type_default_table(self, ectx, tname):
#print "eth_type_default_table(tname='%s')" % (tname)
fname = ectx.eth_type[tname]['ref'][0]
ext = 'ASN1_EXTENSION_ROOT'
else:
ext = 'ASN1_NO_EXTENSIONS'
+ empty_ext_flag = '0'
+ 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)):
+ empty_ext_flag = ext
for e in (self.elt_list):
f = fname + '/' + e.val.name
table += self.out_item(f, e.val, e.optional, ext, ectx)
if (ectx.Ber()):
table += " { NULL, 0, 0, 0, NULL }\n};\n"
else:
- table += " { NULL, 0, 0, NULL }\n};\n"
+ table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag)
return table
#--- SeqOfType -----------------------------------------------------------
if self.val.IsNamed ():
f = fname + '/' + self.val.name
else:
- f = fname + '/' + '_item'
+ f = fname + '/' + ITEM_FIELD_NAME
table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
table += "};\n"
def eth_reg_sub(self, ident, ectx):
itmnm = ident
if not self.val.IsNamed ():
- itmnm += '/' + '_item'
+ itmnm += '/' + ITEM_FIELD_NAME
self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
def eth_tname(self):
def eth_reg_sub(self, ident, ectx):
itmnm = ident
if not self.val.IsNamed ():
- itmnm += '/' + '_item'
+ itmnm += '/' + ITEM_FIELD_NAME
self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
def eth_tname(self):
ctx.outdent ()
return rv
- def eth_reg_sub(self, ident, ectx, components_available=False):
- if self.need_components():
- if components_available:
- self.expand_components(ectx)
- else:
- ectx.eth_comp_req(ident)
- return
- for e in (self.elt_list):
- e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
- if hasattr(self, 'ext_list'):
- for e in (self.ext_list):
- e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
- if hasattr(self, 'elt_list2'):
- for e in (self.elt_list2):
- e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
-
def eth_need_tree(self):
return True
body = '#error Can not decode %s' % (tname)
return body
-#--- SetType ------------------------------------------------------------------
-class SetType(SeqType):
+#--- ExtensionAdditionGroup ---------------------------------------------------
+class ExtensionAdditionGroup (SeqType):
+ def __init__(self,*args, **kw) :
+ self.parent_ident = None
+ self.parent_tname = None
+ SeqType.__init__ (self,*args, **kw)
- def eth_reg_sub(self, ident, ectx, components_available=False):
- if self.need_components():
- if components_available:
- self.expand_components(ectx)
- else:
- ectx.eth_comp_req(ident)
- return
- for e in (self.elt_list):
- e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
- if hasattr(self, 'ext_list'):
- for e in (self.ext_list):
- e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
+ def eth_omit_field(self):
+ return True
+
+ def eth_tname(self):
+ if (self.parent_tname and self.IsNamed()):
+ return self.parent_tname + "_" + self.name
+ else:
+ return SeqType.eth_tname(self)
+
+ def eth_reg_sub(self, ident, ectx):
+ ectx.eth_dummy_eag_field_required()
+ ectx.eth_dep_add(self.parent_ident, ident)
+ SeqType.eth_reg_sub(self, ident, ectx)
+
+ def eth_type_default_pars(self, ectx, tname):
+ pars = Type.eth_type_default_pars(self, ectx, tname)
+ pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
+ return pars
+
+ def eth_type_default_body(self, ectx, tname):
+ if (ectx.Per()):
+ body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset',
+ par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
+ else:
+ body = '#error Can not decode %s' % (tname)
+ return body
+
+
+#--- SetType ------------------------------------------------------------------
+class SetType (SeqType):
def eth_need_tree(self):
return True
def eth_reg_sub(self, ident, ectx):
#print "eth_reg_sub(ident='%s')" % (ident)
+ # check if autotag is required
+ autotag = False
+ if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
+ autotag = True
+ for e in (self.elt_list):
+ if e.HasOwnTag(): autotag = False; break;
+ if autotag and hasattr(self, 'ext_list'):
+ for e in (self.ext_list):
+ if e.HasOwnTag(): autotag = False; break;
+ # do autotag
+ if autotag:
+ atag = 0
+ for e in (self.elt_list):
+ e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
+ atag += 1
+ if autotag and hasattr(self, 'ext_list'):
+ for e in (self.ext_list):
+ e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
+ atag += 1
for e in (self.elt_list):
e.eth_reg(ident, ectx, tstrip=1, parent=ident)
if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
f = fname + '/' + e.name
ef = ectx.field[f]['ethname']
t = ectx.eth_hf[ef]['ethtype']
- efd = ef
- if (ectx.field[f]['impl']):
- efd += '_impl'
if (ectx.Ber()):
opt = ''
if (not e.HasOwnTag()):
ext = 'ASN1_EXTENSION_ROOT'
else:
ext = 'ASN1_NO_EXTENSIONS'
+ empty_ext_flag = '0'
+ if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0):
+ empty_ext_flag = ext
for e in (self.elt_list):
if (tagval): val = e.GetTag(ectx)[1]
else: val = str(cnt)
if (ectx.Ber()):
table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
else:
- table += " { 0, NULL, 0, NULL }\n};\n"
+ table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag)
return table
def eth_type_default_body(self, ectx, tname):
vv = '0x'
vv += self.val[1:-2]
return vv
+ def __int__(self):
+ return int(self.val[1:-2], 16)
#--- FieldSpec ----------------------------------------------------------------
class FieldSpec (Node):
def p_TagDefault_1 (t):
'''TagDefault : EXPLICIT TAGS
- | IMPLICIT TAGS
- | AUTOMATIC TAGS'''
+ | IMPLICIT TAGS
+ | AUTOMATIC TAGS '''
t[0] = Default_Tags (dfl_tag = t[1])
def p_TagDefault_2 (t):
if 'ext_list' in t[3]:
t[0].ext_list = t[3]['ext_list']
if 'elt_list2' in t[3]:
- t[0].ext_list = t[3]['elt_list2']
+ t[0].elt_list2 = t[3]['elt_list2']
def p_ExtensionAndException_1 (t):
'ExtensionAndException : ELLIPSIS'
'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
t[0] = {'elt_list' : [], 'ext_list' : t[2]}
-#def p_RootComponentTypeList (t):
-# 'RootComponentTypeList : ComponentTypeList'
-# t[0] = t[1]
-
def p_ExtensionEndMarker (t):
'ExtensionEndMarker : COMMA ELLIPSIS'
pass
-#def p_extension_additions_1 (t):
-# 'extension_additions : extension_addition_list'
-# t[0] = t[1]
-
-#def p_extension_additions_2 (t):
-# 'extension_additions : '
-# t[0] = []
-
def p_ExtensionAdditionList_1 (t):
- 'ExtensionAdditionList : COMMA extension_addition'
+ 'ExtensionAdditionList : COMMA ExtensionAddition'
t[0] = [t[2]]
def p_ExtensionAdditionList_2 (t):
- 'ExtensionAdditionList : ExtensionAdditionList COMMA extension_addition'
+ 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
t[0] = t[1] + [t[3]]
-def p_extension_addition_1 (t):
- 'extension_addition : ComponentType'
- t[0] = t[1]
+def p_ExtensionAddition_1 (t):
+ 'ExtensionAddition : ExtensionAdditionGroup'
+ t[0] = Node ('elt_type', val = t[1], optional = 0)
+
+def p_ExtensionAddition_2 (t):
+ 'ExtensionAddition : ComponentType'
+ t[0] = t[1]
+
+def p_ExtensionAdditionGroup (t):
+ 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
+ t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3])
+
+def p_VersionNumber_1 (t):
+ 'VersionNumber : '
+
+def p_VersionNumber_2 (t):
+ 'VersionNumber : NUMBER COLON'
+ t[0] = t[1]
def p_ComponentTypeList_1 (t):
'ComponentTypeList : ComponentType'
def p_SetType_2 (t):
'SetType : SET LBRACE ComponentTypeLists RBRACE'
+ t[0] = SetType (elt_list = t[3]['elt_list'])
if 'ext_list' in t[3]:
- t[0] = SetType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
- else:
- t[0] = SetType (elt_list = t[3]['elt_list'])
+ t[0].ext_list = t[3]['ext_list']
+ if 'elt_list2' in t[3]:
+ t[0].elt_list2 = t[3]['elt_list2']
# 27 Notation for set-of types ------------------------------------------------
# 28.1
def p_ChoiceType (t):
- 'ChoiceType : CHOICE LBRACE alternative_type_lists RBRACE'
+ 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
if 'ext_list' in t[3]:
t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
else:
t[0] = ChoiceType (elt_list = t[3]['elt_list'])
-def p_alternative_type_lists_1 (t):
- 'alternative_type_lists : alternative_type_list'
+def p_AlternativeTypeLists_1 (t):
+ 'AlternativeTypeLists : AlternativeTypeList'
t[0] = {'elt_list' : t[1]}
-def p_alternative_type_lists_2 (t):
- '''alternative_type_lists : alternative_type_list COMMA ExtensionAndException extension_addition_alternatives OptionalExtensionMarker'''
+def p_AlternativeTypeLists_2 (t):
+ 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
-def p_extension_addition_alternatives_1 (t):
- 'extension_addition_alternatives : extension_addition_alternatives_list'
+def p_ExtensionAdditionAlternatives_1 (t):
+ 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
t[0] = t[1]
-def p_extension_addition_alternatives_2 (t):
- 'extension_addition_alternatives : '
+def p_ExtensionAdditionAlternatives_2 (t):
+ 'ExtensionAdditionAlternatives : '
t[0] = []
-def p_extension_addition_alternatives_list_1 (t):
- 'extension_addition_alternatives_list : COMMA extension_addition_alternative'
- t[0] = [t[2]]
+def p_ExtensionAdditionAlternativesList_1 (t):
+ 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
+ t[0] = t[2]
-def p_extension_addition_alternatives_list_2 (t):
- 'extension_addition_alternatives_list : extension_addition_alternatives_list COMMA extension_addition_alternative'
- t[0] = t[1] + [t[3]]
+def p_ExtensionAdditionAlternativesList_2 (t):
+ 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
+ t[0] = t[1] + t[3]
-def p_extension_addition_alternative_1 (t):
- 'extension_addition_alternative : NamedType'
+def p_ExtensionAdditionAlternative_1 (t):
+ 'ExtensionAdditionAlternative : NamedType'
+ t[0] = [t[1]]
+
+def p_ExtensionAdditionAlternative_2 (t):
+ 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
t[0] = t[1]
-def p_alternative_type_list_1 (t):
- 'alternative_type_list : NamedType'
+def p_ExtensionAdditionAlternativesGroup (t):
+ 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
+ t[0] = t[3]
+
+def p_AlternativeTypeList_1 (t):
+ 'AlternativeTypeList : NamedType'
t[0] = [t[1]]
-def p_alternative_type_list_2 (t):
- 'alternative_type_list : alternative_type_list COMMA NamedType'
+def p_AlternativeTypeList_2 (t):
+ 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
t[0] = t[1] + [t[3]]
# 28.10
-p proto : Protocol name (implies -S). Default is module-name
from input_file (renamed by #.MODULE if present)
-o name : Output files name core (default is <proto>)
- -O dir : Output directory
+ -O dir : Output directory for dissector
-c cnf_file : Conformance file
-I path : Path for conformance file includes
-e : Create conformance file for exported types
-L : Suppress #line directive from .cnf file
-D dir : Directory for input_file(s) (default: '.')
-C : Add check for SIZE constraints
+ -r prefix : Remove the prefix from type names
input_file(s) : Input ASN.1 file(s)
global lexer
print "ASN.1 to Wireshark dissector compiler";
try:
- opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLC");
+ opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:");
except getopt.GetoptError:
eth_usage(); sys.exit(2)
if len(args) < 1: