blob: b443463509d905dc0f6cb56c87107e4780fcb509 [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::
Rich Lane972be332013-06-04 13:36:48 -070028:: import of_g
29:: ir = of_g.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 = {
39:: for (version, name) in of_g.param_version_names.items():
40 [${version}] = "${name}",
41:: #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:
46local enum_v${version}_${enum.name} = {
47:: 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
57:: values = {
58:: 'of13.flow_mod.type': 'enum_v4_ofp_type',
59:: 'of13.error_msg.type': 'enum_v4_ofp_type',
60:: 'of13.stats_request.type': 'enum_v4_ofp_type',
61:: 'of13.stats_request.stats_type': 'enum_v4_ofp_stats_type',
62:: 'of13.stats_request.flags': 'enum_v4_ofp_stats_request_flags',
63:: 'of13.stats_reply.type': 'enum_v4_ofp_type',
64:: 'of13.stats_reply.stats_type': 'enum_v4_ofp_stats_type',
65:: 'of13.stats_reply.flags': 'enum_v4_ofp_stats_reply_flags',
66:: 'of13.flow_mod.table_id': 'enum_v4_ofp_table',
67:: 'of13.flow_mod._command': 'enum_v4_ofp_flow_mod_command',
68:: 'of13.flow_mod.out_port': 'enum_v4_ofp_port',
69:: 'of13.flow_mod.out_group': 'enum_v4_ofp_group',
70:: 'of13.error_msg.err_type': 'enum_v4_ofp_error_type',
71:: 'of13.port_mod.type': 'enum_v4_ofp_type',
72:: 'of13.hello.type': 'enum_v4_ofp_type',
73:: 'of13.features_request.type': 'enum_v4_ofp_type',
74:: 'of13.features_reply.type': 'enum_v4_ofp_type',
75:: 'of13.barrier_request.type': 'enum_v4_ofp_type',
76:: 'of13.barrier_reply.type': 'enum_v4_ofp_type',
77:: 'of13.echo_request.type': 'enum_v4_ofp_type',
78:: 'of13.echo_reply.type': 'enum_v4_ofp_type',
79:: 'of13.match_t.type': 'enum_v4_ofp_match_type'
80:: }
81
82
Rich Lane364e0292013-10-01 21:05:57 -070083fields = {}
Rich Laneb014bcf2013-06-19 11:14:11 -070084:: for field in fields:
Rich Lane4df40f32013-10-08 15:40:39 -070085:: if field.type in ["uint8", "uint16", "uint32", "uint64"]:
Tomasz635e20a2013-10-23 16:14:29 -070086:: if field.fullname in values:
87fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}", base.${field.base}, ${values[field.fullname]})
88:: else:
Rich Lane4df40f32013-10-08 15:40:39 -070089fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}", base.${field.base})
Tomasz635e20a2013-10-23 16:14:29 -070090:: #endif
Rich Lane4df40f32013-10-08 15:40:39 -070091:: elif field.type in ["ipv4", "ipv6", "ether", "bytes", "stringz"]:
92fields[${repr(field.fullname)}] = ProtoField.${field.type}("${field.fullname}", "${field.name}")
93:: else:
94:: raise NotImplementedError("unknown Wireshark type " + field.type)
95:: #endif
Rich Laneb014bcf2013-06-19 11:14:11 -070096:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -070097
98p_of.fields = {
Rich Laneb014bcf2013-06-19 11:14:11 -070099:: for field in fields:
Rich Lane364e0292013-10-01 21:05:57 -0700100 fields[${repr(field.fullname)}],
Rich Laneb014bcf2013-06-19 11:14:11 -0700101:: #endfor
Rich Lane422d1b12013-06-04 13:09:17 -0700102}
103
Rich Lane4bbdcf52013-10-01 22:07:35 -0700104-- Subclass maps for virtual classes
Rich Lane96641df2013-06-10 13:36:35 -0700105:: for version, ofproto in ir.items():
Rich Lane4bbdcf52013-10-01 22:07:35 -0700106:: for ofclass in ofproto.classes:
107:: if ofclass.virtual:
108${ofclass.name}_v${version}_dissectors = {}
109:: #endif
Rich Lane96641df2013-06-10 13:36:35 -0700110:: #endfor
Rich Lane96641df2013-06-10 13:36:35 -0700111:: #endfor
112
Rich Lane4bbdcf52013-10-01 22:07:35 -0700113--- Dissectors for each class
114
Rich Lane96641df2013-06-10 13:36:35 -0700115:: for version, ofproto in ir.items():
116:: for ofclass in ofproto.classes:
117:: name = 'dissect_%s_v%d' % (ofclass.name, version)
Rich Lane7708c182013-10-01 23:27:27 -0700118:: include('_ofclass_dissector.lua', name=name, ofclass=ofclass, version=version)
Rich Lane4bbdcf52013-10-01 22:07:35 -0700119:: if ofclass.superclass:
Rich Lane586864e2013-10-01 23:26:35 -0700120:: discriminator = ofproto.class_by_name(ofclass.superclass).discriminator
121:: discriminator_value = ofclass.member_by_name(discriminator.name).value
Rich Lane4bbdcf52013-10-01 22:07:35 -0700122${ofclass.superclass}_v${version}_dissectors[${discriminator_value}] = ${name}
Rich Lane96641df2013-06-10 13:36:35 -0700123
124:: #endif
125:: #endfor
126:: #endfor
127
Rich Lane4bbdcf52013-10-01 22:07:35 -0700128local of_message_dissectors = {
129:: for version in ir:
130 [${version}] = of_header_v${version}_dissectors,
131:: #endfor
132}
133
Rich Lane96641df2013-06-10 13:36:35 -0700134function dissect_of_message(buf, root)
Rich Lane93991e42013-10-01 22:24:51 -0700135 local reader = OFReader.new(buf)
Rich Lane422d1b12013-06-04 13:09:17 -0700136 local subtree = root:add(p_of, buf(0))
Rich Lane96641df2013-06-10 13:36:35 -0700137 local version_val = buf(0,1):uint()
Rich Lane422d1b12013-06-04 13:09:17 -0700138 local type_val = buf(1,1):uint()
Rich Laneb017c732013-10-02 14:05:01 -0700139
140 local protocol = "OF ?"
141 if openflow_versions[version_val] then
142 protocol = "OF " .. openflow_versions[version_val]
Rich Lane96641df2013-06-10 13:36:35 -0700143 end
Rich Laneb017c732013-10-02 14:05:01 -0700144
145 local info = "unknown"
146 if of_message_dissectors[version_val] and of_message_dissectors[version_val][type_val] then
147 info = of_message_dissectors[version_val][type_val](reader, subtree)
148 end
149
150 return protocol, info
Rich Lane422d1b12013-06-04 13:09:17 -0700151end
152
153-- of dissector function
154function p_of.dissector (buf, pkt, root)
Rich Lane422d1b12013-06-04 13:09:17 -0700155 local offset = 0
156 repeat
157 if buf:len() - offset >= 4 then
158 msg_len = buf(offset+2,2):uint()
159 if offset + msg_len > buf:len() then
160 -- we don't have all the data we need yet
161 pkt.desegment_len = offset + msg_len - buf:len()
162 return
163 end
164
Rich Laneb017c732013-10-02 14:05:01 -0700165 protocol, info = dissect_of_message(buf(offset, msg_len), root)
166
167 if offset == 0 then
168 pkt.cols.protocol:clear()
169 pkt.cols.info:clear()
170 else
Rich Lane7b8eaa12013-10-02 14:55:35 -0700171 pkt.cols.protocol:append(" + ")
172 pkt.cols.info:append(" + ")
Rich Laneb017c732013-10-02 14:05:01 -0700173 end
174 pkt.cols.protocol:append(protocol)
175 pkt.cols.info:append(info)
Rich Lane422d1b12013-06-04 13:09:17 -0700176 offset = offset + msg_len
177 else
178 -- we don't have all of length field yet
179 pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
180 return
181 end
182 until offset >= buf:len()
183end
184
185-- Initialization routine
186function p_of.init()
187end
188
Rich Lane88d3afc2013-10-01 21:07:22 -0700189-- register a chained dissector for OpenFlow port numbers
Rich Lane422d1b12013-06-04 13:09:17 -0700190local tcp_dissector_table = DissectorTable.get("tcp.port")
191tcp_dissector_table:add(6633, p_of)
Rich Lane88d3afc2013-10-01 21:07:22 -0700192tcp_dissector_table:add(6653, p_of)