Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-openflow_v1.c
Line
Count
Source
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>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 *
12
 * Ref https://www.opennetworking.org/sdn-resources/onf-specifications/openflow
13
 */
14
15
#include "config.h"
16
17
#include <epan/packet.h>
18
#include <epan/expert.h>
19
20
void proto_register_openflow_v1(void);
21
void proto_reg_handoff_openflow_v1(void);
22
23
static dissector_handle_t eth_withoutfcs_handle;
24
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;
31
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;
48
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. */
61
62
static int hf_openflow_port_no;
63
static int hf_openflow_hw_addr;
64
static int hf_openflow_port_name;
65
66
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;
73
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. */
81
82
static int hf_openflow_link_down;    /* No physical link present. */
83
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. */
96
97
static int hf_openflow_config_flags;
98
static int hf_openflow_miss_send_len;
99
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;
146
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;
156
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;
160
161
static const value_string openflow_version_values[] = {
162
    { 0x01, "1.0" },
163
    { 0, NULL }
164
};
165
166
167
/* Immutable messages. */
168
1
#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
1
#define OFPT_1_0_FEATURES_REQUEST          5 /* Controller/switch message */
175
3
#define OFPT_1_0_FEATURES_REPLY            6 /* Controller/switch message */
176
0
#define OFPT_1_0_GET_CONFIG_REQUEST        7 /* Controller/switch message */
177
0
#define OFPT_1_0_GET_CONFIG_REPLY          8 /* Controller/switch message */
178
0
#define OFPT_1_0_SET_CONFIG                9 /* Controller/switch message */
179
/* Asynchronous messages. */
180
5
#define OFPT_1_0_PACKET_IN                10 /* Async message */
181
0
#define OFPT_1_0_FLOW_REMOVED             11 /* Async message */
182
#define OFPT_1_0_PORT_STATUS              12 /* Async message */
183
/* Controller command messages. */
184
5
#define OFPT_1_0_PACKET_OUT               13 /* Controller/switch message */
185
0
#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
0
#define OFPT_1_0_STATS_REQUEST            16 /* Controller/switch message */
189
0
#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 */
196
197
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 }
229
};
230
static value_string_ext openflow_1_0_type_values_ext = VALUE_STRING_EXT_INIT(openflow_1_0_type_values);
231
232
14
#define OFPC_FLOW_STATS   1<<0  /* Flow statistics. */
233
14
#define OFPC_TABLE_STATS  1<<1  /* Table statistics. */
234
14
#define OFPC_PORT_STATS   1<<2  /* Port statistics. */
235
14
#define OFPC_GROUP_STATS  1<<3  /* Group statistics. */
236
14
#define OFPC_IP_REASM     1<<5  /* Can reassemble IP fragments. */
237
14
#define OFPC_QUEUE_STATS  1<<6  /* Queue statistics. */
238
14
#define OFPC_PORT_BLOCKED 1<<8  /* Switch will block looping ports. */
239
240
14
#define OFPAT_OUTPUT_MASK       1<<0  /* Output to switch port. */
241
14
#define OFPAT_SET_VLAN_VID_MASK 1<<1  /* Set the 802.1q VLAN id. */
242
14
#define OFPAT_SET_VLAN_PCP_MASK 1<<2  /* Set the 802.1q priority. */
243
14
#define OFPAT_STRIP_VLAN_MASK   1<<3  /* Strip the 802.1q header. */
244
14
#define OFPAT_SET_DL_SRC_MASK   1<<4  /* Ethernet source address. */
245
14
#define OFPAT_SET_DL_DST_MASK   1<<5  /* Ethernet destination address. */
246
14
#define OFPAT_SET_NW_SRC_MASK   1<<6  /* IP source address. */
247
14
#define OFPAT_SET_NW_DST_MASK   1<<7  /* IP destination address. */
248
14
#define OFPAT_SET_NW_TOS_MASK   1<<8  /* IP ToS (DSCP field, 6 bits). */
249
14
#define OFPAT_SET_TP_SRC_MASK   1<<9  /* TCP/UDP source port. */
250
14
#define OFPAT_SET_TP_DST_MASK   1<<10 /* TCP/UDP destination port. */
251
14
#define OFPAT_ENQUEUE_MASK      1<<11 /* Output to queue. */
252
253
14
#define OFPPC_PORT_DOWN    1<<0 /* Port is administratively down. */
254
14
#define OFPPC_NO_STP       1<<1 /* Disable 802.1D spanning tree on port. */
255
14
#define OFPPC_NO_RECV      1<<2 /* Drop all packets except 802.1D spanning tree packets. */
256
14
#define OFPPC_NO_RECV_STP  1<<3 /* Drop received 802.1D STP packets. */
257
14
#define OFPPC_NO_FLOOD     1<<4 /* Do not include this port when flooding. */
258
14
#define OFPPC_NO_FWD       1<<5 /* Drop packets forwarded to port. */
259
14
#define OFPPC_NO_PACKET_IN 1<<6 /* Do not send packet-in msgs for port. */
260
261
66
#define OFP_MAX_PORT_NAME_LEN 16
262
263
14
#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. */
269
270
271
14
#define OFPPF_10MB_HD      1<<0  /* 10 Mb half-duplex rate support. */
272
14
#define OFPPF_10MB_FD      1<<1  /* 10 Mb full-duplex rate support. */
273
14
#define OFPPF_100MB_HD     1<<2  /* 100 Mb half-duplex rate support. */
274
14
#define OFPPF_100MB_FD     1<<3  /* 100 Mb full-duplex rate support. */
275
14
#define OFPPF_1GB_HD       1<<4  /* 1 Gb half-duplex rate support. */
276
14
#define OFPPF_1GB_FD       1<<5  /* 1 Gb full-duplex rate support. */
277
14
#define OFPPF_10GB_FD      1<<6  /* 10 Gb full-duplex rate support. */
278
14
#define OFPPF_COPPER       1<<7  /* Copper medium. */
279
14
#define OFPPF_FIBER        1<<8  /* Fiber medium. */
280
14
#define OFPPF_AUTONEG      1<<9  /* Auto-negotiation. */
281
14
#define OFPPF_PAUSE        1<<10 /* Pause. */
282
14
#define OFPPF_PAUSE_ASYM   1<<11 /* Asymmetric pause. */
283
284
285
0
#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
296
297
static int
298
dissect_openflow_ofp_match_v1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
299
0
{
300
301
    /* uint32_t wildcards; Wildcard fields. */
302
0
    proto_tree_add_item(tree, hf_openflow_wildcards, tvb, offset, 4, ENC_BIG_ENDIAN);
303
0
    offset+=4;
304
    /* uint16_t in_port; Input switch port. */
305
0
    proto_tree_add_item(tree, hf_openflow_in_port, tvb, offset, 2, ENC_BIG_ENDIAN);
306
0
    offset+=2;
307
308
    /* uint8_t dl_src[OFP_ETH_ALEN];  Ethernet source address. */
309
0
    proto_tree_add_item(tree, hf_openflow_eth_src, tvb, offset, 6, ENC_NA);
310
0
    offset+=6;
311
    /* uint8_t dl_dst[OFP_ETH_ALEN]; Ethernet destination address. */
312
0
    proto_tree_add_item(tree, hf_openflow_eth_dst, tvb, offset, 6, ENC_NA);
313
0
    offset+=6;
314
    /* uint16_t dl_vlan; Input VLAN id. */
315
0
    proto_tree_add_item(tree, hf_openflow_dl_vlan, tvb, offset, 2, ENC_BIG_ENDIAN);
316
0
    offset+=2;
317
    /* uint8_t dl_vlan_pcp; Input VLAN priority. */
318
0
    proto_tree_add_item(tree, hf_openflow_dl_vlan_pcp, tvb, offset, 1, ENC_BIG_ENDIAN);
319
0
    offset++;
320
    /* uint8_t pad1[1]; Align to 64-bits */
321
0
    proto_tree_add_item(tree, hf_openflow_ofp_match_pad, tvb, offset, 1, ENC_NA);
322
0
    offset++;
323
    /* uint16_t dl_type; Ethernet frame type. */
324
0
    proto_tree_add_item(tree, hf_openflow_match_dl_type, tvb, offset, 2, ENC_BIG_ENDIAN);
325
0
    offset += 2;
326
    /* uint8_t nw_tos; IP ToS (actually DSCP field, 6 bits). */
327
0
    proto_tree_add_item(tree, hf_openflow_ofp_match_tos, tvb, offset, 1, ENC_NA);
328
0
    offset++;
329
    /* uint8_t nw_proto; IP protocol or lower 8 bits of
330
     * ARP opcode.
331
     */
332
0
    proto_tree_add_item(tree, hf_openflow_ofp_match_nw_proto, tvb, offset, 1, ENC_NA);
333
0
    offset++;
334
    /* uint8_t pad2[2]; Align to 64-bits */
335
0
    proto_tree_add_item(tree, hf_openflow_ofp_match_pad, tvb, offset, 2, ENC_NA);
336
0
    offset += 2;
337
    /* uint32_t nw_src; IP source address. */
338
0
    proto_tree_add_item(tree, hf_openflow_ofp_source_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
339
0
    offset += 4;
340
    /* uint32_t nw_dst; IP destination address. */
341
0
    proto_tree_add_item(tree, hf_openflow_ofp_dest_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
342
0
    offset += 4;
343
    /* uint16_t tp_src; TCP/UDP source port. */
344
0
    proto_tree_add_item(tree, hf_openflow_ofp_source_port, tvb, offset, 2, ENC_BIG_ENDIAN);
345
0
    offset += 2;
346
    /* uint16_t tp_dst; TCP/UDP destination port. */
347
0
    proto_tree_add_item(tree, hf_openflow_ofp_dest_port, tvb, offset, 2, ENC_BIG_ENDIAN);
348
0
    offset += 2;
349
0
    return offset;
350
0
}
351
352
static int
353
dissect_openflow_flow_stats_request_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
354
0
{
355
    /* struct ofp_match match;  Fields to match */
356
0
    offset = dissect_openflow_ofp_match_v1(tvb, pinfo, tree, offset);
357
358
    /* uint8_t table_id; ID of table to read (from ofp_table_stats),
359
     * 0xff for all tables or 0xfe for emergency.
360
     */
361
0
    proto_tree_add_item(tree, hf_openflow_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
362
0
    offset++;
363
    /* uint8_t pad;  Align to 32 bits. */
364
0
    proto_tree_add_item(tree, hf_openflow_v1_flow_stats_request_pad, tvb, offset, 1, ENC_BIG_ENDIAN);
365
0
    offset++;
366
    /* uint16_t out_port; */
367
0
    proto_tree_add_item(tree, hf_openflow_out_port, tvb, offset, 2, ENC_BIG_ENDIAN);
368
0
    offset += 2;
369
370
0
    return offset;
371
372
0
}
373
374
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 }
388
};
389
390
static int
391
dissect_openflow_action_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
392
0
{
393
0
    uint16_t action_type, action_len;
394
0
    proto_item* ti;
395
396
    /* uint16_t type;  One of OFPAT_*. */
397
0
    ti = proto_tree_add_item_ret_uint16(tree, hf_openflow_action_type, tvb, offset, 2, ENC_BIG_ENDIAN, &action_type);
398
0
    offset+=2;
399
    /* Length of action, including this
400
     * header. This is the length of action,
401
     * including any padding to make it
402
     * 64-bit aligned.
403
     */
404
0
    proto_tree_add_item_ret_uint16(tree, hf_openflow_action_len, tvb, offset, 2, ENC_BIG_ENDIAN, &action_len);
405
0
    offset+=2;
406
407
0
    switch(action_type){
408
0
    case OFPAT_OUTPUT:
409
        /* uint16_t port;  Output port. */
410
0
        proto_tree_add_item(tree, hf_openflow_output_port, tvb, offset, 2, ENC_BIG_ENDIAN);
411
0
        offset+=2;
412
        /* uint16_t max_len;  Max length to send to controller. */
413
0
        proto_tree_add_item(tree, hf_openflow_max_len, tvb, offset, 2, ENC_BIG_ENDIAN);
414
0
        offset+=2;
415
0
        break;
416
0
    default:
417
0
        expert_add_info(pinfo, ti, &ei_openflow_action_type);
418
0
        offset+=(action_len-4);
419
0
        break;
420
0
    }
421
422
0
    return offset;
423
0
}
424
static void
425
dissect_openflow_phy_port(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
426
33
{
427
33
    proto_item *ti;
428
33
    proto_tree *port_cnf_tree, *port_state_tree, *port_cf_tree;
429
430
33
    proto_tree_add_item(tree, hf_openflow_port_no, tvb, offset, 2, ENC_BIG_ENDIAN);
431
33
    offset+=2;
432
33
    proto_tree_add_item(tree, hf_openflow_hw_addr, tvb, offset, 6, ENC_NA);
433
33
    offset+=6;
434
33
    proto_tree_add_item(tree, hf_openflow_port_name, tvb, offset, OFP_MAX_PORT_NAME_LEN, ENC_ASCII);
435
33
    offset+=OFP_MAX_PORT_NAME_LEN;
436
437
    /* Bitmap of OFPPC_* flags. */
438
33
    ti = proto_tree_add_item(tree, hf_openflow_port_config, tvb, offset, 4, ENC_BIG_ENDIAN);
439
33
    port_cnf_tree = proto_item_add_subtree(ti, ett_openflow_port_cnf);
440
441
    /* Port is administratively down. */
442
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_port_down, tvb, offset, 4, ENC_BIG_ENDIAN);
443
    /* Disable 802.1D spanning tree on port. */
444
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_no_stp, tvb, offset, 4, ENC_BIG_ENDIAN);
445
    /* Drop all packets except 802.1D spanning tree packets. */
446
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_no_recv, tvb, offset, 4, ENC_BIG_ENDIAN);
447
    /* Drop received 802.1D STP packets. */
448
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_no_recv_stp, tvb, offset, 4, ENC_BIG_ENDIAN);
449
    /* Do not include this port when flooding. */
450
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_no_flood, tvb, offset, 4, ENC_BIG_ENDIAN);
451
     /* Drop packets forwarded to port. */
452
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_no_fwd, tvb, offset, 4, ENC_BIG_ENDIAN);
453
    /* Do not send packet-in msgs for port. */
454
33
    proto_tree_add_item(port_cnf_tree, hf_openflow_no_packet_in, tvb, offset, 4, ENC_BIG_ENDIAN);
455
33
    offset+=4;
456
457
    /* Bitmap of OFPPS_* flags. */
458
33
    ti = proto_tree_add_item(tree, hf_openflow_port_state, tvb, offset, 4, ENC_BIG_ENDIAN);
459
33
    port_state_tree = proto_item_add_subtree(ti, ett_openflow_port_state);
460
461
    /* No physical link present. */
462
33
    proto_tree_add_item(port_state_tree, hf_openflow_link_down, tvb, offset, 4, ENC_BIG_ENDIAN);
463
464
33
    offset+=4;
465
466
    /* Current features. */
467
33
    ti = proto_tree_add_item(tree, hf_openflow_port_curr, tvb, offset, 4, ENC_BIG_ENDIAN);
468
33
    port_cf_tree = proto_item_add_subtree(ti, ett_openflow_port_cf);
469
    /* 10 Mb half-duplex rate support. */
470
33
    proto_tree_add_item(port_cf_tree, hf_openflow_10mb_hd, tvb, offset, 4, ENC_BIG_ENDIAN);
471
    /* 10 Mb full-duplex rate support. */
472
33
    proto_tree_add_item(port_cf_tree, hf_openflow_10mb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
473
    /* 100 Mb half-duplex rate support. */
474
33
    proto_tree_add_item(port_cf_tree, hf_openflow_100mb_hd, tvb, offset, 4, ENC_BIG_ENDIAN);
475
    /* 100 Mb full-duplex rate support. */
476
33
    proto_tree_add_item(port_cf_tree, hf_openflow_100mb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
477
    /* 1 Gb half-duplex rate support. */
478
33
    proto_tree_add_item(port_cf_tree, hf_openflow_1gb_hd, tvb, offset, 4, ENC_BIG_ENDIAN);
479
    /* 1 Gb full-duplex rate support. */
480
33
    proto_tree_add_item(port_cf_tree, hf_openflow_1gb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
481
    /* 10 Gb full-duplex rate support. */
482
33
    proto_tree_add_item(port_cf_tree, hf_openflow_10gb_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
483
    /* Copper medium. */
484
33
    proto_tree_add_item(port_cf_tree, hf_openflow_copper, tvb, offset, 4, ENC_BIG_ENDIAN);
485
    /* Fiber medium. */
486
33
    proto_tree_add_item(port_cf_tree, hf_openflow_fiber, tvb, offset, 4, ENC_BIG_ENDIAN);
487
    /* Auto-negotiation. */
488
33
    proto_tree_add_item(port_cf_tree, hf_openflow_autoneg, tvb, offset, 4, ENC_BIG_ENDIAN);
489
    /* Pause. */
490
33
    proto_tree_add_item(port_cf_tree, hf_openflow_pause, tvb, offset, 4, ENC_BIG_ENDIAN);
491
    /* Asymmetric pause. */
492
33
    proto_tree_add_item(port_cf_tree, hf_openflow_pause_asym, tvb, offset, 4, ENC_BIG_ENDIAN);
493
33
    offset+=4;
494
495
    /* Features being advertised by the port. */
496
33
    proto_tree_add_item(tree, hf_openflow_port_advertised, tvb, offset, 4, ENC_BIG_ENDIAN);
497
33
    offset+=4;
498
499
    /* Features supported by the port. */
500
33
    proto_tree_add_item(tree, hf_openflow_port_supported, tvb, offset, 4, ENC_BIG_ENDIAN);
501
33
    offset+=4;
502
    /* Features advertised by peer. */
503
33
    proto_tree_add_item(tree, hf_openflow_port_peer, tvb, offset, 4, ENC_BIG_ENDIAN);
504
505
506
33
}
507
508
#if 0
509
/*
510
 * Switch features.
511
 */
512
513
struct ofp_switch_features {
514
    struct ofp_header   header;
515
    uint64_t            datapath_id;  /* Datapath unique ID. The lower 48-bits are for
516
                                         a MAC address, while the upper 16-bits are
517
                                         implementer-defined. */
518
    uint32_t            n_buffers;    /* Max packets buffered at once. */
519
    uint8_t             n_tables;     /* Number of tables supported by datapath. */
520
    uint8_t             pad[3];       /* Align to 64-bits. */
521
    /* Features. */
522
    uint32_t            capabilities; /* Bitmap of support "ofp_capabilities". */
523
    uint32_t            actions;      /* Bitmap of supported "ofp_action_type"s. */
524
    /* Port info.*/
525
    struct ofp_phy_port ports[0];     /* Port definitions. The number of ports
526
                                         is inferred from the length field in
527
                                         the header. */
528
#endif
529
530
static void
531
dissect_openflow_features_reply_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
532
3
{
533
3
    proto_item *ti;
534
3
    proto_tree *path_id_tree, *cap_tree, *act_tree;
535
536
3
    uint16_t length_remaining;
537
538
3
    ti = proto_tree_add_item(tree, hf_openflow_datapath_id, tvb, offset, 8, ENC_BIG_ENDIAN);
539
3
    path_id_tree = proto_item_add_subtree(ti, ett_openflow_path_id);
540
3
    proto_tree_add_item(path_id_tree, hf_openflow_datapath_impl, tvb, offset, 2, ENC_BIG_ENDIAN);
541
3
    offset+=2;
542
3
    proto_tree_add_item(path_id_tree, hf_openflow_datapath_mac, tvb, offset, 6, ENC_NA);
543
3
    offset+=6;
544
545
3
    proto_tree_add_item(tree, hf_openflow_n_buffers, tvb, offset, 4, ENC_BIG_ENDIAN);
546
3
    offset+=4;
547
548
3
    proto_tree_add_item(tree, hf_openflow_n_tables, tvb, offset, 1, ENC_BIG_ENDIAN);
549
3
    offset++;
550
551
3
    proto_tree_add_item(tree, hf_openflow_features_reply_pad, tvb, offset, 3, ENC_NA);
552
3
    offset+=3;
553
554
3
    ti = proto_tree_add_item(tree, hf_openflow_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
555
3
    cap_tree = proto_item_add_subtree(ti, ett_openflow_cap);
556
557
    /* Dissect flags */
558
3
    proto_tree_add_item(cap_tree, hf_openflow_cap_flow_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
559
3
    proto_tree_add_item(cap_tree, hf_openflow_table_stats,    tvb, offset, 4, ENC_BIG_ENDIAN);
560
3
    proto_tree_add_item(cap_tree, hf_openflow_port_stats,     tvb, offset, 4, ENC_BIG_ENDIAN);
561
3
    proto_tree_add_item(cap_tree, hf_openflow_group_stats,    tvb, offset, 4, ENC_BIG_ENDIAN);
562
3
    proto_tree_add_item(cap_tree, hf_openflow_ip_reasm,       tvb, offset, 4, ENC_BIG_ENDIAN);
563
3
    proto_tree_add_item(cap_tree, hf_openflow_queue_stats,    tvb, offset, 4, ENC_BIG_ENDIAN);
564
3
    proto_tree_add_item(cap_tree, hf_openflow_port_blocked,   tvb, offset, 4, ENC_BIG_ENDIAN);
565
3
    offset+=4;
566
567
3
    ti = proto_tree_add_item(tree, hf_openflow_actions, tvb, offset, 4, ENC_BIG_ENDIAN);
568
3
    act_tree = proto_item_add_subtree(ti, ett_openflow_act);
569
    /* Dissect flags */
570
3
    proto_tree_add_item(act_tree, hf_openflow_output, tvb, offset, 4, ENC_BIG_ENDIAN);
571
3
    proto_tree_add_item(act_tree, hf_openflow_set_vlan_vid, tvb, offset, 4, ENC_BIG_ENDIAN);
572
3
    proto_tree_add_item(act_tree, hf_openflow_set_vlan_pcp, tvb, offset, 4, ENC_BIG_ENDIAN);
573
3
    proto_tree_add_item(act_tree, hf_openflow_strip_vlan, tvb, offset, 4, ENC_BIG_ENDIAN);
574
3
    proto_tree_add_item(act_tree, hf_openflow_set_dl_src, tvb, offset, 4, ENC_BIG_ENDIAN);
575
3
    proto_tree_add_item(act_tree, hf_openflow_set_dl_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
576
3
    proto_tree_add_item(act_tree, hf_openflow_set_nw_src, tvb, offset, 4, ENC_BIG_ENDIAN);
577
3
    proto_tree_add_item(act_tree, hf_openflow_set_nw_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
578
3
    proto_tree_add_item(act_tree, hf_openflow_set_nw_tos, tvb, offset, 4, ENC_BIG_ENDIAN);
579
3
    proto_tree_add_item(act_tree, hf_openflow_set_tp_src, tvb, offset, 4, ENC_BIG_ENDIAN);
580
3
    proto_tree_add_item(act_tree, hf_openflow_set_tp_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
581
3
    proto_tree_add_item(act_tree, hf_openflow_enqueue, tvb, offset, 4, ENC_BIG_ENDIAN);
582
3
    offset+=4;
583
584
3
    length_remaining = length-32;
585
3
    if(length_remaining > 0){
586
3
        uint16_t num_ports = length_remaining/48;
587
3
        int i;
588
3
        if((length_remaining&0x003f) != 0){
589
            /* protocol_error */
590
3
        }
591
36
        for(i=0; i<num_ports ;i++){
592
33
            proto_tree *port_tree;
593
594
33
            port_tree = proto_tree_add_subtree_format(tree, tvb, offset, 48, ett_openflow_port, NULL, "Port data %u",i+1);
595
33
            dissect_openflow_phy_port(tvb, pinfo, port_tree, offset);
596
33
            offset+=48;
597
33
        }
598
3
    }
599
600
3
}
601
602
603
static void
604
dissect_openflow_switch_config(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, uint16_t length _U_)
605
0
{
606
607
    /* ofp_config_flags */
608
0
    proto_tree_add_item(tree, hf_openflow_config_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
609
0
    offset+=2;
610
    /* miss_send_len */
611
0
    proto_tree_add_item(tree, hf_openflow_miss_send_len, tvb, offset, 2, ENC_BIG_ENDIAN);
612
    /*offset+=2;*/
613
614
0
}
615
616
#define OFPR_NO_MATCH       0        /* No matching flow (table-miss flow entry). */
617
#define OFPR_ACTION         1        /* Action explicitly output to controller. */
618
#define OFPR_INVALID_TTL    2        /* Packet has invalid TTL */
619
620
static const value_string openflow_reason_values[] = {
621
    { OFPR_NO_MATCH,    "No matching flow (table-miss flow entry)" },
622
    { OFPR_ACTION,      "Action explicitly output to controller" },
623
    { OFPR_INVALID_TTL, "Packet has invalid TTL" },
624
    { 0, NULL }
625
};
626
627
static void
628
dissect_openflow_pkt_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
629
0
{
630
0
    tvbuff_t *next_tvb;
631
632
    /* uint32_t buffer_id;  ID assigned by datapath. */
633
0
    proto_tree_add_item(tree, hf_openflow_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
634
0
    offset+=4;
635
    /* uint16_t total_len;  Full length of frame. */
636
0
    proto_tree_add_item(tree, hf_openflow_total_len, tvb, offset, 2, ENC_BIG_ENDIAN);
637
0
    offset+=2;
638
639
    /* uint16_t in_port;  Port on which frame was received. */
640
0
    proto_tree_add_item(tree, hf_openflow_in_port, tvb, offset, 2, ENC_BIG_ENDIAN);
641
0
    offset+=2;
642
643
    /* uint8_t reason; Reason packet is being sent (one of OFPR_*) */
644
0
    proto_tree_add_item(tree, hf_openflow_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
645
0
    offset++;
646
647
0
    proto_tree_add_item(tree, hf_openflow_pkt_in_pad, tvb, offset, 1, ENC_NA);
648
0
    offset+=1;
649
650
0
    next_tvb = tvb_new_subset_length(tvb, offset, length-offset);
651
0
    call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
652
653
0
}
654
655
#define OFPRR_IDLE_TIMEOUT  0
656
#define OFPRR_HARD_TIMEOUT  1
657
#define OFPRR_DELETE        2
658
static const value_string openflow_flow_removed_reason_values[] = {
659
    { OFPRR_IDLE_TIMEOUT, "OFPRR_IDLE_TIMEOUT" },
660
    { OFPRR_HARD_TIMEOUT, "OFPRR_HARD_TIMEOUT" },
661
    { OFPRR_DELETE,       "OFPRR_DELETE" },
662
    { 0,                  NULL }
663
};
664
665
static void
666
dissect_openflow_flow_removed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length _U_)
667
0
{
668
    /* struct match; */
669
0
    offset = dissect_openflow_ofp_match_v1(tvb, pinfo, tree, offset);
670
671
    /* uint64_t cookie; */
672
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
673
0
    offset+=8;
674
675
    /* uint16_t priority; */
676
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
677
0
    offset+=2;
678
679
    /* uint8_t reason; */
680
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
681
0
    offset+=1;
682
683
    /* uint8_t pad1; */
684
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_pad1, tvb, offset, 1, ENC_BIG_ENDIAN);
685
0
    offset+=1;
686
687
    /* uint32_t duration_sec; */
688
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_duration_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
689
0
    offset+=4;
690
691
    /* uint32_t duration_nsec; */
692
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_duration_nsec, tvb, offset, 4, ENC_BIG_ENDIAN);
693
0
    offset+=4;
694
695
    /* uint16_t idle_timeout; */
696
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
697
0
    offset+=2;
698
699
    /* uint8_t pad2; */
700
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_pad2, tvb, offset, 2, ENC_BIG_ENDIAN);
701
0
    offset+=2;
702
703
    /* uint64_t packet_count; */
704
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_packet_count, tvb, offset, 8, ENC_BIG_ENDIAN);
705
0
    offset+=8;
706
707
    /* uint64_t byte_count; */
708
0
    proto_tree_add_item(tree, hf_openflow_flow_removed_byte_count, tvb, offset, 8, ENC_BIG_ENDIAN);
709
710
0
}
711
712
static void
713
dissect_openflow_pkt_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
714
0
{
715
0
    tvbuff_t *next_tvb;
716
0
    int32_t buffer_id;
717
718
    /* uint32_t buffer_id;  ID assigned by datapath. */
719
0
    buffer_id = tvb_get_ntohl(tvb, offset);
720
0
    proto_tree_add_item(tree, hf_openflow_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
721
0
    offset+=4;
722
723
    /* uint32_t in_port; Packet's input port or OFPP_CONTROLLER. */
724
0
    proto_tree_add_item(tree, hf_openflow_in_port, tvb, offset, 2, ENC_BIG_ENDIAN);
725
0
    offset+=2;
726
727
    /* uint16_t actions_len;  Size of action array in bytes. */
728
0
    proto_tree_add_item(tree, hf_openflow_actions_len, tvb, offset, 2, ENC_BIG_ENDIAN);
729
0
    offset+=2;
730
731
    /* struct ofp_action_header actions[0];  Action list. */
732
0
    offset = dissect_openflow_action_header(tvb, pinfo, tree, offset);
733
    /* Packet data. The length is inferred
734
       from the length field in the header.
735
       (Only meaningful if buffer_id == -1.)
736
     */
737
0
    if(buffer_id == -1){
738
0
        next_tvb = tvb_new_subset_length(tvb, offset, length-offset);
739
0
        call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
740
0
    }
741
0
}
742
743
#define OFPFC_ADD             0 /* New flow. */
744
#define OFPFC_MODIFY          1 /* Modify all matching flows. */
745
#define OFPFC_MODIFY_STRICT   2 /* Modify entry strictly matching wildcards */
746
#define OFPFC_DELETE          3 /* Delete all matching flows. */
747
#define OFPFC_DELETE_STRICT   4 /* Strictly match wildcards and priority. */
748
749
static const value_string openflow_command_values[] = {
750
    { OFPFC_ADD,            "New flow" },
751
    { OFPFC_MODIFY,         "Modify all matching flows" },
752
    { OFPFC_MODIFY_STRICT,  "Modify entry strictly matching wildcards" },
753
    { OFPFC_DELETE,         "Delete all matching flows" },
754
    { OFPFC_DELETE_STRICT,  "Strictly match wildcards and priority" },
755
    { 0, NULL }
756
};
757
758
static void
759
dissect_openflow_flow_mod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length _U_)
760
0
{
761
762
    /* struct ofp_match match;  Fields to match */
763
0
    offset = dissect_openflow_ofp_match_v1(tvb, pinfo, tree, offset);
764
765
    /* uint64_t cookie; Opaque controller-issued identifier. */
766
0
    proto_tree_add_item(tree, hf_openflow_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
767
0
    offset += 8;
768
769
    /* uint16_t command;  One of OFPFC_*. */
770
0
    proto_tree_add_item(tree, hf_openflow_command, tvb, offset, 2, ENC_BIG_ENDIAN);
771
0
    offset += 2;
772
773
    /* uint16_t idle_timeout;  Idle time before discarding (seconds). */
774
0
    proto_tree_add_item(tree, hf_openflow_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
775
0
    offset += 2;
776
    /* uint16_t hard_timeout; Max time before discarding (seconds). */
777
0
    proto_tree_add_item(tree, hf_openflow_hard_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
778
0
    offset += 2;
779
    /* uint16_t priority; Priority level of flow entry. */
780
0
    proto_tree_add_item(tree, hf_openflow_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
781
0
    offset += 2;
782
    /* uint32_t buffer_id;  Buffered packet to apply to, or OFP_NO_BUFFER.
783
       Not meaningful for OFPFC_DELETE*.
784
     */
785
0
    proto_tree_add_item(tree, hf_openflow_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
786
0
    offset += 4;
787
    /* uint32_t out_port; For OFPFC_DELETE* commands, require
788
       matching entries to include this as an output port. A value of OFPP_ANY
789
       indicates no restriction.
790
       */
791
0
    proto_tree_add_item(tree, hf_openflow_out_port, tvb, offset, 2, ENC_BIG_ENDIAN);
792
0
    offset += 2;
793
794
    /* uint16_t flags; One of OFPFF_*. */
795
0
    proto_tree_add_item(tree, hf_openflow_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
796
0
    offset+=2;
797
798
0
    dissect_openflow_action_header(tvb, pinfo, tree, offset);
799
0
}
800
801
802
0
#define    OFPST_DESC 0
803
0
#define    OFPST_FLOW 1
804
#define    OFPST_AGGREGATE 2
805
#define    OFPST_TABLE 3
806
#define    OFPST_PORT 4
807
#define    OFPST_QUEUE 5
808
#define    OFPST_VENDOR  0xffff
809
810
static const value_string openflow_stats_type_values[] = {
811
    { OFPST_DESC,         "OFPST_DESC" },
812
    { OFPST_FLOW,         "OFPST_FLOW" },
813
    { OFPST_AGGREGATE,    "OFPST_AGGREGATE" },
814
    { OFPST_TABLE,        "OFPST_TABLE" },
815
    { OFPST_PORT,         "OFPST_PORT" },
816
    { OFPST_QUEUE,        "OFPST_QUEUE" },
817
    { OFPST_VENDOR,       "OFPST_VENDOR" },
818
    { 0, NULL }
819
};
820
static int
821
dissect_openflow_stats_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length _U_)
822
0
{
823
0
    proto_item *type_item;
824
0
    uint32_t type;
825
826
    /* uint16_t type; */
827
0
    type_item = proto_tree_add_item_ret_uint(tree, hf_openflow_v1_stats_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
828
0
    offset += 2;
829
    /* uint16_t flags; OFPSF_REQ_* flags (none yet defined). */
830
0
    proto_tree_add_item(tree, hf_openflow_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
831
0
    offset += 2;
832
    /* uint8_t body[0];  Body of the request. */
833
0
    switch (type) {
834
0
    case OFPST_DESC:
835
        /* The request body is empty. */
836
0
        break;
837
0
    case OFPST_FLOW:
838
0
        dissect_openflow_flow_stats_request_v1(tvb, pinfo, tree, offset);
839
0
        break;
840
0
    default:
841
0
        expert_add_info(pinfo, type_item, &ei_openflow_1_0_type);
842
0
        break;
843
0
    }
844
845
0
    return offset;
846
0
}
847
848
static int
849
dissect_openflow_stats_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint16_t length)
850
0
{
851
852
0
    proto_item *type_item;
853
0
    uint32_t type;
854
855
    /* uint16_t type; */
856
0
    type_item = proto_tree_add_item_ret_uint(tree, hf_openflow_v1_stats_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
857
0
    offset += 2;
858
    /* uint16_t flags; OFPSF_REQ_ */
859
0
    proto_tree_add_item(tree, hf_openflow_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
860
0
    offset += 2;
861
    /* uint8_t body[0];  Body of the request. */
862
0
    if (length == 12 ) {
863
        /* No body */
864
0
        return offset;
865
0
    }
866
0
    switch (type) {
867
0
    case OFPST_DESC:
868
        /* The request body is empty. */
869
0
        break;
870
0
    case OFPST_FLOW:
871
        /* fall trough */
872
0
    default:
873
0
        expert_add_info(pinfo, type_item, &ei_openflow_1_0_type);
874
0
        break;
875
0
    }
876
877
0
    return offset;
878
0
}
879
880
static int
881
dissect_openflow_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
882
5
{
883
5
    proto_item *ti, *type_item;
884
5
    proto_tree *openflow_tree;
885
5
    unsigned offset = 0;
886
5
    uint8_t type;
887
5
    uint16_t length;
888
889
5
    type    = tvb_get_uint8(tvb, 1);
890
891
5
    col_append_fstr(pinfo->cinfo, COL_INFO, "Type: %s",
892
5
                  val_to_str_ext_const(type, &openflow_1_0_type_values_ext, "Unknown message type"));
893
894
    /* Stop the Ethernet frame from overwriting the columns */
895
5
    if((type == OFPT_1_0_PACKET_IN) || (type == OFPT_1_0_PACKET_OUT)){
896
0
        col_set_writable(pinfo->cinfo, -1, false);
897
0
    }
898
899
    /* Create display subtree for the protocol */
900
5
    ti = proto_tree_add_item(tree, proto_openflow_v1, tvb, 0, -1, ENC_NA);
901
5
    openflow_tree = proto_item_add_subtree(ti, ett_openflow);
902
903
    /* A.1 OpenFlow Header. */
904
    /* OFP_VERSION. */
905
5
    proto_tree_add_item(openflow_tree, hf_openflow_version, tvb, offset, 1, ENC_BIG_ENDIAN);
906
5
    offset++;
907
908
    /* One of the OFPT_ constants. */
909
5
    type_item = proto_tree_add_item(openflow_tree, hf_openflow_1_0_type, tvb, offset, 1, ENC_BIG_ENDIAN);
910
5
    offset++;
911
912
    /* Length including this ofp_header. */
913
5
    proto_tree_add_item_ret_uint16(openflow_tree, hf_openflow_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
914
5
    offset+=2;
915
916
    /* Transaction id associated with this packet. Replies use the same id as was in the request
917
     * to facilitate pairing.
918
     */
919
5
    proto_tree_add_item(openflow_tree, hf_openflow_xid, tvb, offset, 4, ENC_BIG_ENDIAN);
920
5
    offset+=4;
921
922
5
    switch(type){
923
1
    case OFPT_1_0_HELLO: /* 0 */
924
        /* 5.5.1 Hello
925
         * The OFPT_HELLO message has no body;
926
         */
927
1
        break;
928
1
    case OFPT_1_0_FEATURES_REQUEST: /* 5 */
929
        /* 5.3.1 Handshake
930
         * Upon TLS session establishment, the controller sends an OFPT_FEATURES_REQUEST
931
         * message. This message does not contain a body beyond the OpenFlow header.
932
         */
933
1
        break;
934
3
    case OFPT_1_0_FEATURES_REPLY: /* 6 */
935
3
        dissect_openflow_features_reply_v1(tvb, pinfo, openflow_tree, offset, length);
936
3
        break;
937
0
    case OFPT_1_0_GET_CONFIG_REQUEST: /* 7 */
938
        /* A.3.2 There is no body for OFPT_GET_CONFIG_REQUEST beyond the OpenFlow header. */
939
0
        break;
940
0
    case OFPT_1_0_GET_CONFIG_REPLY: /* 8 */
941
        /* Fall trough */
942
0
    case OFPT_1_0_SET_CONFIG: /* 9 */
943
0
        dissect_openflow_switch_config(tvb, pinfo, openflow_tree, offset, length);
944
0
        break;
945
0
    case OFPT_1_0_PACKET_IN: /* 10 */
946
0
        dissect_openflow_pkt_in(tvb, pinfo, openflow_tree, offset, length);
947
0
        break;
948
0
    case OFPT_1_0_FLOW_REMOVED: /* 11 */
949
0
        dissect_openflow_flow_removed(tvb, pinfo, openflow_tree, offset, length);
950
0
        break;
951
0
    case OFPT_1_0_PACKET_OUT: /* 13 */
952
0
        dissect_openflow_pkt_out(tvb, pinfo, openflow_tree, offset, length);
953
0
        break;
954
0
    case OFPT_1_0_FLOW_MOD: /* 14 */
955
0
        dissect_openflow_flow_mod(tvb, pinfo, openflow_tree, offset, length);
956
0
        break;
957
0
    case OFPT_1_0_STATS_REQUEST: /* 16 */
958
0
        dissect_openflow_stats_req(tvb, pinfo, openflow_tree, offset, length);
959
0
        break;
960
0
    case OFPT_1_0_STATS_REPLY: /* 17 */
961
0
        dissect_openflow_stats_resp(tvb, pinfo, openflow_tree, offset, length);
962
0
        break;
963
0
    default:
964
0
        if(length>8){
965
0
            expert_add_info(pinfo, type_item, &ei_openflow_1_0_type);
966
0
        }
967
0
        break;
968
5
    }
969
970
2
    return tvb_reported_length(tvb);
971
972
5
}
973
974
975
/*
976
 * Register the protocol with Wireshark.
977
 */
978
void
979
proto_register_openflow_v1(void)
980
14
{
981
14
    static hf_register_info hf[] = {
982
14
        { &hf_openflow_version,
983
14
            { "Version", "openflow.version",
984
14
               FT_UINT8, BASE_HEX, VALS(openflow_version_values), 0x7f,
985
14
               NULL, HFILL }
986
14
        },
987
14
        { &hf_openflow_1_0_type,
988
14
            { "Type", "openflow_1_0.type",
989
14
               FT_UINT8, BASE_DEC | BASE_EXT_STRING, &openflow_1_0_type_values_ext, 0x0,
990
14
               NULL, HFILL }
991
14
        },
992
14
        { &hf_openflow_xid,
993
14
            { "Transaction ID", "openflow.xid",
994
14
               FT_UINT32, BASE_DEC, NULL, 0x0,
995
14
               NULL, HFILL }
996
14
        },
997
14
        { &hf_openflow_length,
998
14
            { "Length", "openflow.length",
999
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1000
14
               NULL, HFILL }
1001
14
        },
1002
14
        { &hf_openflow_datapath_id,
1003
14
            { "Datapath unique ID", "openflow.datapath_id",
1004
14
               FT_UINT64, BASE_HEX, NULL, 0x0,
1005
14
               NULL, HFILL }
1006
14
        },
1007
14
        { &hf_openflow_datapath_mac,
1008
14
            { "MAC addr", "openflow.datapath_mac",
1009
14
               FT_ETHER, BASE_NONE, NULL, 0x0,
1010
14
               NULL, HFILL }
1011
14
        },
1012
14
        { &hf_openflow_datapath_impl,
1013
14
            { "Implementers part", "openflow.datapath_imp",
1014
14
               FT_UINT16, BASE_HEX, NULL, 0x0,
1015
14
               NULL, HFILL }
1016
14
        },
1017
14
        { &hf_openflow_n_buffers,
1018
14
            { "n_buffers", "openflow.n_buffers",
1019
14
               FT_UINT32, BASE_DEC, NULL, 0x0,
1020
14
               NULL, HFILL }
1021
14
        },
1022
14
        { &hf_openflow_n_tables,
1023
14
            { "n_tables", "openflow.n_tables",
1024
14
               FT_UINT8, BASE_DEC, NULL, 0x0,
1025
14
               NULL, HFILL }
1026
14
        },
1027
#if 0
1028
        { &hf_openflow_auxiliary_id,
1029
            { "auxiliary_id", "openflow.auxiliary_id",
1030
               FT_UINT8, BASE_DEC, NULL, 0x0,
1031
               NULL, HFILL }
1032
        },
1033
#endif
1034
14
        { &hf_openflow_capabilities,
1035
14
            { "capabilities", "openflow.capabilities",
1036
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1037
14
               NULL, HFILL }
1038
14
        },
1039
14
        { &hf_openflow_actions,
1040
14
            { "actions", "openflow.actions",
1041
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1042
14
               NULL, HFILL }
1043
14
        },
1044
#if 0
1045
        { &hf_openflow_reserved32,
1046
            { "Reserved", "openflow.reserved32",
1047
               FT_UINT32, BASE_DEC, NULL, 0x0,
1048
               NULL, HFILL }
1049
        },
1050
#endif
1051
14
        { &hf_openflow_cap_flow_stats,
1052
14
            { "Flow statistics", "openflow.flow_stats",
1053
14
               FT_BOOLEAN, 32, NULL, OFPC_FLOW_STATS,
1054
14
               NULL, HFILL }
1055
14
        },
1056
14
        { &hf_openflow_table_stats,
1057
14
            { "Table statistics", "openflow.table_stats",
1058
14
               FT_BOOLEAN, 32, NULL, OFPC_TABLE_STATS,
1059
14
               NULL, HFILL }
1060
14
        },
1061
14
        { &hf_openflow_port_stats,
1062
14
            { "Port statistics", "openflow.port_stats",
1063
14
               FT_BOOLEAN, 32, NULL,  OFPC_PORT_STATS,
1064
14
               NULL, HFILL }
1065
14
        },
1066
14
        { &hf_openflow_group_stats,
1067
14
            { "Group statistics", "openflow.group_stats",
1068
14
               FT_BOOLEAN, 32, NULL, OFPC_GROUP_STATS,
1069
14
               NULL, HFILL }
1070
14
        },
1071
14
        { &hf_openflow_ip_reasm,
1072
14
            { "Can reassemble IP fragments", "openflow.ip_reasm",
1073
14
               FT_BOOLEAN, 32, NULL, OFPC_IP_REASM,
1074
14
               NULL, HFILL }
1075
14
        },
1076
14
        { &hf_openflow_queue_stats,
1077
14
            { "Queue statistics", "openflow.queue_stats",
1078
14
               FT_BOOLEAN, 32, NULL, OFPC_QUEUE_STATS,
1079
14
               NULL, HFILL }
1080
14
        },
1081
14
        { &hf_openflow_port_blocked,
1082
14
            { "Switch will block looping ports", "openflow.port_blocked",
1083
14
               FT_BOOLEAN, 32, NULL, OFPC_PORT_BLOCKED,
1084
14
               NULL, HFILL }
1085
14
        },
1086
14
        { &hf_openflow_output,
1087
14
            { "Output to switch port", "openflow.output",
1088
14
               FT_BOOLEAN, 32, NULL, OFPAT_OUTPUT_MASK,
1089
14
               NULL, HFILL }
1090
14
        },
1091
14
        { &hf_openflow_set_vlan_vid,
1092
14
            { "Set the 802.1q VLAN id", "openflow.set_vlan_vid",
1093
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_VLAN_VID_MASK,
1094
14
               NULL, HFILL }
1095
14
        },
1096
14
        { &hf_openflow_set_vlan_pcp,
1097
14
            { "Set the 802.1q priority", "openflow.set_vlan_pcp",
1098
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_VLAN_PCP_MASK,
1099
14
               NULL, HFILL }
1100
14
        },
1101
14
        { &hf_openflow_strip_vlan,
1102
14
            { "Strip the 802.1q header", "openflow.strip_vlan",
1103
14
               FT_BOOLEAN, 32, NULL, OFPAT_STRIP_VLAN_MASK,
1104
14
               NULL, HFILL }
1105
14
        },
1106
14
        { &hf_openflow_set_dl_src,
1107
14
            { "Ethernet source address", "openflow.set_dl_src",
1108
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_DL_SRC_MASK,
1109
14
               NULL, HFILL }
1110
14
        },
1111
14
        { &hf_openflow_set_dl_dst,
1112
14
            { "Ethernet destination address", "openflow.set_dl_ds",
1113
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_DL_DST_MASK,
1114
14
               NULL, HFILL }
1115
14
        },
1116
14
        { &hf_openflow_set_nw_src,
1117
14
            { "IP source address", "openflow.set_nw_src",
1118
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_NW_SRC_MASK,
1119
14
               NULL, HFILL }
1120
14
        },
1121
14
        { &hf_openflow_set_nw_dst,
1122
14
            { "IP destination address", "openflow.set_nw_ds",
1123
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_NW_DST_MASK,
1124
14
               NULL, HFILL }
1125
14
        },
1126
14
        { &hf_openflow_set_nw_tos,
1127
14
            { "IP ToS (DSCP field, 6 bits)", "openflow.set_nw_tos",
1128
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_NW_TOS_MASK,
1129
14
               NULL, HFILL }
1130
14
        },
1131
14
        { &hf_openflow_set_tp_src,
1132
14
            { "TCP/UDP source port", "openflow.set_tp_src",
1133
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_TP_SRC_MASK,
1134
14
               NULL, HFILL }
1135
14
        },
1136
14
        { &hf_openflow_set_tp_dst,
1137
14
            { "TCP/UDP destination port", "openflow.set_tp_dst",
1138
14
               FT_BOOLEAN, 32, NULL, OFPAT_SET_TP_DST_MASK,
1139
14
               NULL, HFILL }
1140
14
        },
1141
14
        { &hf_openflow_enqueue,
1142
14
            { "Output to queue", "openflow.enqueue",
1143
14
               FT_BOOLEAN, 32, NULL, OFPAT_ENQUEUE_MASK,
1144
14
               NULL, HFILL }
1145
14
        },
1146
14
        { &hf_openflow_port_no,
1147
14
            { "Port number", "openflow.port_no",
1148
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1149
14
               NULL, HFILL }
1150
14
        },
1151
14
        { &hf_openflow_hw_addr,
1152
14
            { "HW Address", "openflow.hw_add",
1153
14
               FT_ETHER, BASE_NONE, NULL, 0x0,
1154
14
               NULL, HFILL }
1155
14
        },
1156
14
        { &hf_openflow_port_name,
1157
14
            { "Port Name", "openflow.port_name",
1158
14
               FT_STRING, BASE_NONE, NULL, 0x0,
1159
14
               NULL, HFILL }
1160
14
        },
1161
14
        { &hf_openflow_port_config,
1162
14
            { "Config flags", "openflow.port_config",
1163
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1164
14
               NULL, HFILL }
1165
14
        },
1166
14
        { &hf_openflow_port_state,
1167
14
            { "State flags", "openflow.port_state",
1168
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1169
14
               NULL, HFILL }
1170
14
        },
1171
14
        { &hf_openflow_port_curr,
1172
14
            { "Current features", "openflow.port_curr",
1173
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1174
14
               NULL, HFILL }
1175
14
        },
1176
14
        { &hf_openflow_port_advertised,
1177
14
            { "Advertised features", "openflow.port_advertised",
1178
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1179
14
               NULL, HFILL }
1180
14
        },
1181
14
        { &hf_openflow_port_supported,
1182
14
            { "Features supported", "openflow.port_supported",
1183
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1184
14
               NULL, HFILL }
1185
14
        },
1186
14
        { &hf_openflow_port_peer,
1187
14
            { "Features advertised by peer", "openflow.port_peer",
1188
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1189
14
               NULL, HFILL }
1190
14
        },
1191
14
        { &hf_openflow_port_down,
1192
14
            { "Port is administratively down", "openflow.port_down",
1193
14
               FT_BOOLEAN, 32, NULL, OFPPC_PORT_DOWN,
1194
14
               NULL, HFILL }
1195
14
        },
1196
14
        { &hf_openflow_no_stp,
1197
14
            { "Disable 802.1D spanning tree on port", "openflow.no_stp",
1198
14
               FT_BOOLEAN, 32, NULL, OFPPC_NO_STP,
1199
14
               NULL, HFILL }
1200
14
        },
1201
14
        { &hf_openflow_no_recv,
1202
14
            { "Drop all packets except 802.1D spanning tree packets", "openflow.no_recv",
1203
14
               FT_BOOLEAN, 32, NULL, OFPPC_NO_RECV,
1204
14
               NULL, HFILL }
1205
14
        },
1206
14
        { &hf_openflow_no_recv_stp,
1207
14
            { "Drop received 802.1D STP packets", "openflow.no_recv_stp",
1208
14
               FT_BOOLEAN, 32, NULL, OFPPC_NO_RECV_STP,
1209
14
               NULL, HFILL }
1210
14
        },
1211
14
        { &hf_openflow_no_flood,
1212
14
            { "Do not include this port when flooding", "openflow.no_flood",
1213
14
               FT_BOOLEAN, 32, NULL, OFPPC_NO_FLOOD,
1214
14
               NULL, HFILL }
1215
14
        },
1216
14
        { &hf_openflow_no_fwd,
1217
14
            { "Drop packets forwarded to port", "openflow.no_fwd",
1218
14
               FT_BOOLEAN, 32, NULL, OFPPC_NO_FWD,
1219
14
               NULL, HFILL }
1220
14
        },
1221
14
        { &hf_openflow_no_packet_in,
1222
14
            { "Do not send packet-in msgs for port", "openflow.no_packet_in",
1223
14
               FT_BOOLEAN, 32, NULL, OFPPC_NO_PACKET_IN,
1224
14
               NULL, HFILL }
1225
14
        },
1226
14
        { &hf_openflow_link_down,
1227
14
            { "No physical link present", "openflow.link_down",
1228
14
               FT_BOOLEAN, 32, NULL, OFPPS_LINK_DOWN,
1229
14
               NULL, HFILL }
1230
14
        },
1231
14
        { &hf_openflow_10mb_hd,
1232
14
            { "10 Mb half-duplex rate support", "openflow.10mb_hd",
1233
14
               FT_BOOLEAN, 32, NULL, OFPPF_10MB_HD,
1234
14
               NULL, HFILL }
1235
14
        },
1236
14
        { &hf_openflow_10mb_fd,
1237
14
            { "10 Mb full-duplex rate support", "openflow.10mb_fd",
1238
14
               FT_BOOLEAN, 32, NULL, OFPPF_10MB_FD,
1239
14
               NULL, HFILL }
1240
14
        },
1241
14
        { &hf_openflow_100mb_hd,
1242
14
            { "100 Mb half-duplex rate support", "openflow.100mb_hd",
1243
14
               FT_BOOLEAN, 32, NULL, OFPPF_100MB_HD,
1244
14
               NULL, HFILL }
1245
14
        },
1246
14
        { &hf_openflow_100mb_fd,
1247
14
            { "100 Mb full-duplex rate support", "openflow.100mb_0fd",
1248
14
               FT_BOOLEAN, 32, NULL, OFPPF_100MB_FD,
1249
14
               NULL, HFILL }
1250
14
        },
1251
14
        { &hf_openflow_1gb_hd,
1252
14
            { "1 Gb half-duplex rate support", "openflow.1gb_hd",
1253
14
               FT_BOOLEAN, 32, NULL, OFPPF_1GB_HD,
1254
14
               NULL, HFILL }
1255
14
        },
1256
14
        { &hf_openflow_1gb_fd,
1257
14
            { "1 Gb full-duplex rate support", "openflow.1gb_fd",
1258
14
               FT_BOOLEAN, 32, NULL, OFPPF_1GB_FD,
1259
14
               NULL, HFILL }
1260
14
        },
1261
14
        { &hf_openflow_10gb_fd,
1262
14
            { "10 Gb full-duplex rate support", "openflow.10gb_fd",
1263
14
               FT_BOOLEAN, 32, NULL, OFPPF_10GB_FD,
1264
14
               NULL, HFILL }
1265
14
        },
1266
14
        { &hf_openflow_copper,
1267
14
            { "Copper medium", "openflow.copper",
1268
14
               FT_BOOLEAN, 32, NULL, OFPPF_COPPER,
1269
14
               NULL, HFILL }
1270
14
        },
1271
14
        { &hf_openflow_fiber,
1272
14
            { "Fiber medium", "openflow.fiber",
1273
14
               FT_BOOLEAN, 32, NULL, OFPPF_FIBER,
1274
14
               NULL, HFILL }
1275
14
        },
1276
14
        { &hf_openflow_autoneg,
1277
14
            { "Auto-negotiation", "openflow.autoneg",
1278
14
               FT_BOOLEAN, 32, NULL, OFPPF_AUTONEG,
1279
14
               NULL, HFILL }
1280
14
        },
1281
14
        { &hf_openflow_pause,
1282
14
            { "Pause", "openflow.pause",
1283
14
               FT_BOOLEAN, 32, NULL, OFPPF_PAUSE,
1284
14
               NULL, HFILL }
1285
14
        },
1286
14
        { &hf_openflow_pause_asym,
1287
14
            { "Asymmetric pause", "openflow.pause_asym",
1288
14
               FT_BOOLEAN, 32, NULL, OFPPF_PAUSE_ASYM,
1289
14
               NULL, HFILL }
1290
14
        },
1291
14
        { &hf_openflow_config_flags,
1292
14
            { "Config flags", "openflow.config_flags",
1293
14
               FT_UINT16, BASE_HEX, NULL, 0x0,
1294
14
               NULL, HFILL }
1295
14
        },
1296
14
        { &hf_openflow_miss_send_len,
1297
14
            { "Max bytes of packet", "openflow.miss_send_len",
1298
14
               FT_UINT16, BASE_HEX, NULL, 0x0,
1299
14
               NULL, HFILL }
1300
14
        },
1301
14
        { &hf_openflow_buffer_id,
1302
14
            { "Buffer Id", "openflow.buffer_id",
1303
14
               FT_UINT32, BASE_HEX, NULL, 0x0,
1304
14
               NULL, HFILL }
1305
14
        },
1306
14
        { &hf_openflow_total_len,
1307
14
            { "Total length", "openflow.total_len",
1308
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1309
14
               NULL, HFILL }
1310
14
        },
1311
14
        { &hf_openflow_in_port,
1312
14
            { "In port", "openflow.in_port",
1313
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1314
14
               NULL, HFILL }
1315
14
        },
1316
14
        { &hf_openflow_reason,
1317
14
            { "Reason", "openflow.reason",
1318
14
               FT_UINT8, BASE_DEC, VALS(openflow_reason_values), 0x0,
1319
14
               NULL, HFILL }
1320
14
        },
1321
1322
14
        { &hf_openflow_pkt_in_pad,
1323
14
            { "Pad", "openflow.pkt_in.pad",
1324
14
               FT_BYTES, BASE_NONE, NULL, 0x0,
1325
14
               NULL, HFILL }
1326
14
        },
1327
14
        { &hf_openflow_flow_removed_cookie,
1328
14
            { "Cookie", "openflow.flow_removed.cookie",
1329
14
               FT_UINT64, BASE_HEX, NULL, 0x0,
1330
14
               NULL, HFILL }
1331
14
        },
1332
14
        { &hf_openflow_flow_removed_priority,
1333
14
            { "Priority", "openflow.flow_removed.priority",
1334
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1335
14
               NULL, HFILL }
1336
14
        },
1337
14
        { &hf_openflow_flow_removed_reason,
1338
14
            { "Reason", "openflow.flow_removed.reason",
1339
14
               FT_UINT8, BASE_DEC, VALS(openflow_flow_removed_reason_values), 0x0,
1340
14
               NULL, HFILL }
1341
14
        },
1342
14
        { &hf_openflow_flow_removed_pad1,
1343
14
            { "Pad1", "openflow.flow_removed.pad1",
1344
14
               FT_UINT8, BASE_HEX, NULL, 0x0,
1345
14
               NULL, HFILL }
1346
14
        },
1347
14
        { &hf_openflow_flow_removed_duration_sec,
1348
14
            { "Duration sec", "openflow.flow_removed.duration_sec",
1349
14
               FT_UINT32, BASE_DEC, NULL, 0x0,
1350
14
               NULL, HFILL }
1351
14
        },
1352
14
        { &hf_openflow_flow_removed_duration_nsec,
1353
14
            { "Duration nsec", "openflow.flow_removed.duration_nsec",
1354
14
               FT_UINT32, BASE_DEC, NULL, 0x0,
1355
14
               NULL, HFILL }
1356
14
        },
1357
14
        { &hf_openflow_flow_removed_idle_timeout,
1358
14
            { "Idle timeout", "openflow.flow_removed.idle_timeout",
1359
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1360
14
               NULL, HFILL }
1361
14
        },
1362
14
        { &hf_openflow_flow_removed_pad2,
1363
14
            { "Pad2", "openflow.flow_removed.pad2",
1364
14
               FT_UINT16, BASE_HEX, NULL, 0x0,
1365
14
               NULL, HFILL }
1366
14
        },
1367
14
        { &hf_openflow_flow_removed_packet_count,
1368
14
            { "Packet count", "openflow.flow_removed.packet_count",
1369
14
               FT_UINT64, BASE_DEC, NULL, 0x0,
1370
14
               NULL, HFILL }
1371
14
        },
1372
14
        { &hf_openflow_flow_removed_byte_count,
1373
14
            { "Byte count", "openflow.flow_removed.byte_count",
1374
14
               FT_UINT64, BASE_DEC, NULL, 0x0,
1375
14
               NULL, HFILL }
1376
14
        },
1377
14
        { &hf_openflow_table_id,
1378
14
            { "Table Id", "openflow.table_id",
1379
14
               FT_UINT8, BASE_DEC, NULL, 0x0,
1380
14
               NULL, HFILL }
1381
14
        },
1382
14
        { &hf_openflow_cookie,
1383
14
            { "Cookie", "openflow.cookie",
1384
14
               FT_UINT64, BASE_HEX, NULL, 0x0,
1385
14
               NULL, HFILL }
1386
14
        },
1387
#if 0
1388
        { &hf_openflow_cookie_mask,
1389
            { "Cookie mask", "openflow.cookie_mask",
1390
               FT_UINT64, BASE_HEX, NULL, 0x0,
1391
               NULL, HFILL }
1392
        },
1393
#endif
1394
14
        { &hf_openflow_features_reply_pad,
1395
14
            { "Pad", "openflow.features_reply.pad",
1396
14
               FT_BYTES, BASE_NONE, NULL, 0x0,
1397
14
               NULL, HFILL }
1398
14
        },
1399
14
        { &hf_openflow_actions_len,
1400
14
            { "Actions length", "openflow.actions_len",
1401
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1402
14
               NULL, HFILL }
1403
14
        },
1404
14
        { &hf_openflow_action_type,
1405
14
            { "Actions type", "openflow.action_typ",
1406
14
               FT_UINT16, BASE_DEC, VALS(openflow_action_values), 0x0,
1407
14
               NULL, HFILL }
1408
14
        },
1409
14
        { &hf_openflow_action_len,
1410
14
            { "Action length", "openflow.action_len",
1411
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1412
14
               NULL, HFILL }
1413
14
        },
1414
14
        { &hf_openflow_output_port,
1415
14
            { "Output port", "openflow.output_port",
1416
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1417
14
               NULL, HFILL }
1418
14
        },
1419
14
        { &hf_openflow_max_len,
1420
14
            { "Max length", "openflow.max_len",
1421
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1422
14
               NULL, HFILL }
1423
14
        },
1424
14
        { &hf_openflow_wildcards,
1425
14
            { "Wildcards", "openflow.wildcards",
1426
14
               FT_UINT32, BASE_DEC, NULL, 0x0,
1427
14
               NULL, HFILL }
1428
14
        },
1429
14
        { &hf_openflow_command,
1430
14
            { "Command", "openflow.command",
1431
14
               FT_UINT16, BASE_DEC, VALS(openflow_command_values), 0x0,
1432
14
               NULL, HFILL }
1433
14
        },
1434
14
        { &hf_openflow_eth_src,
1435
14
            { "Ethernet source address", "openflow.eth_src",
1436
14
               FT_ETHER, BASE_NONE, NULL, 0x0,
1437
14
               NULL, HFILL }
1438
14
        },
1439
14
        { &hf_openflow_eth_dst,
1440
14
            { "Ethernet destination address", "openflow.eth_dst",
1441
14
               FT_ETHER, BASE_NONE, NULL, 0x0,
1442
14
               NULL, HFILL }
1443
14
        },
1444
14
        { &hf_openflow_dl_vlan,
1445
14
            { "Input VLAN id", "openflow.dl_vlan",
1446
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1447
14
               NULL, HFILL }
1448
14
        },
1449
14
        { &hf_openflow_dl_vlan_pcp,
1450
14
            { "Input VLAN priority", "openflow.dl_vlan_pcp",
1451
14
               FT_UINT8, BASE_DEC, NULL, 0x0,
1452
14
               NULL, HFILL }
1453
14
        },
1454
14
        { &hf_openflow_ofp_match_pad,
1455
14
            { "Pad", "openflow.ofp_match.pad",
1456
14
              FT_BYTES, BASE_NONE, NULL, 0x0,
1457
14
               NULL, HFILL }
1458
14
        },
1459
14
        { &hf_openflow_match_dl_type,
1460
14
            { "Dl type", "openflow.ofp_match.dl_type",
1461
14
              FT_UINT16, BASE_DEC, NULL, 0x0,
1462
14
               NULL, HFILL }
1463
14
        },
1464
14
        { &hf_openflow_ofp_match_tos,
1465
14
            { "IP ToS", "openflow.ofp_match.tos",
1466
14
              FT_UINT8, BASE_DEC, NULL, 0x0,
1467
14
               NULL, HFILL }
1468
14
        },
1469
14
        { &hf_openflow_ofp_match_nw_proto,
1470
14
            { "IP protocol", "openflow.ofp_match.nw_proto",
1471
14
              FT_UINT8, BASE_DEC, NULL, 0x0,
1472
14
               NULL, HFILL }
1473
14
        },
1474
14
        { &hf_openflow_ofp_source_addr,
1475
14
            { "Source Address", "openflow.ofp_match.source_addr",
1476
14
              FT_IPv4, BASE_NONE, NULL, 0x0,
1477
14
               NULL, HFILL }
1478
14
        },
1479
14
        { &hf_openflow_ofp_dest_addr,
1480
14
            { "Destination Address", "openflow.ofp_match.dest_addr",
1481
14
              FT_IPv4, BASE_NONE, NULL, 0x0,
1482
14
               NULL, HFILL }
1483
14
        },
1484
14
        { &hf_openflow_ofp_source_port,
1485
14
            { "Source Port", "openflow.ofp_match.source_port",
1486
14
              FT_UINT16, BASE_DEC, NULL, 0x0,
1487
14
               NULL, HFILL }
1488
14
        },
1489
14
        { &hf_openflow_ofp_dest_port,
1490
14
            { "Destination Port", "openflow.ofp_match.dest_port",
1491
14
              FT_UINT16, BASE_DEC, NULL, 0x0,
1492
14
               NULL, HFILL }
1493
14
        },
1494
14
        { &hf_openflow_idle_timeout,
1495
14
            { "Idle time-out", "openflow.idle_timeout",
1496
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1497
14
               NULL, HFILL }
1498
14
        },
1499
14
        { &hf_openflow_hard_timeout,
1500
14
            { "hard time-out", "openflow.hard_timeout",
1501
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1502
14
               NULL, HFILL }
1503
14
        },
1504
14
        { &hf_openflow_priority,
1505
14
            { "Priority", "openflow.priority",
1506
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1507
14
               NULL, HFILL }
1508
14
        },
1509
14
        { &hf_openflow_out_port,
1510
14
            { "Out port", "openflow.out_port",
1511
14
               FT_UINT32, BASE_DEC, NULL, 0x0,
1512
14
               NULL, HFILL }
1513
14
        },
1514
#if 0
1515
        { &hf_openflow_out_group,
1516
            { "Out group", "openflow.out_group",
1517
               FT_UINT32, BASE_DEC, NULL, 0x0,
1518
               NULL, HFILL }
1519
        },
1520
#endif
1521
14
        { &hf_openflow_flags,
1522
14
            { "Flags", "openflow.flags",
1523
14
               FT_UINT16, BASE_DEC, NULL, 0x0,
1524
14
               NULL, HFILL }
1525
14
        },
1526
14
        { &hf_openflow_v1_stats_type,
1527
14
            { "Type", "openflow.stats.type",
1528
14
              FT_UINT16, BASE_DEC, VALS(openflow_stats_type_values), 0x0,
1529
14
              NULL, HFILL }
1530
14
        },
1531
14
        { &hf_openflow_v1_flow_stats_request_pad,
1532
14
            { "Pad", "openflow.stats.request_pad",
1533
14
              FT_UINT8, BASE_DEC, NULL, 0x0,
1534
14
              NULL, HFILL }
1535
14
        },
1536
14
    };
1537
1538
14
    static int *ett[] = {
1539
14
        &ett_openflow,
1540
14
        &ett_openflow_path_id,
1541
14
        &ett_openflow_cap,
1542
14
        &ett_openflow_act,
1543
14
        &ett_openflow_port,
1544
14
        &ett_openflow_port_cnf,
1545
14
        &ett_openflow_port_state,
1546
14
        &ett_openflow_port_cf
1547
14
    };
1548
1549
14
    static ei_register_info ei[] = {
1550
#if 0
1551
        { &ei_openflow_undecoded_data, { "openflow.undecoded_data", PI_UNDECODED, PI_WARN, "Data not dissected yet", EXPFILL }},
1552
#endif
1553
14
        { &ei_openflow_action_type, { "openflow.action_typ.undecoded", PI_UNDECODED, PI_WARN, "Action not dissected yet", EXPFILL }},
1554
14
        { &ei_openflow_1_0_type, { "openflow_1_0.type.undecoded", PI_UNDECODED, PI_WARN, "Message data not dissected yet", EXPFILL }},
1555
14
    };
1556
1557
14
    expert_module_t* expert_openflow_v1;
1558
1559
    /* Register the protocol name and description */
1560
14
    proto_openflow_v1 = proto_register_protocol("OpenFlow 1.0", "openflow_v1", "openflow_v1");
1561
1562
14
    register_dissector("openflow_v1", dissect_openflow_v1, proto_openflow_v1);
1563
1564
    /* Required function calls to register the header fields and subtrees */
1565
14
    proto_register_field_array(proto_openflow_v1, hf, array_length(hf));
1566
14
    proto_register_subtree_array(ett, array_length(ett));
1567
14
    expert_openflow_v1 = expert_register_protocol(proto_openflow_v1);
1568
14
    expert_register_field_array(expert_openflow_v1, ei, array_length(ei));
1569
14
}
1570
1571
void
1572
proto_reg_handoff_openflow_v1(void)
1573
14
{
1574
14
    eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_openflow_v1);
1575
14
}
1576
1577
/*
1578
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1579
 *
1580
 * Local variables:
1581
 * c-basic-offset: 4
1582
 * tab-width: 8
1583
 * indent-tabs-mode: nil
1584
 * End:
1585
 *
1586
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1587
 * :indentSize=4:tabSize=8:noTabs=true:
1588
 */