blob: ef826c1024d99dea779ece0b97c822f872f30fba [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 Lane9331e022013-11-20 12:41:25 -080032-- Copy this file to your wireshark plugin directory:
33-- Linux / OS X: ~/.wireshark/plugins/
34-- Windows: C:\Documents and Settings\<username>\Application Data\Wireshark\plugins\
35-- You may need to create the directory.
36
37-- The latest version of this dissector is always available at:
38-- http://www.projectfloodlight.org/openflow.lua
39
Rich Lane872b95a2013-06-17 18:39:14 -070040:: include('_ofreader.lua')
41
Rich Lane422d1b12013-06-04 13:09:17 -070042p_of = Proto ("of", "OpenFlow")
tomaszklimczyk8d18d722014-01-19 23:17:05 -080043ethernet_dissector = Dissector.get("eth")
44
45current_pkt = nil
Rich Lane422d1b12013-06-04 13:09:17 -070046
Rich Lane972be332013-06-04 13:36:48 -070047local openflow_versions = {
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080048:: for version in loxi_globals.OFVersions.all_supported:
49 [${version.wire_version}] = "${version.version}",
Rich Lane972be332013-06-04 13:36:48 -070050:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070051}
52
Rich Lane972be332013-06-04 13:36:48 -070053:: for version, ofproto in ir.items():
54:: for enum in ofproto.enums:
Rich Lane5f9931f2014-09-18 16:38:24 -070055enum_v${version.wire_version}_${enum.name} = {
Rich Lane972be332013-06-04 13:36:48 -070056:: for (name, value) in enum.values:
57 [${value}] = "${name}",
58:: #endfor
59}
60
61:: #endfor
62
63:: #endfor
64
Tomasz635e20a2013-10-23 16:14:29 -070065
Rich Lane364e0292013-10-01 21:05:57 -070066fields = {}
Rich Laneb014bcf2013-06-19 11:14:11 -070067:: for field in fields:
Rich Lane4df40f32013-10-08 15:40:39 -070068:: if field.type in ["uint8", "uint16", "uint32", "uint64"]:
Rich Lane52452662013-10-25 13:34:42 -070069fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}", base.${field.base}, ${field.enum_table})
Rich Lane4df40f32013-10-08 15:40:39 -070070:: elif field.type in ["ipv4", "ipv6", "ether", "bytes", "stringz"]:
71fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}")
72:: else:
73:: raise NotImplementedError("unknown Wireshark type " + field.type)
74:: #endif
Rich Laneb014bcf2013-06-19 11:14:11 -070075:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070076
77p_of.fields = {
Rich Laneb014bcf2013-06-19 11:14:11 -070078:: for field in fields:
Rich Lane364e0292013-10-01 21:05:57 -070079 fields[${repr(field.fullname)}],
Rich Laneb014bcf2013-06-19 11:14:11 -070080:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070081}
82
Rich Lane4bbdcf52013-10-01 22:07:35 -070083-- Subclass maps for virtual classes
Rich Lane96641df2013-06-10 13:36:35 -070084:: for version, ofproto in ir.items():
Rich Lane4bbdcf52013-10-01 22:07:35 -070085:: for ofclass in ofproto.classes:
86:: if ofclass.virtual:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080087${ofclass.name}_v${version.wire_version}_dissectors = {}
Rich Lane4bbdcf52013-10-01 22:07:35 -070088:: #endif
Rich Lane96641df2013-06-10 13:36:35 -070089:: #endfor
Rich Lane96641df2013-06-10 13:36:35 -070090:: #endfor
91
Tomasza19e9d22013-12-08 11:18:11 -080092--- Dissectors for each class
Rich Lane96641df2013-06-10 13:36:35 -070093:: for version, ofproto in ir.items():
94:: for ofclass in ofproto.classes:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080095:: name = 'dissect_%s_v%d' % (ofclass.name, version.wire_version)
Rich Lane7708c182013-10-01 23:27:27 -070096:: include('_ofclass_dissector.lua', name=name, ofclass=ofclass, version=version)
Rich Lane4bbdcf52013-10-01 22:07:35 -070097:: if ofclass.superclass:
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -080098:: discriminator = ofclass.superclass.discriminator
Rich Lane586864e2013-10-01 23:26:35 -070099:: discriminator_value = ofclass.member_by_name(discriminator.name).value
Andreas Wundsamc2ce5fa2013-11-15 15:20:11 -0800100${ofclass.superclass.name}_v${version.wire_version}_dissectors[${discriminator_value}] = ${name}
Rich Lane96641df2013-06-10 13:36:35 -0700101
102:: #endif
103:: #endfor
104:: #endfor
105
Rich Lane4bbdcf52013-10-01 22:07:35 -0700106local of_message_dissectors = {
107:: for version in ir:
Tomasz2663f4f2013-12-10 05:12:42 -0800108 [${version.wire_version}] = dissect_of_header_v${version.wire_version},
Rich Lane4bbdcf52013-10-01 22:07:35 -0700109:: #endfor
110}
111
Tomasz359147c2013-12-17 18:34:20 -0800112local of_port_desc_dissectors = {
113:: for version in ir:
114 [${version.wire_version}] = dissect_of_port_desc_v${version.wire_version},
115:: #endfor
116}
117
Tomasz742c2ba2013-10-24 22:35:45 -0700118local of_oxm_dissectors = {
119:: for version in ir:
Tomasz2663f4f2013-12-10 05:12:42 -0800120 [${version.wire_version}] = dissect_of_oxm_v${version.wire_version},
Tomasz742c2ba2013-10-24 22:35:45 -0700121:: #endfor
122}
123
tomaszklimczyk8c833852014-01-19 23:18:12 -0800124local of_bsn_vport_q_in_q_dissectors = {
125:: for version in ir:
126 [${version.wire_version}] = dissect_of_bsn_vport_q_in_q_v${version.wire_version},
127:: #endfor
128}
129
Tomasz2663f4f2013-12-10 05:12:42 -0800130:: include('_oftype_readers.lua')
131
Rich Lane96641df2013-06-10 13:36:35 -0700132function dissect_of_message(buf, root)
Rich Lane93991e42013-10-01 22:24:51 -0700133 local reader = OFReader.new(buf)
Rich Lane422d1b12013-06-04 13:09:17 -0700134 local subtree = root:add(p_of, buf(0))
Rich Lane96641df2013-06-10 13:36:35 -0700135 local version_val = buf(0,1):uint()
Rich Lane422d1b12013-06-04 13:09:17 -0700136 local type_val = buf(1,1):uint()
Rich Laneb017c732013-10-02 14:05:01 -0700137
138 local protocol = "OF ?"
139 if openflow_versions[version_val] then
140 protocol = "OF " .. openflow_versions[version_val]
tomaszklimczyk4f78cef2014-01-29 10:39:58 -0800141 else
142 return "Unknown protocol", "Dissection error"
Rich Lane96641df2013-06-10 13:36:35 -0700143 end
Tomasz3f1b1f92013-12-10 01:58:10 -0800144
Tomasz4b523342013-12-10 02:02:49 -0800145 local info = "unknown"
Tomasz2663f4f2013-12-10 05:12:42 -0800146 info = of_message_dissectors[version_val](reader, subtree)
Rich Laneb017c732013-10-02 14:05:01 -0700147
148 return protocol, info
Rich Lane422d1b12013-06-04 13:09:17 -0700149end
150
151-- of dissector function
152function p_of.dissector (buf, pkt, root)
Rich Lane422d1b12013-06-04 13:09:17 -0700153 local offset = 0
tomaszklimczyk8d18d722014-01-19 23:17:05 -0800154 current_pkt = pkt
Rich Lane422d1b12013-06-04 13:09:17 -0700155 repeat
156 if buf:len() - offset >= 4 then
Rich Lanefba8f142014-06-06 16:24:14 -0700157 local msg_version = buf(offset,1):uint()
158 local msg_type = buf(offset+1,1):uint()
tomaszklimczyk9b13d9b2014-01-29 14:24:03 -0800159 local msg_len = buf(offset+2,2):uint()
160
Rich Lanefba8f142014-06-06 16:24:14 -0700161 -- Detect obviously broken messages
162 if msg_version == 0 or msg_version > 4 then break end
163 if msg_type > 29 then break end
164 if msg_len < 8 then break end
tomaszklimczyk9b13d9b2014-01-29 14:24:03 -0800165
Rich Lane422d1b12013-06-04 13:09:17 -0700166 if offset + msg_len > buf:len() then
167 -- we don't have all the data we need yet
168 pkt.desegment_len = offset + msg_len - buf:len()
Rich Lanee0eb2862014-06-06 16:26:53 -0700169 pkt.desegment_offset = offset
Rich Lane422d1b12013-06-04 13:09:17 -0700170 return
171 end
172
Rich Laneb017c732013-10-02 14:05:01 -0700173 protocol, info = dissect_of_message(buf(offset, msg_len), root)
174
175 if offset == 0 then
176 pkt.cols.protocol:clear()
177 pkt.cols.info:clear()
178 else
Rich Lane7b8eaa12013-10-02 14:55:35 -0700179 pkt.cols.protocol:append(" + ")
180 pkt.cols.info:append(" + ")
Rich Laneb017c732013-10-02 14:05:01 -0700181 end
182 pkt.cols.protocol:append(protocol)
183 pkt.cols.info:append(info)
Rich Lane422d1b12013-06-04 13:09:17 -0700184 offset = offset + msg_len
185 else
186 -- we don't have all of length field yet
187 pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
Rich Lanee0eb2862014-06-06 16:26:53 -0700188 pkt.desegment_offset = offset
Rich Lane422d1b12013-06-04 13:09:17 -0700189 return
190 end
191 until offset >= buf:len()
192end
193
194-- Initialization routine
195function p_of.init()
196end
197
Rich Lane88d3afc2013-10-01 21:07:22 -0700198-- register a chained dissector for OpenFlow port numbers
Rich Lane422d1b12013-06-04 13:09:17 -0700199local tcp_dissector_table = DissectorTable.get("tcp.port")
200tcp_dissector_table:add(6633, p_of)
Rich Lane88d3afc2013-10-01 21:07:22 -0700201tcp_dissector_table:add(6653, p_of)