blob: 7113281b6517a0bba003f5dd6abfce0afd8fe681 [file] [log] [blame]
Rich Lane9cfa1652013-10-01 21:24:04 -07001:: # Copyright 2013, Big Switch Networks, Inc.
2:: #
3:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4:: # the following special exception:
5:: #
6:: # LOXI Exception
7:: #
8:: # As a special exception to the terms of the EPL, you may distribute libraries
9:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
11:: # from the LoxiGen Libraries and the notice provided below is (i) included in
12:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13:: # documentation for the LoxiGen Libraries, if distributed in binary form.
14:: #
15:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16:: #
17:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18:: # a copy of the EPL at:
19:: #
20:: # http://www.eclipse.org/legal/epl-v10.html
21:: #
22:: # Unless required by applicable law or agreed to in writing, software
23:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25:: # EPL for the specific language governing permissions and limitations
26:: # under the EPL.
27::
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080028:: import loxi_globals
29:: ir = loxi_globals.ir
Rich Laneeb10d162013-10-01 21:15:35 -070030:: include('_copyright.lua')
Rich Lane422d1b12013-06-04 13:09:17 -070031
Rich Lane872b95a2013-06-17 18:39:14 -070032:: include('_ofreader.lua')
33
Rich Lane7708c182013-10-01 23:27:27 -070034:: include('_oftype_readers.lua')
35
Rich Lane422d1b12013-06-04 13:09:17 -070036p_of = Proto ("of", "OpenFlow")
37
Rich Lane972be332013-06-04 13:36:48 -070038local openflow_versions = {
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080039:: for version in loxi_globals.OFVersions.all_supported:
40 [${version.wire_version}] = "${version.version}",
Rich Lane972be332013-06-04 13:36:48 -070041:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070042}
43
Rich Lane972be332013-06-04 13:36:48 -070044:: for version, ofproto in ir.items():
45:: for enum in ofproto.enums:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080046local enum_v${version.wire_version}_${enum.name} = {
Rich Lane972be332013-06-04 13:36:48 -070047:: for (name, value) in enum.values:
48 [${value}] = "${name}",
49:: #endfor
50}
51
52:: #endfor
53
54:: #endfor
55
Tomasz635e20a2013-10-23 16:14:29 -070056
Rich Lane364e0292013-10-01 21:05:57 -070057fields = {}
Rich Laneb014bcf2013-06-19 11:14:11 -070058:: for field in fields:
Rich Lane4df40f32013-10-08 15:40:39 -070059:: if field.type in ["uint8", "uint16", "uint32", "uint64"]:
Rich Lane52452662013-10-25 13:34:42 -070060fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}", base.${field.base}, ${field.enum_table})
Rich Lane4df40f32013-10-08 15:40:39 -070061:: elif field.type in ["ipv4", "ipv6", "ether", "bytes", "stringz"]:
62fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}")
63:: else:
64:: raise NotImplementedError("unknown Wireshark type " + field.type)
65:: #endif
Rich Laneb014bcf2013-06-19 11:14:11 -070066:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070067
68p_of.fields = {
Rich Laneb014bcf2013-06-19 11:14:11 -070069:: for field in fields:
Rich Lane364e0292013-10-01 21:05:57 -070070 fields[${repr(field.fullname)}],
Rich Laneb014bcf2013-06-19 11:14:11 -070071:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070072}
73
Rich Lane4bbdcf52013-10-01 22:07:35 -070074-- Subclass maps for virtual classes
Rich Lane96641df2013-06-10 13:36:35 -070075:: for version, ofproto in ir.items():
Rich Lane4bbdcf52013-10-01 22:07:35 -070076:: for ofclass in ofproto.classes:
77:: if ofclass.virtual:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080078${ofclass.name}_v${version.wire_version}_dissectors = {}
Rich Lane4bbdcf52013-10-01 22:07:35 -070079:: #endif
Rich Lane96641df2013-06-10 13:36:35 -070080:: #endfor
Rich Lane96641df2013-06-10 13:36:35 -070081:: #endfor
82
Rich Lane4bbdcf52013-10-01 22:07:35 -070083--- Dissectors for each class
84
Rich Lane96641df2013-06-10 13:36:35 -070085:: for version, ofproto in ir.items():
86:: for ofclass in ofproto.classes:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080087:: name = 'dissect_%s_v%d' % (ofclass.name, version.wire_version)
Rich Lane7708c182013-10-01 23:27:27 -070088:: include('_ofclass_dissector.lua', name=name, ofclass=ofclass, version=version)
Rich Lane4bbdcf52013-10-01 22:07:35 -070089:: if ofclass.superclass:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080090:: discriminator = ofclass.superclass.discriminator
Rich Lane586864e2013-10-01 23:26:35 -070091:: discriminator_value = ofclass.member_by_name(discriminator.name).value
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080092${ofclass.superclass.name}_v${version.wire_version}_dissectors[${discriminator_value}] = ${name}
Rich Lane96641df2013-06-10 13:36:35 -070093
94:: #endif
95:: #endfor
96:: #endfor
97
Rich Lane4bbdcf52013-10-01 22:07:35 -070098local of_message_dissectors = {
99:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800100 [${version.wire_version}] = of_header_v${version.wire_version}_dissectors,
Rich Lane4bbdcf52013-10-01 22:07:35 -0700101:: #endfor
102}
103
Tomasz742c2ba2013-10-24 22:35:45 -0700104local of_oxm_dissectors = {
105:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800106 [${version.wire_version}] = of_oxm_v${version.wire_version}_dissectors,
Tomasz742c2ba2013-10-24 22:35:45 -0700107:: #endfor
108}
109
110local of_action_dissectors = {
111:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800112 [${version.wire_version}] = of_action_v${version.wire_version}_dissectors,
Tomasz742c2ba2013-10-24 22:35:45 -0700113:: #endfor
114}
115
116local of_instruction_dissectors = {
117:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800118 [${version.wire_version}] = of_instruction_v${version.wire_version}_dissectors,
Tomasz742c2ba2013-10-24 22:35:45 -0700119:: #endfor
120}
121
Tomasza17a6692013-10-30 17:34:18 -0700122local of_bucket_dissectors = {
123:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800124 [${version.wire_version}] = dissect_of_bucket_v${version.wire_version},
Tomasza17a6692013-10-30 17:34:18 -0700125:: #endfor
126}
127
Tomaszc595d5b2013-11-02 13:30:32 -0700128local of_port_desc_dissectors = {
129:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800130 [${version.wire_version}] = dissect_of_port_desc_v${version.wire_version},
Tomaszc595d5b2013-11-02 13:30:32 -0700131:: #endfor
132}
133
134local of_stats_reply_dissectors = {
135:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800136 [${version.wire_version}] = of_stats_reply_v${version.wire_version}_dissectors,
Tomaszc595d5b2013-11-02 13:30:32 -0700137:: #endfor
138}
139
140local of_stats_request_dissectors = {
141:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800142 [${version.wire_version}] = of_stats_request_v${version.wire_version}_dissectors,
Tomaszc595d5b2013-11-02 13:30:32 -0700143:: #endfor
144}
145
146local of_flow_stats_entry_dissectors = {
147:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800148 [${version.wire_version}] = dissect_of_flow_stats_entry_v${version.wire_version},
Tomaszc595d5b2013-11-02 13:30:32 -0700149:: #endfor
150}
151
152local of_port_stats_entry_dissectors = {
153:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800154 [${version.wire_version}] = dissect_of_port_stats_entry_v${version.wire_version},
Tomaszc595d5b2013-11-02 13:30:32 -0700155:: #endfor
156}
157
158local of_table_stats_entry_dissectors = {
159:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800160 [${version.wire_version}] = dissect_of_table_stats_entry_v${version.wire_version},
Tomaszc595d5b2013-11-02 13:30:32 -0700161:: #endfor
162}
163
164local of_queue_stats_entry_dissectors = {
165:: for version in ir:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800166 [${version.wire_version}] = dissect_of_queue_stats_entry_v${version.wire_version},
Tomaszc595d5b2013-11-02 13:30:32 -0700167:: #endfor
168}
169
Rich Lane96641df2013-06-10 13:36:35 -0700170function dissect_of_message(buf, root)
Rich Lane93991e42013-10-01 22:24:51 -0700171 local reader = OFReader.new(buf)
Rich Lane422d1b12013-06-04 13:09:17 -0700172 local subtree = root:add(p_of, buf(0))
Rich Lane96641df2013-06-10 13:36:35 -0700173 local version_val = buf(0,1):uint()
Rich Lane422d1b12013-06-04 13:09:17 -0700174 local type_val = buf(1,1):uint()
Rich Laneb017c732013-10-02 14:05:01 -0700175
176 local protocol = "OF ?"
177 if openflow_versions[version_val] then
178 protocol = "OF " .. openflow_versions[version_val]
Rich Lane96641df2013-06-10 13:36:35 -0700179 end
Rich Laneb017c732013-10-02 14:05:01 -0700180
181 local info = "unknown"
Tomasz771b08a2013-11-02 13:33:57 -0700182 if type_val == 19 then
183 local stats_type = buf(8,2):uint()
184 info = of_stats_reply_dissectors[version_val][stats_type](reader,subtree)
185 elseif type_val == 18 then
186 local stats_type = buf(8,2):uint()
187 info = of_stats_request_dissectors[version_val][stats_type](reader,subtree)
188 elseif of_message_dissectors[version_val] and of_message_dissectors[version_val][type_val] then
Rich Laneb017c732013-10-02 14:05:01 -0700189 info = of_message_dissectors[version_val][type_val](reader, subtree)
190 end
191
192 return protocol, info
Rich Lane422d1b12013-06-04 13:09:17 -0700193end
194
Tomasz742c2ba2013-10-24 22:35:45 -0700195function dissect_of_oxm(reader, subtree, version_val)
Tomasze0584352013-10-23 16:43:26 -0700196 local type_val = reader.peek(0,4):uint()
Tomasze0584352013-10-23 16:43:26 -0700197 local info = "unknown"
Tomasz742c2ba2013-10-24 22:35:45 -0700198 if of_oxm_dissectors[version_val] and of_oxm_dissectors[version_val][type_val] then
199 info = of_oxm_dissectors[version_val][type_val](reader, subtree)
Tomasze0584352013-10-23 16:43:26 -0700200 end
201
202 return info
203end
Tomasz742c2ba2013-10-24 22:35:45 -0700204
205function dissect_of_action(reader, subtree, version_val)
206 local type_val = reader.peek(0,2):uint()
207 local info = "unknown"
208 if of_action_dissectors[version_val] and of_action_dissectors[version_val][type_val] then
209 info = of_action_dissectors[version_val][type_val](reader, subtree)
210 end
211
212 return info
213end
214
215function dissect_of_instruction(reader, subtree, version_val)
216 local type_val = reader.peek(0,2):uint()
217 local info = "unknown"
218 if of_instruction_dissectors[version_val] and of_instruction_dissectors[version_val][type_val] then
219 info = of_instruction_dissectors[version_val][type_val](reader, subtree)
220 end
221
222 return info
223end
224
Tomasza17a6692013-10-30 17:34:18 -0700225function dissect_of_bucket(reader, subtree, version_val)
226 local info = "unknown"
227 if of_bucket_dissectors[version_val] then
228 info = of_bucket_dissectors[version_val](reader, subtree)
229 end
230
231 return info
232end
233
Tomaszc595d5b2013-11-02 13:30:32 -0700234function dissect_of_port_desc(reader, subtree, version_val)
235 local info = "unknown"
236 if of_port_desc_dissectors[version_val] then
237 info = of_port_desc_dissectors[version_val](reader, subtree)
238 end
239
240 return info
241end
242
243function dissect_of_flow_stats_entry(reader, subtree, version_val)
244 local info = "unknown"
245 if of_flow_stats_entry_dissectors[version_val] then
246 info = of_flow_stats_entry_dissectors[version_val](reader, subtree)
247 end
248
249 return info
250end
251
252function dissect_of_port_stats_entry(reader, subtree, version_val)
253 local info = "unknown"
254 if of_port_stats_entry_dissectors[version_val] then
255 info = of_port_stats_entry_dissectors[version_val](reader, subtree)
256 end
257
258 return info
259end
260
261function dissect_of_table_stats_entry(reader, subtree, version_val)
262 local info = "unknown"
263 if of_table_stats_entry_dissectors[version_val] then
264 info = of_table_stats_entry_dissectors[version_val](reader, subtree)
265 end
266
267 return info
268end
269
270function dissect_of_queue_stats_entry(reader, subtree, version_val)
271 local info = "unknown"
272 if of_queue_stats_entry_dissectors[version_val] then
273 info = of_queue_stats_entry_dissectors[version_val](reader, subtree)
274 end
275
276 return info
277end
278
Rich Lane422d1b12013-06-04 13:09:17 -0700279-- of dissector function
280function p_of.dissector (buf, pkt, root)
Rich Lane422d1b12013-06-04 13:09:17 -0700281 local offset = 0
282 repeat
283 if buf:len() - offset >= 4 then
284 msg_len = buf(offset+2,2):uint()
285 if offset + msg_len > buf:len() then
286 -- we don't have all the data we need yet
287 pkt.desegment_len = offset + msg_len - buf:len()
288 return
289 end
290
Rich Laneb017c732013-10-02 14:05:01 -0700291 protocol, info = dissect_of_message(buf(offset, msg_len), root)
292
293 if offset == 0 then
294 pkt.cols.protocol:clear()
295 pkt.cols.info:clear()
296 else
Rich Lane7b8eaa12013-10-02 14:55:35 -0700297 pkt.cols.protocol:append(" + ")
298 pkt.cols.info:append(" + ")
Rich Laneb017c732013-10-02 14:05:01 -0700299 end
300 pkt.cols.protocol:append(protocol)
301 pkt.cols.info:append(info)
Rich Lane422d1b12013-06-04 13:09:17 -0700302 offset = offset + msg_len
303 else
304 -- we don't have all of length field yet
305 pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
306 return
307 end
308 until offset >= buf:len()
309end
310
311-- Initialization routine
312function p_of.init()
313end
314
Rich Lane88d3afc2013-10-01 21:07:22 -0700315-- register a chained dissector for OpenFlow port numbers
Rich Lane422d1b12013-06-04 13:09:17 -0700316local tcp_dissector_table = DissectorTable.get("tcp.port")
317tcp_dissector_table:add(6633, p_of)
Rich Lane88d3afc2013-10-01 21:07:22 -0700318tcp_dissector_table:add(6653, p_of)