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>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * Ref https://www.opennetworking.org/sdn-resources/onf-specifications/openflow
33 #include <epan/packet.h>
34 #include <epan/prefs.h>
36 void proto_register_openflow_v1(void);
37 void proto_reg_handoff_openflow_v1(void);
39 static dissector_handle_t eth_withoutfcs_handle
;
41 /* Initialize the protocol and registered fields */
42 static int proto_openflow_v1
= -1;
43 static int hf_openflow_version
= -1;
44 static int hf_openflow_1_0_type
= -1;
45 static int hf_openflow_length
= -1;
46 static int hf_openflow_xid
= -1;
48 static int hf_openflow_datapath_id
= -1;
49 static int hf_openflow_datapath_mac
= -1;
50 static int hf_openflow_datapath_impl
= -1;
51 static int hf_openflow_n_buffers
= -1;
52 static int hf_openflow_n_tables
= -1;
53 static int hf_openflow_auxiliary_id
= -1;
54 static int hf_openflow_pad3
= -1;
55 static int hf_openflow_capabilities
= -1;
56 static int hf_openflow_actions
= -1;
57 static int hf_openflow_reserved32
= -1;
58 static int hf_openflow_cap_flow_stats
= -1;
59 static int hf_openflow_table_stats
= -1;
60 static int hf_openflow_port_stats
= -1;
61 static int hf_openflow_group_stats
= -1;
62 static int hf_openflow_ip_reasm
= -1;
63 static int hf_openflow_queue_stats
= -1;
64 static int hf_openflow_port_blocked
= -1;
66 static int hf_openflow_output
= -1; /* Output to switch port. */
67 static int hf_openflow_set_vlan_vid
= -1; /* Set the 802.1q VLAN id. */
68 static int hf_openflow_set_vlan_pcp
= -1; /* Set the 802.1q priority. */
69 static int hf_openflow_strip_vlan
= -1; /* Strip the 802.1q header. */
70 static int hf_openflow_set_dl_src
= -1; /* Ethernet source address. */
71 static int hf_openflow_set_dl_dst
= -1; /* Ethernet destination address. */
72 static int hf_openflow_set_nw_src
= -1; /* IP source address. */
73 static int hf_openflow_set_nw_dst
= -1; /* IP destination address. */
74 static int hf_openflow_set_nw_tos
= -1; /* IP ToS (DSCP field, 6 bits). */
75 static int hf_openflow_set_tp_src
= -1; /* TCP/UDP source port. */
76 static int hf_openflow_set_tp_dst
= -1; /* TCP/UDP destination port. */
77 static int hf_openflow_enqueue
= -1; /* Output to queue. */
79 static int hf_openflow_port_no
= -1;
80 static int hf_openflow_hw_addr
= -1;
81 static int hf_openflow_port_name
= -1;
84 static int hf_openflow_port_config
= -1;
85 static int hf_openflow_port_state
= -1;
86 static int hf_openflow_port_curr
= -1;
87 static int hf_openflow_port_advertised
= -1;
88 static int hf_openflow_port_supported
= -1;
89 static int hf_openflow_port_peer
= -1;
91 static int hf_openflow_port_down
= -1; /* Port is administratively down. */
92 static int hf_openflow_no_stp
= -1; /* Disable 802.1D spanning tree on port. */
93 static int hf_openflow_no_recv
= -1; /* Drop all packets except 802.1D spanning tree packets. */
94 static int hf_openflow_no_recv_stp
= -1; /* Drop received 802.1D STP packets. */
95 static int hf_openflow_no_flood
= -1; /* Do not include this port when flooding. */
96 static int hf_openflow_no_fwd
= -1; /* Drop packets forwarded to port. */
97 static int hf_openflow_no_packet_in
= -1; /* Do not send packet-in msgs for port. */
99 static int hf_openflow_link_down
= -1; /* No physical link present. */
101 static int hf_openflow_10mb_hd
= -1; /* 10 Mb half-duplex rate support. */
102 static int hf_openflow_10mb_fd
= -1; /* 10 Mb full-duplex rate support. */
103 static int hf_openflow_100mb_hd
= -1; /* 100 Mb half-duplex rate support. */
104 static int hf_openflow_100mb_fd
= -1; /* 100 Mb full-duplex rate support. */
105 static int hf_openflow_1gb_hd
= -1; /* 1 Gb half-duplex rate support. */
106 static int hf_openflow_1gb_fd
= -1; /* 1 Gb full-duplex rate support. */
107 static int hf_openflow_10gb_fd
= -1; /* 10 Gb full-duplex rate support. */
108 static int hf_openflow_copper
= -1; /* Copper medium. */
109 static int hf_openflow_fiber
= -1; /* Fiber medium. */
110 static int hf_openflow_autoneg
= -1; /* Auto-negotiation. */
111 static int hf_openflow_pause
= -1; /* Pause. */
112 static int hf_openflow_pause_asym
= -1; /* Asymmetric pause. */
114 static int hf_openflow_config_flags
= -1;
115 static int hf_openflow_miss_send_len
= -1;
117 static int hf_openflow_buffer_id
= -1;
118 static int hf_openflow_total_len
= -1;
119 static int hf_openflow_in_port
= -1;
120 static int hf_openflow_reason
= -1;
121 static int hf_openflow_table_id
= -1;
122 static int hf_openflow_cookie
= -1;
123 static int hf_openflow_cookie_mask
= -1;
124 static int hf_openflow_padd8
= -1;
125 static int hf_openflow_padd16
= -1;
126 static int hf_openflow_padd48
= -1;
127 static int hf_openflow_actions_len
= -1;
128 static int hf_openflow_action_type
= -1;
129 static int hf_openflow_action_len
= -1;
130 static int hf_openflow_output_port
= -1;
131 static int hf_openflow_max_len
= -1;
132 static int hf_openflow_wildcards
= -1;
133 static int hf_openflow_command
= -1;
134 static int hf_openflow_eth_src
= -1;
135 static int hf_openflow_eth_dst
= -1;
136 static int hf_openflow_dl_vlan
= -1;
137 static int hf_openflow_dl_vlan_pcp
= -1;
138 static int hf_openflow_idle_timeout
= -1;
139 static int hf_openflow_hard_timeout
= -1;
140 static int hf_openflow_priority
= -1;
141 static int hf_openflow_out_port
= -1;
142 static int hf_openflow_out_group
= -1;
143 static int hf_openflow_flags
= -1;
145 /* Initialize the subtree pointers */
146 static gint ett_openflow
= -1;
147 static gint ett_openflow_path_id
= -1;
148 static gint ett_openflow_cap
= -1;
149 static gint ett_openflow_act
= -1;
150 static gint ett_openflow_port
= -1;
151 static gint ett_openflow_port_cnf
= -1;
152 static gint ett_openflow_port_state
= -1;
153 static gint ett_openflow_port_cf
= -1;
155 static const value_string openflow_version_values
[] = {
161 /* Immutable messages. */
162 #define OFPT_1_0_HELLO 0 /* Symmetric message */
163 #define OFPT_1_0_ERROR 1 /* Symmetric message */
164 #define OFPT_1_0_ECHO_REQUEST 2 /* Symmetric message */
165 #define OFPT_1_0_ECHO_REPLY 3 /* Symmetric message */
166 #define OFPT_1_0_VENDOR 4 /* Symmetric message */
167 /* Switch configuration messages. */
168 #define OFPT_1_0_FEATURES_REQUEST 5 /* Controller/switch message */
169 #define OFPT_1_0_FEATURES_REPLY 6 /* Controller/switch message */
170 #define OFPT_1_0_GET_CONFIG_REQUEST 7 /* Controller/switch message */
171 #define OFPT_1_0_GET_CONFIG_REPLY 8 /* Controller/switch message */
172 #define OFPT_1_0_SET_CONFIG 9 /* Controller/switch message */
173 /* Asynchronous messages. */
174 #define OFPT_1_0_PACKET_IN 10 /* Async message */
175 #define OFPT_1_0_FLOW_REMOVED 11 /* Async message */
176 #define OFPT_1_0_PORT_STATUS 12 /* Async message */
177 /* Controller command messages. */
178 #define OFPT_1_0_PACKET_OUT 13 /* Controller/switch message */
179 #define OFPT_1_0_FLOW_MOD 14 /* Controller/switch message */
180 #define OFPT_1_0_PORT_MOD 15 /* Controller/switch message */
181 /* Statistics messages. */
182 #define OFPT_1_0_STATS_REQUEST 16 /* Controller/switch message */
183 #define OFPT_1_0_STATS_REPLY 17 /* Controller/switch message */
184 /* Barrier messages. */
185 #define OFPT_1_0_BARRIER_REQUEST 18 /* Controller/switch message */
186 #define OFPT_1_0_BARRIER_REPLY 19 /* Controller/switch message */
187 /* Queue Configuration messages. */
188 #define OFPT_1_0_QUEUE_GET_CONFIG_REQUEST 20 /* Controller/switch message */
189 #define OFPT_1_0_QUEUE_GET_CONFIG_REPLY 21 /* Controller/switch message */
192 static const value_string openflow_1_0_type_values
[] = {
193 /* Immutable messages. */
195 /* Immutable messages. */
196 { 0, "OFPT_HELLO" }, /* Symmetric message */
197 { 1, "OFPT_ERROR" }, /* Symmetric message */
198 { 2, "OFPT_ECHO_REQUEST" }, /* Symmetric message */
199 { 3, "OFPT_ECHO_REPLY" }, /* Symmetric message */
200 { 4, "OFPT_VENDOR" }, /* Symmetric message */
201 /* Switch configuration messages. */
202 { 5, "OFPT_FEATURES_REQUEST" }, /* Controller/switch message */
203 { 6, "OFPT_FEATURES_REPLY" }, /* Controller/switch message */
204 { 7, "OFPT_GET_CONFIG_REQUEST" }, /* Controller/switch message */
205 { 8, "OFPT_GET_CONFIG_REPLY" }, /* Controller/switch message */
206 { 9, "OFPT_SET_CONFIG" }, /* Controller/switch message */
207 /* Asynchronous messages. */
208 { 10, "OFPT_PACKET_IN" }, /* Async message */
209 { 11, "OFPT_FLOW_REMOVED" }, /* Async message */
210 { 12, "OFPT_PORT_STATUS" }, /* Async message */
211 /* Controller command messages. */
212 { 13, "OFPT_PACKET_OUT" }, /* Controller/switch message */
213 { 14, "OFPT_FLOW_MOD" }, /* Controller/switch message */
214 { 15, "OFPT_PORT_MOD" }, /* Controller/switch message */
215 /* Statistics messages. */
216 { 16, "OFPT_STATS_REQUEST" }, /* Controller/switch message */
217 { 17, "OFPT_STATS_REPLY" }, /* Controller/switch message */
218 /* Barrier messages. */
219 { 18, "OFPT_BARRIER_REQUEST" }, /* Controller/switch message */
220 { 19, "OFPT_BARRIER_REPLY" }, /* Controller/switch message */
221 /* Queue Configuration messages. */
222 { 20, "OFPT_QUEUE_GET_CONFIG_REQUEST" }, /* Controller/switch message */
223 { 21, "OFPT_QUEUE_GET_CONFIG_REPLY" }, /* Controller/switch message */
228 #define OFPC_FLOW_STATS 1<<0 /* Flow statistics. */
229 #define OFPC_TABLE_STATS 1<<1 /* Table statistics. */
230 #define OFPC_PORT_STATS 1<<2 /* Port statistics. */
231 #define OFPC_GROUP_STATS 1<<3 /* Group statistics. */
232 #define OFPC_IP_REASM 1<<5 /* Can reassemble IP fragments. */
233 #define OFPC_QUEUE_STATS 1<<6 /* Queue statistics. */
234 #define OFPC_PORT_BLOCKED 1<<8 /* Switch will block looping ports. */
236 #define OFPAT_OUTPUT_MASK 1<<0 /* Output to switch port. */
237 #define OFPAT_SET_VLAN_VID_MASK 1<<1 /* Set the 802.1q VLAN id. */
238 #define OFPAT_SET_VLAN_PCP_MASK 1<<2 /* Set the 802.1q priority. */
239 #define OFPAT_STRIP_VLAN_MASK 1<<3 /* Strip the 802.1q header. */
240 #define OFPAT_SET_DL_SRC_MASK 1<<4 /* Ethernet source address. */
241 #define OFPAT_SET_DL_DST_MASK 1<<5 /* Ethernet destination address. */
242 #define OFPAT_SET_NW_SRC_MASK 1<<6 /* IP source address. */
243 #define OFPAT_SET_NW_DST_MASK 1<<7 /* IP destination address. */
244 #define OFPAT_SET_NW_TOS_MASK 1<<8 /* IP ToS (DSCP field, 6 bits). */
245 #define OFPAT_SET_TP_SRC_MASK 1<<9 /* TCP/UDP source port. */
246 #define OFPAT_SET_TP_DST_MASK 1<<10 /* TCP/UDP destination port. */
247 #define OFPAT_ENQUEUE_MASK 1<<11 /* Output to queue. */
249 #define OFPPC_PORT_DOWN 1<<0 /* Port is administratively down. */
250 #define OFPPC_NO_STP 1<<1 /* Disable 802.1D spanning tree on port. */
251 #define OFPPC_NO_RECV 1<<2 /* Drop all packets except 802.1D spanning tree packets. */
252 #define OFPPC_NO_RECV_STP 1<<3 /* Drop received 802.1D STP packets. */
253 #define OFPPC_NO_FLOOD 1<<4 /* Do not include this port when flooding. */
254 #define OFPPC_NO_FWD 1<<5 /* Drop packets forwarded to port. */
255 #define OFPPC_NO_PACKET_IN 1<<6 /* Do not send packet-in msgs for port. */
257 #define OFP_MAX_PORT_NAME_LEN 16
259 #define OFPPS_LINK_DOWN 1<<0 /* No physical link present. */
260 #define OFPPS_STP_LISTEN 0<<8 /* Not learning or relaying frames. */
261 #define OFPPS_STP_LEARN 1<<8 /* Learning but not relaying frames. */
262 #define OFPPS_STP_FORWARD 2<<8 /* Learning and relaying frames. */
263 #define OFPPS_STP_BLOCK 3<<8 /* Not part of spanning tree. */
264 #define OFPPS_STP_MASK 3<<8 /* Bit mask for OFPPS_STP_* values. */
267 #define OFPPF_10MB_HD 1<<0 /* 10 Mb half-duplex rate support. */
268 #define OFPPF_10MB_FD 1<<1 /* 10 Mb full-duplex rate support. */
269 #define OFPPF_100MB_HD 1<<2 /* 100 Mb half-duplex rate support. */
270 #define OFPPF_100MB_FD 1<<3 /* 100 Mb full-duplex rate support. */
271 #define OFPPF_1GB_HD 1<<4 /* 1 Gb half-duplex rate support. */
272 #define OFPPF_1GB_FD 1<<5 /* 1 Gb full-duplex rate support. */
273 #define OFPPF_10GB_FD 1<<6 /* 10 Gb full-duplex rate support. */
274 #define OFPPF_COPPER 1<<7 /* Copper medium. */
275 #define OFPPF_FIBER 1<<8 /* Fiber medium. */
276 #define OFPPF_AUTONEG 1<<9 /* Auto-negotiation. */
277 #define OFPPF_PAUSE 1<<10 /* Pause. */
278 #define OFPPF_PAUSE_ASYM 1<<11 /* Asymmetric pause. */
281 #define OFPAT_OUTPUT 0 /* Output to switch port. */
282 #define OFPAT_SET_VLAN_VID 1 /* Set the 802.1q VLAN id. */
283 #define OFPAT_SET_VLAN_PCP 2 /* Set the 802.1q priority. */
284 #define OFPAT_STRIP_VLAN 3 /* Strip the 802.1q header. */
285 #define OFPAT_SET_DL_SRC 4 /* Ethernet source address. */
286 #define OFPAT_SET_DL_DST 5 /* Ethernet destination address. */
287 #define OFPAT_SET_NW_SRC 6 /* IP source address. */
288 #define OFPAT_SET_NW_DST 7 /* IP destination address. */
289 #define OFPAT_SET_TP_SRC 8 /* TCP/UDP source port. */
290 #define OFPAT_SET_TP_DST 9 /* TCP/UDP destination port. */
291 #define OFPAT_VENDOR 0xffff
294 dissect_openflow_ofp_match_v1(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
297 /* uint32_t wildcards; Wildcard fields. */
298 proto_tree_add_item(tree
, hf_openflow_wildcards
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
300 /* uint16_t in_port; Input switch port. */
301 proto_tree_add_item(tree
, hf_openflow_in_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
304 /* uint8_t dl_src[OFP_ETH_ALEN]; Ethernet source address. */
305 proto_tree_add_item(tree
, hf_openflow_eth_src
, tvb
, offset
, 6, ENC_NA
);
307 /* uint8_t dl_dst[OFP_ETH_ALEN]; Ethernet destination address. */
308 proto_tree_add_item(tree
, hf_openflow_eth_dst
, tvb
, offset
, 6, ENC_NA
);
310 /* uint16_t dl_vlan; Input VLAN id. */
311 proto_tree_add_item(tree
, hf_openflow_dl_vlan
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
313 /* uint8_t dl_vlan_pcp; Input VLAN priority. */
314 proto_tree_add_item(tree
, hf_openflow_dl_vlan_pcp
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
316 /* uint8_t pad1[1]; Align to 64-bits */
317 proto_tree_add_item(tree
, hf_openflow_padd8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
319 /* uint16_t dl_type; Ethernet frame type. */
320 /* uint8_t nw_tos; IP ToS (actually DSCP field, 6 bits). */
321 /* uint8_t nw_proto; IP protocol or lower 8 bits of
324 /* uint8_t pad2[2]; Align to 64-bits */
325 /* uint32_t nw_src; IP source address. */
326 /* uint32_t nw_dst; IP destination address. */
327 /* uint16_t tp_src; TCP/UDP source port. */
328 /* uint16_t tp_dst; TCP/UDP destination port. */
329 proto_tree_add_text(tree
, tvb
, offset
, 18, "Data not dissected yet");
336 static const value_string openflow_action_values
[] = {
337 { OFPAT_OUTPUT
, "Output to switch port" },
338 { OFPAT_SET_VLAN_VID
, "Set the 802.1q VLAN id" },
339 { OFPAT_SET_VLAN_PCP
, "Set the 802.1q priority" },
340 { OFPAT_STRIP_VLAN
, "Strip the 802.1q header" },
341 { OFPAT_SET_DL_SRC
, "Ethernet source address" },
342 { OFPAT_SET_DL_DST
, "Ethernet destination address" },
343 { OFPAT_SET_NW_SRC
, "IP source address" },
344 { OFPAT_SET_NW_DST
, "IP destination address" },
345 { OFPAT_SET_TP_SRC
, "TCP/UDP source port" },
346 { OFPAT_SET_TP_DST
, "TCP/UDP destination port" },
347 { OFPAT_VENDOR
, "Vendor specific action"},
352 dissect_openflow_action_header(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
354 guint16 action_type
, action_len
;
356 /* uint16_t type; One of OFPAT_*. */
357 action_type
= tvb_get_ntohs(tvb
, offset
);
358 proto_tree_add_item(tree
, hf_openflow_action_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
360 /* Length of action, including this
361 * header. This is the length of action,
362 * including any padding to make it
365 action_len
= tvb_get_ntohs(tvb
, offset
);
366 proto_tree_add_item(tree
, hf_openflow_action_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
371 /* uint16_t port; Output port. */
372 proto_tree_add_item(tree
, hf_openflow_output_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
374 /* uint16_t max_len; Max length to send to controller. */
375 proto_tree_add_item(tree
, hf_openflow_max_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
379 proto_tree_add_text(tree
, tvb
, offset
, action_len
-4, "Action not dissected yet");
380 offset
+=(action_len
-4);
387 dissect_openflow_phy_port(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
390 proto_tree
*port_cnf_tree
, *port_state_tree
, *port_cf_tree
;
392 proto_tree_add_item(tree
, hf_openflow_port_no
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
394 proto_tree_add_item(tree
, hf_openflow_hw_addr
, tvb
, offset
, 6, ENC_NA
);
396 proto_tree_add_item(tree
, hf_openflow_port_name
, tvb
, offset
, OFP_MAX_PORT_NAME_LEN
, ENC_ASCII
|ENC_NA
);
397 offset
+=OFP_MAX_PORT_NAME_LEN
;
399 /* Bitmap of OFPPC_* flags. */
400 ti
= proto_tree_add_item(tree
, hf_openflow_port_config
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
401 port_cnf_tree
= proto_item_add_subtree(ti
, ett_openflow_port_cnf
);
403 /* Port is administratively down. */
404 proto_tree_add_item(port_cnf_tree
, hf_openflow_port_down
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
405 /* Disable 802.1D spanning tree on port. */
406 proto_tree_add_item(port_cnf_tree
, hf_openflow_no_stp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
407 /* Drop all packets except 802.1D spanning tree packets. */
408 proto_tree_add_item(port_cnf_tree
, hf_openflow_no_recv
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
409 /* Drop received 802.1D STP packets. */
410 proto_tree_add_item(port_cnf_tree
, hf_openflow_no_recv_stp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
411 /* Do not include this port when flooding. */
412 proto_tree_add_item(port_cnf_tree
, hf_openflow_no_flood
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
413 /* Drop packets forwarded to port. */
414 proto_tree_add_item(port_cnf_tree
, hf_openflow_no_fwd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
415 /* Do not send packet-in msgs for port. */
416 proto_tree_add_item(port_cnf_tree
, hf_openflow_no_packet_in
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
419 /* Bitmap of OFPPS_* flags. */
420 ti
= proto_tree_add_item(tree
, hf_openflow_port_state
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
421 port_state_tree
= proto_item_add_subtree(ti
, ett_openflow_port_state
);
423 /* No physical link present. */
424 proto_tree_add_item(port_state_tree
, hf_openflow_link_down
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
428 /* Current features. */
429 ti
= proto_tree_add_item(tree
, hf_openflow_port_curr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
430 port_cf_tree
= proto_item_add_subtree(ti
, ett_openflow_port_cf
);
431 /* 10 Mb half-duplex rate support. */
432 proto_tree_add_item(port_cf_tree
, hf_openflow_10mb_hd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
433 /* 10 Mb full-duplex rate support. */
434 proto_tree_add_item(port_cf_tree
, hf_openflow_10mb_fd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
435 /* 100 Mb half-duplex rate support. */
436 proto_tree_add_item(port_cf_tree
, hf_openflow_100mb_hd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
437 /* 100 Mb full-duplex rate support. */
438 proto_tree_add_item(port_cf_tree
, hf_openflow_100mb_fd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
439 /* 1 Gb half-duplex rate support. */
440 proto_tree_add_item(port_cf_tree
, hf_openflow_1gb_hd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
441 /* 1 Gb full-duplex rate support. */
442 proto_tree_add_item(port_cf_tree
, hf_openflow_1gb_fd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
443 /* 10 Gb full-duplex rate support. */
444 proto_tree_add_item(port_cf_tree
, hf_openflow_10gb_fd
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
446 proto_tree_add_item(port_cf_tree
, hf_openflow_copper
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
448 proto_tree_add_item(port_cf_tree
, hf_openflow_fiber
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
449 /* Auto-negotiation. */
450 proto_tree_add_item(port_cf_tree
, hf_openflow_autoneg
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
452 proto_tree_add_item(port_cf_tree
, hf_openflow_pause
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
453 /* Asymmetric pause. */
454 proto_tree_add_item(port_cf_tree
, hf_openflow_pause_asym
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
457 /* Features being advertised by the port. */
458 proto_tree_add_item(tree
, hf_openflow_port_advertised
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
461 /* Features supported by the port. */
462 proto_tree_add_item(tree
, hf_openflow_port_supported
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
464 /* Features advertised by peer. */
465 proto_tree_add_item(tree
, hf_openflow_port_peer
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
475 struct ofp_switch_features
{
476 struct ofp_header header
;
477 uint64_t datapath_id
; /* Datapath unique ID. The lower 48-bits are for
478 a MAC address, while the upper 16-bits are
479 implementer-defined. */
480 uint32_t n_buffers
; /* Max packets buffered at once. */
481 uint8_t n_tables
; /* Number of tables supported by datapath. */
482 uint8_t pad
[3]; /* Align to 64-bits. */
484 uint32_t capabilities
; /* Bitmap of support "ofp_capabilities". */
485 uint32_t actions
; /* Bitmap of supported "ofp_action_type"s. */
487 struct ofp_phy_port ports
[0]; /* Port definitions. The number of ports
488 is inferred from the length field in
493 dissect_openflow_features_reply_v1(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, guint16 length
)
496 proto_tree
*path_id_tree
, *cap_tree
, *act_tree
;
498 guint16 length_remaining
;
500 ti
= proto_tree_add_item(tree
, hf_openflow_datapath_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
501 path_id_tree
= proto_item_add_subtree(ti
, ett_openflow_path_id
);
502 proto_tree_add_item(path_id_tree
, hf_openflow_datapath_mac
, tvb
, offset
, 6, ENC_NA
);
504 proto_tree_add_item(path_id_tree
, hf_openflow_datapath_impl
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
507 proto_tree_add_item(tree
, hf_openflow_n_buffers
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
510 proto_tree_add_item(tree
, hf_openflow_n_tables
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
513 ti
= proto_tree_add_item(tree
, hf_openflow_capabilities
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
514 cap_tree
= proto_item_add_subtree(ti
, ett_openflow_cap
);
517 proto_tree_add_item(cap_tree
, hf_openflow_cap_flow_stats
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
518 proto_tree_add_item(cap_tree
, hf_openflow_table_stats
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
519 proto_tree_add_item(cap_tree
, hf_openflow_port_stats
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
520 proto_tree_add_item(cap_tree
, hf_openflow_group_stats
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
521 proto_tree_add_item(cap_tree
, hf_openflow_ip_reasm
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
522 proto_tree_add_item(cap_tree
, hf_openflow_queue_stats
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
523 proto_tree_add_item(cap_tree
, hf_openflow_port_blocked
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
526 ti
= proto_tree_add_item(tree
, hf_openflow_actions
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
527 act_tree
= proto_item_add_subtree(ti
, ett_openflow_act
);
529 proto_tree_add_item(act_tree
, hf_openflow_output
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
530 proto_tree_add_item(act_tree
, hf_openflow_set_vlan_vid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
531 proto_tree_add_item(act_tree
, hf_openflow_set_vlan_pcp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
532 proto_tree_add_item(act_tree
, hf_openflow_strip_vlan
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
533 proto_tree_add_item(act_tree
, hf_openflow_set_dl_src
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
534 proto_tree_add_item(act_tree
, hf_openflow_set_dl_dst
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
535 proto_tree_add_item(act_tree
, hf_openflow_set_nw_src
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
536 proto_tree_add_item(act_tree
, hf_openflow_set_nw_dst
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
537 proto_tree_add_item(act_tree
, hf_openflow_set_nw_tos
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
538 proto_tree_add_item(act_tree
, hf_openflow_set_tp_src
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
539 proto_tree_add_item(act_tree
, hf_openflow_set_tp_dst
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
540 proto_tree_add_item(act_tree
, hf_openflow_enqueue
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
543 length_remaining
= length
-32;
544 if(length_remaining
> 0){
545 guint16 num_ports
= length_remaining
/48;
547 if ((length_remaining
&0x003f) != 0){
550 for(i
=0; i
<num_ports
;i
++){
551 proto_tree
*port_tree
;
553 ti
= proto_tree_add_text(tree
, tvb
, offset
, 48, "Port data %u",i
+1);
554 port_tree
= proto_item_add_subtree(ti
, ett_openflow_port
);
555 dissect_openflow_phy_port(tvb
, pinfo
, port_tree
, offset
);
564 dissect_openflow_switch_config(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
, guint16 length _U_
)
567 /* ofp_config_flags */
568 proto_tree_add_item(tree
, hf_openflow_config_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
571 proto_tree_add_item(tree
, hf_openflow_miss_send_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
576 #define OFPR_NO_MATCH 0 /* No matching flow (table-miss flow entry). */
577 #define OFPR_ACTION 1 /* Action explicitly output to controller. */
578 #define OFPR_INVALID_TTL 2 /* Packet has invalid TTL */
580 static const value_string openflow_reason_values
[] = {
581 { OFPR_NO_MATCH
, "No matching flow (table-miss flow entry)" },
582 { OFPR_ACTION
, "Action explicitly output to controller" },
583 { OFPR_INVALID_TTL
, "Packet has invalid TTL" },
588 dissect_openflow_pkt_in(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
, guint16 length
)
592 /* uint32_t buffer_id; ID assigned by datapath. */
593 proto_tree_add_item(tree
, hf_openflow_buffer_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
595 /* uint16_t total_len; Full length of frame. */
596 proto_tree_add_item(tree
, hf_openflow_total_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
599 /* uint16_t in_port; Port on which frame was received. */
600 proto_tree_add_item(tree
, hf_openflow_in_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
603 /* uint8_t reason; Reason packet is being sent (one of OFPR_*) */
604 proto_tree_add_item(tree
, hf_openflow_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
607 proto_tree_add_item(tree
, hf_openflow_padd8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
610 /*proto_tree_add_text(tree, tvb, offset, length-offset, "Offset=%u, remaining %u", offset, length-offset);*/
611 next_tvb
= tvb_new_subset(tvb
, offset
, length
-offset
, length
-offset
);
612 call_dissector(eth_withoutfcs_handle
, next_tvb
, pinfo
, tree
);
617 dissect_openflow_pkt_out(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
, guint16 length _U_
)
622 /* uint32_t buffer_id; ID assigned by datapath. */
623 buffer_id
= tvb_get_ntohl(tvb
, offset
);
624 proto_tree_add_item(tree
, hf_openflow_buffer_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
627 /* uint32_t in_port; Packet's input port or OFPP_CONTROLLER. */
628 proto_tree_add_item(tree
, hf_openflow_in_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
631 /* uint16_t actions_len; Size of action array in bytes. */
632 proto_tree_add_item(tree
, hf_openflow_actions_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
635 /* struct ofp_action_header actions[0]; Action list. */
636 offset
= dissect_openflow_action_header(tvb
, pinfo
, tree
, offset
);
637 /* Packet data. The length is inferred
638 from the length field in the header.
639 (Only meaningful if buffer_id == -1.)
642 /* proto_tree_add_text(tree, tvb, offset, -1, "Packet data"); */
643 next_tvb
= tvb_new_subset(tvb
, offset
, length
-offset
, length
-offset
);
644 call_dissector(eth_withoutfcs_handle
, next_tvb
, pinfo
, tree
);
648 #define OFPFC_ADD 0 /* New flow. */
649 #define OFPFC_MODIFY 1 /* Modify all matching flows. */
650 #define OFPFC_MODIFY_STRICT 2 /* Modify entry strictly matching wildcards */
651 #define OFPFC_DELETE 3 /* Delete all matching flows. */
652 #define OFPFC_DELETE_STRICT 4 /* Strictly match wildcards and priority. */
654 static const value_string openflow_command_values
[] = {
655 { OFPFC_ADD
, "New flow" },
656 { OFPFC_MODIFY
, "Modify all matching flows" },
657 { OFPFC_MODIFY_STRICT
, "Modify entry strictly matching wildcards" },
658 { OFPFC_DELETE
, "Delete all matching flows" },
659 { OFPFC_DELETE_STRICT
, "Strictly match wildcards and priority" },
664 dissect_openflow_flow_mod(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, guint16 length _U_
)
667 /* struct ofp_match match; Fields to match */
668 offset
= dissect_openflow_ofp_match_v1(tvb
, pinfo
, tree
, offset
);
670 /* uint64_t cookie; Opaque controller-issued identifier. */
671 proto_tree_add_item(tree
, hf_openflow_cookie
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
674 /* uint16_t command; One of OFPFC_*. */
675 proto_tree_add_item(tree
, hf_openflow_command
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
678 /* uint16_t idle_timeout; Idle time before discarding (seconds). */
679 proto_tree_add_item(tree
, hf_openflow_idle_timeout
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
681 /* uint16_t hard_timeout; Max time before discarding (seconds). */
682 proto_tree_add_item(tree
, hf_openflow_hard_timeout
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
684 /* uint16_t priority; Priority level of flow entry. */
685 proto_tree_add_item(tree
, hf_openflow_priority
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
687 /* uint32_t buffer_id; Buffered packet to apply to, or OFP_NO_BUFFER.
688 Not meaningful for OFPFC_DELETE*.
690 proto_tree_add_item(tree
, hf_openflow_buffer_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
692 /* uint32_t out_port; For OFPFC_DELETE* commands, require
693 matching entries to include this as an output port. A value of OFPP_ANY
694 indicates no restriction.
696 proto_tree_add_item(tree
, hf_openflow_out_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
699 /* uint16_t flags; One of OFPFF_*. */
700 proto_tree_add_item(tree
, hf_openflow_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
705 dissect_openflow_v1(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
708 proto_tree
*openflow_tree
;
713 type
= tvb_get_guint8(tvb
, 1);
715 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Type: %s",
716 val_to_str_const(type
, openflow_1_0_type_values
, "Unknown Messagetype"));
718 /* Stop the Ethernet frame from overwriting the columns */
719 if((type
== OFPT_1_0_PACKET_IN
) || (type
== OFPT_1_0_PACKET_OUT
)){
720 col_set_writable(pinfo
->cinfo
, FALSE
);
723 /* Create display subtree for the protocol */
724 ti
= proto_tree_add_item(tree
, proto_openflow_v1
, tvb
, 0, -1, ENC_NA
);
725 openflow_tree
= proto_item_add_subtree(ti
, ett_openflow
);
727 /* A.1 OpenFlow Header. */
729 proto_tree_add_item(openflow_tree
, hf_openflow_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
732 /* One of the OFPT_ constants. */
733 proto_tree_add_item(openflow_tree
, hf_openflow_1_0_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
736 /* Length including this ofp_header. */
737 length
= tvb_get_ntohs(tvb
, offset
);
738 proto_tree_add_item(openflow_tree
, hf_openflow_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
741 /* Transaction id associated with this packet. Replies use the same id as was in the request
742 * to facilitate pairing.
744 proto_tree_add_item(openflow_tree
, hf_openflow_xid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
748 case OFPT_1_0_HELLO
: /* 0 */
750 * The OFPT_HELLO message has no body;
753 case OFPT_1_0_FEATURES_REQUEST
: /* 5 */
755 * Upon TLS session establishment, the controller sends an OFPT_FEATURES_REQUEST
756 * message. This message does not contain a body beyond the OpenFlow header.
759 case OFPT_1_0_FEATURES_REPLY
: /* 6 */
760 dissect_openflow_features_reply_v1(tvb
, pinfo
, openflow_tree
, offset
, length
);
762 case OFPT_1_0_GET_CONFIG_REQUEST
: /* 7 */
763 /* A.3.2 There is no body for OFPT_GET_CONFIG_REQUEST beyond the OpenFlow header. */
765 case OFPT_1_0_GET_CONFIG_REPLY
: /* 8 */
767 case OFPT_1_0_SET_CONFIG
: /* 9 */
768 dissect_openflow_switch_config(tvb
, pinfo
, openflow_tree
, offset
, length
);
770 case OFPT_1_0_PACKET_IN
: /* 10 */
771 dissect_openflow_pkt_in(tvb
, pinfo
, openflow_tree
, offset
, length
);
773 case OFPT_1_0_PACKET_OUT
: /* 13 */
774 dissect_openflow_pkt_out(tvb
, pinfo
, openflow_tree
, offset
, length
);
776 case OFPT_1_0_FLOW_MOD
: /* 14 */
777 dissect_openflow_flow_mod(tvb
, pinfo
, openflow_tree
, offset
, length
);
781 proto_tree_add_text(tree
, tvb
, offset
, -1, "Message data not dissected yet");
786 return tvb_length(tvb
);
792 * Register the protocol with Wireshark.
795 proto_register_openflow_v1(void)
797 static hf_register_info hf
[] = {
798 { &hf_openflow_version
,
799 { "Version", "openflow.version",
800 FT_UINT8
, BASE_HEX
, VALS(openflow_version_values
), 0x7f,
803 { &hf_openflow_1_0_type
,
804 { "Type", "openflow_1_0.type",
805 FT_UINT8
, BASE_DEC
, VALS(openflow_1_0_type_values
), 0x0,
809 { "Transaction ID", "openflow.xid",
810 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
813 { &hf_openflow_length
,
814 { "Length", "openflow.length",
815 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
818 { &hf_openflow_datapath_id
,
819 { "Datapath unique ID", "openflow.datapath_id",
820 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
823 { &hf_openflow_datapath_mac
,
824 { "MAC addr", "openflow.datapath_mac",
825 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
828 { &hf_openflow_datapath_impl
,
829 { "Implementers part", "openflow.datapath_imp",
830 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
833 { &hf_openflow_n_buffers
,
834 { "n_buffers", "openflow.n_buffers",
835 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
838 { &hf_openflow_n_tables
,
839 { "n_tables", "openflow.n_tables",
840 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
843 { &hf_openflow_auxiliary_id
,
844 { "auxiliary_id", "openflow.auxiliary_id",
845 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
849 { "Padding", "openflow.pad3",
850 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
853 { &hf_openflow_capabilities
,
854 { "capabilities", "openflow.capabilities",
855 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
858 { &hf_openflow_actions
,
859 { "actions", "openflow.actions",
860 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
863 { &hf_openflow_reserved32
,
864 { "Reserved", "openflow.reserved32",
865 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
868 { &hf_openflow_cap_flow_stats
,
869 { "Flow statistics", "openflow.flow_stats",
870 FT_BOOLEAN
, 32, NULL
, OFPC_FLOW_STATS
,
873 { &hf_openflow_table_stats
,
874 { "Table statistics", "openflow.table_stats",
875 FT_BOOLEAN
, 32, NULL
, OFPC_TABLE_STATS
,
878 { &hf_openflow_port_stats
,
879 { "Port statistics", "openflow.port_stats",
880 FT_BOOLEAN
, 32, NULL
, OFPC_PORT_STATS
,
883 { &hf_openflow_group_stats
,
884 { "Group statistics", "openflow.group_stats",
885 FT_BOOLEAN
, 32, NULL
, OFPC_GROUP_STATS
,
888 { &hf_openflow_ip_reasm
,
889 { "Can reassemble IP fragments", "openflow.ip_reasm",
890 FT_BOOLEAN
, 32, NULL
, OFPC_IP_REASM
,
893 { &hf_openflow_queue_stats
,
894 { "Queue statistics", "openflow.queue_stats",
895 FT_BOOLEAN
, 32, NULL
, OFPC_QUEUE_STATS
,
898 { &hf_openflow_port_blocked
,
899 { "Switch will block looping ports", "openflow.port_blocked",
900 FT_BOOLEAN
, 32, NULL
, OFPC_PORT_BLOCKED
,
903 { &hf_openflow_output
,
904 { "Output to switch port", "openflow.output",
905 FT_BOOLEAN
, 32, NULL
, OFPAT_OUTPUT_MASK
,
908 { &hf_openflow_set_vlan_vid
,
909 { "Set the 802.1q VLAN id", "openflow.set_vlan_vid",
910 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_VLAN_VID_MASK
,
913 { &hf_openflow_set_vlan_pcp
,
914 { "Set the 802.1q priority", "openflow.set_vlan_pcp",
915 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_VLAN_PCP_MASK
,
918 { &hf_openflow_strip_vlan
,
919 { "Strip the 802.1q header", "openflow.strip_vlan",
920 FT_BOOLEAN
, 32, NULL
, OFPAT_STRIP_VLAN_MASK
,
923 { &hf_openflow_set_dl_src
,
924 { "Ethernet source address", "openflow.set_dl_src",
925 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_DL_SRC_MASK
,
928 { &hf_openflow_set_dl_dst
,
929 { "Ethernet destination address", "openflow.set_dl_ds",
930 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_DL_DST_MASK
,
933 { &hf_openflow_set_nw_src
,
934 { "IP source address", "openflow.set_nw_src",
935 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_NW_SRC_MASK
,
938 { &hf_openflow_set_nw_dst
,
939 { "IP destination address", "openflow.set_nw_ds",
940 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_NW_DST_MASK
,
943 { &hf_openflow_set_nw_tos
,
944 { "IP ToS (DSCP field, 6 bits)", "openflow.set_nw_tos",
945 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_NW_TOS_MASK
,
948 { &hf_openflow_set_tp_src
,
949 { "TCP/UDP source port", "openflow.set_tp_src",
950 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_TP_SRC_MASK
,
953 { &hf_openflow_set_tp_dst
,
954 { "TCP/UDP destination port", "openflow.set_tp_dst",
955 FT_BOOLEAN
, 32, NULL
, OFPAT_SET_TP_DST_MASK
,
958 { &hf_openflow_enqueue
,
959 { "Output to queue", "openflow.enqueue",
960 FT_BOOLEAN
, 32, NULL
, OFPAT_ENQUEUE_MASK
,
963 { &hf_openflow_port_no
,
964 { "Port number", "openflow.port_no",
965 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
968 { &hf_openflow_hw_addr
,
969 { "HW Address", "openflow.hw_add",
970 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
973 { &hf_openflow_port_name
,
974 { "Name", "openflow.hw_add",
975 FT_STRING
, BASE_NONE
, NULL
, 0x0,
978 { &hf_openflow_port_config
,
979 { "Config flags", "openflow.port_config",
980 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
983 { &hf_openflow_port_state
,
984 { "State flags", "openflow.port_state",
985 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
988 { &hf_openflow_port_curr
,
989 { "Current features", "openflow.port_curr",
990 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
993 { &hf_openflow_port_advertised
,
994 { "Advertised features", "openflow.port_advertised",
995 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
998 { &hf_openflow_port_supported
,
999 { "Features supported", "openflow.port_supported",
1000 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1003 { &hf_openflow_port_peer
,
1004 { "Features advertised by peer", "openflow.port_peer",
1005 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1008 { &hf_openflow_port_down
,
1009 { "Port is administratively down", "openflow.port_down",
1010 FT_BOOLEAN
, 32, NULL
, OFPPC_PORT_DOWN
,
1013 { &hf_openflow_no_stp
,
1014 { "Disable 802.1D spanning tree on port", "openflow.no_stp",
1015 FT_BOOLEAN
, 32, NULL
, OFPPC_NO_STP
,
1018 { &hf_openflow_no_recv
,
1019 { "Drop all packets except 802.1D spanning tree packets", "openflow.no_recv",
1020 FT_BOOLEAN
, 32, NULL
, OFPPC_NO_RECV
,
1023 { &hf_openflow_no_recv_stp
,
1024 { "Drop received 802.1D STP packets", "openflow.no_recv",
1025 FT_BOOLEAN
, 32, NULL
, OFPPC_NO_RECV_STP
,
1028 { &hf_openflow_no_flood
,
1029 { "Do not include this port when flooding", "openflow.no_flood",
1030 FT_BOOLEAN
, 32, NULL
, OFPPC_NO_FLOOD
,
1033 { &hf_openflow_no_fwd
,
1034 { "Drop packets forwarded to port", "openflow.no_fwd",
1035 FT_BOOLEAN
, 32, NULL
, OFPPC_NO_FWD
,
1038 { &hf_openflow_no_packet_in
,
1039 { "Do not send packet-in msgs for port", "openflow.no_packet_in",
1040 FT_BOOLEAN
, 32, NULL
, OFPPC_NO_PACKET_IN
,
1043 { &hf_openflow_link_down
,
1044 { "No physical link present", "openflow.link_down",
1045 FT_BOOLEAN
, 32, NULL
, OFPPS_LINK_DOWN
,
1048 { &hf_openflow_10mb_hd
,
1049 { "10 Mb half-duplex rate support", "openflow.10mb_hd",
1050 FT_BOOLEAN
, 32, NULL
, OFPPF_10MB_HD
,
1053 { &hf_openflow_10mb_fd
,
1054 { "10 Mb full-duplex rate support", "openflow.10mb_fd",
1055 FT_BOOLEAN
, 32, NULL
, OFPPF_10MB_FD
,
1058 { &hf_openflow_100mb_hd
,
1059 { "100 Mb half-duplex rate support", "openflow.100mb_hd",
1060 FT_BOOLEAN
, 32, NULL
, OFPPF_100MB_HD
,
1063 { &hf_openflow_100mb_fd
,
1064 { "100 Mb full-duplex rate support", "openflow.100mb_0fd",
1065 FT_BOOLEAN
, 32, NULL
, OFPPF_100MB_FD
,
1068 { &hf_openflow_1gb_hd
,
1069 { "1 Gb half-duplex rate support", "openflow.1gb_hd",
1070 FT_BOOLEAN
, 32, NULL
, OFPPF_1GB_HD
,
1073 { &hf_openflow_1gb_fd
,
1074 { "1 Gb full-duplex rate support", "openflow.1gb_fd",
1075 FT_BOOLEAN
, 32, NULL
, OFPPF_1GB_FD
,
1078 { &hf_openflow_10gb_fd
,
1079 { "10 Gb full-duplex rate support", "openflow.10gb_fd",
1080 FT_BOOLEAN
, 32, NULL
, OFPPF_10GB_FD
,
1083 { &hf_openflow_copper
,
1084 { "Copper medium", "openflow.copper",
1085 FT_BOOLEAN
, 32, NULL
, OFPPF_COPPER
,
1088 { &hf_openflow_fiber
,
1089 { "Fiber medium", "openflow.fiber",
1090 FT_BOOLEAN
, 32, NULL
, OFPPF_FIBER
,
1093 { &hf_openflow_autoneg
,
1094 { "Auto-negotiation", "openflow.autoneg",
1095 FT_BOOLEAN
, 32, NULL
, OFPPF_AUTONEG
,
1098 { &hf_openflow_pause
,
1099 { "Pause", "openflow.pause",
1100 FT_BOOLEAN
, 32, NULL
, OFPPF_PAUSE
,
1103 { &hf_openflow_pause_asym
,
1104 { "Asymmetric pause", "openflow.pause_asym",
1105 FT_BOOLEAN
, 32, NULL
, OFPPF_PAUSE_ASYM
,
1108 { &hf_openflow_config_flags
,
1109 { "Config flags", "openflow.config_flags",
1110 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1113 { &hf_openflow_miss_send_len
,
1114 { "Max bytes of packet", "openflow.miss_send_len",
1115 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1118 { &hf_openflow_buffer_id
,
1119 { "Buffser Id", "openflow.buffer_id",
1120 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1123 { &hf_openflow_total_len
,
1124 { "Total length", "openflow.total_len",
1125 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1128 { &hf_openflow_in_port
,
1129 { "In port", "openflow.in_port",
1130 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1133 { &hf_openflow_reason
,
1134 { "Reason", "openflow.reason",
1135 FT_UINT8
, BASE_DEC
, VALS(openflow_reason_values
), 0x0,
1138 { &hf_openflow_table_id
,
1139 { "Table Id", "openflow.table_id",
1140 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1143 { &hf_openflow_cookie
,
1144 { "Cookie", "openflow.cookie",
1145 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
1148 { &hf_openflow_cookie_mask
,
1149 { "Cookie mask", "openflow.cookie",
1150 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
1153 { &hf_openflow_padd8
,
1154 { "Padding", "openflow.padding8",
1155 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1158 { &hf_openflow_padd16
,
1159 { "Padding", "openflow.padding16",
1160 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1163 { &hf_openflow_padd48
,
1164 { "Padding", "openflow.padding48",
1165 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
1168 { &hf_openflow_actions_len
,
1169 { "Actions length", "openflow.actions_len",
1170 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1173 { &hf_openflow_action_type
,
1174 { "Actions type", "openflow.action_typ",
1175 FT_UINT16
, BASE_DEC
, VALS(openflow_action_values
), 0x0,
1178 { &hf_openflow_action_len
,
1179 { "Action length", "openflow.action_len",
1180 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1183 { &hf_openflow_output_port
,
1184 { "Output port", "openflow.output_port",
1185 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1188 { &hf_openflow_max_len
,
1189 { "Max length", "openflow.max_len",
1190 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1193 { &hf_openflow_wildcards
,
1194 { "Wildcards", "openflow.wildcards",
1195 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1198 { &hf_openflow_command
,
1199 { "Command", "openflow.command",
1200 FT_UINT16
, BASE_DEC
, VALS(openflow_command_values
), 0x0,
1203 { &hf_openflow_eth_src
,
1204 { "Ethernet source address", "openflow.eth_src",
1205 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1208 { &hf_openflow_eth_dst
,
1209 { "Ethernet destination address", "openflow.eth_src",
1210 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1213 { &hf_openflow_dl_vlan
,
1214 { "Input VLAN id", "openflow.dl_vlan",
1215 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1218 { &hf_openflow_dl_vlan_pcp
,
1219 { "Input VLAN priority", "openflow.dl_vlan_pcp",
1220 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1223 { &hf_openflow_idle_timeout
,
1224 { "Idle time-out", "openflow.idle_timeout",
1225 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1228 { &hf_openflow_hard_timeout
,
1229 { "hard time-out", "openflow.hard_timeout",
1230 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1233 { &hf_openflow_priority
,
1234 { "Priority", "openflow.priority",
1235 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1238 { &hf_openflow_out_port
,
1239 { "Out port", "openflow.out_port",
1240 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1243 { &hf_openflow_out_group
,
1244 { "Out group", "openflow.out_group",
1245 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1248 { &hf_openflow_flags
,
1249 { "Flags", "openflow.flags",
1250 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1255 static gint
*ett
[] = {
1257 &ett_openflow_path_id
,
1261 &ett_openflow_port_cnf
,
1262 &ett_openflow_port_state
,
1263 &ett_openflow_port_cf
1266 /* Register the protocol name and description */
1267 proto_openflow_v1
= proto_register_protocol("OpenFlow 1.0",
1268 "openflow_v1", "openflow_v1");
1270 new_register_dissector("openflow_v1", dissect_openflow_v1
, proto_openflow_v1
);
1272 eth_withoutfcs_handle
= find_dissector("eth_withoutfcs");
1274 /* Required function calls to register the header fields and subtrees */
1275 proto_register_field_array(proto_openflow_v1
, hf
, array_length(hf
));
1276 proto_register_subtree_array(ett
, array_length(ett
));