File: | builds/wireshark/wireshark/epan/dissectors/packet-geneve.c |
Warning: | line 245, column 13 Value stored to 'offset' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* packet-geneve.c |
2 | * Routines for Geneve - Generic Network Virtualization Encapsulation |
3 | * https://tools.ietf.org/html/draft-ietf-nvo3-geneve |
4 | * |
5 | * Copyright (c) 2024 cPacket Networks, Inc. All Rights Reserved. |
6 | * Author: Martin Greenberg <mgreenberg@cpacket.com> |
7 | * |
8 | * Copyright (c) 2014 VMware, Inc. All Rights Reserved. |
9 | * Author: Jesse Gross <jesse@nicira.com> |
10 | * |
11 | * Copyright 2021, Atul Sharma <asharm37@ncsu.edu> |
12 | * |
13 | * Wireshark - Network traffic analyzer |
14 | * By Gerald Combs <gerald@wireshark.org> |
15 | * Copyright 1998 Gerald Combs |
16 | * |
17 | * SPDX-License-Identifier: GPL-2.0-or-later |
18 | */ |
19 | |
20 | |
21 | #include "config.h" |
22 | |
23 | #include <epan/packet.h> |
24 | #include <epan/etypes.h> |
25 | #include <epan/expert.h> |
26 | #include <epan/value_string.h> |
27 | #include <epan/tfs.h> |
28 | #include <epan/unit_strings.h> |
29 | |
30 | #define UDP_PORT_GENEVE6081 6081 |
31 | #define GENEVE_VER0 0 |
32 | |
33 | #define VER_SHIFT6 6 |
34 | #define HDR_OPTS_LEN_MASK0x3F 0x3F |
35 | |
36 | #define FLAG_OAM(1 << 7) (1 << 7) |
37 | |
38 | #define OPT_TYPE_CRITICAL(1 << 7) (1 << 7) |
39 | #define OPT_FLAGS_SHIFT5 5 |
40 | #define OPT_LEN_MASK0x1F 0x1F |
41 | |
42 | static const range_string class_id_names[] = { |
43 | { 0, 0xFF, "Standard" }, |
44 | { 0x0100, 0x0100, "Linux" }, |
45 | { 0x0101, 0x0101, "Open vSwitch" }, |
46 | { 0x0102, 0x0102, "Open Virtual Networking (OVN)" }, |
47 | { 0x0103, 0x0103, "In-band Network Telemetry (INT)" }, |
48 | { 0x0104, 0x0104, "VMware" }, |
49 | { 0x0105, 0x0105, "Amazon.com, Inc."}, |
50 | { 0x0106, 0x0106, "Cisco Systems, Inc." }, |
51 | { 0x0107, 0x0107, "Oracle Corporation" }, |
52 | { 0x0108, 0x0110, "Amazon.com, Inc." }, |
53 | { 0x0111, 0x0118, "IBM" }, |
54 | { 0x0119, 0x0128, "Ericsson" }, |
55 | { 0x0129, 0x0129, "Oxide Computer Company" }, |
56 | { 0x0130, 0x0131, "Cisco Systems, Inc." }, |
57 | { 0x0132, 0x0135, "Google LLC" }, |
58 | { 0x0136, 0x0136, "InfoQuick Global Connection Tech Ltd." }, |
59 | { 0x0137, 0x0163, "Unssigned" }, |
60 | { 0x0164, 0x0164, "cPacket Networks, Inc." }, |
61 | { 0x0165, 0xFEFF, "Unassigned" }, |
62 | { 0xFFF0, 0xFFFF, "Experimental" }, |
63 | { 0, 0, NULL((void*)0) } |
64 | }; |
65 | |
66 | #define GENEVE_GCP_VNID0x013201 0x013201 |
67 | #define GENEVE_GCP_ENDPOINT0x013202 0x013202 |
68 | #define GENEVE_GCP_PROFILE0x013203 0x013203 |
69 | #define GENEVE_CPACKET_METADATA0x016400 0x016400 |
70 | |
71 | static const val64_string option_names[] = { |
72 | { GENEVE_GCP_VNID0x013201, "GCP Virtual Network ID" }, |
73 | { GENEVE_GCP_ENDPOINT0x013202, "GCP Endpoint ID" }, |
74 | { GENEVE_GCP_PROFILE0x013203, "GCP Profile ID" }, |
75 | { GENEVE_CPACKET_METADATA0x016400, "cPacket Meta-data" }, |
76 | { 0, NULL((void*)0) } |
77 | }; |
78 | |
79 | void proto_register_geneve(void); |
80 | void proto_reg_handoff_geneve(void); |
81 | |
82 | static dissector_handle_t geneve_handle; |
83 | |
84 | static int proto_geneve; |
85 | |
86 | static int hf_geneve_version; |
87 | static int hf_geneve_flags; |
88 | static int hf_geneve_flag_oam; |
89 | static int hf_geneve_flag_critical; |
90 | static int hf_geneve_flag_reserved; |
91 | static int hf_geneve_proto_type; |
92 | static int hf_geneve_vni; |
93 | static int hf_geneve_reserved; |
94 | static int hf_geneve_options; |
95 | static int hf_geneve_option_class; |
96 | static int hf_geneve_option_type; |
97 | static int hf_geneve_option_type_critical; |
98 | static int hf_geneve_option_flags; |
99 | static int hf_geneve_option_flags_reserved; |
100 | static int hf_geneve_option_length; |
101 | static int hf_geneve_option; |
102 | static int hf_geneve_opt_gcp_vnid; |
103 | static int hf_geneve_opt_gcp_reserved; |
104 | static int hf_geneve_opt_gcp_direction; |
105 | static int hf_geneve_opt_gcp_endpoint; |
106 | static int hf_geneve_opt_gcp_profile; |
107 | static int hf_geneve_opt_cpkt_seqnum; |
108 | static int hf_geneve_opt_cpkt_origlen; |
109 | static int hf_geneve_opt_cpkt_reserved; |
110 | static int hf_geneve_opt_cpkt_timestamp; |
111 | static int hf_geneve_opt_cpkt_ts_sec; |
112 | static int hf_geneve_opt_cpkt_ts_nsec; |
113 | static int hf_geneve_opt_cpkt_ts_fracns; |
114 | static int hf_geneve_opt_cpkt_version; |
115 | static int hf_geneve_opt_cpkt_devid; |
116 | static int hf_geneve_opt_cpkt_portid; |
117 | |
118 | static int hf_geneve_opt_unknown_data; |
119 | |
120 | static int ett_geneve; |
121 | static int ett_geneve_flags; |
122 | static int ett_geneve_opt_flags; |
123 | static int ett_geneve_options; |
124 | static int ett_geneve_opt_data; |
125 | |
126 | static expert_field ei_geneve_ver_unknown; |
127 | static expert_field ei_geneve_opt_len_invalid; |
128 | |
129 | static dissector_table_t ethertype_dissector_table; |
130 | |
131 | static const struct true_false_string tfs_geneve_gcp_direction = { |
132 | "Egress", |
133 | "Ingress" |
134 | }; |
135 | |
136 | static const char * |
137 | format_option_name(wmem_allocator_t *scope, uint16_t opt_class, uint8_t opt_type) |
138 | { |
139 | const char *name; |
140 | |
141 | name = wmem_strdup_printf(scope, |
142 | "%s, Class: %s (0x%04x) Type: 0x%02x", |
143 | val64_to_str_const(((uint64_t)opt_class << 8) | opt_type, |
144 | option_names, "Unknown"), |
145 | rval_to_str_const(opt_class, class_id_names, "Unknown"), |
146 | opt_class, opt_type); |
147 | |
148 | return name; |
149 | } |
150 | |
151 | static void |
152 | dissect_option(wmem_allocator_t *scope, tvbuff_t *tvb, proto_tree *opts_tree, int offset, |
153 | uint16_t opt_class, uint8_t opt_type, int len) |
154 | { |
155 | proto_item *opt_item, *type_item, *hidden_item, *flag_item; |
156 | proto_tree *opt_tree, *flag_tree; |
157 | const char *critical; |
158 | uint8_t flags; |
159 | |
160 | critical = opt_type & OPT_TYPE_CRITICAL(1 << 7) ? "Critical" : "Non-critical"; |
161 | |
162 | opt_item = proto_tree_add_item(opts_tree, hf_geneve_option, |
163 | tvb, offset, len, ENC_NA0x00000000); |
164 | proto_item_set_text(opt_item, "%s (%s)", |
165 | format_option_name(scope, opt_class, opt_type), |
166 | critical); |
167 | |
168 | opt_tree = proto_item_add_subtree(opt_item, ett_geneve_opt_data); |
169 | |
170 | proto_tree_add_item(opt_tree, hf_geneve_option_class, tvb, |
171 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
172 | offset += 2; |
173 | |
174 | type_item = proto_tree_add_item(opt_tree, hf_geneve_option_type, tvb, |
175 | offset, 1, ENC_BIG_ENDIAN0x00000000); |
176 | proto_item_append_text(type_item, " (%s)", critical); |
177 | hidden_item = proto_tree_add_item(opt_tree, hf_geneve_option_type_critical, |
178 | tvb, offset, 1, ENC_BIG_ENDIAN0x00000000); |
179 | proto_item_set_hidden(hidden_item); |
180 | offset += 1; |
181 | |
182 | flags = tvb_get_uint8(tvb, offset) >> OPT_FLAGS_SHIFT5; |
183 | flag_item = proto_tree_add_uint(opt_tree, hf_geneve_option_flags, tvb, |
184 | offset, 1, flags); |
185 | flag_tree = proto_item_add_subtree(flag_item, ett_geneve_opt_flags); |
186 | proto_tree_add_item(flag_tree, hf_geneve_option_flags_reserved, tvb, |
187 | offset, 1, ENC_BIG_ENDIAN0x00000000); |
188 | if (flags) { |
189 | proto_item_append_text(flag_item, " (RSVD)"); |
190 | } else { |
191 | proto_item_set_hidden(flag_item); |
192 | } |
193 | |
194 | proto_tree_add_uint(opt_tree, hf_geneve_option_length, tvb, offset, 1, len); |
195 | offset += 1; |
196 | |
197 | switch (((uint64_t)opt_class << 8) | opt_type) { |
198 | case GENEVE_GCP_VNID0x013201: |
199 | proto_tree_add_bits_item(opt_tree, hf_geneve_opt_gcp_vnid, tvb, offset * 8, |
200 | 28, ENC_BIG_ENDIAN0x00000000); |
201 | proto_tree_add_item(opt_tree, hf_geneve_opt_gcp_direction, tvb, offset, |
202 | 4, ENC_NA0x00000000); |
203 | proto_tree_add_item(opt_tree, hf_geneve_opt_gcp_reserved, tvb, offset, |
204 | 4, ENC_NA0x00000000); |
205 | break; |
206 | case GENEVE_GCP_ENDPOINT0x013202: |
207 | proto_tree_add_item(opt_tree, hf_geneve_opt_gcp_endpoint, tvb, offset, |
208 | len - 4, ENC_NA0x00000000); |
209 | break; |
210 | case GENEVE_GCP_PROFILE0x013203: |
211 | proto_tree_add_item(opt_tree, hf_geneve_opt_gcp_profile, tvb, offset, |
212 | len - 4, ENC_BIG_ENDIAN0x00000000); |
213 | break; |
214 | case GENEVE_CPACKET_METADATA0x016400: |
215 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_seqnum, tvb, offset, |
216 | 4, ENC_BIG_ENDIAN0x00000000); |
217 | offset += 4; |
218 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_origlen, tvb, offset, |
219 | 2, ENC_BIG_ENDIAN0x00000000); |
220 | offset += 2; |
221 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_reserved, tvb, offset, |
222 | 1, ENC_BIG_ENDIAN0x00000000); |
223 | offset += 1; |
224 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_version, tvb, offset, |
225 | 1, ENC_BIG_ENDIAN0x00000000); |
226 | offset += 1; |
227 | // PTPv2 timestamp has more resolution than NStime supports/displays, |
228 | // but parse appropriate subsection of into NStime for user convenience |
229 | proto_tree_add_time_item(opt_tree, hf_geneve_opt_cpkt_timestamp, tvb, offset+2, 8, |
230 | ENC_TIME_SECS_NSECS0x00000000, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
231 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_ts_sec, tvb, offset, |
232 | 6, ENC_BIG_ENDIAN0x00000000); |
233 | offset += 6; |
234 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_ts_nsec, tvb, offset, |
235 | 4, ENC_BIG_ENDIAN0x00000000); |
236 | offset += 4; |
237 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_ts_fracns, tvb, offset, |
238 | 2, ENC_BIG_ENDIAN0x00000000); |
239 | offset += 2; |
240 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_devid, tvb, offset, |
241 | 2, ENC_BIG_ENDIAN0x00000000); |
242 | offset += 2; |
243 | proto_tree_add_item(opt_tree, hf_geneve_opt_cpkt_portid, tvb, offset, |
244 | 2, ENC_BIG_ENDIAN0x00000000); |
245 | offset += 2; |
Value stored to 'offset' is never read | |
246 | break; |
247 | default: |
248 | proto_tree_add_item(opt_tree, hf_geneve_opt_unknown_data, tvb, offset, |
249 | len - 4, ENC_NA0x00000000); |
250 | break; |
251 | } |
252 | } |
253 | |
254 | static void |
255 | dissect_geneve_options(tvbuff_t *tvb, packet_info *pinfo, |
256 | proto_tree *geneve_tree, int offset, int len) |
257 | { |
258 | proto_item *opts_item; |
259 | proto_tree *opts_tree; |
260 | uint16_t opt_class; |
261 | uint8_t opt_type; |
262 | uint8_t opt_len; |
263 | |
264 | opts_item = proto_tree_add_item(geneve_tree, hf_geneve_options, tvb, |
265 | offset, len, ENC_NA0x00000000); |
266 | proto_item_set_text(opts_item, "Options: (%u bytes)", len); |
267 | opts_tree = proto_item_add_subtree(opts_item, ett_geneve_options); |
268 | |
269 | while (len > 0) { |
270 | opt_class = tvb_get_ntohs(tvb, offset); |
271 | opt_type = tvb_get_uint8(tvb, offset + 2); |
272 | opt_len = 4 + ((tvb_get_uint8(tvb, offset + 3) & OPT_LEN_MASK0x1F) * 4); |
273 | |
274 | if (opt_len > len) { |
275 | proto_tree_add_expert_format(opts_tree, pinfo, |
276 | &ei_geneve_opt_len_invalid, tvb, |
277 | offset + 3, 1, |
278 | "%s (length of %u is past end of options)", |
279 | format_option_name(pinfo->pool, opt_class, opt_type), |
280 | opt_len); |
281 | return; |
282 | } |
283 | |
284 | dissect_option(pinfo->pool, tvb, opts_tree, offset, opt_class, opt_type, opt_len); |
285 | |
286 | offset += opt_len; |
287 | len -= opt_len; |
288 | }; |
289 | } |
290 | |
291 | static int |
292 | dissect_geneve(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused))) |
293 | { |
294 | proto_item *ti, *rsvd_item; |
295 | proto_tree *geneve_tree; |
296 | tvbuff_t *next_tvb; |
297 | int offset = 0; |
298 | uint8_t ver_opt; |
299 | uint8_t ver; |
300 | uint8_t flags; |
301 | uint16_t proto_type; |
302 | int opts_len; |
303 | static int * const flag_fields[] = { |
304 | &hf_geneve_flag_oam, |
305 | &hf_geneve_flag_critical, |
306 | &hf_geneve_flag_reserved, |
307 | NULL((void*)0) |
308 | }; |
309 | |
310 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Geneve"); |
311 | col_clear(pinfo->cinfo, COL_INFO); |
312 | |
313 | ti = proto_tree_add_item(tree, proto_geneve, tvb, offset, -1, ENC_NA0x00000000); |
314 | geneve_tree = proto_item_add_subtree(ti, ett_geneve); |
315 | |
316 | /* Version. */ |
317 | ver_opt = tvb_get_uint8(tvb, offset); |
318 | ver = ver_opt >> VER_SHIFT6; |
319 | proto_tree_add_uint(geneve_tree, hf_geneve_version, tvb, |
320 | offset, 1, ver); |
321 | |
322 | if (ver != GENEVE_VER0) { |
323 | proto_tree_add_expert_format(geneve_tree, pinfo, |
324 | &ei_geneve_ver_unknown, tvb, offset, 1, |
325 | "Unknown version %u", ver); |
326 | col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown Geneve version %u", ver); |
327 | } |
328 | |
329 | /* Option length. */ |
330 | opts_len = (ver_opt & HDR_OPTS_LEN_MASK0x3F) * 4; |
331 | proto_tree_add_uint(geneve_tree, hf_geneve_option_length, tvb, |
332 | offset, 1, opts_len); |
333 | offset += 1; |
334 | |
335 | /* Flags. */ |
336 | flags = tvb_get_uint8(tvb, offset); |
337 | proto_tree_add_bitmask(geneve_tree, tvb, offset, hf_geneve_flags, ett_geneve_flags, flag_fields, ENC_BIG_ENDIAN0x00000000); |
338 | offset += 1; |
339 | |
340 | /* Protocol Type. */ |
341 | proto_tree_add_item(geneve_tree, hf_geneve_proto_type, tvb, |
342 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
343 | |
344 | proto_type = tvb_get_ntohs(tvb, offset); |
345 | col_add_fstr(pinfo->cinfo, COL_INFO, "Encapsulated %s", |
346 | val_to_str(proto_type, etype_vals, "0x%04x (unknown)")); |
347 | |
348 | offset += 2; |
349 | |
350 | /* VNI. */ |
351 | proto_tree_add_item(geneve_tree, hf_geneve_vni, tvb, offset, 3, |
352 | ENC_BIG_ENDIAN0x00000000); |
353 | proto_item_append_text(ti, ", VNI: 0x%06x%s", tvb_get_ntoh24(tvb, offset), |
354 | flags & FLAG_OAM(1 << 7) ? ", OAM" : ""); |
355 | offset += 3; |
356 | |
357 | /* Reserved. */ |
358 | rsvd_item = proto_tree_add_item(geneve_tree, hf_geneve_reserved, tvb, |
359 | offset, 1, ENC_BIG_ENDIAN0x00000000); |
360 | if (!tvb_get_uint8(tvb, offset)) { |
361 | proto_item_set_hidden(rsvd_item); |
362 | } |
363 | offset += 1; |
364 | |
365 | /* Options. */ |
366 | if (tree && opts_len) { |
367 | dissect_geneve_options(tvb, pinfo, geneve_tree, offset, opts_len); |
368 | } |
369 | offset += opts_len; |
370 | |
371 | proto_item_set_len(ti, offset); |
372 | |
373 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
374 | if (!dissector_try_uint(ethertype_dissector_table, proto_type, next_tvb, pinfo, tree)) |
375 | call_data_dissector(next_tvb, pinfo, tree); |
376 | |
377 | return tvb_captured_length(tvb); |
378 | } |
379 | |
380 | /* Register Geneve with Wireshark */ |
381 | void |
382 | proto_register_geneve(void) |
383 | { |
384 | static hf_register_info hf[] = { |
385 | { &hf_geneve_version, |
386 | { "Version", "geneve.version", |
387 | FT_UINT8, BASE_DEC, NULL((void*)0), 0x00, |
388 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
389 | }, |
390 | { &hf_geneve_flags, |
391 | { "Flags", "geneve.flags", |
392 | FT_UINT8, BASE_HEX, NULL((void*)0), 0x00, |
393 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
394 | }, |
395 | { &hf_geneve_flag_oam, |
396 | { "Operations, Administration and Management Frame", "geneve.flags.oam", |
397 | FT_BOOLEAN, 8, NULL((void*)0), 0x80, |
398 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
399 | }, |
400 | { &hf_geneve_flag_critical, |
401 | { "Critical Options Present", "geneve.flags.critical", |
402 | FT_BOOLEAN, 8, NULL((void*)0), 0x40, |
403 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
404 | }, |
405 | { &hf_geneve_flag_reserved, |
406 | { "Reserved", "geneve.flags.reserved", |
407 | FT_BOOLEAN, 8, NULL((void*)0), 0x3F, |
408 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
409 | }, |
410 | { &hf_geneve_proto_type, |
411 | { "Protocol Type", "geneve.proto_type", |
412 | FT_UINT16, BASE_HEX, VALS(etype_vals)((0 ? (const struct _value_string*)0 : ((etype_vals)))), 0x0, |
413 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
414 | }, |
415 | { &hf_geneve_vni, |
416 | { "Virtual Network Identifier (VNI)", "geneve.vni", |
417 | FT_UINT24, BASE_HEX_DEC, NULL((void*)0), 0x0, |
418 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
419 | }, |
420 | { &hf_geneve_reserved, |
421 | { "Reserved", "geneve.reserved", |
422 | FT_UINT8, BASE_HEX, NULL((void*)0), 0x00, |
423 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
424 | }, |
425 | { &hf_geneve_options, |
426 | { "Geneve Options", "geneve.options", |
427 | FT_BYTES, BASE_NONE, NULL((void*)0), 0x00, |
428 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
429 | }, |
430 | { &hf_geneve_option_class, |
431 | { "Class", "geneve.option.class", |
432 | FT_UINT16, BASE_HEX | BASE_RANGE_STRING0x00000100, RVALS(class_id_names)((0 ? (const struct _range_string*)0 : ((class_id_names)))), 0x00, |
433 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
434 | }, |
435 | { &hf_geneve_option_type, |
436 | { "Type", "geneve.option.type", |
437 | FT_UINT8, BASE_HEX, NULL((void*)0), 0x00, |
438 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
439 | }, |
440 | { &hf_geneve_option_type_critical, |
441 | { "Critical Option", "geneve.option.type.critical", |
442 | FT_BOOLEAN, 8, NULL((void*)0), 0x80, |
443 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
444 | }, |
445 | { &hf_geneve_option_flags, |
446 | { "Flags", "geneve.option.flags", |
447 | FT_UINT8, BASE_HEX, NULL((void*)0), 0x00, |
448 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
449 | }, |
450 | { &hf_geneve_option_flags_reserved, |
451 | { "Reserved", "geneve.option.flags.reserved", |
452 | FT_BOOLEAN, 8, NULL((void*)0), 0xE0, |
453 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
454 | }, |
455 | { &hf_geneve_option_length, |
456 | { "Length", "geneve.option.length", |
457 | FT_UINT8, BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytes)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytes )))), 0x00, |
458 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
459 | }, |
460 | { &hf_geneve_option, |
461 | { "Option", "geneve.option", |
462 | FT_BYTES, BASE_NONE, NULL((void*)0), 0x00, |
463 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
464 | }, |
465 | { &hf_geneve_opt_gcp_vnid, |
466 | { "GCP Virtual Network ID", "geneve.option.gcp.vnid", |
467 | FT_UINT32, BASE_DEC, NULL((void*)0), 0x00, |
468 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
469 | }, |
470 | { &hf_geneve_opt_gcp_reserved, |
471 | { "GCP Reserved bits", "geneve.option.gcp.reserved", |
472 | FT_BOOLEAN, 32, NULL((void*)0), 0x0000000E, |
473 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
474 | }, |
475 | { &hf_geneve_opt_gcp_direction, |
476 | { "GCP Traffic Direction", "geneve.option.gcp.direction", |
477 | FT_BOOLEAN, 32, TFS(&tfs_geneve_gcp_direction)((0 ? (const struct true_false_string*)0 : ((&tfs_geneve_gcp_direction )))), 0x00000001, |
478 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
479 | }, |
480 | { &hf_geneve_opt_gcp_endpoint, |
481 | { "GCP Endpoint ID", "geneve.option.gcp.endpoint", |
482 | FT_BYTES, BASE_NONE, NULL((void*)0), 0x00, |
483 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
484 | }, |
485 | { &hf_geneve_opt_gcp_profile, |
486 | { "GCP Profile ID", "geneve.option.gcp.profile", |
487 | FT_UINT64, BASE_DEC, NULL((void*)0), 0x00, |
488 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
489 | }, |
490 | { &hf_geneve_opt_cpkt_seqnum, |
491 | { "cPacket Packet ID", "geneve.option.cPacket.packetid", |
492 | FT_UINT32, BASE_DEC, NULL((void*)0), 0x00, |
493 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
494 | }, |
495 | { &hf_geneve_opt_cpkt_origlen, |
496 | { "cPacket Original length", "geneve.option.cPacket.orig_len", |
497 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x00, |
498 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
499 | }, |
500 | { &hf_geneve_opt_cpkt_reserved, |
501 | { "cPacket Reserved", "geneve.option.cPacket.reserved", |
502 | FT_UINT8, BASE_HEX, NULL((void*)0), 0x00, |
503 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
504 | }, |
505 | { &hf_geneve_opt_cpkt_version, |
506 | { "cPacket Metadata version", "geneve.option.cPacket.version", |
507 | FT_UINT8, BASE_DEC, NULL((void*)0), 0x00, |
508 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
509 | }, |
510 | { &hf_geneve_opt_cpkt_timestamp, |
511 | { "cPacket Timestamp", "geneve.option.cPacket.timestamp", |
512 | FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL((void*)0), 0x00, |
513 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
514 | }, |
515 | { &hf_geneve_opt_cpkt_ts_sec, |
516 | { "cPacket Timestamp (s)", "geneve.option.cPacket.ts_sec", |
517 | FT_UINT48, BASE_DEC, NULL((void*)0), 0x00, |
518 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
519 | }, |
520 | { &hf_geneve_opt_cpkt_ts_nsec, |
521 | { "cPacket Timestamp (ns)", "geneve.option.cPacket.ts_nsec", |
522 | FT_UINT32, BASE_DEC, NULL((void*)0), 0x00, |
523 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
524 | }, |
525 | { &hf_geneve_opt_cpkt_ts_fracns, |
526 | { "cPacket Timestamp (frac. ns)", "geneve.option.cPacket.ts_fracns", |
527 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x00, |
528 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
529 | }, |
530 | { &hf_geneve_opt_cpkt_devid, |
531 | { "cPacket Device ID", "geneve.option.cPacket.device_id", |
532 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x00, |
533 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
534 | }, |
535 | { &hf_geneve_opt_cpkt_portid, |
536 | { "cPacket Port ID", "geneve.option.cPacket.port_id", |
537 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x00, |
538 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
539 | }, |
540 | { &hf_geneve_opt_unknown_data, |
541 | { "Unknown Option Data", "geneve.option.unknown.data", |
542 | FT_BYTES, BASE_NONE, NULL((void*)0), 0x00, |
543 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
544 | }, |
545 | }; |
546 | |
547 | static int *ett[] = { |
548 | &ett_geneve, |
549 | &ett_geneve_flags, |
550 | &ett_geneve_options, |
551 | &ett_geneve_opt_flags, |
552 | &ett_geneve_opt_data, |
553 | }; |
554 | |
555 | static ei_register_info ei[] = { |
556 | { &ei_geneve_ver_unknown, { "geneve.version.unknown", |
557 | PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Unknown version", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE , ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void *)0)}} }}, |
558 | { &ei_geneve_opt_len_invalid, { "geneve.option.length.invalid", |
559 | PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Invalid length for option", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE , ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void *)0)}} }}, |
560 | }; |
561 | |
562 | expert_module_t *expert_geneve; |
563 | |
564 | /* Register the protocol name and description */ |
565 | proto_geneve = proto_register_protocol("Generic Network Virtualization Encapsulation", |
566 | "Geneve", "geneve"); |
567 | |
568 | proto_register_field_array(proto_geneve, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0])); |
569 | proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0])); |
570 | |
571 | expert_geneve = expert_register_protocol(proto_geneve); |
572 | expert_register_field_array(expert_geneve, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0])); |
573 | |
574 | geneve_handle = register_dissector("geneve", dissect_geneve, proto_geneve); |
575 | } |
576 | |
577 | void |
578 | proto_reg_handoff_geneve(void) |
579 | { |
580 | dissector_add_uint_with_preference("udp.port", UDP_PORT_GENEVE6081, geneve_handle); |
581 | |
582 | ethertype_dissector_table = find_dissector_table("ethertype"); |
583 | } |
584 | |
585 | /* |
586 | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
587 | * |
588 | * Local variables: |
589 | * c-basic-offset: 4 |
590 | * tab-width: 8 |
591 | * indent-tabs-mode: nil |
592 | * End: |
593 | * |
594 | * vi: set shiftwidth=4 tabstop=8 expandtab: |
595 | * :indentSize=4:tabSize=8:noTabs=true: |
596 | */ |