Coverage Report

Created: 2025-02-15 06:25

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