Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-avsp.c
blob5620dc40c0410dbd09001114abf21f0d0c1953f6
1 /* packet-avsp.c
2 * Arista Vendor Specific ethertype Protocol (AVSP)
4 * Copyright (c) 2018-2022 by Arista Networks
5 * Author: Nikhil AP <nikhilap@arista.com>
6 * Author: PMcL <peterm@arista.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 /* Arista Vendor-Specific EtherType Protocol Identifier
17 * Arista applied for, and received the assignment of, a vendor-specific EtherType Protocol Identifier in May of 2016. Details below:
19 * Ethertype number is: D28B
20 * Issue date is: May 12, 2016
22 * Arista Subtype 0x0001 is a Timestamp L2 Header
23 * Arista Subtype 0xCAFE is a TGen L2 header
25 * The timestamp L2 header consists of the following fields:
27 * Arista Vendor Specific Protocol EtherType (0xD28B)
28 * Two-byte protocol subtype of 0x0001
29 * Two-byte protocol version: 0x0010 for 64-bit timestamp and 0x0020 for 48-bit timestamp
30 * UTC timestamp value in IEEE 1588 time of day format (either 64-bit or 48-bit) with the lower 32-bits representing nanoseconds and upper bits representing seconds.
32 * The TGen L2 header consists of the following fields:
34 * Arista Vendor Specific Protocol EtherType (0xD28B)
35 * Two-byte protocol subtype of 0xCAFE
36 * Two-byte protocol version: 0x0001
39 #include "config.h"
40 #include <epan/packet.h>
41 #include <epan/exceptions.h>
42 #include <epan/etypes.h>
43 #include <epan/expert.h>
44 #include <epan/address.h>
46 #include <wsutil/str_util.h>
48 #include "packet-eth.h"
50 #define ARISTA_SUBTYPE_TIMESTAMP 0x0001
52 #define ARISTA_TIMESTAMP_64_TAI 0x0010
53 #define ARISTA_TIMESTAMP_64_UTC 0x0110
54 #define ARISTA_TIMESTAMP_48_TAI 0x0020
55 #define ARISTA_TIMESTAMP_48_UTC 0x0120
56 #define ARISTA_TIMESTAMP_64_TAI_J2 0x0011
57 #define ARISTA_TIMESTAMP_64_UTC_J2 0x0111
58 #define ARISTA_TIMESTAMP_48_TAI_J2 0x0021
59 #define ARISTA_TIMESTAMP_48_UTC_J2 0x0121
61 #define ARISTA_SUBTYPE_GREENTAP 0x0003
63 #define ARISTA_GREENTAP_48_TAI 0x0020
64 #define ARISTA_GREENTAP_48_UTC 0x0120
66 #define ARISTA_SUBTYPE_GREENT 0x0004
68 #define ARISTA_GREENT_VER_1 0x0001
70 #define ARISTA_SUBTYPE_DZGRE_A 0x0007
72 #define ARISTA_DZGRE_A_VER_1 0x0001
74 #define ARISTA_SUBTYPE_DZGRE_B 0x0008
76 #define ARISTA_DZGRE_B_VER_1 0x0001
78 #define ARISTA_SUBTYPE_DZGRE_TS 0x0009
80 #define ARISTA_DZGRE_TS_64_TAI 0x0011
81 #define ARISTA_DZGRE_TS_64_UTC 0x0111
83 #define ARISTA_SUBTYPE_TGEN 0xCAFE
84 #define ARISTA_TGEN_VER_1 0x0001
86 #define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
88 void proto_reg_handoff_avsp(void);
89 void proto_register_avsp(void);
91 static dissector_handle_t avsp_handle;
92 static int proto_avsp;
94 /* sub trees */
95 static int ett_avsp;
96 static int ett_avsp_ts_48;
97 static int ett_avsp_ts_64;
98 static int ett_avsp_dzgre_a_hdr;
99 static int ett_avsp_dzgre_b_hdr;
100 static int ett_avsp_dzgre_ts_hdr;
101 static int ett_avsp_dzgre_ts_tai;
102 static int ett_avsp_dzgre_ts_utc;
103 static int ett_avsp_greent_hdr;
104 static int ett_avsp_greent_sample_hdr;
105 static int ett_avsp_greent_sample_data;
106 static int ett_avsp_tgen_hdr;
107 static int ett_avsp_tgen_hdr_ctrl;
108 static int ett_avsp_tgen_payload;
110 /* AVSP Timestamp subtype header fields */
111 static int hf_avsp_subtype;
112 static int hf_avsp_ts_version;
113 static int hf_avsp_ts_64_tai;
114 static int hf_avsp_ts_64_utc;
115 static int hf_avsp_ts_64_sec;
116 static int hf_avsp_ts_64_ns;
117 static int hf_avsp_ts_48_tai;
118 static int hf_avsp_ts_48_utc;
119 static int hf_avsp_ts_48_sec;
120 static int hf_avsp_ts_48_ns;
122 static int hf_avsp_etype;
123 static int hf_avsp_trailer;
126 GREENTAP Timestamping format
127 0.............7...............15..............23..............31
128 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129 | Protocol Subtype = 0x0003 | Protocol Version |
130 +---------------+---------------+---------------+---------------+
131 | Session ID | Timestamp (seconds) |
132 +---------------+---------------+---------------+---------------+
133 |0 0| Timestamp (nanoseconds) |
134 +---------------+---------------+---------------+---------------+
137 /* AVSP GREENTAP subtype header fields */
138 static int hf_avsp_greentap_version;
139 static int hf_avsp_greentap_tai;
140 static int hf_avsp_greentap_utc;
141 static int hf_avsp_greentap_sec;
142 static int hf_avsp_greentap_ns;
145 GREENT subtype format
146 0.............7...............15..............23..............31
147 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148 | Protocol Subtype = 0x0004 | Protocol Version |
149 +---------------+---------------+---------------+---------------+
150 | Session ID | Flags | Sample Count |
151 +---------------+---------------+---------------+---------------+
153 Each sample has a header of the format:
154 0.............7...............15..............23..............31
155 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156 | Length | IEEE 1588 TS (seconds) |
157 +---------------+---------------+---------------+---------------+
158 | IEEE 1588 TS (nanoseconds) |
159 +---------------+---------------+---------------+---------------+
160 | Ingress Port (SNMP ifIndex) |
161 +---------------+---------------+---------------+---------------+
162 | Egress Port (SNMP ifIndex) |
163 +---------------+---------------+---------------+---------------+
164 | Sample Rate (multiplier 1K) | Payload Checksum |
165 +---------------+---------------+---------------+---------------+
166 | Sample (padded to 4 byte boundary) |
167 +---------------+---------------+---------------+---------------+
170 /* AVSP GREENT subtype header fields */
171 static int hf_avsp_greent_hdr;
172 static int hf_avsp_greent_version;
173 static int hf_avsp_greent_session;
174 static int hf_avsp_greent_flags;
175 static int hf_avsp_greent_sample_count;
177 /* GREENT sample header fields */
178 static int hf_avsp_greent_sample_hdr;
179 static int hf_avsp_greent_sample_len;
180 static int hf_avsp_greent_sample_sec;
181 static int hf_avsp_greent_sample_ns;
182 static int hf_avsp_greent_sample_ingress;
183 static int hf_avsp_greent_sample_egress;
184 static int hf_avsp_greent_sample_rate;
185 static int hf_avsp_greent_sample_sum;
186 static int hf_avsp_greent_sample_data;
189 DzGRE Plan A subtype format
190 0.............7...............15..............23..............31
191 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192 | Protocol Subtype = 0x0007 | Protocol Version |
193 +---------------+---------------+---------------+---------------+
194 | Switch ID | Port ID |
195 +---------------+---------------+---------------+---------------+
196 | Policy ID | Reserved |
197 +---------------+---------------+---------------+---------------+
199 DzGRE Plan B subtype format
200 0.............7...............15..............23..............31
201 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202 | Protocol Subtype = 0x0008 | Protocol Version |
203 +---------------+---------------+---------------+---------------+
204 |0 0 0 0| Port ID |0 0 0 0| Policy ID |
205 +---------------+---------------+---------------+---------------+
207 DzGRE with timestamping
208 0.............7...............15..............23..............31
209 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210 | Protocol Subtype = 0x0009 | Protocol Version |
211 +---------------+---------------+---------------+---------------+
212 | Switch ID | Port ID |
213 +---------------+---------------+---------------+---------------+
214 | Policy ID | Reserved |
215 +---------------+---------------+---------------+---------------+
216 | UTC Timestamp (seconds) |
217 +---------------+---------------+---------------+---------------+
218 | UTC Timestamp (nanoseconds) |
219 +---------------+---------------+---------------+---------------+
222 /* AVSP DzGRE header fields */
223 static int hf_avsp_dzgre_a_hdr;
224 static int hf_avsp_dzgre_a_version;
225 static int hf_avsp_dzgre_a_switch;
226 static int hf_avsp_dzgre_a_port;
227 static int hf_avsp_dzgre_a_policy;
228 static int hf_avsp_dzgre_a_reserved;
230 static int hf_avsp_dzgre_b_hdr;
231 static int hf_avsp_dzgre_b_version;
232 static int hf_avsp_dzgre_b_port;
233 static int hf_avsp_dzgre_b_policy;
235 static int hf_avsp_dzgre_ts_hdr;
236 static int hf_avsp_dzgre_ts_version;
237 static int hf_avsp_dzgre_ts_switch;
238 static int hf_avsp_dzgre_ts_port;
239 static int hf_avsp_dzgre_ts_policy;
240 static int hf_avsp_dzgre_ts_reserved;
241 static int hf_avsp_dzgre_ts_tai;
242 static int hf_avsp_dzgre_ts_utc;
243 static int hf_avsp_dzgre_ts_sec;
244 static int hf_avsp_dzgre_ts_ns;
247 TGen subtype format
248 0.............7...............15..............23..............31
249 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
250 | Ethertype = 0xD28B | Protocol Subtype = 0xCAFE |
251 +---------------+---------------+---------------+---------------+
252 | Protocol Version = 0x0001 | TGen Control Word |
253 +---------------+---------------+---------------+---------------+
254 | TGen Sequence Number | TGen Payload Length |
255 +---------------+---------------+---------------+---------------+
256 | TGen Data Payload |
257 +---------------+---------------+---------------+---------------+
258 | ... |
259 +---------------+---------------+---------------+---------------+
260 | TGen Data Payload |
261 +---------------+---------------+---------------+---------------+
264 /* AVSP TGen subtype header fields */
265 static int hf_avsp_tgen_version;
266 static int hf_avsp_tgen_hdr;
267 static int hf_avsp_tgen_hdr_ctrl;
268 static int hf_avsp_tgen_hdr_ctrl_fcs_inverted;
269 static int hf_avsp_tgen_hdr_ctrl_reserved;
270 static int hf_avsp_tgen_hdr_seq_num;
271 static int hf_avsp_tgen_hdr_payload_len;
272 static int hf_avsp_tgen_payload;
273 static int hf_avsp_tgen_payload_data;
275 static int* const avsp_tgen_ctrl[] = {
276 &hf_avsp_tgen_hdr_ctrl_fcs_inverted,
277 &hf_avsp_tgen_hdr_ctrl_reserved,
278 NULL
281 static dissector_handle_t ethertype_handle;
283 static const value_string arista_subtypes[] = {
284 {ARISTA_SUBTYPE_TIMESTAMP, "timestamp"},
285 {ARISTA_SUBTYPE_GREENTAP, "GRE TAP"},
286 {ARISTA_SUBTYPE_GREENT, "Postcard"},
287 {ARISTA_SUBTYPE_DZGRE_A, "DzGRE (plan A)"},
288 {ARISTA_SUBTYPE_DZGRE_B, "DzGRE (plan B)"},
289 {ARISTA_SUBTYPE_DZGRE_TS, "DzGRE (timestamped)"},
290 {ARISTA_SUBTYPE_TGEN, "TGen"},
291 {0, NULL}
294 static const value_string ts_versions[] = {
295 {ARISTA_TIMESTAMP_64_TAI, "010"},
296 {ARISTA_TIMESTAMP_64_UTC, "110"},
297 {ARISTA_TIMESTAMP_48_TAI, "020"},
298 {ARISTA_TIMESTAMP_48_UTC, "120"},
299 {ARISTA_TIMESTAMP_64_TAI_J2, "011"},
300 {ARISTA_TIMESTAMP_64_UTC_J2, "111"},
301 {ARISTA_TIMESTAMP_48_TAI_J2, "021"},
302 {ARISTA_TIMESTAMP_48_UTC_J2, "121"},
303 {0, NULL}
306 static const value_string greentap_versions[] = {
307 {ARISTA_GREENTAP_48_TAI, "48bit TAI"},
308 {ARISTA_GREENTAP_48_UTC, "48bit UTC"},
309 {0, NULL}
312 static const value_string greent_versions[] = {
313 {ARISTA_GREENT_VER_1, "1"},
314 {0, NULL}
317 static const value_string dzgre_a_versions[] = {
318 {ARISTA_DZGRE_A_VER_1, "1"},
319 {0, NULL}
322 static const value_string dzgre_b_versions[] = {
323 {ARISTA_DZGRE_A_VER_1, "1"},
324 {0, NULL}
327 static const value_string dzgre_ts_versions[] = {
328 {ARISTA_DZGRE_TS_64_TAI, "64bit TAI"},
329 {ARISTA_DZGRE_TS_64_UTC, "64bit UTC"},
330 {0, NULL}
333 static const value_string tgen_versions[] = {
334 {ARISTA_TGEN_VER_1, "1"},
335 {0, NULL}
338 static expert_field ei_avsp_unknown_subtype;
339 static expert_field ei_avsp_ts_unknown_version;
340 static expert_field ei_avsp_greentap_unknown_version;
341 static expert_field ei_avsp_greent_unknown_version;
342 static expert_field ei_avsp_dzgre_a_unknown_version;
343 static expert_field ei_avsp_dzgre_b_unknown_version;
344 static expert_field ei_avsp_dzgre_ts_unknown_version;
345 static expert_field ei_avsp_tgen_unknown_version;
347 static int
348 dissect_avsp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
350 volatile int offset = 0;
351 uint32_t version, subtype, tgen_payload_len = 0;
352 uint64_t tgen_ctrl;
353 uint32_t tgen_seq_num, sample_len, count, u32;
354 volatile uint32_t i; // potentially held across vfork
355 const char* str;
356 uint16_t encap_proto;
357 ethertype_data_t ethertype_data;
358 tvbuff_t* volatile tgen_payload_tvb = NULL;
360 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVSP");
361 col_clear(pinfo->cinfo, COL_INFO);
363 proto_item* avsp_ti, * ti;
364 proto_tree* avsp_tree, * avsp_48_tree = NULL, * avsp_64_tree = NULL,
365 * avsp_tgen_hdr = NULL, * avsp_tgen_payload = NULL,
366 * avsp_dzgre_hdr = NULL, * avsp_greent_hdr = NULL,
367 * avsp_greent_sample_hdr = NULL, *header_tree = NULL;
369 /* Adding Items and Values to the Protocol Tree */
370 avsp_ti = proto_tree_add_item(tree, proto_avsp, tvb, 0, -1,
371 ENC_NA);
372 avsp_tree = proto_item_add_subtree(avsp_ti, ett_avsp);
374 /* add the subtype to avsp */
375 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_subtype, tvb,
376 offset, 2, ENC_BIG_ENDIAN, &subtype);
377 str = try_val_to_str(subtype, arista_subtypes);
378 if (str) {
379 proto_item_append_text(avsp_ti, ", Subtype: %s", str);
381 offset += 2;
383 /* Based on the subtype, add the version and further custom protocol fields */
384 switch (subtype) {
385 case ARISTA_SUBTYPE_TIMESTAMP:
386 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_ts_version, tvb, offset,
387 2, ENC_BIG_ENDIAN, &version);
388 str = try_val_to_str(version, ts_versions);
389 if (str) {
390 proto_item_append_text(avsp_ti, ", Version: %s", str);
392 offset += 2;
394 switch (version) {
395 case ARISTA_TIMESTAMP_64_TAI:
396 case ARISTA_TIMESTAMP_64_TAI_J2:
397 ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_64_tai, tvb, 0, -1,
398 ENC_NA);
399 avsp_64_tree = proto_item_add_subtree(ti, ett_avsp);
400 col_set_str(pinfo->cinfo, COL_INFO, "64bit TAI timestamp");
401 proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_sec, tvb, offset,
402 4, ENC_BIG_ENDIAN);
403 offset += 4;
404 proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_ns, tvb, offset,
405 4, ENC_BIG_ENDIAN);
406 offset += 4;
407 break;
408 case ARISTA_TIMESTAMP_64_UTC:
409 case ARISTA_TIMESTAMP_64_UTC_J2:
410 ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_64_utc, tvb, 0, -1,
411 ENC_NA);
412 avsp_64_tree = proto_item_add_subtree(ti, ett_avsp);
413 col_set_str(pinfo->cinfo, COL_INFO, "64bit UTC timestamp");
414 proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_sec, tvb, offset,
415 4, ENC_BIG_ENDIAN);
416 offset += 4;
417 proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_ns, tvb, offset,
418 4, ENC_BIG_ENDIAN);
419 offset += 4;
420 break;
421 case ARISTA_TIMESTAMP_48_TAI:
422 case ARISTA_TIMESTAMP_48_TAI_J2:
423 ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_48_tai, tvb, 0, -1,
424 ENC_NA);
425 avsp_48_tree = proto_item_add_subtree(ti, ett_avsp);
426 col_set_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp");
427 proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_sec, tvb, offset,
428 2, ENC_BIG_ENDIAN);
429 offset += 2;
430 proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_ns, tvb, offset,
431 4, ENC_BIG_ENDIAN);
432 offset += 4;
433 break;
434 case ARISTA_TIMESTAMP_48_UTC:
435 case ARISTA_TIMESTAMP_48_UTC_J2:
436 ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_48_utc, tvb, 0, -1,
437 ENC_NA);
438 avsp_48_tree = proto_item_add_subtree(ti, ett_avsp);
439 col_set_str(pinfo->cinfo, COL_INFO, "48bit UTC timestamp");
440 proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_sec, tvb, offset,
441 2, ENC_BIG_ENDIAN);
442 offset += 2;
443 proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_ns, tvb, offset,
444 4, ENC_BIG_ENDIAN);
445 offset += 4;
446 break;
447 default:
448 expert_add_info_format(pinfo, avsp_ti, &ei_avsp_ts_unknown_version,
449 "Unknown timestamp version: 0x%0x", version);
450 return tvb_captured_length(tvb);
453 encap_proto = tvb_get_ntohs(tvb, offset);
454 proto_tree_add_uint(avsp_tree, hf_avsp_etype, tvb, offset, 2, encap_proto);
455 offset += 2;
457 ethertype_data.etype = encap_proto;
458 ethertype_data.payload_offset = offset;
459 ethertype_data.fh_tree = avsp_tree;
460 ethertype_data.trailer_id = hf_avsp_trailer;
461 ethertype_data.fcs_len = 0;
463 call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, &ethertype_data);
464 break;
466 case ARISTA_SUBTYPE_GREENTAP:
467 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_greentap_version, tvb,
468 offset, 2, ENC_BIG_ENDIAN, &version);
469 str = try_val_to_str(version, greentap_versions);
470 if (str) {
471 proto_item_append_text(avsp_ti, ", Version: %s", str);
473 offset += 2;
475 switch (version) {
476 case ARISTA_GREENTAP_48_TAI:
477 ti = proto_tree_add_item(avsp_tree, hf_avsp_greentap_tai, tvb,
478 0, -1, ENC_NA);
479 avsp_48_tree = proto_item_add_subtree(ti, ett_avsp);
480 col_set_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp");
481 proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_sec,
482 tvb, offset, 2, ENC_BIG_ENDIAN);
483 offset += 2;
484 proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_ns,
485 tvb, offset, 4, ENC_BIG_ENDIAN);
486 offset += 4;
487 break;
488 case ARISTA_GREENTAP_48_UTC:
489 ti = proto_tree_add_item(avsp_tree, hf_avsp_greentap_utc, tvb,
490 0, -1, ENC_NA);
491 avsp_48_tree = proto_item_add_subtree(ti, ett_avsp);
492 col_set_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp");
493 proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_sec,
494 tvb, offset, 2, ENC_BIG_ENDIAN);
495 offset += 2;
496 proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_ns,
497 tvb, offset, 4, ENC_BIG_ENDIAN);
498 offset += 4;
499 break;
500 default:
501 expert_add_info_format(pinfo, avsp_ti,
502 &ei_avsp_greentap_unknown_version,
503 "Unknown GRE TAP version: 0x%0x", version);
504 return tvb_captured_length(tvb);
507 encap_proto = tvb_get_ntohs(tvb, offset);
508 proto_tree_add_uint(avsp_tree, hf_avsp_etype, tvb, offset, 2,
509 encap_proto);
510 offset += 2;
512 ethertype_data.etype = encap_proto;
513 ethertype_data.payload_offset = offset;
514 ethertype_data.fh_tree = avsp_tree;
515 ethertype_data.trailer_id = hf_avsp_trailer;
516 ethertype_data.fcs_len = 0;
518 call_dissector_with_data(ethertype_handle, tvb, pinfo, tree,
519 &ethertype_data);
520 break;
522 case ARISTA_SUBTYPE_GREENT:
523 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_greent_version, tvb,
524 offset, 2, ENC_BIG_ENDIAN, &version);
525 str = try_val_to_str(version, greent_versions);
526 if (str) {
527 proto_item_append_text(avsp_ti, ", Version: %s", str);
529 offset += 2;
531 switch (version) {
532 case ARISTA_GREENT_VER_1:
533 col_set_str(pinfo->cinfo, COL_INFO, "Arista Postcard Telemetry");
534 ti = proto_tree_add_item(avsp_tree, hf_avsp_greent_hdr, tvb, 0,
535 -1, ENC_NA);
536 avsp_greent_hdr = proto_item_add_subtree(ti, ett_avsp_greent_hdr);
538 /* Session ID */
539 proto_tree_add_item_ret_uint(avsp_greent_hdr,
540 hf_avsp_greent_session, tvb, offset, 2, ENC_BIG_ENDIAN,
541 &u32);
542 proto_item_append_text(ti, ", Session ID: %u", u32);
543 offset += 2;
545 /* Flags */
546 proto_tree_add_item_ret_uint(avsp_greent_hdr,
547 hf_avsp_greent_flags, tvb, offset, 1, ENC_BIG_ENDIAN,
548 &u32);
549 proto_item_append_text(ti, ", Flags: 0x%02x", u32);
550 offset += 1;
552 /* Sample Count */
553 proto_tree_add_item_ret_uint(avsp_greent_hdr,
554 hf_avsp_greent_sample_count, tvb, offset, 1, ENC_BIG_ENDIAN,
555 &count);
556 proto_item_append_text(ti, ", Count: %u", count);
557 offset += 1;
559 for (i = 0; i < count; i++) {
560 ti = proto_tree_add_item(avsp_greent_hdr,
561 hf_avsp_greent_sample_hdr, tvb, 0, -1, ENC_NA);
562 avsp_greent_sample_hdr = proto_item_add_subtree(ti,
563 ett_avsp_greent_sample_hdr);
565 /* Length */
566 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
567 hf_avsp_greent_sample_len, tvb, offset, 2,
568 ENC_BIG_ENDIAN, &sample_len);
569 proto_item_append_text(ti, ", Length: %u", sample_len);
570 offset += 2;
572 /* Seconds */
573 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
574 hf_avsp_greent_sample_sec, tvb, offset, 2,
575 ENC_BIG_ENDIAN, &u32);
576 proto_item_append_text(ti, ", Seconds: %u", u32);
577 offset += 2;
579 /* Nanoseconds */
580 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
581 hf_avsp_greent_sample_ns, tvb, offset, 4,
582 ENC_BIG_ENDIAN, &u32);
583 proto_item_append_text(ti, ", Nanoseconds: %u", u32);
584 offset += 4;
586 /* Ingress */
587 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
588 hf_avsp_greent_sample_ingress, tvb, offset, 4,
589 ENC_BIG_ENDIAN, &u32);
590 proto_item_append_text(ti, ", Ingress: %u", u32);
591 offset += 4;
593 /* Egress */
594 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
595 hf_avsp_greent_sample_egress, tvb, offset, 4,
596 ENC_BIG_ENDIAN, &u32);
597 proto_item_append_text(ti, ", Egress: %u", u32);
598 offset += 4;
600 /* Sample Rate */
601 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
602 hf_avsp_greent_sample_rate, tvb, offset, 2,
603 ENC_BIG_ENDIAN, &u32);
604 proto_item_append_text(ti, ", Rate: %u", u32);
605 offset += 2;
607 /* Checksum */
608 proto_tree_add_item_ret_uint(avsp_greent_sample_hdr,
609 hf_avsp_greent_sample_sum, tvb, offset, 2,
610 ENC_BIG_ENDIAN, &u32);
611 proto_item_append_text(ti, ", Checksum: 0x%04x", u32);
612 offset += 2;
614 /* Sample Data */
615 ti = proto_tree_add_item(avsp_greent_sample_hdr,
616 hf_avsp_greent_sample_data, tvb, offset, sample_len,
617 ENC_NA);
618 header_tree = proto_item_add_subtree(ti,
619 ett_avsp_greent_sample_data);
622 * We call the ethernet dissector on the sample, but since
623 * the sample is truncated it will likely generate errors.
624 * This is an attempt to isolate those errors, borrowed from
625 * sflow.
628 tvbuff_t *next_tvb;
629 address save_dl_src, save_dl_dst, save_net_src,
630 save_net_dst, save_src, save_dst;
631 bool save_writable, save_in_error_pkt;
633 sample_len = ROUNDUP(sample_len, 4);
634 next_tvb = tvb_new_subset_length(tvb, offset, sample_len);
636 save_in_error_pkt = pinfo->flags.in_error_pkt;
637 pinfo->flags.in_error_pkt = true;
639 save_writable = col_get_writable(pinfo->cinfo, -1);
640 col_set_writable(pinfo->cinfo, -1, false);
641 copy_address_shallow(&save_dl_src, &pinfo->dl_src);
642 copy_address_shallow(&save_dl_dst, &pinfo->dl_dst);
643 copy_address_shallow(&save_net_src, &pinfo->net_src);
644 copy_address_shallow(&save_net_dst, &pinfo->net_dst);
645 copy_address_shallow(&save_src, &pinfo->src);
646 copy_address_shallow(&save_dst, &pinfo->dst);
650 // always ethernet for greent
651 ethertype_data.etype = ETHERTYPE_ETHBRIDGE;
652 ethertype_data.payload_offset = 0;
653 ethertype_data.fh_tree = header_tree;
654 ethertype_data.trailer_id = hf_avsp_trailer;
655 ethertype_data.fcs_len = 0;
657 call_dissector_with_data(ethertype_handle, next_tvb,
658 pinfo, header_tree, &ethertype_data);
660 CATCH_BOUNDS_ERRORS {
662 ENDTRY;
664 col_set_writable(pinfo->cinfo, -1, save_writable);
665 pinfo->flags.in_error_pkt = save_in_error_pkt;
666 copy_address_shallow(&pinfo->dl_src, &save_dl_src);
667 copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
668 copy_address_shallow(&pinfo->net_src, &save_net_src);
669 copy_address_shallow(&pinfo->net_dst, &save_net_dst);
670 copy_address_shallow(&pinfo->src, &save_src);
671 copy_address_shallow(&pinfo->dst, &save_dst);
674 break;
675 default:
676 expert_add_info_format(pinfo, avsp_ti,
677 &ei_avsp_greent_unknown_version,
678 "Unknown version: 0x%0x", version);
679 return tvb_captured_length(tvb);
681 break;
683 case ARISTA_SUBTYPE_DZGRE_A:
684 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_dzgre_a_version, tvb,
685 offset, 2, ENC_BIG_ENDIAN, &version);
686 str = try_val_to_str(version, dzgre_a_versions);
687 if (str) {
688 proto_item_append_text(avsp_ti, ", Version: %s", str);
690 offset += 2;
692 switch (version) {
693 case ARISTA_DZGRE_A_VER_1:
694 col_set_str(pinfo->cinfo, COL_INFO, "Arista DzGRE(A) Frame");
695 ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_a_hdr, tvb,
696 0, -1, ENC_NA);
697 avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_a_hdr);
699 /* Switch ID */
700 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
701 hf_avsp_dzgre_a_switch, tvb, offset, 2, ENC_BIG_ENDIAN,
702 &u32);
703 proto_item_append_text(ti, ", Switch ID: %u", u32);
704 offset += 2;
706 /* Port ID */
707 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
708 hf_avsp_dzgre_a_port, tvb, offset, 2, ENC_BIG_ENDIAN,
709 &u32);
710 proto_item_append_text(ti, ", Port ID: %u", u32);
711 offset += 2;
713 /* Policy ID */
714 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
715 hf_avsp_dzgre_a_policy, tvb, offset, 2, ENC_BIG_ENDIAN,
716 &u32);
717 proto_item_append_text(ti, ", Policy ID: %u", u32);
718 offset += 2;
720 /* Reserved */
721 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
722 hf_avsp_dzgre_a_reserved, tvb, offset, 2, ENC_BIG_ENDIAN,
723 &u32);
724 offset += 2;
725 break;
726 default:
727 expert_add_info_format(pinfo, avsp_ti,
728 &ei_avsp_dzgre_a_unknown_version,
729 "Unknown version: 0x%0x", version);
730 return tvb_captured_length(tvb);
733 ethertype_data.etype = ETHERTYPE_ETHBRIDGE; // always ethernet
734 ethertype_data.payload_offset = offset;
735 ethertype_data.fh_tree = avsp_tree;
736 ethertype_data.trailer_id = hf_avsp_trailer;
737 ethertype_data.fcs_len = 0;
739 call_dissector_with_data(ethertype_handle, tvb, pinfo, tree,
740 &ethertype_data);
741 break;
743 case ARISTA_SUBTYPE_DZGRE_B:
744 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_dzgre_b_version, tvb,
745 offset, 2, ENC_BIG_ENDIAN, &version);
746 str = try_val_to_str(version, dzgre_b_versions);
747 if (str) {
748 proto_item_append_text(avsp_ti, ", Version: %s", str);
750 offset += 2;
752 switch (version) {
753 case ARISTA_DZGRE_B_VER_1:
754 col_set_str(pinfo->cinfo, COL_INFO, "Arista DzGRE(B) Frame");
755 ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_b_hdr, tvb,
756 0, -1, ENC_NA);
757 avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_b_hdr);
759 /* Port ID */
760 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
761 hf_avsp_dzgre_b_port, tvb, offset, 2, ENC_BIG_ENDIAN,
762 &u32);
763 proto_item_append_text(ti, ", Port ID: %u", u32);
764 offset += 2;
766 /* Policy ID */
767 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
768 hf_avsp_dzgre_b_policy, tvb, offset, 2, ENC_BIG_ENDIAN,
769 &u32);
770 proto_item_append_text(ti, ", Policy ID: %u", u32);
771 offset += 2;
772 break;
773 default:
774 expert_add_info_format(pinfo, avsp_ti,
775 &ei_avsp_dzgre_b_unknown_version,
776 "Unknown version: 0x%0x", version);
777 return tvb_captured_length(tvb);
780 ethertype_data.etype = ETHERTYPE_ETHBRIDGE; // always ethernet
781 ethertype_data.payload_offset = offset;
782 ethertype_data.fh_tree = avsp_tree;
783 ethertype_data.trailer_id = hf_avsp_trailer;
784 ethertype_data.fcs_len = 0;
786 call_dissector_with_data(ethertype_handle, tvb, pinfo, tree,
787 &ethertype_data);
788 break;
790 case ARISTA_SUBTYPE_DZGRE_TS:
791 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_dzgre_ts_version, tvb,
792 offset, 2, ENC_BIG_ENDIAN, &version);
793 str = try_val_to_str(version, dzgre_ts_versions);
794 if (str) {
795 proto_item_append_text(avsp_ti, ", Version: %s", str);
797 offset += 2;
799 switch (version) {
800 case ARISTA_DZGRE_TS_64_TAI:
801 col_set_str(pinfo->cinfo, COL_INFO, "Arista DzGRE(A) Frame");
802 ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_ts_hdr, tvb,
803 0, -1, ENC_NA);
804 avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_ts_hdr);
806 /* Switch ID */
807 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
808 hf_avsp_dzgre_ts_switch, tvb, offset, 2, ENC_BIG_ENDIAN,
809 &u32);
810 proto_item_append_text(ti, ", Switch ID: %u", u32);
811 offset += 2;
813 /* Port ID */
814 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
815 hf_avsp_dzgre_ts_port, tvb, offset, 2, ENC_BIG_ENDIAN,
816 &u32);
817 proto_item_append_text(ti, ", Port ID: %u", u32);
818 offset += 2;
820 /* Policy ID */
821 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
822 hf_avsp_dzgre_ts_policy, tvb, offset, 2, ENC_BIG_ENDIAN,
823 &u32);
824 proto_item_append_text(ti, ", Policy ID: %u", u32);
825 offset += 2;
827 /* Reserved */
828 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
829 hf_avsp_dzgre_ts_reserved, tvb, offset, 2, ENC_BIG_ENDIAN,
830 &u32);
831 offset += 2;
833 /* Timestamp */
834 ti = proto_tree_add_item(avsp_dzgre_hdr,
835 hf_avsp_dzgre_ts_tai, tvb, 0, -1, ENC_NA);
836 avsp_64_tree = proto_item_add_subtree(ti,
837 ett_avsp_dzgre_ts_tai);
839 col_set_str(pinfo->cinfo, COL_INFO, "64bit TAI timestamp");
841 proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_sec,
842 tvb, offset, 4, ENC_BIG_ENDIAN);
843 offset += 4;
844 proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_ns,
845 tvb, offset, 4, ENC_BIG_ENDIAN);
846 offset += 4;
847 break;
848 case ARISTA_DZGRE_TS_64_UTC:
849 col_set_str(pinfo->cinfo, COL_INFO,
850 "Arista DzGRE(timestamped) Frame");
851 ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_ts_hdr, tvb,
852 0, -1, ENC_NA);
853 avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_ts_hdr);
855 /* Switch ID */
856 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
857 hf_avsp_dzgre_ts_switch, tvb, offset, 2, ENC_BIG_ENDIAN,
858 &u32);
859 proto_item_append_text(ti, ", Switch ID: 0x%u", u32);
860 offset += 2;
862 /* Port ID */
863 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
864 hf_avsp_dzgre_ts_port, tvb, offset, 2, ENC_BIG_ENDIAN,
865 &u32);
866 proto_item_append_text(ti, ", Port ID: 0x%u", u32);
867 offset += 2;
869 /* Policy ID */
870 proto_tree_add_item_ret_uint(avsp_dzgre_hdr,
871 hf_avsp_dzgre_ts_policy, tvb, offset, 2, ENC_BIG_ENDIAN,
872 &u32);
873 proto_item_append_text(ti, ", Policy ID: 0x%u", u32);
874 offset += 2;
876 /* Reserved */
877 offset += 2;
879 /* Timestamp */
880 ti = proto_tree_add_item(avsp_dzgre_hdr,
881 hf_avsp_dzgre_ts_utc, tvb, 0, -1, ENC_NA);
882 avsp_64_tree = proto_item_add_subtree(ti,
883 ett_avsp_dzgre_ts_utc);
885 col_set_str(pinfo->cinfo, COL_INFO, "64bit UTC timestamp");
887 proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_sec,
888 tvb, offset, 4, ENC_BIG_ENDIAN);
889 offset += 4;
890 proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_ns,
891 tvb, offset, 4, ENC_BIG_ENDIAN);
892 offset += 4;
893 break;
894 default:
895 expert_add_info_format(pinfo, avsp_ti,
896 &ei_avsp_dzgre_ts_unknown_version,
897 "Unknown version: 0x%0x", version);
898 return tvb_captured_length(tvb);
901 ethertype_data.etype = ETHERTYPE_ETHBRIDGE; // always ethernet
902 ethertype_data.payload_offset = offset;
903 ethertype_data.fh_tree = avsp_tree;
904 ethertype_data.trailer_id = hf_avsp_trailer;
905 ethertype_data.fcs_len = 0;
907 call_dissector_with_data(ethertype_handle, tvb, pinfo, tree,
908 &ethertype_data);
909 break;
911 case ARISTA_SUBTYPE_TGEN:
912 proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_tgen_version, tvb,
913 offset, 2, ENC_BIG_ENDIAN, &version);
914 str = try_val_to_str(version, tgen_versions);
915 if (str) {
916 proto_item_append_text(avsp_ti, ", Version: %s", str);
918 offset += 2;
920 switch (version) {
921 case ARISTA_TGEN_VER_1:
922 col_set_str(pinfo->cinfo, COL_INFO, "Arista TGen Frame");
924 /* Get TGen Header Control Word. */
925 ti = proto_tree_add_item(avsp_tree, hf_avsp_tgen_hdr, tvb, offset, 6,
926 ENC_NA);
927 avsp_tgen_hdr = proto_item_add_subtree(ti, ett_avsp_tgen_hdr);
928 proto_tree_add_bitmask_ret_uint64(avsp_tgen_hdr, tvb, offset,
929 hf_avsp_tgen_hdr_ctrl, ett_avsp_tgen_hdr_ctrl, avsp_tgen_ctrl,
930 ENC_BIG_ENDIAN, &tgen_ctrl);
931 proto_item_append_text(ti, ", Control Word: 0x%04" PRIx64, tgen_ctrl);
932 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Ctrl=0x%04" PRIx64, tgen_ctrl);
933 offset += 2;
935 /* Get TGen Header Sequence Number*/
936 proto_tree_add_item_ret_uint(avsp_tgen_hdr, hf_avsp_tgen_hdr_seq_num, tvb,
937 offset, 2, ENC_BIG_ENDIAN, &tgen_seq_num);
938 proto_item_append_text(ti, ", Sequence Number: %u", tgen_seq_num);
939 col_append_str_uint(pinfo->cinfo, COL_INFO, "Seq", tgen_seq_num, ", ");
940 offset += 2;
942 /* Get TGen Header Payload Length */
943 proto_tree_add_item_ret_uint(avsp_tgen_hdr,
944 hf_avsp_tgen_hdr_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN,
945 &tgen_payload_len);
946 proto_item_append_text(ti, ", Payload Length: %u", tgen_payload_len);
947 col_append_str_uint(pinfo->cinfo, COL_INFO, "Len", tgen_payload_len, ", ");
948 offset += 2;
950 /* Try to construct a tvbuff containing only
951 the data specified by the tgen_payload_len field. */
953 TRY {
954 tgen_payload_tvb = tvb_new_subset_length(tvb, offset, tgen_payload_len);
956 CATCH_BOUNDS_ERRORS {
957 /* So:
958 the packet doesn't have "tgen_payload_len" bytes worth of
959 captured data left in it so the "tvb_new_subset_length()"
960 creating "payload_tvb" threw an exception
962 This means that all the data in the frame is within the
963 length value, so we give all the data to the payload. */
964 tgen_payload_tvb = tvb_new_subset_remaining(tvb, offset);
966 ENDTRY;
968 /* Get the TGen payload captured length. */
969 uint16_t tgen_payload_captured_len = tvb_captured_length(tgen_payload_tvb);
971 /* Add the TGen payload to the tree, with a heading that displays
972 the TGgen payload captured length. */
973 ti = proto_tree_add_none_format(avsp_tree, hf_avsp_tgen_payload,
974 tgen_payload_tvb, 0, -1, "TGen Payload (%u byte%s)",
975 tgen_payload_captured_len,
976 plurality(tgen_payload_captured_len, "", "s"));
977 avsp_tgen_payload = proto_item_add_subtree(ti, ett_avsp_tgen_payload);
978 proto_tree_add_item(avsp_tgen_payload, hf_avsp_tgen_payload_data, tgen_payload_tvb,
979 0, -1, ENC_NA);
981 /* Now we know the TGen payload captured length (which may be less than
982 that specified in the TGen header because the captured frame may have
983 been truncated) we can set the length of the entire AVSP protocol. */
984 proto_item_set_len(avsp_ti, offset + tgen_payload_captured_len);
986 /* We have a length field, so set it here so that the higher level
987 * (ethertype) dissector can add the trailer. That way the FCS
988 * will be calculated correctly.
990 set_actual_length(tvb, offset + tgen_payload_captured_len);
991 break;
993 default:
994 expert_add_info_format(pinfo, avsp_ti, &ei_avsp_tgen_unknown_version,
995 "Unknown version: 0x%0x", version);
996 return tvb_captured_length(tvb);
998 break;
1000 default:
1001 expert_add_info_format(pinfo, avsp_ti, &ei_avsp_unknown_subtype,
1002 "Unknown subtype: 0x%0x", subtype);
1003 return tvb_captured_length(tvb);
1005 return tvb_captured_length(tvb);
1008 void proto_reg_handoff_avsp(void)
1010 dissector_add_uint("ethertype", ETHERTYPE_AVSP, avsp_handle);
1011 ethertype_handle = find_dissector_add_dependency("ethertype", proto_avsp);
1012 dissector_add_uint("gre.proto", ETHERTYPE_AVSP, avsp_handle);
1015 void proto_register_avsp(void)
1017 /* Field Registration */
1018 static hf_register_info hf[] = {
1019 /* For avsp */
1020 {&hf_avsp_subtype,
1021 {"Subtype", "avsp.subtype",
1022 FT_UINT16, BASE_HEX,
1023 VALS(arista_subtypes), 0x0,
1024 NULL, HFILL}
1026 {&hf_avsp_ts_version,
1027 {"Version", "avsp.ts.ver",
1028 FT_UINT16, BASE_HEX,
1029 VALS(ts_versions), 0x0,
1030 NULL, HFILL}
1032 {&hf_avsp_ts_64_tai,
1033 {"Timestamp (TAI)", "avsp.ts.64.tai",
1034 FT_NONE, BASE_NONE,
1035 NULL, 0x0,
1036 NULL, HFILL}
1038 {&hf_avsp_ts_64_utc,
1039 {"Timestamp (UTC)", "avsp.ts.64.utc",
1040 FT_NONE, BASE_NONE,
1041 NULL, 0x0,
1042 NULL, HFILL}
1044 {&hf_avsp_ts_64_sec,
1045 {"Seconds", "avsp.ts.64.sec",
1046 FT_UINT32, BASE_DEC,
1047 NULL, 0x0,
1048 NULL, HFILL}
1050 {&hf_avsp_ts_64_ns,
1051 {"Nanoseconds", "avsp.ts.64.ns",
1052 FT_UINT32, BASE_DEC,
1053 NULL, 0x0,
1054 NULL, HFILL}
1056 {&hf_avsp_ts_48_tai,
1057 {"Timestamp (TAI)", "avsp.ts.48.tai",
1058 FT_NONE, BASE_NONE,
1059 NULL, 0x0,
1060 NULL, HFILL}
1062 {&hf_avsp_ts_48_utc,
1063 {"Timestamp (UTC)", "avsp.ts.48.utc",
1064 FT_NONE, BASE_NONE,
1065 NULL, 0x0,
1066 NULL, HFILL}
1068 {&hf_avsp_ts_48_sec,
1069 {"Seconds", "avsp.ts.48.sec",
1070 FT_UINT16, BASE_DEC,
1071 NULL, 0x0,
1072 NULL, HFILL}
1074 {&hf_avsp_ts_48_ns,
1075 {"Nanoseconds", "avsp.ts.48.ns",
1076 FT_UINT32, BASE_DEC,
1077 NULL, 0x0,
1078 NULL, HFILL}
1080 {&hf_avsp_etype,
1081 {"Type", "avsp.etype",
1082 FT_UINT16, BASE_HEX,
1083 VALS(etype_vals), 0x0,
1084 "Ethertype", HFILL}
1086 {&hf_avsp_trailer,
1087 {"Trailer", "avsp.trailer",
1088 FT_BYTES, BASE_NONE,
1089 NULL, 0x0,
1090 "AVSP Trailer", HFILL}
1092 {&hf_avsp_greentap_version,
1093 {"Version", "avsp.greentap.ver",
1094 FT_UINT16, BASE_DEC,
1095 VALS(greentap_versions), 0x0,
1096 NULL, HFILL}
1098 {&hf_avsp_greentap_tai,
1099 {"Timestamp (TAI)", "avsp.greentap.tai",
1100 FT_NONE, BASE_NONE,
1101 NULL, 0x0,
1102 NULL, HFILL}
1104 {&hf_avsp_greentap_utc,
1105 {"Timestamp (UTC)", "avsp.greentap.utc",
1106 FT_NONE, BASE_NONE,
1107 NULL, 0x0,
1108 NULL, HFILL}
1110 {&hf_avsp_greentap_sec,
1111 {"Seconds", "avsp.greentap.sec",
1112 FT_UINT16, BASE_DEC,
1113 NULL, 0x0,
1114 NULL, HFILL}
1116 {&hf_avsp_greentap_ns,
1117 {"Nanoseconds", "avsp.greentap.ns",
1118 FT_UINT32, BASE_DEC,
1119 NULL, 0x0,
1120 NULL, HFILL}
1122 {&hf_avsp_greent_version,
1123 {"Version", "avsp.greent.ver",
1124 FT_UINT16, BASE_DEC,
1125 VALS(greent_versions), 0x0,
1126 NULL, HFILL}
1128 {&hf_avsp_greent_hdr,
1129 {"GREENT Header", "avsp.greent.hdr",
1130 FT_NONE, BASE_NONE,
1131 NULL, 0x0,
1132 NULL, HFILL}
1134 {&hf_avsp_greent_session,
1135 {"Session ID", "avsp.greent.session",
1136 FT_UINT16, BASE_DEC,
1137 NULL, 0x0,
1138 NULL, HFILL}
1140 {&hf_avsp_greent_flags,
1141 {"Flags", "avsp.greent.flags",
1142 FT_UINT8, BASE_HEX,
1143 NULL, 0x0,
1144 NULL, HFILL}
1146 {&hf_avsp_greent_sample_count,
1147 {"Sample Count", "avsp.greent.sample_count",
1148 FT_UINT8, BASE_DEC,
1149 NULL, 0x0,
1150 NULL, HFILL}
1152 {&hf_avsp_greent_sample_hdr,
1153 {"Sample Header", "avsp.greent.sample.hdr",
1154 FT_NONE, BASE_NONE,
1155 NULL, 0x0,
1156 NULL, HFILL}
1158 {&hf_avsp_greent_sample_len,
1159 {"Length", "avsp.greent.sample.len",
1160 FT_UINT16, BASE_DEC,
1161 NULL, 0x0,
1162 NULL, HFILL}
1164 {&hf_avsp_greent_sample_sec,
1165 {"Seconds", "avsp.greent.sample.sec",
1166 FT_UINT16, BASE_DEC,
1167 NULL, 0x0,
1168 NULL, HFILL}
1170 {&hf_avsp_greent_sample_ns,
1171 {"Nanoseconds", "avsp.greent.sample.ns",
1172 FT_UINT32, BASE_DEC,
1173 NULL, 0x0,
1174 NULL, HFILL}
1176 {&hf_avsp_greent_sample_ingress,
1177 {"Ingress Interface", "avsp.greent.sample.ingress",
1178 FT_UINT32, BASE_DEC,
1179 NULL, 0x0,
1180 NULL, HFILL}
1182 {&hf_avsp_greent_sample_egress,
1183 {"Egress Interface", "avsp.greent.sample.egress",
1184 FT_UINT32, BASE_DEC,
1185 NULL, 0x0,
1186 NULL, HFILL}
1188 {&hf_avsp_greent_sample_rate,
1189 {"Rate(*1K)", "avsp.greent.sample.rate",
1190 FT_UINT16, BASE_DEC,
1191 NULL, 0x0,
1192 NULL, HFILL}
1194 {&hf_avsp_greent_sample_sum,
1195 {"Checksum", "avsp.greent.sample.sum",
1196 FT_UINT16, BASE_HEX,
1197 NULL, 0x0,
1198 NULL, HFILL}
1200 {&hf_avsp_greent_sample_data,
1201 {"Header of sampled packet", "avsp.greent.sample.data",
1202 FT_BYTES, BASE_NONE,
1203 NULL, 0x0,
1204 "Data from sampled header", HFILL}
1206 {&hf_avsp_dzgre_a_version,
1207 {"Version", "avsp.dzgre_a.ver",
1208 FT_UINT16, BASE_DEC,
1209 VALS(dzgre_a_versions), 0x0,
1210 NULL, HFILL}
1212 {&hf_avsp_dzgre_a_hdr,
1213 {"DzGRE(A) Header", "avsp.dzgre_a.hdr",
1214 FT_NONE, BASE_NONE,
1215 NULL, 0x0,
1216 NULL, HFILL}
1218 {&hf_avsp_dzgre_a_switch,
1219 {"Switch ID", "avsp.dzgre_a.switch",
1220 FT_UINT16, BASE_DEC,
1221 NULL, 0x0,
1222 NULL, HFILL}
1224 {&hf_avsp_dzgre_a_port,
1225 {"Port ID", "avsp.dzgre_a.port",
1226 FT_UINT16, BASE_DEC,
1227 NULL, 0x0,
1228 NULL, HFILL}
1230 {&hf_avsp_dzgre_a_policy,
1231 {"Policy ID", "avsp.dzgre_a.policy",
1232 FT_UINT16, BASE_DEC,
1233 NULL, 0x0,
1234 NULL, HFILL}
1236 {&hf_avsp_dzgre_a_reserved,
1237 {"Reserved", "avsp.dzgre_a.reserved",
1238 FT_UINT16, BASE_HEX,
1239 NULL, 0x0,
1240 NULL, HFILL}
1242 {&hf_avsp_dzgre_b_version,
1243 {"Version", "avsp.dzgre_b.ver",
1244 FT_UINT16, BASE_DEC,
1245 VALS(dzgre_b_versions), 0x0,
1246 NULL, HFILL}
1248 {&hf_avsp_dzgre_b_hdr,
1249 {"DzGRE(B) Header", "avsp.dzgre_b.hdr",
1250 FT_NONE, BASE_NONE,
1251 NULL, 0x0,
1252 NULL, HFILL}
1254 {&hf_avsp_dzgre_b_port,
1255 {"Port ID", "avsp.dzgre_b.port",
1256 FT_UINT16, BASE_DEC,
1257 NULL, 0x0,
1258 NULL, HFILL}
1260 {&hf_avsp_dzgre_b_policy,
1261 {"Policy ID", "avsp.dzgre_b.policy",
1262 FT_UINT16, BASE_DEC,
1263 NULL, 0x0,
1264 NULL, HFILL}
1266 {&hf_avsp_dzgre_ts_version,
1267 {"Version", "avsp.dzgre_ts.ver",
1268 FT_UINT16, BASE_DEC,
1269 VALS(dzgre_ts_versions), 0x0,
1270 NULL, HFILL}
1272 {&hf_avsp_dzgre_ts_hdr,
1273 {"DzGRE(B) Header", "avsp.dzgre_ts.hdr",
1274 FT_NONE, BASE_NONE,
1275 NULL, 0x0,
1276 NULL, HFILL}
1278 {&hf_avsp_dzgre_ts_switch,
1279 {"Switch ID", "avsp.dzgre_ts.switch",
1280 FT_UINT16, BASE_DEC,
1281 NULL, 0x0,
1282 NULL, HFILL}
1284 {&hf_avsp_dzgre_ts_port,
1285 {"Port ID", "avsp.dzgre_ts.port",
1286 FT_UINT16, BASE_DEC,
1287 NULL, 0x0,
1288 NULL, HFILL}
1290 {&hf_avsp_dzgre_ts_policy,
1291 {"Policy ID", "avsp.dzgre_ts.policy",
1292 FT_UINT16, BASE_DEC,
1293 NULL, 0x0,
1294 NULL, HFILL}
1296 {&hf_avsp_dzgre_ts_reserved,
1297 {"Reserved", "avsp.dzgre_ts.reserved",
1298 FT_UINT16, BASE_HEX,
1299 NULL, 0x0,
1300 NULL, HFILL}
1302 {&hf_avsp_dzgre_ts_tai,
1303 {"Timestamp (TAI)", "avsp.dzgre_ts.tai",
1304 FT_NONE, BASE_NONE,
1305 NULL, 0x0,
1306 NULL, HFILL}
1308 {&hf_avsp_dzgre_ts_utc,
1309 {"Timestamp (UTC)", "avsp.dzgre_ts.utc",
1310 FT_NONE, BASE_NONE,
1311 NULL, 0x0,
1312 NULL, HFILL}
1314 {&hf_avsp_dzgre_ts_sec,
1315 {"Seconds", "avsp.ts.dzgre_ts.sec",
1316 FT_UINT32, BASE_DEC,
1317 NULL, 0x0,
1318 NULL, HFILL}
1320 {&hf_avsp_dzgre_ts_ns,
1321 {"Nanoseconds", "avsp.dzgre_ts.48.ns",
1322 FT_UINT32, BASE_DEC,
1323 NULL, 0x0,
1324 NULL, HFILL}
1326 {&hf_avsp_tgen_version,
1327 {"Version", "avsp.tgen.ver",
1328 FT_UINT16, BASE_DEC,
1329 VALS(tgen_versions), 0x0,
1330 NULL, HFILL}
1332 {&hf_avsp_tgen_hdr,
1333 {"TGen Header", "avsp.tgen.hdr",
1334 FT_NONE, BASE_NONE,
1335 NULL, 0x0,
1336 NULL, HFILL}
1338 {&hf_avsp_tgen_hdr_ctrl,
1339 {"Control Word", "avsp.tgen.hdr.ctrl",
1340 FT_UINT16, BASE_HEX,
1341 NULL, 0x0,
1342 NULL, HFILL}
1344 {&hf_avsp_tgen_hdr_ctrl_fcs_inverted,
1345 {"FCS Inverted", "avsp.tgen.hdr.ctrl.fcs_inverted",
1346 FT_BOOLEAN, 16,
1347 NULL, 0x0001,
1348 NULL, HFILL}
1350 {&hf_avsp_tgen_hdr_ctrl_reserved,
1351 {"Reserved", "avsp.tgen.hdr.ctrl.reserved",
1352 FT_UINT16, BASE_HEX,
1353 NULL, 0xFFFE,
1354 NULL, HFILL}
1356 {&hf_avsp_tgen_hdr_seq_num,
1357 {"Sequence Number", "avsp.tgen.hdr.seq_num",
1358 FT_UINT16, BASE_DEC,
1359 NULL, 0x0,
1360 NULL, HFILL}
1362 {&hf_avsp_tgen_hdr_payload_len,
1363 {"Payload Length", "avsp.tgen.hdr.payload_len",
1364 FT_UINT16, BASE_DEC,
1365 NULL, 0x0,
1366 NULL, HFILL}
1368 { &hf_avsp_tgen_payload,
1369 {"TGen Payload", "avsp.tgen.payload",
1370 FT_NONE, BASE_NONE,
1371 NULL, 0x0,
1372 NULL, HFILL}
1374 { &hf_avsp_tgen_payload_data,
1375 {"Data", "avsp.tgen.payload.data",
1376 FT_BYTES, BASE_NONE,
1377 NULL, 0x0,
1378 NULL, HFILL}
1382 /* Setup protocol subtree array */
1383 static int* ett[] = {
1384 &ett_avsp, /* main avsp tree */
1385 &ett_avsp_ts_48, /* subtree above for 48 bit timestamp */
1386 &ett_avsp_ts_64, /* subtree above for 64 bit timestamp */
1387 &ett_avsp_dzgre_a_hdr, /* subtree for DzGRE plan A */
1388 &ett_avsp_dzgre_b_hdr, /* subtree for DzGRE plan B */
1389 &ett_avsp_dzgre_ts_hdr, /* subtree for DzGRE with timestamps */
1390 &ett_avsp_dzgre_ts_tai, /* subtree for DzGRE timestamp */
1391 &ett_avsp_dzgre_ts_utc, /* subtree for DzGRE timestamp */
1392 &ett_avsp_greent_hdr, /* subtree for GREENT header */
1393 &ett_avsp_greent_sample_hdr, /* subtree for GREENT sample header */
1394 &ett_avsp_greent_sample_data, /* subtree for GREENT sample data */
1395 &ett_avsp_tgen_hdr, /* subtree for TGen header */
1396 &ett_avsp_tgen_hdr_ctrl, /* subtree for TGen header control bits */
1397 &ett_avsp_tgen_payload, /* subtree for TGen payload */
1400 static ei_register_info ei[] = {
1401 { &ei_avsp_unknown_subtype, { "avsp.unknown_subtype", PI_SEQUENCE, PI_WARN, "Unknown AVSP subtype", EXPFILL}},
1402 { &ei_avsp_ts_unknown_version, { "avsp.ts.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown timestamp version", EXPFILL }},
1403 { &ei_avsp_greentap_unknown_version, { "avsp.greentap.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown GREENTAP version", EXPFILL }},
1404 { &ei_avsp_greent_unknown_version, { "avsp.greent.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown GREENT version", EXPFILL }},
1405 { &ei_avsp_dzgre_a_unknown_version, { "avsp.dzgre_a.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown DzGRE(A) version", EXPFILL }},
1406 { &ei_avsp_dzgre_b_unknown_version, { "avsp.dzgre_b.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown DzGRE(B) version", EXPFILL }},
1407 { &ei_avsp_dzgre_ts_unknown_version, { "avsp.dzgre_ts.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown DzGRE(timestamped) version", EXPFILL }},
1408 { &ei_avsp_tgen_unknown_version, { "avsp.tgen.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown TGen version", EXPFILL }},
1411 /* Register the AVSP protocol. */
1412 proto_avsp = proto_register_protocol("Arista Vendor Specific Protocol", "AVSP", "avsp");
1414 /* Register header fields and subtrees. */
1415 proto_register_field_array(proto_avsp, hf, array_length(hf));
1417 /* Register subtree types. */
1418 proto_register_subtree_array(ett, array_length(ett));
1420 /* Register the expert module. */
1421 expert_register_field_array(expert_register_protocol(proto_avsp), ei, array_length(ei));
1423 /* Register the dissector handle. */
1424 avsp_handle = register_dissector("avsp", dissect_avsp, proto_avsp);
1428 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1430 * Local variables:
1431 * c-basic-offset: 4
1432 * tab-width: 8
1433 * indent-tabs-mode: nil
1434 * End:
1436 * vi: set shiftwidth=4 tabstop=8 expandtab:
1437 * :indentSize=4:tabSize=8:noTabs=true: