Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-openflow_v1.c
blobb6e43d0a01e2f5e342f09ece1894accc083721f4
1 /* packet-openflow_v1.c
2 * Routines for OpenFlow dissection
3 * Copyright 2013, Anders Broman <anders.broman@ericsson.com>
4 * Copyright 2013, Zoltan Lajos Kis <zoltan.lajos.kis@ericsson.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Ref https://www.opennetworking.org/sdn-resources/onf-specifications/openflow
15 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/expert.h>
20 void proto_register_openflow_v1(void);
21 void proto_reg_handoff_openflow_v1(void);
23 static dissector_handle_t eth_withoutfcs_handle;
25 /* Initialize the protocol and registered fields */
26 static int proto_openflow_v1;
27 static int hf_openflow_version;
28 static int hf_openflow_1_0_type;
29 static int hf_openflow_length;
30 static int hf_openflow_xid;
32 static int hf_openflow_datapath_id;
33 static int hf_openflow_datapath_mac;
34 static int hf_openflow_datapath_impl;
35 static int hf_openflow_n_buffers;
36 static int hf_openflow_n_tables;
37 /* static int hf_openflow_auxiliary_id; */
38 static int hf_openflow_capabilities;
39 static int hf_openflow_actions;
40 /* static int hf_openflow_reserved32; */
41 static int hf_openflow_cap_flow_stats;
42 static int hf_openflow_table_stats;
43 static int hf_openflow_port_stats;
44 static int hf_openflow_group_stats;
45 static int hf_openflow_ip_reasm;
46 static int hf_openflow_queue_stats;
47 static int hf_openflow_port_blocked;
49 static int hf_openflow_output; /* Output to switch port. */
50 static int hf_openflow_set_vlan_vid; /* Set the 802.1q VLAN id. */
51 static int hf_openflow_set_vlan_pcp; /* Set the 802.1q priority. */
52 static int hf_openflow_strip_vlan; /* Strip the 802.1q header. */
53 static int hf_openflow_set_dl_src; /* Ethernet source address. */
54 static int hf_openflow_set_dl_dst; /* Ethernet destination address. */
55 static int hf_openflow_set_nw_src; /* IP source address. */
56 static int hf_openflow_set_nw_dst; /* IP destination address. */
57 static int hf_openflow_set_nw_tos; /* IP ToS (DSCP field, 6 bits). */
58 static int hf_openflow_set_tp_src; /* TCP/UDP source port. */
59 static int hf_openflow_set_tp_dst; /* TCP/UDP destination port. */
60 static int hf_openflow_enqueue; /* Output to queue. */
62 static int hf_openflow_port_no;
63 static int hf_openflow_hw_addr;
64 static int hf_openflow_port_name;
67 static int hf_openflow_port_config;
68 static int hf_openflow_port_state;
69 static int hf_openflow_port_curr;
70 static int hf_openflow_port_advertised;
71 static int hf_openflow_port_supported;
72 static int hf_openflow_port_peer;
74 static int hf_openflow_port_down; /* Port is administratively down. */
75 static int hf_openflow_no_stp; /* Disable 802.1D spanning tree on port. */
76 static int hf_openflow_no_recv; /* Drop all packets except 802.1D spanning tree packets. */
77 static int hf_openflow_no_recv_stp; /* Drop received 802.1D STP packets. */
78 static int hf_openflow_no_flood; /* Do not include this port when flooding. */
79 static int hf_openflow_no_fwd; /* Drop packets forwarded to port. */
80 static int hf_openflow_no_packet_in; /* Do not send packet-in msgs for port. */
82 static int hf_openflow_link_down; /* No physical link present. */
84 static int hf_openflow_10mb_hd; /* 10 Mb half-duplex rate support. */
85 static int hf_openflow_10mb_fd; /* 10 Mb full-duplex rate support. */
86 static int hf_openflow_100mb_hd; /* 100 Mb half-duplex rate support. */
87 static int hf_openflow_100mb_fd; /* 100 Mb full-duplex rate support. */
88 static int hf_openflow_1gb_hd; /* 1 Gb half-duplex rate support. */
89 static int hf_openflow_1gb_fd; /* 1 Gb full-duplex rate support. */
90 static int hf_openflow_10gb_fd; /* 10 Gb full-duplex rate support. */
91 static int hf_openflow_copper; /* Copper medium. */
92 static int hf_openflow_fiber; /* Fiber medium. */
93 static int hf_openflow_autoneg; /* Auto-negotiation. */
94 static int hf_openflow_pause; /* Pause. */
95 static int hf_openflow_pause_asym; /* Asymmetric pause. */
97 static int hf_openflow_config_flags;
98 static int hf_openflow_miss_send_len;
100 static int hf_openflow_buffer_id;
101 static int hf_openflow_total_len;
102 static int hf_openflow_in_port;
103 static int hf_openflow_reason;
104 static int hf_openflow_pkt_in_pad;
105 static int hf_openflow_flow_removed_cookie;
106 static int hf_openflow_flow_removed_priority;
107 static int hf_openflow_flow_removed_reason;
108 static int hf_openflow_flow_removed_pad1;
109 static int hf_openflow_flow_removed_duration_sec;
110 static int hf_openflow_flow_removed_duration_nsec;
111 static int hf_openflow_flow_removed_idle_timeout;
112 static int hf_openflow_flow_removed_pad2;
113 static int hf_openflow_flow_removed_packet_count;
114 static int hf_openflow_flow_removed_byte_count;
115 static int hf_openflow_table_id;
116 static int hf_openflow_cookie;
117 /* static int hf_openflow_cookie_mask; */
118 static int hf_openflow_features_reply_pad;
119 static int hf_openflow_actions_len;
120 static int hf_openflow_action_type;
121 static int hf_openflow_action_len;
122 static int hf_openflow_output_port;
123 static int hf_openflow_max_len;
124 static int hf_openflow_wildcards;
125 static int hf_openflow_command;
126 static int hf_openflow_eth_src;
127 static int hf_openflow_eth_dst;
128 static int hf_openflow_dl_vlan;
129 static int hf_openflow_dl_vlan_pcp;
130 static int hf_openflow_ofp_match_pad;
131 static int hf_openflow_match_dl_type;
132 static int hf_openflow_ofp_match_tos;
133 static int hf_openflow_ofp_match_nw_proto;
134 static int hf_openflow_ofp_source_addr;
135 static int hf_openflow_ofp_dest_addr;
136 static int hf_openflow_ofp_source_port;
137 static int hf_openflow_ofp_dest_port;
138 static int hf_openflow_idle_timeout;
139 static int hf_openflow_hard_timeout;
140 static int hf_openflow_priority;
141 static int hf_openflow_out_port;
142 /* static int hf_openflow_out_group; */
143 static int hf_openflow_flags;
144 static int hf_openflow_v1_stats_type;
145 static int hf_openflow_v1_flow_stats_request_pad;
147 /* Initialize the subtree pointers */
148 static int ett_openflow;
149 static int ett_openflow_path_id;
150 static int ett_openflow_cap;
151 static int ett_openflow_act;
152 static int ett_openflow_port;
153 static int ett_openflow_port_cnf;
154 static int ett_openflow_port_state;
155 static int ett_openflow_port_cf;
157 /* static expert_field ei_openflow_undecoded_data; */
158 static expert_field ei_openflow_action_type;
159 static expert_field ei_openflow_1_0_type;
161 static const value_string openflow_version_values[] = {
162 { 0x01, "1.0" },
163 { 0, NULL }
167 /* Immutable messages. */
168 #define OFPT_1_0_HELLO 0 /* Symmetric message */
169 #define OFPT_1_0_ERROR 1 /* Symmetric message */
170 #define OFPT_1_0_ECHO_REQUEST 2 /* Symmetric message */
171 #define OFPT_1_0_ECHO_REPLY 3 /* Symmetric message */
172 #define OFPT_1_0_VENDOR 4 /* Symmetric message */
173 /* Switch configuration messages. */
174 #define OFPT_1_0_FEATURES_REQUEST 5 /* Controller/switch message */
175 #define OFPT_1_0_FEATURES_REPLY 6 /* Controller/switch message */
176 #define OFPT_1_0_GET_CONFIG_REQUEST 7 /* Controller/switch message */
177 #define OFPT_1_0_GET_CONFIG_REPLY 8 /* Controller/switch message */
178 #define OFPT_1_0_SET_CONFIG 9 /* Controller/switch message */
179 /* Asynchronous messages. */
180 #define OFPT_1_0_PACKET_IN 10 /* Async message */
181 #define OFPT_1_0_FLOW_REMOVED 11 /* Async message */
182 #define OFPT_1_0_PORT_STATUS 12 /* Async message */
183 /* Controller command messages. */
184 #define OFPT_1_0_PACKET_OUT 13 /* Controller/switch message */
185 #define OFPT_1_0_FLOW_MOD 14 /* Controller/switch message */
186 #define OFPT_1_0_PORT_MOD 15 /* Controller/switch message */
187 /* Statistics messages. */
188 #define OFPT_1_0_STATS_REQUEST 16 /* Controller/switch message */
189 #define OFPT_1_0_STATS_REPLY 17 /* Controller/switch message */
190 /* Barrier messages. */
191 #define OFPT_1_0_BARRIER_REQUEST 18 /* Controller/switch message */
192 #define OFPT_1_0_BARRIER_REPLY 19 /* Controller/switch message */
193 /* Queue Configuration messages. */
194 #define OFPT_1_0_QUEUE_GET_CONFIG_REQUEST 20 /* Controller/switch message */
195 #define OFPT_1_0_QUEUE_GET_CONFIG_REPLY 21 /* Controller/switch message */
198 static const value_string openflow_1_0_type_values[] = {
199 /* Immutable messages. */
200 { 0, "OFPT_HELLO" }, /* Symmetric message */
201 { 1, "OFPT_ERROR" }, /* Symmetric message */
202 { 2, "OFPT_ECHO_REQUEST" }, /* Symmetric message */
203 { 3, "OFPT_ECHO_REPLY" }, /* Symmetric message */
204 { 4, "OFPT_VENDOR" }, /* Symmetric message */
205 /* Switch configuration messages. */
206 { 5, "OFPT_FEATURES_REQUEST" }, /* Controller/switch message */
207 { 6, "OFPT_FEATURES_REPLY" }, /* Controller/switch message */
208 { 7, "OFPT_GET_CONFIG_REQUEST" }, /* Controller/switch message */
209 { 8, "OFPT_GET_CONFIG_REPLY" }, /* Controller/switch message */
210 { 9, "OFPT_SET_CONFIG" }, /* Controller/switch message */
211 /* Asynchronous messages. */
212 { 10, "OFPT_PACKET_IN" }, /* Async message */
213 { 11, "OFPT_FLOW_REMOVED" }, /* Async message */
214 { 12, "OFPT_PORT_STATUS" }, /* Async message */
215 /* Controller command messages. */
216 { 13, "OFPT_PACKET_OUT" }, /* Controller/switch message */
217 { 14, "OFPT_FLOW_MOD" }, /* Controller/switch message */
218 { 15, "OFPT_PORT_MOD" }, /* Controller/switch message */
219 /* Statistics messages. */
220 { 16, "OFPT_STATS_REQUEST" }, /* Controller/switch message */
221 { 17, "OFPT_STATS_REPLY" }, /* Controller/switch message */
222 /* Barrier messages. */
223 { 18, "OFPT_BARRIER_REQUEST" }, /* Controller/switch message */
224 { 19, "OFPT_BARRIER_REPLY" }, /* Controller/switch message */
225 /* Queue Configuration messages. */
226 { 20, "OFPT_QUEUE_GET_CONFIG_REQUEST" }, /* Controller/switch message */
227 { 21, "OFPT_QUEUE_GET_CONFIG_REPLY" }, /* Controller/switch message */
228 { 0, NULL }
230 static value_string_ext openflow_1_0_type_values_ext = VALUE_STRING_EXT_INIT(openflow_1_0_type_values);
232 #define OFPC_FLOW_STATS 1<<0 /* Flow statistics. */
233 #define OFPC_TABLE_STATS 1<<1 /* Table statistics. */
234 #define OFPC_PORT_STATS 1<<2 /* Port statistics. */
235 #define OFPC_GROUP_STATS 1<<3 /* Group statistics. */
236 #define OFPC_IP_REASM 1<<5 /* Can reassemble IP fragments. */
237 #define OFPC_QUEUE_STATS 1<<6 /* Queue statistics. */
238 #define OFPC_PORT_BLOCKED 1<<8 /* Switch will block looping ports. */
240 #define OFPAT_OUTPUT_MASK 1<<0 /* Output to switch port. */
241 #define OFPAT_SET_VLAN_VID_MASK 1<<1 /* Set the 802.1q VLAN id. */
242 #define OFPAT_SET_VLAN_PCP_MASK 1<<2 /* Set the 802.1q priority. */
243 #define OFPAT_STRIP_VLAN_MASK 1<<3 /* Strip the 802.1q header. */
244 #define OFPAT_SET_DL_SRC_MASK 1<<4 /* Ethernet source address. */
245 #define OFPAT_SET_DL_DST_MASK 1<<5 /* Ethernet destination address. */
246 #define OFPAT_SET_NW_SRC_MASK 1<<6 /* IP source address. */
247 #define OFPAT_SET_NW_DST_MASK 1<<7 /* IP destination address. */
248 #define OFPAT_SET_NW_TOS_MASK 1<<8 /* IP ToS (DSCP field, 6 bits). */
249 #define OFPAT_SET_TP_SRC_MASK 1<<9 /* TCP/UDP source port. */
250 #define OFPAT_SET_TP_DST_MASK 1<<10 /* TCP/UDP destination port. */
251 #define OFPAT_ENQUEUE_MASK 1<<11 /* Output to queue. */
253 #define OFPPC_PORT_DOWN 1<<0 /* Port is administratively down. */
254 #define OFPPC_NO_STP 1<<1 /* Disable 802.1D spanning tree on port. */
255 #define OFPPC_NO_RECV 1<<2 /* Drop all packets except 802.1D spanning tree packets. */
256 #define OFPPC_NO_RECV_STP 1<<3 /* Drop received 802.1D STP packets. */
257 #define OFPPC_NO_FLOOD 1<<4 /* Do not include this port when flooding. */
258 #define OFPPC_NO_FWD 1<<5 /* Drop packets forwarded to port. */
259 #define OFPPC_NO_PACKET_IN 1<<6 /* Do not send packet-in msgs for port. */
261 #define OFP_MAX_PORT_NAME_LEN 16
263 #define OFPPS_LINK_DOWN 1<<0 /* No physical link present. */
264 #define OFPPS_STP_LISTEN 0<<8 /* Not learning or relaying frames. */
265 #define OFPPS_STP_LEARN 1<<8 /* Learning but not relaying frames. */
266 #define OFPPS_STP_FORWARD 2<<8 /* Learning and relaying frames. */
267 #define OFPPS_STP_BLOCK 3<<8 /* Not part of spanning tree. */
268 #define OFPPS_STP_MASK 3<<8 /* Bit mask for OFPPS_STP_* values. */
271 #define OFPPF_10MB_HD 1<<0 /* 10 Mb half-duplex rate support. */
272 #define OFPPF_10MB_FD 1<<1 /* 10 Mb full-duplex rate support. */
273 #define OFPPF_100MB_HD 1<<2 /* 100 Mb half-duplex rate support. */
274 #define OFPPF_100MB_FD 1<<3 /* 100 Mb full-duplex rate support. */
275 #define OFPPF_1GB_HD 1<<4 /* 1 Gb half-duplex rate support. */
276 #define OFPPF_1GB_FD 1<<5 /* 1 Gb full-duplex rate support. */
277 #define OFPPF_10GB_FD 1<<6 /* 10 Gb full-duplex rate support. */
278 #define OFPPF_COPPER 1<<7 /* Copper medium. */
279 #define OFPPF_FIBER 1<<8 /* Fiber medium. */
280 #define OFPPF_AUTONEG 1<<9 /* Auto-negotiation. */
281 #define OFPPF_PAUSE 1<<10 /* Pause. */
282 #define OFPPF_PAUSE_ASYM 1<<11 /* Asymmetric pause. */
285 #define OFPAT_OUTPUT 0 /* Output to switch port. */
286 #define OFPAT_SET_VLAN_VID 1 /* Set the 802.1q VLAN id. */
287 #define OFPAT_SET_VLAN_PCP 2 /* Set the 802.1q priority. */
288 #define OFPAT_STRIP_VLAN 3 /* Strip the 802.1q header. */
289 #define OFPAT_SET_DL_SRC 4 /* Ethernet source address. */
290 #define OFPAT_SET_DL_DST 5 /* Ethernet destination address. */
291 #define OFPAT_SET_NW_SRC 6 /* IP source address. */
292 #define OFPAT_SET_NW_DST 7 /* IP destination address. */
293 #define OFPAT_SET_TP_SRC 8 /* TCP/UDP source port. */
294 #define OFPAT_SET_TP_DST 9 /* TCP/UDP destination port. */
295 #define OFPAT_VENDOR 0xffff
297 static int
298 dissect_openflow_ofp_match_v1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
301 /* uint32_t wildcards; Wildcard fields. */
302 proto_tree_add_item(tree, hf_openflow_wildcards, tvb, offset, 4, ENC_BIG_ENDIAN);
303 offset+=4;
304 /* uint16_t in_port; Input switch port. */
305 proto_tree_add_item(tree, hf_openflow_in_port, tvb, offset, 2, ENC_BIG_ENDIAN);
306 offset+=2;
308 /* uint8_t dl_src[OFP_ETH_ALEN]; Ethernet source address. */
309 proto_tree_add_item(tree, hf_openflow_eth_src, tvb, offset, 6, ENC_NA);
310 offset+=6;
311 /* uint8_t dl_dst[OFP_ETH_ALEN]; Ethernet destination address. */
312 proto_tree_add_item(tree, hf_openflow_eth_dst, tvb, offset, 6, ENC_NA);
313 offset+=6;
314 /* uint16_t dl_vlan; Input VLAN id. */
315 proto_tree_add_item(tree, hf_openflow_dl_vlan, tvb, offset, 2, ENC_BIG_ENDIAN);
316 offset+=2;
317 /* uint8_t dl_vlan_pcp; Input VLAN priority. */
318 proto_tree_add_item(tree, hf_openflow_dl_vlan_pcp, tvb, offset, 1, ENC_BIG_ENDIAN);
319 offset++;
320 /* uint8_t pad1[1]; Align to 64-bits */
321 proto_tree_add_item(tree, hf_openflow_ofp_match_pad, tvb, offset, 1, ENC_NA);
322 offset++;
323 /* uint16_t dl_type; Ethernet frame type. */
324 proto_tree_add_item(tree, hf_openflow_match_dl_type, tvb, offset, 2, ENC_BIG_ENDIAN);
325 offset += 2;
326 /* uint8_t nw_tos; IP ToS (actually DSCP field, 6 bits). */
327 proto_tree_add_item(tree, hf_openflow_ofp_match_tos, tvb, offset, 1, ENC_NA);
328 offset++;
329 /* uint8_t nw_proto; IP protocol or lower 8 bits of
330 * ARP opcode.
332 proto_tree_add_item(tree, hf_openflow_ofp_match_nw_proto, tvb, offset, 1, ENC_NA);
333 offset++;
334 /* uint8_t pad2[2]; Align to 64-bits */
335 proto_tree_add_item(tree, hf_openflow_ofp_match_pad, tvb, offset, 2, ENC_NA);
336 offset += 2;
337 /* uint32_t nw_src; IP source address. */
338 proto_tree_add_item(tree, hf_openflow_ofp_source_addr, tvb, offset, 4, ENC_NA);
339 offset += 4;
340 /* uint32_t nw_dst; IP destination address. */
341 proto_tree_add_item(tree, hf_openflow_ofp_dest_addr, tvb, offset, 4, ENC_NA);
342 offset += 4;
343 /* uint16_t tp_src; TCP/UDP source port. */
344 proto_tree_add_item(tree, hf_openflow_ofp_source_port, tvb, offset, 2, ENC_BIG_ENDIAN);
345 offset += 2;
346 /* uint16_t tp_dst; TCP/UDP destination port. */
347 proto_tree_add_item(tree, hf_openflow_ofp_dest_port, tvb, offset, 2, ENC_BIG_ENDIAN);
348 offset += 2;
349 return offset;
352 static int
353 dissect_openflow_flow_stats_request_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
355 /* struct ofp_match match; Fields to match */
356 offset = dissect_openflow_ofp_match_v1(tvb, pinfo, tree, offset);
358 /* uint8_t table_id; ID of table to read (from ofp_table_stats),
359 * 0xff for all tables or 0xfe for emergency.
361 proto_tree_add_item(tree, hf_openflow_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
362 offset++;
363 /* uint8_t pad; Align to 32 bits. */
364 proto_tree_add_item(tree, hf_openflow_v1_flow_stats_request_pad, tvb, offset, 1, ENC_BIG_ENDIAN);
365 offset++;
366 /* uint16_t out_port; */
367 proto_tree_add_item(tree, hf_openflow_out_port, tvb, offset, 2, ENC_BIG_ENDIAN);
368 offset += 2;
370 return offset;
375 static const value_string openflow_action_values[] = {
376 { OFPAT_OUTPUT, "Output to switch port" },
377 { OFPAT_SET_VLAN_VID, "Set the 802.1q VLAN id" },
378 { OFPAT_SET_VLAN_PCP, "Set the 802.1q priority" },
379 { OFPAT_STRIP_VLAN, "Strip the 802.1q header" },
380 { OFPAT_SET_DL_SRC, "Ethernet source address" },
381 { OFPAT_SET_DL_DST, "Ethernet destination address" },
382 { OFPAT_SET_NW_SRC, "IP source address" },
383 { OFPAT_SET_NW_DST, "IP destination address" },
384 { OFPAT_SET_TP_SRC, "TCP/UDP source port" },
385 { OFPAT_SET_TP_DST, "TCP/UDP destination port" },
386 { OFPAT_VENDOR, "Vendor specific action"},
387 { 0, NULL }
390 static int
391 dissect_openflow_action_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
393 uint16_t action_type, action_len;
394 proto_item* ti;
396 /* uint16_t type; One of OFPAT_*. */
397 action_type = tvb_get_ntohs(tvb, offset);
398 ti = proto_tree_add_item(tree, hf_openflow_action_type, tvb, offset, 2, ENC_BIG_ENDIAN);
399 offset+=2;
400 /* Length of action, including this
401 * header. This is the length of action,
402 * including any padding to make it
403 * 64-bit aligned.
405 action_len = tvb_get_ntohs(tvb, offset);
406 proto_tree_add_item(tree, hf_openflow_action_len, tvb, offset, 2, ENC_BIG_ENDIAN);
407 offset+=2;
409 switch(action_type){
410 case OFPAT_OUTPUT:
411 /* uint16_t port; Output port. */
412 proto_tree_add_item(tree, hf_openflow_output_port, tvb, offset, 2, ENC_BIG_ENDIAN);
413 offset+=2;
414 /* uint16_t max_len; Max length to send to controller. */
415 proto_tree_add_item(tree, hf_openflow_max_len, tvb, offset, 2, ENC_BIG_ENDIAN);
416 offset+=2;
417 break;
418 default:
419 expert_add_info(pinfo, ti, &ei_openflow_action_type);
420 offset+=(action_len-4);
421 break;
424 return offset;
426 static void
427 dissect_openflow_phy_port(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
429 proto_item *ti;
430 proto_tree *port_cnf_tree, *port_state_tree, *port_cf_tree;
432 proto_tree_add_item(tree, hf_openflow_port_no, tvb, offset, 2, ENC_BIG_ENDIAN);
433 offset+=2;
434 proto_tree_add_item(tree, hf_openflow_hw_addr, tvb, offset, 6, ENC_NA);
435 offset+=6;
436 proto_tree_add_item(tree, hf_openflow_port_name, tvb, offset, OFP_MAX_PORT_NAME_LEN, ENC_ASCII);
437 offset+=OFP_MAX_PORT_NAME_LEN;
439 /* Bitmap of OFPPC_* flags. */
440 ti = proto_tree_add_item(tree, hf_openflow_port_config, tvb, offset, 4, ENC_BIG_ENDIAN);
441 port_cnf_tree = proto_item_add_subtree(ti, ett_openflow_port_cnf);
443 /* Port is administratively down. */
444 proto_tree_add_item(port_cnf_tree, hf_openflow_port_down, tvb, offset, 4, ENC_BIG_ENDIAN);
445 /* Disable 802.1D spanning tree on port. */
446 proto_tree_add_item(port_cnf_tree, hf_openflow_no_stp, tvb, offset, 4, ENC_BIG_ENDIAN);
447 /* Drop all packets except 802.1D spanning tree packets. */
448 proto_tree_add_item(port_cnf_tree, hf_openflow_no_recv, tvb, offset, 4, ENC_BIG_ENDIAN);
449 /* Drop received 802.1D STP packets. */
450 proto_tree_add_item(port_cnf_tree, hf_openflow_no_recv_stp, tvb, offset, 4, ENC_BIG_ENDIAN);
451 /* Do not include this port when flooding. */
452 proto_tree_add_item(port_cnf_tree, hf_openflow_no_flood, tvb, offset, 4, ENC_BIG_ENDIAN);
453 /* Drop packets forwarded to port. */
454 proto_tree_add_item(port_cnf_tree, hf_openflow_no_fwd, tvb, offset, 4, ENC_BIG_ENDIAN);
455 /* Do not send packet-in msgs for port. */
456 proto_tree_add_item(port_cnf_tree, hf_openflow_no_packet_in, tvb, offset, 4, ENC_BIG_ENDIAN);
457 offset+=4;
459 /* Bitmap of OFPPS_* flags. */
460 ti = proto_tree_add_item(tree, hf_openflow_port_state, tvb, offset, 4, ENC_BIG_ENDIAN);
461 port_state_tree = proto_item_add_subtree(ti, ett_openflow_port_state);
463 /* No physical link present. */
464 proto_tree_add_item(port_state_tree, hf_openflow_link_down, tvb, offset, 4, ENC_BIG_ENDIAN);
466 offset+=4;
468 /* Current features. */
469 ti = proto_tree_add_item(tree, hf_openflow_port_curr, tvb, offset, 4, ENC_BIG_ENDIAN);
470 port_cf_tree = proto_item_add_subtree(ti, ett_openflow_port_cf);
471 /* 10 Mb half-duplex rate support. */
472 proto_tree_add_item(port_cf_tree, hf_openflow_10mb_hd, tvb, offset, 4, ENC_BIG_ENDIAN);
473 /* 10 Mb full-duplex rate support. */
474 proto_tree_add_item(port_cf_tree, hf_openflow_10mb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
475 /* 100 Mb half-duplex rate support. */
476 proto_tree_add_item(port_cf_tree, hf_openflow_100mb_hd, tvb, offset, 4, ENC_BIG_ENDIAN);
477 /* 100 Mb full-duplex rate support. */
478 proto_tree_add_item(port_cf_tree, hf_openflow_100mb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
479 /* 1 Gb half-duplex rate support. */
480 proto_tree_add_item(port_cf_tree, hf_openflow_1gb_hd, tvb, offset, 4, ENC_BIG_ENDIAN);
481 /* 1 Gb full-duplex rate support. */
482 proto_tree_add_item(port_cf_tree, hf_openflow_1gb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
483 /* 10 Gb full-duplex rate support. */
484 proto_tree_add_item(port_cf_tree, hf_openflow_10gb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
485 /* Copper medium. */
486 proto_tree_add_item(port_cf_tree, hf_openflow_copper, tvb, offset, 4, ENC_BIG_ENDIAN);
487 /* Fiber medium. */
488 proto_tree_add_item(port_cf_tree, hf_openflow_fiber, tvb, offset, 4, ENC_BIG_ENDIAN);
489 /* Auto-negotiation. */
490 proto_tree_add_item(port_cf_tree, hf_openflow_autoneg, tvb, offset, 4, ENC_BIG_ENDIAN);
491 /* Pause. */
492 proto_tree_add_item(port_cf_tree, hf_openflow_pause, tvb, offset, 4, ENC_BIG_ENDIAN);
493 /* Asymmetric pause. */
494 proto_tree_add_item(port_cf_tree, hf_openflow_pause_asym, tvb, offset, 4, ENC_BIG_ENDIAN);
495 offset+=4;
497 /* Features being advertised by the port. */
498 proto_tree_add_item(tree, hf_openflow_port_advertised, tvb, offset, 4, ENC_BIG_ENDIAN);
499 offset+=4;
501 /* Features supported by the port. */
502 proto_tree_add_item(tree, hf_openflow_port_supported, tvb, offset, 4, ENC_BIG_ENDIAN);
503 offset+=4;
504 /* Features advertised by peer. */
505 proto_tree_add_item(tree, hf_openflow_port_peer, tvb, offset, 4, ENC_BIG_ENDIAN);
510 #if 0
512 * Switch features.
515 struct ofp_switch_features {
516 struct ofp_header header;
517 uint64_t datapath_id; /* Datapath unique ID. The lower 48-bits are for
518 a MAC address, while the upper 16-bits are
519 implementer-defined. */
520 uint32_t n_buffers; /* Max packets buffered at once. */
521 uint8_t n_tables; /* Number of tables supported by datapath. */
522 uint8_t pad[3]; /* Align to 64-bits. */
523 /* Features. */
524 uint32_t capabilities; /* Bitmap of support "ofp_capabilities". */
525 uint32_t actions; /* Bitmap of supported "ofp_action_type"s. */
526 /* Port info.*/
527 struct ofp_phy_port ports[0]; /* Port definitions. The number of ports
528 is inferred from the length field in
529 the header. */
530 #endif
532 static void
533 dissect_openflow_features_reply_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
535 proto_item *ti;
536 proto_tree *path_id_tree, *cap_tree, *act_tree;
538 uint16_t length_remaining;
540 ti = proto_tree_add_item(tree, hf_openflow_datapath_id, tvb, offset, 8, ENC_BIG_ENDIAN);
541 path_id_tree = proto_item_add_subtree(ti, ett_openflow_path_id);
542 proto_tree_add_item(path_id_tree, hf_openflow_datapath_impl, tvb, offset, 2, ENC_BIG_ENDIAN);
543 offset+=2;
544 proto_tree_add_item(path_id_tree, hf_openflow_datapath_mac, tvb, offset, 6, ENC_NA);
545 offset+=6;
547 proto_tree_add_item(tree, hf_openflow_n_buffers, tvb, offset, 4, ENC_BIG_ENDIAN);
548 offset+=4;
550 proto_tree_add_item(tree, hf_openflow_n_tables, tvb, offset, 1, ENC_BIG_ENDIAN);
551 offset++;
553 proto_tree_add_item(tree, hf_openflow_features_reply_pad, tvb, offset, 3, ENC_NA);
554 offset+=3;
556 ti = proto_tree_add_item(tree, hf_openflow_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
557 cap_tree = proto_item_add_subtree(ti, ett_openflow_cap);
559 /* Dissect flags */
560 proto_tree_add_item(cap_tree, hf_openflow_cap_flow_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
561 proto_tree_add_item(cap_tree, hf_openflow_table_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
562 proto_tree_add_item(cap_tree, hf_openflow_port_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
563 proto_tree_add_item(cap_tree, hf_openflow_group_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
564 proto_tree_add_item(cap_tree, hf_openflow_ip_reasm, tvb, offset, 4, ENC_BIG_ENDIAN);
565 proto_tree_add_item(cap_tree, hf_openflow_queue_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
566 proto_tree_add_item(cap_tree, hf_openflow_port_blocked, tvb, offset, 4, ENC_BIG_ENDIAN);
567 offset+=4;
569 ti = proto_tree_add_item(tree, hf_openflow_actions, tvb, offset, 4, ENC_BIG_ENDIAN);
570 act_tree = proto_item_add_subtree(ti, ett_openflow_act);
571 /* Dissect flags */
572 proto_tree_add_item(act_tree, hf_openflow_output, tvb, offset, 4, ENC_BIG_ENDIAN);
573 proto_tree_add_item(act_tree, hf_openflow_set_vlan_vid, tvb, offset, 4, ENC_BIG_ENDIAN);
574 proto_tree_add_item(act_tree, hf_openflow_set_vlan_pcp, tvb, offset, 4, ENC_BIG_ENDIAN);
575 proto_tree_add_item(act_tree, hf_openflow_strip_vlan, tvb, offset, 4, ENC_BIG_ENDIAN);
576 proto_tree_add_item(act_tree, hf_openflow_set_dl_src, tvb, offset, 4, ENC_BIG_ENDIAN);
577 proto_tree_add_item(act_tree, hf_openflow_set_dl_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
578 proto_tree_add_item(act_tree, hf_openflow_set_nw_src, tvb, offset, 4, ENC_BIG_ENDIAN);
579 proto_tree_add_item(act_tree, hf_openflow_set_nw_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
580 proto_tree_add_item(act_tree, hf_openflow_set_nw_tos, tvb, offset, 4, ENC_BIG_ENDIAN);
581 proto_tree_add_item(act_tree, hf_openflow_set_tp_src, tvb, offset, 4, ENC_BIG_ENDIAN);
582 proto_tree_add_item(act_tree, hf_openflow_set_tp_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
583 proto_tree_add_item(act_tree, hf_openflow_enqueue, tvb, offset, 4, ENC_BIG_ENDIAN);
584 offset+=4;
586 length_remaining = length-32;
587 if(length_remaining > 0){
588 uint16_t num_ports = length_remaining/48;
589 int i;
590 if((length_remaining&0x003f) != 0){
591 /* protocol_error */
593 for(i=0; i<num_ports ;i++){
594 proto_tree *port_tree;
596 port_tree = proto_tree_add_subtree_format(tree, tvb, offset, 48, ett_openflow_port, NULL, "Port data %u",i+1);
597 dissect_openflow_phy_port(tvb, pinfo, port_tree, offset);
598 offset+=48;
605 static void
606 dissect_openflow_switch_config(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, uint16_t length _U_)
609 /* ofp_config_flags */
610 proto_tree_add_item(tree, hf_openflow_config_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
611 offset+=2;
612 /* miss_send_len */
613 proto_tree_add_item(tree, hf_openflow_miss_send_len, tvb, offset, 2, ENC_BIG_ENDIAN);
614 /*offset+=2;*/
618 #define OFPR_NO_MATCH 0 /* No matching flow (table-miss flow entry). */
619 #define OFPR_ACTION 1 /* Action explicitly output to controller. */
620 #define OFPR_INVALID_TTL 2 /* Packet has invalid TTL */
622 static const value_string openflow_reason_values[] = {
623 { OFPR_NO_MATCH, "No matching flow (table-miss flow entry)" },
624 { OFPR_ACTION, "Action explicitly output to controller" },
625 { OFPR_INVALID_TTL, "Packet has invalid TTL" },
626 { 0, NULL }
629 static void
630 dissect_openflow_pkt_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
632 tvbuff_t *next_tvb;
634 /* uint32_t buffer_id; ID assigned by datapath. */
635 proto_tree_add_item(tree, hf_openflow_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
636 offset+=4;
637 /* uint16_t total_len; Full length of frame. */
638 proto_tree_add_item(tree, hf_openflow_total_len, tvb, offset, 2, ENC_BIG_ENDIAN);
639 offset+=2;
641 /* uint16_t in_port; Port on which frame was received. */
642 proto_tree_add_item(tree, hf_openflow_in_port, tvb, offset, 2, ENC_BIG_ENDIAN);
643 offset+=2;
645 /* uint8_t reason; Reason packet is being sent (one of OFPR_*) */
646 proto_tree_add_item(tree, hf_openflow_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
647 offset++;
649 proto_tree_add_item(tree, hf_openflow_pkt_in_pad, tvb, offset, 1, ENC_NA);
650 offset+=1;
652 next_tvb = tvb_new_subset_length(tvb, offset, length-offset);
653 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
657 #define OFPRR_IDLE_TIMEOUT 0
658 #define OFPRR_HARD_TIMEOUT 1
659 #define OFPRR_DELETE 2
660 static const value_string openflow_flow_removed_reason_values[] = {
661 { OFPRR_IDLE_TIMEOUT, "OFPRR_IDLE_TIMEOUT" },
662 { OFPRR_HARD_TIMEOUT, "OFPRR_HARD_TIMEOUT" },
663 { OFPRR_DELETE, "OFPRR_DELETE" },
664 { 0, NULL }
667 static void
668 dissect_openflow_flow_removed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length _U_)
670 /* struct match; */
671 offset = dissect_openflow_ofp_match_v1(tvb, pinfo, tree, offset);
673 /* uint64_t cookie; */
674 proto_tree_add_item(tree, hf_openflow_flow_removed_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
675 offset+=8;
677 /* uint16_t priority; */
678 proto_tree_add_item(tree, hf_openflow_flow_removed_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
679 offset+=2;
681 /* uint8_t reason; */
682 proto_tree_add_item(tree, hf_openflow_flow_removed_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
683 offset+=1;
685 /* uint8_t pad1; */
686 proto_tree_add_item(tree, hf_openflow_flow_removed_pad1, tvb, offset, 1, ENC_BIG_ENDIAN);
687 offset+=1;
689 /* uint32_t duration_sec; */
690 proto_tree_add_item(tree, hf_openflow_flow_removed_duration_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
691 offset+=4;
693 /* uint32_t duration_nsec; */
694 proto_tree_add_item(tree, hf_openflow_flow_removed_duration_nsec, tvb, offset, 4, ENC_BIG_ENDIAN);
695 offset+=4;
697 /* uint16_t idle_timeout; */
698 proto_tree_add_item(tree, hf_openflow_flow_removed_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
699 offset+=2;
701 /* uint8_t pad2; */
702 proto_tree_add_item(tree, hf_openflow_flow_removed_pad2, tvb, offset, 2, ENC_BIG_ENDIAN);
703 offset+=2;
705 /* uint64_t packet_count; */
706 proto_tree_add_item(tree, hf_openflow_flow_removed_packet_count, tvb, offset, 8, ENC_BIG_ENDIAN);
707 offset+=8;
709 /* uint64_t byte_count; */
710 proto_tree_add_item(tree, hf_openflow_flow_removed_byte_count, tvb, offset, 8, ENC_BIG_ENDIAN);
714 static void
715 dissect_openflow_pkt_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
717 tvbuff_t *next_tvb;
718 int32_t buffer_id;
720 /* uint32_t buffer_id; ID assigned by datapath. */
721 buffer_id = tvb_get_ntohl(tvb, offset);
722 proto_tree_add_item(tree, hf_openflow_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
723 offset+=4;
725 /* uint32_t in_port; Packet's input port or OFPP_CONTROLLER. */
726 proto_tree_add_item(tree, hf_openflow_in_port, tvb, offset, 2, ENC_BIG_ENDIAN);
727 offset+=2;
729 /* uint16_t actions_len; Size of action array in bytes. */
730 proto_tree_add_item(tree, hf_openflow_actions_len, tvb, offset, 2, ENC_BIG_ENDIAN);
731 offset+=2;
733 /* struct ofp_action_header actions[0]; Action list. */
734 offset = dissect_openflow_action_header(tvb, pinfo, tree, offset);
735 /* Packet data. The length is inferred
736 from the length field in the header.
737 (Only meaningful if buffer_id == -1.)
739 if(buffer_id == -1){
740 next_tvb = tvb_new_subset_length(tvb, offset, length-offset);
741 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
745 #define OFPFC_ADD 0 /* New flow. */
746 #define OFPFC_MODIFY 1 /* Modify all matching flows. */
747 #define OFPFC_MODIFY_STRICT 2 /* Modify entry strictly matching wildcards */
748 #define OFPFC_DELETE 3 /* Delete all matching flows. */
749 #define OFPFC_DELETE_STRICT 4 /* Strictly match wildcards and priority. */
751 static const value_string openflow_command_values[] = {
752 { OFPFC_ADD, "New flow" },
753 { OFPFC_MODIFY, "Modify all matching flows" },
754 { OFPFC_MODIFY_STRICT, "Modify entry strictly matching wildcards" },
755 { OFPFC_DELETE, "Delete all matching flows" },
756 { OFPFC_DELETE_STRICT, "Strictly match wildcards and priority" },
757 { 0, NULL }
760 static void
761 dissect_openflow_flow_mod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length _U_)
764 /* struct ofp_match match; Fields to match */
765 offset = dissect_openflow_ofp_match_v1(tvb, pinfo, tree, offset);
767 /* uint64_t cookie; Opaque controller-issued identifier. */
768 proto_tree_add_item(tree, hf_openflow_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
769 offset += 8;
771 /* uint16_t command; One of OFPFC_*. */
772 proto_tree_add_item(tree, hf_openflow_command, tvb, offset, 2, ENC_BIG_ENDIAN);
773 offset += 2;
775 /* uint16_t idle_timeout; Idle time before discarding (seconds). */
776 proto_tree_add_item(tree, hf_openflow_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
777 offset += 2;
778 /* uint16_t hard_timeout; Max time before discarding (seconds). */
779 proto_tree_add_item(tree, hf_openflow_hard_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
780 offset += 2;
781 /* uint16_t priority; Priority level of flow entry. */
782 proto_tree_add_item(tree, hf_openflow_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
783 offset += 2;
784 /* uint32_t buffer_id; Buffered packet to apply to, or OFP_NO_BUFFER.
785 Not meaningful for OFPFC_DELETE*.
787 proto_tree_add_item(tree, hf_openflow_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
788 offset += 4;
789 /* uint32_t out_port; For OFPFC_DELETE* commands, require
790 matching entries to include this as an output port. A value of OFPP_ANY
791 indicates no restriction.
793 proto_tree_add_item(tree, hf_openflow_out_port, tvb, offset, 2, ENC_BIG_ENDIAN);
794 offset += 2;
796 /* uint16_t flags; One of OFPFF_*. */
797 proto_tree_add_item(tree, hf_openflow_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
798 offset+=2;
800 dissect_openflow_action_header(tvb, pinfo, tree, offset);
804 #define OFPST_DESC 0
805 #define OFPST_FLOW 1
806 #define OFPST_AGGREGATE 2
807 #define OFPST_TABLE 3
808 #define OFPST_PORT 4
809 #define OFPST_QUEUE 5
810 #define OFPST_VENDOR 0xffff
812 static const value_string openflow_stats_type_values[] = {
813 { OFPST_DESC, "OFPST_DESC" },
814 { OFPST_FLOW, "OFPST_FLOW" },
815 { OFPST_AGGREGATE, "OFPST_AGGREGATE" },
816 { OFPST_TABLE, "OFPST_TABLE" },
817 { OFPST_PORT, "OFPST_PORT" },
818 { OFPST_QUEUE, "OFPST_QUEUE" },
819 { OFPST_VENDOR, "OFPST_VENDOR" },
820 { 0, NULL }
822 static int
823 dissect_openflow_stats_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length _U_)
825 proto_item *type_item;
826 uint32_t type;
828 /* uint16_t type; */
829 type_item = proto_tree_add_item_ret_uint(tree, hf_openflow_v1_stats_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
830 offset += 2;
831 /* uint16_t flags; OFPSF_REQ_* flags (none yet defined). */
832 proto_tree_add_item(tree, hf_openflow_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
833 offset += 2;
834 /* uint8_t body[0]; Body of the request. */
835 switch (type) {
836 case OFPST_DESC:
837 /* The request body is empty. */
838 break;
839 case OFPST_FLOW:
840 dissect_openflow_flow_stats_request_v1(tvb, pinfo, tree, offset);
841 break;
842 default:
843 expert_add_info(pinfo, type_item, &ei_openflow_1_0_type);
844 break;
847 return offset;
850 static int
851 dissect_openflow_stats_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
854 proto_item *type_item;
855 uint32_t type;
857 /* uint16_t type; */
858 type_item = proto_tree_add_item_ret_uint(tree, hf_openflow_v1_stats_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
859 offset += 2;
860 /* uint16_t flags; OFPSF_REQ_ */
861 proto_tree_add_item(tree, hf_openflow_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
862 offset += 2;
863 /* uint8_t body[0]; Body of the request. */
864 if (length == 12 ) {
865 /* No body */
866 return offset;
868 switch (type) {
869 case OFPST_DESC:
870 /* The request body is empty. */
871 break;
872 case OFPST_FLOW:
873 /* fall trough */
874 default:
875 expert_add_info(pinfo, type_item, &ei_openflow_1_0_type);
876 break;
879 return offset;
882 static int
883 dissect_openflow_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
885 proto_item *ti, *type_item;
886 proto_tree *openflow_tree;
887 unsigned offset = 0;
888 uint8_t type;
889 uint16_t length;
891 type = tvb_get_uint8(tvb, 1);
893 col_append_fstr(pinfo->cinfo, COL_INFO, "Type: %s",
894 val_to_str_ext_const(type, &openflow_1_0_type_values_ext, "Unknown message type"));
896 /* Stop the Ethernet frame from overwriting the columns */
897 if((type == OFPT_1_0_PACKET_IN) || (type == OFPT_1_0_PACKET_OUT)){
898 col_set_writable(pinfo->cinfo, -1, false);
901 /* Create display subtree for the protocol */
902 ti = proto_tree_add_item(tree, proto_openflow_v1, tvb, 0, -1, ENC_NA);
903 openflow_tree = proto_item_add_subtree(ti, ett_openflow);
905 /* A.1 OpenFlow Header. */
906 /* OFP_VERSION. */
907 proto_tree_add_item(openflow_tree, hf_openflow_version, tvb, offset, 1, ENC_BIG_ENDIAN);
908 offset++;
910 /* One of the OFPT_ constants. */
911 type_item = proto_tree_add_item(openflow_tree, hf_openflow_1_0_type, tvb, offset, 1, ENC_BIG_ENDIAN);
912 offset++;
914 /* Length including this ofp_header. */
915 length = tvb_get_ntohs(tvb, offset);
916 proto_tree_add_item(openflow_tree, hf_openflow_length, tvb, offset, 2, ENC_BIG_ENDIAN);
917 offset+=2;
919 /* Transaction id associated with this packet. Replies use the same id as was in the request
920 * to facilitate pairing.
922 proto_tree_add_item(openflow_tree, hf_openflow_xid, tvb, offset, 4, ENC_BIG_ENDIAN);
923 offset+=4;
925 switch(type){
926 case OFPT_1_0_HELLO: /* 0 */
927 /* 5.5.1 Hello
928 * The OFPT_HELLO message has no body;
930 break;
931 case OFPT_1_0_FEATURES_REQUEST: /* 5 */
932 /* 5.3.1 Handshake
933 * Upon TLS session establishment, the controller sends an OFPT_FEATURES_REQUEST
934 * message. This message does not contain a body beyond the OpenFlow header.
936 break;
937 case OFPT_1_0_FEATURES_REPLY: /* 6 */
938 dissect_openflow_features_reply_v1(tvb, pinfo, openflow_tree, offset, length);
939 break;
940 case OFPT_1_0_GET_CONFIG_REQUEST: /* 7 */
941 /* A.3.2 There is no body for OFPT_GET_CONFIG_REQUEST beyond the OpenFlow header. */
942 break;
943 case OFPT_1_0_GET_CONFIG_REPLY: /* 8 */
944 /* Fall trough */
945 case OFPT_1_0_SET_CONFIG: /* 9 */
946 dissect_openflow_switch_config(tvb, pinfo, openflow_tree, offset, length);
947 break;
948 case OFPT_1_0_PACKET_IN: /* 10 */
949 dissect_openflow_pkt_in(tvb, pinfo, openflow_tree, offset, length);
950 break;
951 case OFPT_1_0_FLOW_REMOVED: /* 11 */
952 dissect_openflow_flow_removed(tvb, pinfo, openflow_tree, offset, length);
953 break;
954 case OFPT_1_0_PACKET_OUT: /* 13 */
955 dissect_openflow_pkt_out(tvb, pinfo, openflow_tree, offset, length);
956 break;
957 case OFPT_1_0_FLOW_MOD: /* 14 */
958 dissect_openflow_flow_mod(tvb, pinfo, openflow_tree, offset, length);
959 break;
960 case OFPT_1_0_STATS_REQUEST: /* 16 */
961 dissect_openflow_stats_req(tvb, pinfo, openflow_tree, offset, length);
962 break;
963 case OFPT_1_0_STATS_REPLY: /* 17 */
964 dissect_openflow_stats_resp(tvb, pinfo, openflow_tree, offset, length);
965 break;
966 default:
967 if(length>8){
968 expert_add_info(pinfo, type_item, &ei_openflow_1_0_type);
970 break;
973 return tvb_reported_length(tvb);
979 * Register the protocol with Wireshark.
981 void
982 proto_register_openflow_v1(void)
984 static hf_register_info hf[] = {
985 { &hf_openflow_version,
986 { "Version", "openflow.version",
987 FT_UINT8, BASE_HEX, VALS(openflow_version_values), 0x7f,
988 NULL, HFILL }
990 { &hf_openflow_1_0_type,
991 { "Type", "openflow_1_0.type",
992 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &openflow_1_0_type_values_ext, 0x0,
993 NULL, HFILL }
995 { &hf_openflow_xid,
996 { "Transaction ID", "openflow.xid",
997 FT_UINT32, BASE_DEC, NULL, 0x0,
998 NULL, HFILL }
1000 { &hf_openflow_length,
1001 { "Length", "openflow.length",
1002 FT_UINT16, BASE_DEC, NULL, 0x0,
1003 NULL, HFILL }
1005 { &hf_openflow_datapath_id,
1006 { "Datapath unique ID", "openflow.datapath_id",
1007 FT_UINT64, BASE_HEX, NULL, 0x0,
1008 NULL, HFILL }
1010 { &hf_openflow_datapath_mac,
1011 { "MAC addr", "openflow.datapath_mac",
1012 FT_ETHER, BASE_NONE, NULL, 0x0,
1013 NULL, HFILL }
1015 { &hf_openflow_datapath_impl,
1016 { "Implementers part", "openflow.datapath_imp",
1017 FT_UINT16, BASE_HEX, NULL, 0x0,
1018 NULL, HFILL }
1020 { &hf_openflow_n_buffers,
1021 { "n_buffers", "openflow.n_buffers",
1022 FT_UINT32, BASE_DEC, NULL, 0x0,
1023 NULL, HFILL }
1025 { &hf_openflow_n_tables,
1026 { "n_tables", "openflow.n_tables",
1027 FT_UINT8, BASE_DEC, NULL, 0x0,
1028 NULL, HFILL }
1030 #if 0
1031 { &hf_openflow_auxiliary_id,
1032 { "auxiliary_id", "openflow.auxiliary_id",
1033 FT_UINT8, BASE_DEC, NULL, 0x0,
1034 NULL, HFILL }
1036 #endif
1037 { &hf_openflow_capabilities,
1038 { "capabilities", "openflow.capabilities",
1039 FT_UINT32, BASE_HEX, NULL, 0x0,
1040 NULL, HFILL }
1042 { &hf_openflow_actions,
1043 { "actions", "openflow.actions",
1044 FT_UINT32, BASE_HEX, NULL, 0x0,
1045 NULL, HFILL }
1047 #if 0
1048 { &hf_openflow_reserved32,
1049 { "Reserved", "openflow.reserved32",
1050 FT_UINT32, BASE_DEC, NULL, 0x0,
1051 NULL, HFILL }
1053 #endif
1054 { &hf_openflow_cap_flow_stats,
1055 { "Flow statistics", "openflow.flow_stats",
1056 FT_BOOLEAN, 32, NULL, OFPC_FLOW_STATS,
1057 NULL, HFILL }
1059 { &hf_openflow_table_stats,
1060 { "Table statistics", "openflow.table_stats",
1061 FT_BOOLEAN, 32, NULL, OFPC_TABLE_STATS,
1062 NULL, HFILL }
1064 { &hf_openflow_port_stats,
1065 { "Port statistics", "openflow.port_stats",
1066 FT_BOOLEAN, 32, NULL, OFPC_PORT_STATS,
1067 NULL, HFILL }
1069 { &hf_openflow_group_stats,
1070 { "Group statistics", "openflow.group_stats",
1071 FT_BOOLEAN, 32, NULL, OFPC_GROUP_STATS,
1072 NULL, HFILL }
1074 { &hf_openflow_ip_reasm,
1075 { "Can reassemble IP fragments", "openflow.ip_reasm",
1076 FT_BOOLEAN, 32, NULL, OFPC_IP_REASM,
1077 NULL, HFILL }
1079 { &hf_openflow_queue_stats,
1080 { "Queue statistics", "openflow.queue_stats",
1081 FT_BOOLEAN, 32, NULL, OFPC_QUEUE_STATS,
1082 NULL, HFILL }
1084 { &hf_openflow_port_blocked,
1085 { "Switch will block looping ports", "openflow.port_blocked",
1086 FT_BOOLEAN, 32, NULL, OFPC_PORT_BLOCKED,
1087 NULL, HFILL }
1089 { &hf_openflow_output,
1090 { "Output to switch port", "openflow.output",
1091 FT_BOOLEAN, 32, NULL, OFPAT_OUTPUT_MASK,
1092 NULL, HFILL }
1094 { &hf_openflow_set_vlan_vid,
1095 { "Set the 802.1q VLAN id", "openflow.set_vlan_vid",
1096 FT_BOOLEAN, 32, NULL, OFPAT_SET_VLAN_VID_MASK,
1097 NULL, HFILL }
1099 { &hf_openflow_set_vlan_pcp,
1100 { "Set the 802.1q priority", "openflow.set_vlan_pcp",
1101 FT_BOOLEAN, 32, NULL, OFPAT_SET_VLAN_PCP_MASK,
1102 NULL, HFILL }
1104 { &hf_openflow_strip_vlan,
1105 { "Strip the 802.1q header", "openflow.strip_vlan",
1106 FT_BOOLEAN, 32, NULL, OFPAT_STRIP_VLAN_MASK,
1107 NULL, HFILL }
1109 { &hf_openflow_set_dl_src,
1110 { "Ethernet source address", "openflow.set_dl_src",
1111 FT_BOOLEAN, 32, NULL, OFPAT_SET_DL_SRC_MASK,
1112 NULL, HFILL }
1114 { &hf_openflow_set_dl_dst,
1115 { "Ethernet destination address", "openflow.set_dl_ds",
1116 FT_BOOLEAN, 32, NULL, OFPAT_SET_DL_DST_MASK,
1117 NULL, HFILL }
1119 { &hf_openflow_set_nw_src,
1120 { "IP source address", "openflow.set_nw_src",
1121 FT_BOOLEAN, 32, NULL, OFPAT_SET_NW_SRC_MASK,
1122 NULL, HFILL }
1124 { &hf_openflow_set_nw_dst,
1125 { "IP destination address", "openflow.set_nw_ds",
1126 FT_BOOLEAN, 32, NULL, OFPAT_SET_NW_DST_MASK,
1127 NULL, HFILL }
1129 { &hf_openflow_set_nw_tos,
1130 { "IP ToS (DSCP field, 6 bits)", "openflow.set_nw_tos",
1131 FT_BOOLEAN, 32, NULL, OFPAT_SET_NW_TOS_MASK,
1132 NULL, HFILL }
1134 { &hf_openflow_set_tp_src,
1135 { "TCP/UDP source port", "openflow.set_tp_src",
1136 FT_BOOLEAN, 32, NULL, OFPAT_SET_TP_SRC_MASK,
1137 NULL, HFILL }
1139 { &hf_openflow_set_tp_dst,
1140 { "TCP/UDP destination port", "openflow.set_tp_dst",
1141 FT_BOOLEAN, 32, NULL, OFPAT_SET_TP_DST_MASK,
1142 NULL, HFILL }
1144 { &hf_openflow_enqueue,
1145 { "Output to queue", "openflow.enqueue",
1146 FT_BOOLEAN, 32, NULL, OFPAT_ENQUEUE_MASK,
1147 NULL, HFILL }
1149 { &hf_openflow_port_no,
1150 { "Port number", "openflow.port_no",
1151 FT_UINT16, BASE_DEC, NULL, 0x0,
1152 NULL, HFILL }
1154 { &hf_openflow_hw_addr,
1155 { "HW Address", "openflow.hw_add",
1156 FT_ETHER, BASE_NONE, NULL, 0x0,
1157 NULL, HFILL }
1159 { &hf_openflow_port_name,
1160 { "Port Name", "openflow.port_name",
1161 FT_STRING, BASE_NONE, NULL, 0x0,
1162 NULL, HFILL }
1164 { &hf_openflow_port_config,
1165 { "Config flags", "openflow.port_config",
1166 FT_UINT32, BASE_HEX, NULL, 0x0,
1167 NULL, HFILL }
1169 { &hf_openflow_port_state,
1170 { "State flags", "openflow.port_state",
1171 FT_UINT32, BASE_HEX, NULL, 0x0,
1172 NULL, HFILL }
1174 { &hf_openflow_port_curr,
1175 { "Current features", "openflow.port_curr",
1176 FT_UINT32, BASE_HEX, NULL, 0x0,
1177 NULL, HFILL }
1179 { &hf_openflow_port_advertised,
1180 { "Advertised features", "openflow.port_advertised",
1181 FT_UINT32, BASE_HEX, NULL, 0x0,
1182 NULL, HFILL }
1184 { &hf_openflow_port_supported,
1185 { "Features supported", "openflow.port_supported",
1186 FT_UINT32, BASE_HEX, NULL, 0x0,
1187 NULL, HFILL }
1189 { &hf_openflow_port_peer,
1190 { "Features advertised by peer", "openflow.port_peer",
1191 FT_UINT32, BASE_HEX, NULL, 0x0,
1192 NULL, HFILL }
1194 { &hf_openflow_port_down,
1195 { "Port is administratively down", "openflow.port_down",
1196 FT_BOOLEAN, 32, NULL, OFPPC_PORT_DOWN,
1197 NULL, HFILL }
1199 { &hf_openflow_no_stp,
1200 { "Disable 802.1D spanning tree on port", "openflow.no_stp",
1201 FT_BOOLEAN, 32, NULL, OFPPC_NO_STP,
1202 NULL, HFILL }
1204 { &hf_openflow_no_recv,
1205 { "Drop all packets except 802.1D spanning tree packets", "openflow.no_recv",
1206 FT_BOOLEAN, 32, NULL, OFPPC_NO_RECV,
1207 NULL, HFILL }
1209 { &hf_openflow_no_recv_stp,
1210 { "Drop received 802.1D STP packets", "openflow.no_recv_stp",
1211 FT_BOOLEAN, 32, NULL, OFPPC_NO_RECV_STP,
1212 NULL, HFILL }
1214 { &hf_openflow_no_flood,
1215 { "Do not include this port when flooding", "openflow.no_flood",
1216 FT_BOOLEAN, 32, NULL, OFPPC_NO_FLOOD,
1217 NULL, HFILL }
1219 { &hf_openflow_no_fwd,
1220 { "Drop packets forwarded to port", "openflow.no_fwd",
1221 FT_BOOLEAN, 32, NULL, OFPPC_NO_FWD,
1222 NULL, HFILL }
1224 { &hf_openflow_no_packet_in,
1225 { "Do not send packet-in msgs for port", "openflow.no_packet_in",
1226 FT_BOOLEAN, 32, NULL, OFPPC_NO_PACKET_IN,
1227 NULL, HFILL }
1229 { &hf_openflow_link_down,
1230 { "No physical link present", "openflow.link_down",
1231 FT_BOOLEAN, 32, NULL, OFPPS_LINK_DOWN,
1232 NULL, HFILL }
1234 { &hf_openflow_10mb_hd,
1235 { "10 Mb half-duplex rate support", "openflow.10mb_hd",
1236 FT_BOOLEAN, 32, NULL, OFPPF_10MB_HD,
1237 NULL, HFILL }
1239 { &hf_openflow_10mb_fd,
1240 { "10 Mb full-duplex rate support", "openflow.10mb_fd",
1241 FT_BOOLEAN, 32, NULL, OFPPF_10MB_FD,
1242 NULL, HFILL }
1244 { &hf_openflow_100mb_hd,
1245 { "100 Mb half-duplex rate support", "openflow.100mb_hd",
1246 FT_BOOLEAN, 32, NULL, OFPPF_100MB_HD,
1247 NULL, HFILL }
1249 { &hf_openflow_100mb_fd,
1250 { "100 Mb full-duplex rate support", "openflow.100mb_0fd",
1251 FT_BOOLEAN, 32, NULL, OFPPF_100MB_FD,
1252 NULL, HFILL }
1254 { &hf_openflow_1gb_hd,
1255 { "1 Gb half-duplex rate support", "openflow.1gb_hd",
1256 FT_BOOLEAN, 32, NULL, OFPPF_1GB_HD,
1257 NULL, HFILL }
1259 { &hf_openflow_1gb_fd,
1260 { "1 Gb full-duplex rate support", "openflow.1gb_fd",
1261 FT_BOOLEAN, 32, NULL, OFPPF_1GB_FD,
1262 NULL, HFILL }
1264 { &hf_openflow_10gb_fd,
1265 { "10 Gb full-duplex rate support", "openflow.10gb_fd",
1266 FT_BOOLEAN, 32, NULL, OFPPF_10GB_FD,
1267 NULL, HFILL }
1269 { &hf_openflow_copper,
1270 { "Copper medium", "openflow.copper",
1271 FT_BOOLEAN, 32, NULL, OFPPF_COPPER,
1272 NULL, HFILL }
1274 { &hf_openflow_fiber,
1275 { "Fiber medium", "openflow.fiber",
1276 FT_BOOLEAN, 32, NULL, OFPPF_FIBER,
1277 NULL, HFILL }
1279 { &hf_openflow_autoneg,
1280 { "Auto-negotiation", "openflow.autoneg",
1281 FT_BOOLEAN, 32, NULL, OFPPF_AUTONEG,
1282 NULL, HFILL }
1284 { &hf_openflow_pause,
1285 { "Pause", "openflow.pause",
1286 FT_BOOLEAN, 32, NULL, OFPPF_PAUSE,
1287 NULL, HFILL }
1289 { &hf_openflow_pause_asym,
1290 { "Asymmetric pause", "openflow.pause_asym",
1291 FT_BOOLEAN, 32, NULL, OFPPF_PAUSE_ASYM,
1292 NULL, HFILL }
1294 { &hf_openflow_config_flags,
1295 { "Config flags", "openflow.config_flags",
1296 FT_UINT16, BASE_HEX, NULL, 0x0,
1297 NULL, HFILL }
1299 { &hf_openflow_miss_send_len,
1300 { "Max bytes of packet", "openflow.miss_send_len",
1301 FT_UINT16, BASE_HEX, NULL, 0x0,
1302 NULL, HFILL }
1304 { &hf_openflow_buffer_id,
1305 { "Buffer Id", "openflow.buffer_id",
1306 FT_UINT32, BASE_HEX, NULL, 0x0,
1307 NULL, HFILL }
1309 { &hf_openflow_total_len,
1310 { "Total length", "openflow.total_len",
1311 FT_UINT16, BASE_DEC, NULL, 0x0,
1312 NULL, HFILL }
1314 { &hf_openflow_in_port,
1315 { "In port", "openflow.in_port",
1316 FT_UINT16, BASE_DEC, NULL, 0x0,
1317 NULL, HFILL }
1319 { &hf_openflow_reason,
1320 { "Reason", "openflow.reason",
1321 FT_UINT8, BASE_DEC, VALS(openflow_reason_values), 0x0,
1322 NULL, HFILL }
1325 { &hf_openflow_pkt_in_pad,
1326 { "Pad", "openflow.pkt_in.pad",
1327 FT_BYTES, BASE_NONE, NULL, 0x0,
1328 NULL, HFILL }
1330 { &hf_openflow_flow_removed_cookie,
1331 { "Cookie", "openflow.flow_removed.cookie",
1332 FT_UINT64, BASE_HEX, NULL, 0x0,
1333 NULL, HFILL }
1335 { &hf_openflow_flow_removed_priority,
1336 { "Priority", "openflow.flow_removed.priority",
1337 FT_UINT16, BASE_DEC, NULL, 0x0,
1338 NULL, HFILL }
1340 { &hf_openflow_flow_removed_reason,
1341 { "Reason", "openflow.flow_removed.reason",
1342 FT_UINT8, BASE_DEC, VALS(openflow_flow_removed_reason_values), 0x0,
1343 NULL, HFILL }
1345 { &hf_openflow_flow_removed_pad1,
1346 { "Pad1", "openflow.flow_removed.pad1",
1347 FT_UINT8, BASE_HEX, NULL, 0x0,
1348 NULL, HFILL }
1350 { &hf_openflow_flow_removed_duration_sec,
1351 { "Duration sec", "openflow.flow_removed.duration_sec",
1352 FT_UINT32, BASE_DEC, NULL, 0x0,
1353 NULL, HFILL }
1355 { &hf_openflow_flow_removed_duration_nsec,
1356 { "Duration nsec", "openflow.flow_removed.duration_nsec",
1357 FT_UINT32, BASE_DEC, NULL, 0x0,
1358 NULL, HFILL }
1360 { &hf_openflow_flow_removed_idle_timeout,
1361 { "Idle timeout", "openflow.flow_removed.idle_timeout",
1362 FT_UINT16, BASE_DEC, NULL, 0x0,
1363 NULL, HFILL }
1365 { &hf_openflow_flow_removed_pad2,
1366 { "Pad2", "openflow.flow_removed.pad2",
1367 FT_UINT16, BASE_HEX, NULL, 0x0,
1368 NULL, HFILL }
1370 { &hf_openflow_flow_removed_packet_count,
1371 { "Packet count", "openflow.flow_removed.packet_count",
1372 FT_UINT64, BASE_DEC, NULL, 0x0,
1373 NULL, HFILL }
1375 { &hf_openflow_flow_removed_byte_count,
1376 { "Byte count", "openflow.flow_removed.byte_count",
1377 FT_UINT64, BASE_DEC, NULL, 0x0,
1378 NULL, HFILL }
1380 { &hf_openflow_table_id,
1381 { "Table Id", "openflow.table_id",
1382 FT_UINT8, BASE_DEC, NULL, 0x0,
1383 NULL, HFILL }
1385 { &hf_openflow_cookie,
1386 { "Cookie", "openflow.cookie",
1387 FT_UINT64, BASE_HEX, NULL, 0x0,
1388 NULL, HFILL }
1390 #if 0
1391 { &hf_openflow_cookie_mask,
1392 { "Cookie mask", "openflow.cookie_mask",
1393 FT_UINT64, BASE_HEX, NULL, 0x0,
1394 NULL, HFILL }
1396 #endif
1397 { &hf_openflow_features_reply_pad,
1398 { "Pad", "openflow.features_reply.pad",
1399 FT_BYTES, BASE_NONE, NULL, 0x0,
1400 NULL, HFILL }
1402 { &hf_openflow_actions_len,
1403 { "Actions length", "openflow.actions_len",
1404 FT_UINT16, BASE_DEC, NULL, 0x0,
1405 NULL, HFILL }
1407 { &hf_openflow_action_type,
1408 { "Actions type", "openflow.action_typ",
1409 FT_UINT16, BASE_DEC, VALS(openflow_action_values), 0x0,
1410 NULL, HFILL }
1412 { &hf_openflow_action_len,
1413 { "Action length", "openflow.action_len",
1414 FT_UINT16, BASE_DEC, NULL, 0x0,
1415 NULL, HFILL }
1417 { &hf_openflow_output_port,
1418 { "Output port", "openflow.output_port",
1419 FT_UINT16, BASE_DEC, NULL, 0x0,
1420 NULL, HFILL }
1422 { &hf_openflow_max_len,
1423 { "Max length", "openflow.max_len",
1424 FT_UINT16, BASE_DEC, NULL, 0x0,
1425 NULL, HFILL }
1427 { &hf_openflow_wildcards,
1428 { "Wildcards", "openflow.wildcards",
1429 FT_UINT32, BASE_DEC, NULL, 0x0,
1430 NULL, HFILL }
1432 { &hf_openflow_command,
1433 { "Command", "openflow.command",
1434 FT_UINT16, BASE_DEC, VALS(openflow_command_values), 0x0,
1435 NULL, HFILL }
1437 { &hf_openflow_eth_src,
1438 { "Ethernet source address", "openflow.eth_src",
1439 FT_ETHER, BASE_NONE, NULL, 0x0,
1440 NULL, HFILL }
1442 { &hf_openflow_eth_dst,
1443 { "Ethernet destination address", "openflow.eth_dst",
1444 FT_ETHER, BASE_NONE, NULL, 0x0,
1445 NULL, HFILL }
1447 { &hf_openflow_dl_vlan,
1448 { "Input VLAN id", "openflow.dl_vlan",
1449 FT_UINT16, BASE_DEC, NULL, 0x0,
1450 NULL, HFILL }
1452 { &hf_openflow_dl_vlan_pcp,
1453 { "Input VLAN priority", "openflow.dl_vlan_pcp",
1454 FT_UINT8, BASE_DEC, NULL, 0x0,
1455 NULL, HFILL }
1457 { &hf_openflow_ofp_match_pad,
1458 { "Pad", "openflow.ofp_match.pad",
1459 FT_BYTES, BASE_NONE, NULL, 0x0,
1460 NULL, HFILL }
1462 { &hf_openflow_match_dl_type,
1463 { "Dl type", "openflow.ofp_match.dl_type",
1464 FT_UINT16, BASE_DEC, NULL, 0x0,
1465 NULL, HFILL }
1467 { &hf_openflow_ofp_match_tos,
1468 { "IP ToS", "openflow.ofp_match.tos",
1469 FT_UINT8, BASE_DEC, NULL, 0x0,
1470 NULL, HFILL }
1472 { &hf_openflow_ofp_match_nw_proto,
1473 { "IP protocol", "openflow.ofp_match.nw_proto",
1474 FT_UINT8, BASE_DEC, NULL, 0x0,
1475 NULL, HFILL }
1477 { &hf_openflow_ofp_source_addr,
1478 { "Source Address", "openflow.ofp_match.source_addr",
1479 FT_IPv4, BASE_NONE, NULL, 0x0,
1480 NULL, HFILL }
1482 { &hf_openflow_ofp_dest_addr,
1483 { "Destination Address", "openflow.ofp_match.dest_addr",
1484 FT_IPv4, BASE_NONE, NULL, 0x0,
1485 NULL, HFILL }
1487 { &hf_openflow_ofp_source_port,
1488 { "Source Port", "openflow.ofp_match.source_port",
1489 FT_UINT16, BASE_DEC, NULL, 0x0,
1490 NULL, HFILL }
1492 { &hf_openflow_ofp_dest_port,
1493 { "Destination Port", "openflow.ofp_match.dest_port",
1494 FT_UINT16, BASE_DEC, NULL, 0x0,
1495 NULL, HFILL }
1497 { &hf_openflow_idle_timeout,
1498 { "Idle time-out", "openflow.idle_timeout",
1499 FT_UINT16, BASE_DEC, NULL, 0x0,
1500 NULL, HFILL }
1502 { &hf_openflow_hard_timeout,
1503 { "hard time-out", "openflow.hard_timeout",
1504 FT_UINT16, BASE_DEC, NULL, 0x0,
1505 NULL, HFILL }
1507 { &hf_openflow_priority,
1508 { "Priority", "openflow.priority",
1509 FT_UINT16, BASE_DEC, NULL, 0x0,
1510 NULL, HFILL }
1512 { &hf_openflow_out_port,
1513 { "Out port", "openflow.out_port",
1514 FT_UINT32, BASE_DEC, NULL, 0x0,
1515 NULL, HFILL }
1517 #if 0
1518 { &hf_openflow_out_group,
1519 { "Out group", "openflow.out_group",
1520 FT_UINT32, BASE_DEC, NULL, 0x0,
1521 NULL, HFILL }
1523 #endif
1524 { &hf_openflow_flags,
1525 { "Flags", "openflow.flags",
1526 FT_UINT16, BASE_DEC, NULL, 0x0,
1527 NULL, HFILL }
1529 { &hf_openflow_v1_stats_type,
1530 { "Type", "openflow.stats.type",
1531 FT_UINT16, BASE_DEC, VALS(openflow_stats_type_values), 0x0,
1532 NULL, HFILL }
1534 { &hf_openflow_v1_flow_stats_request_pad,
1535 { "Pad", "openflow.stats.request_pad",
1536 FT_UINT8, BASE_DEC, NULL, 0x0,
1537 NULL, HFILL }
1541 static int *ett[] = {
1542 &ett_openflow,
1543 &ett_openflow_path_id,
1544 &ett_openflow_cap,
1545 &ett_openflow_act,
1546 &ett_openflow_port,
1547 &ett_openflow_port_cnf,
1548 &ett_openflow_port_state,
1549 &ett_openflow_port_cf
1552 static ei_register_info ei[] = {
1553 #if 0
1554 { &ei_openflow_undecoded_data, { "openflow.undecoded_data", PI_UNDECODED, PI_WARN, "Data not dissected yet", EXPFILL }},
1555 #endif
1556 { &ei_openflow_action_type, { "openflow.action_typ.undecoded", PI_UNDECODED, PI_WARN, "Action not dissected yet", EXPFILL }},
1557 { &ei_openflow_1_0_type, { "openflow_1_0.type.undecoded", PI_UNDECODED, PI_WARN, "Message data not dissected yet", EXPFILL }},
1560 expert_module_t* expert_openflow_v1;
1562 /* Register the protocol name and description */
1563 proto_openflow_v1 = proto_register_protocol("OpenFlow 1.0", "openflow_v1", "openflow_v1");
1565 register_dissector("openflow_v1", dissect_openflow_v1, proto_openflow_v1);
1567 /* Required function calls to register the header fields and subtrees */
1568 proto_register_field_array(proto_openflow_v1, hf, array_length(hf));
1569 proto_register_subtree_array(ett, array_length(ett));
1570 expert_openflow_v1 = expert_register_protocol(proto_openflow_v1);
1571 expert_register_field_array(expert_openflow_v1, ei, array_length(ei));
1574 void
1575 proto_reg_handoff_openflow_v1(void)
1577 eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_openflow_v1);
1581 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1583 * Local variables:
1584 * c-basic-offset: 4
1585 * tab-width: 8
1586 * indent-tabs-mode: nil
1587 * End:
1589 * vi: set shiftwidth=4 tabstop=8 expandtab:
1590 * :indentSize=4:tabSize=8:noTabs=true: