3 # File : wireshark_be.py
5 # Author : Frank Singleton (frank.singleton@ericsson.com)
7 # Copyright (C) 2001 Frank Singleton, Ericsson Inc.
9 # This file is a backend to "omniidl", used to generate "Wireshark"
10 # dissectors from IDL descriptions. The output language generated
11 # is "C". It will generate code to use the GIOP/IIOP get_CDR_XXX API.
13 # Please see packet-giop.h in Wireshark distro for API description.
14 # Wireshark is available at https://www.wireshark.org/
16 # Omniidl is part of the OmniOrb distribution, and is available at
17 # http://omniorb.sourceforge.net
19 # SPDX-License-Identifier: GPL-2.0-or-later
24 # Omniidl Back-end which parses an IDL data structure provided by the frontend
25 # and generates packet-idl-xxx.[ch] for compiling as a dissector in Wireshark.
30 # Crawl all the way down all branches until I hit "Operation", "Enum", "Attribute",
31 # "Struct" and "Union" nodes. Then store these nodes in lists.
33 # Pass these lists (via an object ref) to the src code
34 # generator (wireshark_gen) class and let it do the hard work !
37 # Don't forget structs can contain embedded structs etc .. so don't forget
38 # to peek inside and check :-)
41 """Wireshark IDL compiler back-end."""
43 from __future__
import print_function
49 from omniidl
import idlast
, idltype
, output
51 from wireshark_gen
import wireshark_gen_C
54 class WiresharkVisitor
:
55 """This class finds the "Operation" nodes ,Enum Nodes, "Attribute" nodes, Struct Nodes
56 and Union Nodes. Then it hands them off to an instance of the source code generator
57 class "wireshark_gen" """
59 def __init__(self
, st
, debug
=False):
62 self
.oplist
= [] # list of operation nodes
63 self
.enlist
= [] # list of enum nodes
64 self
.atlist
= [] # list of attribute nodes
65 self
.stlist
= [] # list of struct nodes
66 self
.unlist
= [] # list of union nodes
68 def visitAST(self
, node
):
70 print("XXX visitAST() node = ", node
)
72 for n
in node
.declarations():
73 if isinstance(n
, idlast
.Module
):
75 if isinstance(n
, idlast
.Interface
):
76 self
.visitInterface(n
)
77 if isinstance(n
, idlast
.Operation
):
78 self
.visitOperation(n
)
79 if isinstance(n
, idlast
.Attribute
):
80 self
.visitAttribute(n
)
81 if isinstance(n
, idlast
.Enum
):
83 if isinstance(n
, idlast
.Struct
):
85 if isinstance(n
, idlast
.Union
):
88 # Check for Typedef structs and unions
90 if isinstance(n
, idlast
.Typedef
):
91 self
.visitTypedef(n
) # who are you ?
93 def visitModule(self
, node
):
95 print("XXX visitModule() node = ", node
)
97 for n
in node
.definitions():
98 if isinstance(n
, idlast
.Module
):
100 if isinstance(n
, idlast
.Interface
):
101 self
.visitInterface(n
)
102 if isinstance(n
, idlast
.Operation
):
103 self
.visitOperation(n
)
104 if isinstance(n
, idlast
.Attribute
):
105 self
.visitAttribute(n
)
106 if isinstance(n
, idlast
.Enum
):
108 if isinstance(n
, idlast
.Struct
):
110 if isinstance(n
, idlast
.Union
):
113 # Check for Typedef structs and unions
115 if isinstance(n
, idlast
.Typedef
):
116 self
.visitTypedef(n
) # who are you ?
118 def visitInterface(self
, node
):
120 print("XXX visitInterface() node = ", node
)
122 for c
in node
.callables():
123 if isinstance(c
, idlast
.Operation
):
124 self
.visitOperation(c
)
125 if isinstance(c
, idlast
.Attribute
):
126 self
.visitAttribute(c
)
128 for d
in node
.contents():
129 if isinstance(d
, idlast
.Enum
):
132 if isinstance(d
, idlast
.Struct
):
135 if isinstance(d
, idlast
.Union
):
138 # Check for Typedef structs and unions
140 if isinstance(d
, idlast
.Typedef
):
141 self
.visitTypedef(d
) # who are you ?
143 def visitOperation(self
, opnode
):
144 """populates the operations node list "oplist" """
145 if opnode
not in self
.oplist
:
146 self
.oplist
.append(opnode
) # store operation node
148 def visitAttribute(self
, atnode
):
149 """populates the attribute node list "atlist" """
150 if atnode
not in self
.atlist
:
151 self
.atlist
.append(atnode
) # store attribute node
153 def visitEnum(self
, enode
):
154 """populates the Enum node list "enlist" """
155 if enode
not in self
.enlist
:
156 self
.enlist
.append(enode
) # store enum node if unique
158 def visitTypedef(self
, td
):
159 """Search to see if its a typedef'd struct, union, or enum
161 eg: typdef enum colors {red, green, blue } mycolors;
164 d
= td
.aliasType() # get Type, possibly Declared
165 if isinstance(d
, idltype
.Declared
):
166 self
.visitDeclared(d
)
168 def visitDeclared(self
, d
):
169 """Search to see if its a struct, union, or enum"""
170 if isinstance(d
, idltype
.Declared
):
171 sue
= d
.decl() # grab the struct or union or enum
173 if isinstance(sue
, idlast
.Struct
):
174 self
.visitStruct(sue
)
175 if isinstance(sue
, idlast
.Union
):
177 if isinstance(sue
, idlast
.Enum
):
180 def visitStruct(self
, stnode
):
181 # populates the struct node list "stlist"
182 # and checks its members also
183 if stnode
not in self
.stlist
:
184 self
.stlist
.append(stnode
) # store struct node if unique and avoid recursive loops
185 # if we come across recursive structs
187 for m
in stnode
.members(): # find embedded struct definitions within this
189 if isinstance(mt
, idltype
.Declared
):
190 self
.visitDeclared(mt
) # if declared, then check it out
192 def visitUnion(self
, unnode
):
193 # populates the struct node list "unlist"
194 # and checks its members also
195 if unnode
not in self
.unlist
:
196 self
.unlist
.append(unnode
) # store union node if unique
198 if unnode
.constrType(): # enum defined within switch type
199 if isinstance(unnode
.switchType(), idltype
.Declared
):
200 self
.visitDeclared(unnode
.switchType())
202 for c
in unnode
.cases():
204 if isinstance(ct
, idltype
.Declared
):
205 self
.visitDeclared(ct
) # if declared, then check it out
210 DEBUG
= "debug" in args
211 AGGRESSIVE
= "aggressive" in args
213 st
= output
.Stream(sys
.stdout
, 4) # set indent for stream
214 ev
= WiresharkVisitor(st
, DEBUG
) # create visitor object
216 ev
.visitAST(tree
) # go find some operations
218 # Grab name of main IDL file being compiled.
220 # Assumption: Name is of the form abcdefg.xyz (eg: CosNaming.idl)
222 fname
= path
.basename(tree
.file()) # grab basename only, don't care about path
223 nl
= fname
.split(".")[0] # split name of main IDL file using "." as separator
224 # and grab first field (eg: CosNaming)
228 print("XXX - Operation node ", i
, " repoId() = ", i
.repoId())
230 print("XXX - Attribute node ", i
, " identifiers() = ", i
.identifiers())
232 print("XXX - Enum node ", i
, " repoId() = ", i
.repoId())
234 print("XXX - Struct node ", i
, " repoId() = ", i
.repoId())
236 print("XXX - Union node ", i
, " repoId() = ", i
.repoId())
238 # create a C generator object
239 # and generate some C code
241 eg
= wireshark_gen_C(ev
.st
,
244 nl
.capitalize() + " Dissector Using GIOP API",
246 aggressive
=AGGRESSIVE
)
248 eg
.genCode(ev
.oplist
, ev
.atlist
, ev
.enlist
, ev
.stlist
, ev
.unlist
) # pass them onto the C generator
251 # Editor modelines - https://www.wireshark.org/tools/modelines.html
255 # indent-tabs-mode: nil
258 # vi: set shiftwidth=4 expandtab:
259 # :indentSize=4:noTabs=true: