aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-10-01 19:54:46 +0000
committerGuy Harris <guy@alum.mit.edu>2004-10-01 19:54:46 +0000
commit6aad0b0543480ffbb4a089fecd873a895922e28c (patch)
treeba1e56acf5a0553217a6758e15f2b618cc79d6dd /tools
parent017d788da09a70cd6fea59403f8126f05a809ed1 (diff)
From Tomas Kukosa:
- fix for protocol registration (register_dissector() does not return handle) - new directive REGISTER which can register PDU more than once - implicit tagging environment is supported svn path=/trunk/; revision=12177
Diffstat (limited to 'tools')
-rw-r--r--tools/asn2eth.py141
1 files changed, 86 insertions, 55 deletions
diff --git a/tools/asn2eth.py b/tools/asn2eth.py
index 85870429a2..174b155c04 100644
--- a/tools/asn2eth.py
+++ b/tools/asn2eth.py
@@ -17,7 +17,7 @@
# http://www.pobox.com/~asl2/software/PyZ3950/
# (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
#
-# It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 1.3.1)
+# It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 1.5)
# http://systems.cs.uchicago.edu/ply/
#
#
@@ -1040,10 +1040,9 @@ class EthCtx:
dis = self.proto
if (pdu['reg'] != '.'):
dis += '.' + pdu['reg']
- ret = ''
+ fx.write(' register_dissector("%s", dissect_%s, proto_%s);\n' % (dis, f, self.eproto))
if (not pdu['hidden']):
- ret = '%s_handle = ' % (asn2c(dis))
- fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (ret, dis, f, self.eproto))
+ fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
fempty = False
fx.write('\n')
self.output.file_close(fx, discard=fempty)
@@ -1052,22 +1051,27 @@ class EthCtx:
def eth_output_dis_tab(self):
fx = self.output.file_open('dis-tab')
fempty = True
- for f in self.eth_hfpdu_ord:
- pdu = self.eth_hf[f]['pdu']
- if (pdu and pdu.has_key('rtype')):
- if (pdu['rtype'] in ('NUM', 'STR')):
- rstr = ''
- if (pdu['rtype'] == 'STR'): rstr = '_string'
- if (pdu and pdu['reg'] and not pdu['hidden']):
- dis = self.proto
- if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
+ for k in self.conform.get_order('REGISTER'):
+ reg = self.conform.use_item('REGISTER', k)
+ if not self.field.has_key(reg['pdu']): continue
+ f = self.field[reg['pdu']]['ethname']
+ pdu = self.eth_hf[f]['pdu']
+ if (reg['rtype'] in ('NUM', 'STR')):
+ rstr = ''
+ if (reg['rtype'] == 'STR'): rstr = '_string'
+ if (pdu['reg']):
+ dis = self.proto
+ if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
+ if (not pdu['hidden']):
hnd = '%s_handle' % (asn2c(dis))
else:
- hnd = 'create_dissector_handle(dissect_%s, proto_%s)' % (f, self.eproto)
- fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, pdu['rtable'], pdu['rport'], hnd))
- elif (pdu['rtype'] in ('BER', 'PER')):
- fx.write(' register_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (pdu['rtype'].lower(), pdu['roid'], f, self.eproto, pdu['roidname']))
- fempty = False
+ hnd = 'find_dissector("%s")' % (dis)
+ else:
+ hnd = 'create_dissector_handle(dissect_%s, proto_%s)' % (f, self.eproto)
+ fx.write(' dissector_add%s("%s", %s, %s);\n' % (rstr, reg['rtable'], reg['rport'], hnd))
+ elif (reg['rtype'] in ('BER', 'PER')):
+ fx.write(' register_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (reg['rtype'].lower(), reg['roid'], f, self.eproto, reg['roidname']))
+ fempty = False
fx.write('\n')
self.output.file_close(fx, discard=fempty)
@@ -1103,10 +1107,12 @@ class EthCnf:
def __init__(self):
self.tblcfg = {}
self.table = {}
+ self.order = {}
self.fn = {}
# 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['PDU'] = { '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.tblcfg['MODULE_IMPORT'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
@@ -1123,6 +1129,7 @@ class EthCnf:
for k in self.tblcfg.keys() :
self.table[k] = {}
+ self.order[k] = []
def add_item(self, table, key, fn, lineno, **kw):
if self.tblcfg[table]['chk_dup'] and self.table[table].has_key(key):
@@ -1132,6 +1139,10 @@ class EthCnf:
return
self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
self.table[table][key].update(kw)
+ self.order[table].append(key)
+
+ def get_order(self, table):
+ return self.order[table]
def check_item(self, table, key):
return self.table[table].has_key(key)
@@ -1167,6 +1178,39 @@ class EthCnf:
return '';
return self.fn[name][ctx]['text']
+ def add_pdu(self, par, fn, lineno):
+ #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
+ (reg, hidden) = (None, False)
+ if (len(par) > 1): reg = par[1]
+ if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
+ attr = {'reg' : reg, 'hidden' : hidden}
+ self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
+ return
+
+ def add_register(self, pdu, par, fn, lineno):
+ #print "add_pdu(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
+ if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
+ elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
+ elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
+ elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
+ else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
+ if ((len(par)-1) < pmin):
+ warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
+ return
+ if ((len(par)-1) > pmax):
+ warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
+ attr = {'pdu' : pdu, 'rtype' : rtype}
+ if (rtype in ('NUM', 'STR')):
+ attr['rtable'] = par[1]
+ attr['rport'] = par[2]
+ rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
+ elif (rtype in ('BER', 'PER')):
+ attr['roid'] = par[1]
+ attr['roidname'] = '""'
+ if (len(par)>=3): attr['roidname'] = par[2]
+ rkey = '/'.join([rtype, attr['roid']])
+ self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
+
def read(self, fn):
def get_par(line, pmin, pmax, fn, lineno):
par = line.split(None, pmax)
@@ -1243,7 +1287,7 @@ class EthCnf:
if comment.search(line): continue
result = directive.search(line)
if result: # directive
- if result.group('name') in ('EXPORTS', 'PDU', 'USER_DEFINED', 'NO_EMIT', 'MODULE_IMPORT', 'OMIT_ASSIGNMENT',
+ if result.group('name') in ('EXPORTS', 'PDU', 'REGISTER', 'USER_DEFINED', 'NO_EMIT', 'MODULE_IMPORT', 'OMIT_ASSIGNMENT',
'TYPE_RENAME', 'FIELD_RENAME', 'IMPORT_TAG',
'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
ctx = result.group('name')
@@ -1293,32 +1337,16 @@ class EthCnf:
if empty.match(line): continue
par = get_par(line, 1, 5, fn=fn, lineno=lineno)
if not par: continue
- (reg, hidden) = (None, False)
- if (len(par) > 1): reg = par[1]
- if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
- attr = {'reg' : reg, 'hidden' : hidden}
- rtype = None
+ self.add_pdu(par[0:2], fn, lineno)
if (len(par)>=3):
- if (par[2] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
- elif (par[2] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
- elif (par[2] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
- elif (par[2] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
- else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno)
- if (rtype and ((len(par)-3) < pmin)):
- warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
- rtype = None
- if (rtype and ((len(par)-3) > pmax)):
- warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
- if (rtype):
- attr['rtype'] = rtype
- if (rtype in ('NUM', 'STR')):
- attr['rtable'] = par[3]
- attr['rport'] = par[4]
- elif (rtype in ('BER', 'PER')):
- attr['roid'] = par[3]
- attr['roidname'] = '""'
- if (len(par)>=5): attr['roidname'] = par[4]
- self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
+ self.add_register(par[0], par[2:5], fn, lineno)
+ elif ctx == 'REGISTER':
+ if empty.match(line): continue
+ par = get_par(line, 3, 4, fn=fn, lineno=lineno)
+ if not par: continue
+ if not self.check_item('PDU', par[0]):
+ self.add_pdu(par[0:1], fn, lineno)
+ self.add_register(par[0], par[1:4], fn, lineno)
elif ctx == 'MODULE_IMPORT':
if empty.match(line): continue
par = get_par(line, 2, 2, fn=fn, lineno=lineno)
@@ -1501,7 +1529,7 @@ class Node:
l.append (x.str_depth (depth+1))
else:
l.append (indent + " " + str(x) + "\n")
- return keystr + "[\n" + ''.join (l) + indent + "]\n"
+ return keystr + "[\n" + ''.join(l) + indent + "]\n"
else:
return keystr + str (child) + "\n"
def str_depth (self, depth): # ugh
@@ -1551,8 +1579,10 @@ class Type (Node):
def HasOwnTag(self):
return self.__dict__.has_key('tag')
- def HasImplicitTag(self):
- return self.HasOwnTag() and (self.tag.mode == 'IMPLICIT')
+ def HasImplicitTag(self, ectx):
+ return (self.HasOwnTag() and
+ ((self.tag.mode == 'IMPLICIT') or
+ ((self.tag.mode == 'default') and (ectx.tag_def == 'IMPLICIT'))))
def IndetermTag(self, ectx):
return False
@@ -1615,7 +1645,7 @@ class Type (Node):
if self.type == 'Type_Ref':
ectx.eth_reg_type(nm, self)
if (ectx.conform.check_item('PDU', nm)):
- ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(), pdu=ectx.conform.use_item('PDU', nm))
+ ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
if self.type == 'Type_Ref':
if ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm):
ectx.eth_reg_type(nm, self) # new type
@@ -1626,9 +1656,9 @@ class Type (Node):
ectx.eth_reg_type(nm, self)
if ident:
if self.type == 'Type_Ref':
- ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag())
+ ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
else:
- ectx.eth_reg_field(nm, nm, idx=idx, parent=parent, impl=self.HasImplicitTag())
+ ectx.eth_reg_field(nm, nm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
self.eth_reg_sub(nm, ectx)
def eth_get_size_constr(self, ):
@@ -1709,6 +1739,7 @@ class Module (Node):
def to_eth (self, ectx):
if (not ectx.proto):
ectx.proto = self.ident.val
+ ectx.tag_def = self.tag_def.dfl_tag
self.body.to_eth(ectx)
class Module_Body (Node):
@@ -1830,7 +1861,7 @@ class SqType (Type):
efd = ef
if (ectx.OBer() and ectx.field[f]['impl']):
efd += '_impl'
- if (ectx.encoding == 'ber'):
+ 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)
opt = ''
@@ -1839,7 +1870,7 @@ class SqType (Type):
if (not val.HasOwnTag()):
if (opt): opt += '|'
opt += 'BER_FLAGS_NOOWNTAG'
- elif (val.HasImplicitTag()):
+ elif (val.HasImplicitTag(ectx)):
if (opt): opt += '|'
opt += 'BER_FLAGS_IMPLTAG'
if (val.IndetermTag(ectx)):
@@ -2072,7 +2103,7 @@ class SequenceType (SqType):
for e in (self.ext_list):
f = fname + '/' + e.val.name
out += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
- if (ectx.encoding == 'ber'):
+ if (ectx.Ber()):
out += " { 0, 0, 0, NULL }\n};\n"
else:
out += " { NULL, 0, 0, NULL }\n};\n"
@@ -2248,7 +2279,7 @@ class ChoiceType (Type):
efd = ef
if (ectx.field[f]['impl']):
efd += '_impl'
- if (ectx.encoding == 'ber'):
+ if (ectx.Ber()):
opt = ''
if (not e.HasOwnTag()):
opt = 'BER_FLAGS_NOOWNTAG'
@@ -2305,7 +2336,7 @@ class ChoiceType (Type):
else: val = str(cnt)
out += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
cnt += 1
- if (ectx.encoding == 'ber'):
+ if (ectx.Ber()):
out += " { 0, 0, 0, 0, NULL }\n};\n"
else:
out += " { 0, NULL, 0, NULL }\n};\n"