/src/wireshark/epan/dissectors/packet-avsp.c
Line | Count | Source |
1 | | /* packet-avsp.c |
2 | | * Arista Vendor Specific ethertype Protocol (AVSP) |
3 | | * |
4 | | * Copyright (c) 2018-2022 by Arista Networks |
5 | | * Author: Nikhil AP <nikhilap@arista.com> |
6 | | * Author: PMcL <peterm@arista.com> |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@wireshark.org> |
10 | | * Copyright 1999 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | |
15 | | /* Arista Vendor-Specific EtherType Protocol Identifier |
16 | | * |
17 | | * Arista applied for, and received the assignment of, a vendor-specific EtherType Protocol Identifier in May of 2016. Details below: |
18 | | * |
19 | | * Ethertype number is: D28B |
20 | | * Issue date is: May 12, 2016 |
21 | | * |
22 | | * Arista Subtype 0x0001 is a Timestamp L2 Header |
23 | | * Arista Subtype 0xCAFE is a TGen L2 header |
24 | | * |
25 | | * The timestamp L2 header consists of the following fields: |
26 | | * |
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. |
31 | | * |
32 | | * The TGen L2 header consists of the following fields: |
33 | | * |
34 | | * Arista Vendor Specific Protocol EtherType (0xD28B) |
35 | | * Two-byte protocol subtype of 0xCAFE |
36 | | * Two-byte protocol version: 0x0001 |
37 | | */ |
38 | | |
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> |
45 | | |
46 | | #include <wsutil/str_util.h> |
47 | | |
48 | | #include "packet-eth.h" |
49 | | |
50 | 0 | #define ARISTA_SUBTYPE_TIMESTAMP 0x0001 |
51 | | |
52 | 0 | #define ARISTA_TIMESTAMP_64_TAI 0x0010 |
53 | 0 | #define ARISTA_TIMESTAMP_64_UTC 0x0110 |
54 | 0 | #define ARISTA_TIMESTAMP_48_TAI 0x0020 |
55 | 0 | #define ARISTA_TIMESTAMP_48_UTC 0x0120 |
56 | 0 | #define ARISTA_TIMESTAMP_64_TAI_J2 0x0011 |
57 | 0 | #define ARISTA_TIMESTAMP_64_UTC_J2 0x0111 |
58 | 0 | #define ARISTA_TIMESTAMP_48_TAI_J2 0x0021 |
59 | 0 | #define ARISTA_TIMESTAMP_48_UTC_J2 0x0121 |
60 | | |
61 | 0 | #define ARISTA_SUBTYPE_GREENTAP 0x0003 |
62 | | |
63 | 0 | #define ARISTA_GREENTAP_48_TAI 0x0020 |
64 | 0 | #define ARISTA_GREENTAP_48_UTC 0x0120 |
65 | | |
66 | 0 | #define ARISTA_SUBTYPE_GREENT 0x0004 |
67 | | |
68 | 0 | #define ARISTA_GREENT_VER_1 0x0001 |
69 | | |
70 | 0 | #define ARISTA_SUBTYPE_DZGRE_A 0x0007 |
71 | | |
72 | 0 | #define ARISTA_DZGRE_A_VER_1 0x0001 |
73 | | |
74 | 0 | #define ARISTA_SUBTYPE_DZGRE_B 0x0008 |
75 | | |
76 | 0 | #define ARISTA_DZGRE_B_VER_1 0x0001 |
77 | | |
78 | 0 | #define ARISTA_SUBTYPE_DZGRE_TS 0x0009 |
79 | | |
80 | 0 | #define ARISTA_DZGRE_TS_64_TAI 0x0011 |
81 | 0 | #define ARISTA_DZGRE_TS_64_UTC 0x0111 |
82 | | |
83 | 0 | #define ARISTA_SUBTYPE_TGEN 0xCAFE |
84 | 0 | #define ARISTA_TGEN_VER_1 0x0001 |
85 | | |
86 | 0 | #define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) |
87 | | |
88 | | void proto_reg_handoff_avsp(void); |
89 | | void proto_register_avsp(void); |
90 | | |
91 | | static dissector_handle_t avsp_handle; |
92 | | static int proto_avsp; |
93 | | |
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; |
109 | | |
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; |
121 | | |
122 | | static int hf_avsp_etype; |
123 | | static int hf_avsp_trailer; |
124 | | |
125 | | /* |
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 | | +---------------+---------------+---------------+---------------+ |
135 | | */ |
136 | | |
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; |
143 | | |
144 | | /* |
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 | | +---------------+---------------+---------------+---------------+ |
152 | | |
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 | | +---------------+---------------+---------------+---------------+ |
168 | | */ |
169 | | |
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; |
176 | | |
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; |
187 | | |
188 | | /* |
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 | | +---------------+---------------+---------------+---------------+ |
198 | | |
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 | | +---------------+---------------+---------------+---------------+ |
206 | | |
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 | | +---------------+---------------+---------------+---------------+ |
220 | | */ |
221 | | |
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; |
229 | | |
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; |
234 | | |
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; |
245 | | |
246 | | /* |
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 | | +---------------+---------------+---------------+---------------+ |
262 | | */ |
263 | | |
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; |
274 | | |
275 | | static int* const avsp_tgen_ctrl[] = { |
276 | | &hf_avsp_tgen_hdr_ctrl_fcs_inverted, |
277 | | &hf_avsp_tgen_hdr_ctrl_reserved, |
278 | | NULL |
279 | | }; |
280 | | |
281 | | static dissector_handle_t ethertype_handle; |
282 | | |
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} |
292 | | }; |
293 | | |
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} |
304 | | }; |
305 | | |
306 | | static const value_string greentap_versions[] = { |
307 | | {ARISTA_GREENTAP_48_TAI, "48bit TAI"}, |
308 | | {ARISTA_GREENTAP_48_UTC, "48bit UTC"}, |
309 | | {0, NULL} |
310 | | }; |
311 | | |
312 | | static const value_string greent_versions[] = { |
313 | | {ARISTA_GREENT_VER_1, "1"}, |
314 | | {0, NULL} |
315 | | }; |
316 | | |
317 | | static const value_string dzgre_a_versions[] = { |
318 | | {ARISTA_DZGRE_A_VER_1, "1"}, |
319 | | {0, NULL} |
320 | | }; |
321 | | |
322 | | static const value_string dzgre_b_versions[] = { |
323 | | {ARISTA_DZGRE_A_VER_1, "1"}, |
324 | | {0, NULL} |
325 | | }; |
326 | | |
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} |
331 | | }; |
332 | | |
333 | | static const value_string tgen_versions[] = { |
334 | | {ARISTA_TGEN_VER_1, "1"}, |
335 | | {0, NULL} |
336 | | }; |
337 | | |
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; |
346 | | |
347 | | static int |
348 | | dissect_avsp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) |
349 | 0 | { |
350 | 0 | volatile int offset = 0; |
351 | 0 | uint32_t version, subtype, tgen_payload_len = 0; |
352 | 0 | uint64_t tgen_ctrl; |
353 | 0 | uint32_t tgen_seq_num, sample_len, count, u32; |
354 | 0 | volatile uint32_t i; // potentially held across vfork |
355 | 0 | const char* str; |
356 | 0 | uint16_t encap_proto; |
357 | 0 | ethertype_data_t ethertype_data; |
358 | 0 | tvbuff_t* volatile tgen_payload_tvb = NULL; |
359 | |
|
360 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVSP"); |
361 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
362 | |
|
363 | 0 | proto_item* avsp_ti, * ti; |
364 | 0 | proto_tree* avsp_tree, * avsp_48_tree = NULL, * avsp_64_tree = NULL, |
365 | 0 | * avsp_tgen_hdr = NULL, * avsp_tgen_payload = NULL, |
366 | 0 | * avsp_dzgre_hdr = NULL, * avsp_greent_hdr = NULL, |
367 | 0 | * avsp_greent_sample_hdr = NULL, *header_tree = NULL; |
368 | | |
369 | | /* Adding Items and Values to the Protocol Tree */ |
370 | 0 | avsp_ti = proto_tree_add_item(tree, proto_avsp, tvb, 0, -1, |
371 | 0 | ENC_NA); |
372 | 0 | avsp_tree = proto_item_add_subtree(avsp_ti, ett_avsp); |
373 | | |
374 | | /* add the subtype to avsp */ |
375 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_subtype, tvb, |
376 | 0 | offset, 2, ENC_BIG_ENDIAN, &subtype); |
377 | 0 | str = try_val_to_str(subtype, arista_subtypes); |
378 | 0 | if (str) { |
379 | 0 | proto_item_append_text(avsp_ti, ", Subtype: %s", str); |
380 | 0 | } |
381 | 0 | offset += 2; |
382 | | |
383 | | /* Based on the subtype, add the version and further custom protocol fields */ |
384 | 0 | switch (subtype) { |
385 | 0 | case ARISTA_SUBTYPE_TIMESTAMP: |
386 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_ts_version, tvb, offset, |
387 | 0 | 2, ENC_BIG_ENDIAN, &version); |
388 | 0 | str = try_val_to_str(version, ts_versions); |
389 | 0 | if (str) { |
390 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
391 | 0 | } |
392 | 0 | offset += 2; |
393 | |
|
394 | 0 | switch (version) { |
395 | 0 | case ARISTA_TIMESTAMP_64_TAI: |
396 | 0 | case ARISTA_TIMESTAMP_64_TAI_J2: |
397 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_64_tai, tvb, 0, -1, |
398 | 0 | ENC_NA); |
399 | 0 | avsp_64_tree = proto_item_add_subtree(ti, ett_avsp); |
400 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "64bit TAI timestamp"); |
401 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_sec, tvb, offset, |
402 | 0 | 4, ENC_BIG_ENDIAN); |
403 | 0 | offset += 4; |
404 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_ns, tvb, offset, |
405 | 0 | 4, ENC_BIG_ENDIAN); |
406 | 0 | offset += 4; |
407 | 0 | break; |
408 | 0 | case ARISTA_TIMESTAMP_64_UTC: |
409 | 0 | case ARISTA_TIMESTAMP_64_UTC_J2: |
410 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_64_utc, tvb, 0, -1, |
411 | 0 | ENC_NA); |
412 | 0 | avsp_64_tree = proto_item_add_subtree(ti, ett_avsp); |
413 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "64bit UTC timestamp"); |
414 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_sec, tvb, offset, |
415 | 0 | 4, ENC_BIG_ENDIAN); |
416 | 0 | offset += 4; |
417 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_ns, tvb, offset, |
418 | 0 | 4, ENC_BIG_ENDIAN); |
419 | 0 | offset += 4; |
420 | 0 | break; |
421 | 0 | case ARISTA_TIMESTAMP_48_TAI: |
422 | 0 | case ARISTA_TIMESTAMP_48_TAI_J2: |
423 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_48_tai, tvb, 0, -1, |
424 | 0 | ENC_NA); |
425 | 0 | avsp_48_tree = proto_item_add_subtree(ti, ett_avsp); |
426 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp"); |
427 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_sec, tvb, offset, |
428 | 0 | 2, ENC_BIG_ENDIAN); |
429 | 0 | offset += 2; |
430 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_ns, tvb, offset, |
431 | 0 | 4, ENC_BIG_ENDIAN); |
432 | 0 | offset += 4; |
433 | 0 | break; |
434 | 0 | case ARISTA_TIMESTAMP_48_UTC: |
435 | 0 | case ARISTA_TIMESTAMP_48_UTC_J2: |
436 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_48_utc, tvb, 0, -1, |
437 | 0 | ENC_NA); |
438 | 0 | avsp_48_tree = proto_item_add_subtree(ti, ett_avsp); |
439 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "48bit UTC timestamp"); |
440 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_sec, tvb, offset, |
441 | 0 | 2, ENC_BIG_ENDIAN); |
442 | 0 | offset += 2; |
443 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_ns, tvb, offset, |
444 | 0 | 4, ENC_BIG_ENDIAN); |
445 | 0 | offset += 4; |
446 | 0 | break; |
447 | 0 | default: |
448 | 0 | expert_add_info_format(pinfo, avsp_ti, &ei_avsp_ts_unknown_version, |
449 | 0 | "Unknown timestamp version: 0x%0x", version); |
450 | 0 | return tvb_captured_length(tvb); |
451 | 0 | } |
452 | | |
453 | 0 | encap_proto = tvb_get_ntohs(tvb, offset); |
454 | 0 | proto_tree_add_uint(avsp_tree, hf_avsp_etype, tvb, offset, 2, encap_proto); |
455 | 0 | offset += 2; |
456 | |
|
457 | 0 | ethertype_data.etype = encap_proto; |
458 | 0 | ethertype_data.payload_offset = offset; |
459 | 0 | ethertype_data.fh_tree = avsp_tree; |
460 | 0 | ethertype_data.trailer_id = hf_avsp_trailer; |
461 | 0 | ethertype_data.fcs_len = 0; |
462 | |
|
463 | 0 | call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, ðertype_data); |
464 | 0 | break; |
465 | | |
466 | 0 | case ARISTA_SUBTYPE_GREENTAP: |
467 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_greentap_version, tvb, |
468 | 0 | offset, 2, ENC_BIG_ENDIAN, &version); |
469 | 0 | str = try_val_to_str(version, greentap_versions); |
470 | 0 | if (str) { |
471 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
472 | 0 | } |
473 | 0 | offset += 2; |
474 | |
|
475 | 0 | switch (version) { |
476 | 0 | case ARISTA_GREENTAP_48_TAI: |
477 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_greentap_tai, tvb, |
478 | 0 | 0, -1, ENC_NA); |
479 | 0 | avsp_48_tree = proto_item_add_subtree(ti, ett_avsp); |
480 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp"); |
481 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_sec, |
482 | 0 | tvb, offset, 2, ENC_BIG_ENDIAN); |
483 | 0 | offset += 2; |
484 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_ns, |
485 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN); |
486 | 0 | offset += 4; |
487 | 0 | break; |
488 | 0 | case ARISTA_GREENTAP_48_UTC: |
489 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_greentap_utc, tvb, |
490 | 0 | 0, -1, ENC_NA); |
491 | 0 | avsp_48_tree = proto_item_add_subtree(ti, ett_avsp); |
492 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp"); |
493 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_sec, |
494 | 0 | tvb, offset, 2, ENC_BIG_ENDIAN); |
495 | 0 | offset += 2; |
496 | 0 | proto_tree_add_item(avsp_48_tree, hf_avsp_greentap_ns, |
497 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN); |
498 | 0 | offset += 4; |
499 | 0 | break; |
500 | 0 | default: |
501 | 0 | expert_add_info_format(pinfo, avsp_ti, |
502 | 0 | &ei_avsp_greentap_unknown_version, |
503 | 0 | "Unknown GRE TAP version: 0x%0x", version); |
504 | 0 | return tvb_captured_length(tvb); |
505 | 0 | } |
506 | | |
507 | 0 | encap_proto = tvb_get_ntohs(tvb, offset); |
508 | 0 | proto_tree_add_uint(avsp_tree, hf_avsp_etype, tvb, offset, 2, |
509 | 0 | encap_proto); |
510 | 0 | offset += 2; |
511 | |
|
512 | 0 | ethertype_data.etype = encap_proto; |
513 | 0 | ethertype_data.payload_offset = offset; |
514 | 0 | ethertype_data.fh_tree = avsp_tree; |
515 | 0 | ethertype_data.trailer_id = hf_avsp_trailer; |
516 | 0 | ethertype_data.fcs_len = 0; |
517 | |
|
518 | 0 | call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, |
519 | 0 | ðertype_data); |
520 | 0 | break; |
521 | | |
522 | 0 | case ARISTA_SUBTYPE_GREENT: |
523 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_greent_version, tvb, |
524 | 0 | offset, 2, ENC_BIG_ENDIAN, &version); |
525 | 0 | str = try_val_to_str(version, greent_versions); |
526 | 0 | if (str) { |
527 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
528 | 0 | } |
529 | 0 | offset += 2; |
530 | |
|
531 | 0 | switch (version) { |
532 | 0 | case ARISTA_GREENT_VER_1: |
533 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Arista Postcard Telemetry"); |
534 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_greent_hdr, tvb, 0, |
535 | 0 | -1, ENC_NA); |
536 | 0 | avsp_greent_hdr = proto_item_add_subtree(ti, ett_avsp_greent_hdr); |
537 | | |
538 | | /* Session ID */ |
539 | 0 | proto_tree_add_item_ret_uint(avsp_greent_hdr, |
540 | 0 | hf_avsp_greent_session, tvb, offset, 2, ENC_BIG_ENDIAN, |
541 | 0 | &u32); |
542 | 0 | proto_item_append_text(ti, ", Session ID: %u", u32); |
543 | 0 | offset += 2; |
544 | | |
545 | | /* Flags */ |
546 | 0 | proto_tree_add_item_ret_uint(avsp_greent_hdr, |
547 | 0 | hf_avsp_greent_flags, tvb, offset, 1, ENC_BIG_ENDIAN, |
548 | 0 | &u32); |
549 | 0 | proto_item_append_text(ti, ", Flags: 0x%02x", u32); |
550 | 0 | offset += 1; |
551 | | |
552 | | /* Sample Count */ |
553 | 0 | proto_tree_add_item_ret_uint(avsp_greent_hdr, |
554 | 0 | hf_avsp_greent_sample_count, tvb, offset, 1, ENC_BIG_ENDIAN, |
555 | 0 | &count); |
556 | 0 | proto_item_append_text(ti, ", Count: %u", count); |
557 | 0 | offset += 1; |
558 | |
|
559 | 0 | for (i = 0; i < count; i++) { |
560 | 0 | ti = proto_tree_add_item(avsp_greent_hdr, |
561 | 0 | hf_avsp_greent_sample_hdr, tvb, 0, -1, ENC_NA); |
562 | 0 | avsp_greent_sample_hdr = proto_item_add_subtree(ti, |
563 | 0 | ett_avsp_greent_sample_hdr); |
564 | | |
565 | | /* Length */ |
566 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
567 | 0 | hf_avsp_greent_sample_len, tvb, offset, 2, |
568 | 0 | ENC_BIG_ENDIAN, &sample_len); |
569 | 0 | proto_item_append_text(ti, ", Length: %u", sample_len); |
570 | 0 | offset += 2; |
571 | | |
572 | | /* Seconds */ |
573 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
574 | 0 | hf_avsp_greent_sample_sec, tvb, offset, 2, |
575 | 0 | ENC_BIG_ENDIAN, &u32); |
576 | 0 | proto_item_append_text(ti, ", Seconds: %u", u32); |
577 | 0 | offset += 2; |
578 | | |
579 | | /* Nanoseconds */ |
580 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
581 | 0 | hf_avsp_greent_sample_ns, tvb, offset, 4, |
582 | 0 | ENC_BIG_ENDIAN, &u32); |
583 | 0 | proto_item_append_text(ti, ", Nanoseconds: %u", u32); |
584 | 0 | offset += 4; |
585 | | |
586 | | /* Ingress */ |
587 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
588 | 0 | hf_avsp_greent_sample_ingress, tvb, offset, 4, |
589 | 0 | ENC_BIG_ENDIAN, &u32); |
590 | 0 | proto_item_append_text(ti, ", Ingress: %u", u32); |
591 | 0 | offset += 4; |
592 | | |
593 | | /* Egress */ |
594 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
595 | 0 | hf_avsp_greent_sample_egress, tvb, offset, 4, |
596 | 0 | ENC_BIG_ENDIAN, &u32); |
597 | 0 | proto_item_append_text(ti, ", Egress: %u", u32); |
598 | 0 | offset += 4; |
599 | | |
600 | | /* Sample Rate */ |
601 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
602 | 0 | hf_avsp_greent_sample_rate, tvb, offset, 2, |
603 | 0 | ENC_BIG_ENDIAN, &u32); |
604 | 0 | proto_item_append_text(ti, ", Rate: %u", u32); |
605 | 0 | offset += 2; |
606 | | |
607 | | /* Checksum */ |
608 | 0 | proto_tree_add_item_ret_uint(avsp_greent_sample_hdr, |
609 | 0 | hf_avsp_greent_sample_sum, tvb, offset, 2, |
610 | 0 | ENC_BIG_ENDIAN, &u32); |
611 | 0 | proto_item_append_text(ti, ", Checksum: 0x%04x", u32); |
612 | 0 | offset += 2; |
613 | | |
614 | | /* Sample Data */ |
615 | 0 | ti = proto_tree_add_item(avsp_greent_sample_hdr, |
616 | 0 | hf_avsp_greent_sample_data, tvb, offset, sample_len, |
617 | 0 | ENC_NA); |
618 | 0 | header_tree = proto_item_add_subtree(ti, |
619 | 0 | ett_avsp_greent_sample_data); |
620 | | |
621 | | /* |
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. |
626 | | */ |
627 | 0 | { |
628 | 0 | tvbuff_t *next_tvb; |
629 | 0 | address save_dl_src, save_dl_dst, save_net_src, |
630 | 0 | save_net_dst, save_src, save_dst; |
631 | 0 | bool save_writable, save_in_error_pkt; |
632 | |
|
633 | 0 | sample_len = ROUNDUP(sample_len, 4); |
634 | 0 | next_tvb = tvb_new_subset_length(tvb, offset, sample_len); |
635 | |
|
636 | 0 | save_in_error_pkt = pinfo->flags.in_error_pkt; |
637 | 0 | pinfo->flags.in_error_pkt = true; |
638 | |
|
639 | 0 | save_writable = col_get_writable(pinfo->cinfo, -1); |
640 | 0 | col_set_writable(pinfo->cinfo, -1, false); |
641 | 0 | copy_address_shallow(&save_dl_src, &pinfo->dl_src); |
642 | 0 | copy_address_shallow(&save_dl_dst, &pinfo->dl_dst); |
643 | 0 | copy_address_shallow(&save_net_src, &pinfo->net_src); |
644 | 0 | copy_address_shallow(&save_net_dst, &pinfo->net_dst); |
645 | 0 | copy_address_shallow(&save_src, &pinfo->src); |
646 | 0 | copy_address_shallow(&save_dst, &pinfo->dst); |
647 | |
|
648 | 0 | TRY |
649 | 0 | { |
650 | | // always ethernet for greent |
651 | 0 | ethertype_data.etype = ETHERTYPE_ETHBRIDGE; |
652 | 0 | ethertype_data.payload_offset = 0; |
653 | 0 | ethertype_data.fh_tree = header_tree; |
654 | 0 | ethertype_data.trailer_id = hf_avsp_trailer; |
655 | 0 | ethertype_data.fcs_len = 0; |
656 | |
|
657 | 0 | call_dissector_with_data(ethertype_handle, next_tvb, |
658 | 0 | pinfo, header_tree, ðertype_data); |
659 | 0 | } |
660 | 0 | CATCH_BOUNDS_ERRORS { |
661 | 0 | } |
662 | 0 | ENDTRY; |
663 | |
|
664 | 0 | col_set_writable(pinfo->cinfo, -1, save_writable); |
665 | 0 | pinfo->flags.in_error_pkt = save_in_error_pkt; |
666 | 0 | copy_address_shallow(&pinfo->dl_src, &save_dl_src); |
667 | 0 | copy_address_shallow(&pinfo->dl_dst, &save_dl_dst); |
668 | 0 | copy_address_shallow(&pinfo->net_src, &save_net_src); |
669 | 0 | copy_address_shallow(&pinfo->net_dst, &save_net_dst); |
670 | 0 | copy_address_shallow(&pinfo->src, &save_src); |
671 | 0 | copy_address_shallow(&pinfo->dst, &save_dst); |
672 | 0 | } |
673 | 0 | } |
674 | 0 | break; |
675 | 0 | default: |
676 | 0 | expert_add_info_format(pinfo, avsp_ti, |
677 | 0 | &ei_avsp_greent_unknown_version, |
678 | 0 | "Unknown version: 0x%0x", version); |
679 | 0 | return tvb_captured_length(tvb); |
680 | 0 | } |
681 | 0 | break; |
682 | | |
683 | 0 | case ARISTA_SUBTYPE_DZGRE_A: |
684 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_dzgre_a_version, tvb, |
685 | 0 | offset, 2, ENC_BIG_ENDIAN, &version); |
686 | 0 | str = try_val_to_str(version, dzgre_a_versions); |
687 | 0 | if (str) { |
688 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
689 | 0 | } |
690 | 0 | offset += 2; |
691 | |
|
692 | 0 | switch (version) { |
693 | 0 | case ARISTA_DZGRE_A_VER_1: |
694 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Arista DzGRE(A) Frame"); |
695 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_a_hdr, tvb, |
696 | 0 | 0, -1, ENC_NA); |
697 | 0 | avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_a_hdr); |
698 | | |
699 | | /* Switch ID */ |
700 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
701 | 0 | hf_avsp_dzgre_a_switch, tvb, offset, 2, ENC_BIG_ENDIAN, |
702 | 0 | &u32); |
703 | 0 | proto_item_append_text(ti, ", Switch ID: %u", u32); |
704 | 0 | offset += 2; |
705 | | |
706 | | /* Port ID */ |
707 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
708 | 0 | hf_avsp_dzgre_a_port, tvb, offset, 2, ENC_BIG_ENDIAN, |
709 | 0 | &u32); |
710 | 0 | proto_item_append_text(ti, ", Port ID: %u", u32); |
711 | 0 | offset += 2; |
712 | | |
713 | | /* Policy ID */ |
714 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
715 | 0 | hf_avsp_dzgre_a_policy, tvb, offset, 2, ENC_BIG_ENDIAN, |
716 | 0 | &u32); |
717 | 0 | proto_item_append_text(ti, ", Policy ID: %u", u32); |
718 | 0 | offset += 2; |
719 | | |
720 | | /* Reserved */ |
721 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
722 | 0 | hf_avsp_dzgre_a_reserved, tvb, offset, 2, ENC_BIG_ENDIAN, |
723 | 0 | &u32); |
724 | 0 | offset += 2; |
725 | 0 | break; |
726 | 0 | default: |
727 | 0 | expert_add_info_format(pinfo, avsp_ti, |
728 | 0 | &ei_avsp_dzgre_a_unknown_version, |
729 | 0 | "Unknown version: 0x%0x", version); |
730 | 0 | return tvb_captured_length(tvb); |
731 | 0 | } |
732 | | |
733 | 0 | ethertype_data.etype = ETHERTYPE_ETHBRIDGE; // always ethernet |
734 | 0 | ethertype_data.payload_offset = offset; |
735 | 0 | ethertype_data.fh_tree = avsp_tree; |
736 | 0 | ethertype_data.trailer_id = hf_avsp_trailer; |
737 | 0 | ethertype_data.fcs_len = 0; |
738 | |
|
739 | 0 | call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, |
740 | 0 | ðertype_data); |
741 | 0 | break; |
742 | | |
743 | 0 | case ARISTA_SUBTYPE_DZGRE_B: |
744 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_dzgre_b_version, tvb, |
745 | 0 | offset, 2, ENC_BIG_ENDIAN, &version); |
746 | 0 | str = try_val_to_str(version, dzgre_b_versions); |
747 | 0 | if (str) { |
748 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
749 | 0 | } |
750 | 0 | offset += 2; |
751 | |
|
752 | 0 | switch (version) { |
753 | 0 | case ARISTA_DZGRE_B_VER_1: |
754 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Arista DzGRE(B) Frame"); |
755 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_b_hdr, tvb, |
756 | 0 | 0, -1, ENC_NA); |
757 | 0 | avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_b_hdr); |
758 | | |
759 | | /* Port ID */ |
760 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
761 | 0 | hf_avsp_dzgre_b_port, tvb, offset, 2, ENC_BIG_ENDIAN, |
762 | 0 | &u32); |
763 | 0 | proto_item_append_text(ti, ", Port ID: %u", u32); |
764 | 0 | offset += 2; |
765 | | |
766 | | /* Policy ID */ |
767 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
768 | 0 | hf_avsp_dzgre_b_policy, tvb, offset, 2, ENC_BIG_ENDIAN, |
769 | 0 | &u32); |
770 | 0 | proto_item_append_text(ti, ", Policy ID: %u", u32); |
771 | 0 | offset += 2; |
772 | 0 | break; |
773 | 0 | default: |
774 | 0 | expert_add_info_format(pinfo, avsp_ti, |
775 | 0 | &ei_avsp_dzgre_b_unknown_version, |
776 | 0 | "Unknown version: 0x%0x", version); |
777 | 0 | return tvb_captured_length(tvb); |
778 | 0 | } |
779 | | |
780 | 0 | ethertype_data.etype = ETHERTYPE_ETHBRIDGE; // always ethernet |
781 | 0 | ethertype_data.payload_offset = offset; |
782 | 0 | ethertype_data.fh_tree = avsp_tree; |
783 | 0 | ethertype_data.trailer_id = hf_avsp_trailer; |
784 | 0 | ethertype_data.fcs_len = 0; |
785 | |
|
786 | 0 | call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, |
787 | 0 | ðertype_data); |
788 | 0 | break; |
789 | | |
790 | 0 | case ARISTA_SUBTYPE_DZGRE_TS: |
791 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_dzgre_ts_version, tvb, |
792 | 0 | offset, 2, ENC_BIG_ENDIAN, &version); |
793 | 0 | str = try_val_to_str(version, dzgre_ts_versions); |
794 | 0 | if (str) { |
795 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
796 | 0 | } |
797 | 0 | offset += 2; |
798 | |
|
799 | 0 | switch (version) { |
800 | 0 | case ARISTA_DZGRE_TS_64_TAI: |
801 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Arista DzGRE(A) Frame"); |
802 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_ts_hdr, tvb, |
803 | 0 | 0, -1, ENC_NA); |
804 | 0 | avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_ts_hdr); |
805 | | |
806 | | /* Switch ID */ |
807 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
808 | 0 | hf_avsp_dzgre_ts_switch, tvb, offset, 2, ENC_BIG_ENDIAN, |
809 | 0 | &u32); |
810 | 0 | proto_item_append_text(ti, ", Switch ID: %u", u32); |
811 | 0 | offset += 2; |
812 | | |
813 | | /* Port ID */ |
814 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
815 | 0 | hf_avsp_dzgre_ts_port, tvb, offset, 2, ENC_BIG_ENDIAN, |
816 | 0 | &u32); |
817 | 0 | proto_item_append_text(ti, ", Port ID: %u", u32); |
818 | 0 | offset += 2; |
819 | | |
820 | | /* Policy ID */ |
821 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
822 | 0 | hf_avsp_dzgre_ts_policy, tvb, offset, 2, ENC_BIG_ENDIAN, |
823 | 0 | &u32); |
824 | 0 | proto_item_append_text(ti, ", Policy ID: %u", u32); |
825 | 0 | offset += 2; |
826 | | |
827 | | /* Reserved */ |
828 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
829 | 0 | hf_avsp_dzgre_ts_reserved, tvb, offset, 2, ENC_BIG_ENDIAN, |
830 | 0 | &u32); |
831 | 0 | offset += 2; |
832 | | |
833 | | /* Timestamp */ |
834 | 0 | ti = proto_tree_add_item(avsp_dzgre_hdr, |
835 | 0 | hf_avsp_dzgre_ts_tai, tvb, 0, -1, ENC_NA); |
836 | 0 | avsp_64_tree = proto_item_add_subtree(ti, |
837 | 0 | ett_avsp_dzgre_ts_tai); |
838 | |
|
839 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "64bit TAI timestamp"); |
840 | |
|
841 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_sec, |
842 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN); |
843 | 0 | offset += 4; |
844 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_ns, |
845 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN); |
846 | 0 | offset += 4; |
847 | 0 | break; |
848 | 0 | case ARISTA_DZGRE_TS_64_UTC: |
849 | 0 | col_set_str(pinfo->cinfo, COL_INFO, |
850 | 0 | "Arista DzGRE(timestamped) Frame"); |
851 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_dzgre_ts_hdr, tvb, |
852 | 0 | 0, -1, ENC_NA); |
853 | 0 | avsp_dzgre_hdr = proto_item_add_subtree(ti, ett_avsp_dzgre_ts_hdr); |
854 | | |
855 | | /* Switch ID */ |
856 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
857 | 0 | hf_avsp_dzgre_ts_switch, tvb, offset, 2, ENC_BIG_ENDIAN, |
858 | 0 | &u32); |
859 | 0 | proto_item_append_text(ti, ", Switch ID: 0x%u", u32); |
860 | 0 | offset += 2; |
861 | | |
862 | | /* Port ID */ |
863 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
864 | 0 | hf_avsp_dzgre_ts_port, tvb, offset, 2, ENC_BIG_ENDIAN, |
865 | 0 | &u32); |
866 | 0 | proto_item_append_text(ti, ", Port ID: 0x%u", u32); |
867 | 0 | offset += 2; |
868 | | |
869 | | /* Policy ID */ |
870 | 0 | proto_tree_add_item_ret_uint(avsp_dzgre_hdr, |
871 | 0 | hf_avsp_dzgre_ts_policy, tvb, offset, 2, ENC_BIG_ENDIAN, |
872 | 0 | &u32); |
873 | 0 | proto_item_append_text(ti, ", Policy ID: 0x%u", u32); |
874 | 0 | offset += 2; |
875 | | |
876 | | /* Reserved */ |
877 | 0 | offset += 2; |
878 | | |
879 | | /* Timestamp */ |
880 | 0 | ti = proto_tree_add_item(avsp_dzgre_hdr, |
881 | 0 | hf_avsp_dzgre_ts_utc, tvb, 0, -1, ENC_NA); |
882 | 0 | avsp_64_tree = proto_item_add_subtree(ti, |
883 | 0 | ett_avsp_dzgre_ts_utc); |
884 | |
|
885 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "64bit UTC timestamp"); |
886 | |
|
887 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_sec, |
888 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN); |
889 | 0 | offset += 4; |
890 | 0 | proto_tree_add_item(avsp_64_tree, hf_avsp_dzgre_ts_ns, |
891 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN); |
892 | 0 | offset += 4; |
893 | 0 | break; |
894 | 0 | default: |
895 | 0 | expert_add_info_format(pinfo, avsp_ti, |
896 | 0 | &ei_avsp_dzgre_ts_unknown_version, |
897 | 0 | "Unknown version: 0x%0x", version); |
898 | 0 | return tvb_captured_length(tvb); |
899 | 0 | } |
900 | | |
901 | 0 | ethertype_data.etype = ETHERTYPE_ETHBRIDGE; // always ethernet |
902 | 0 | ethertype_data.payload_offset = offset; |
903 | 0 | ethertype_data.fh_tree = avsp_tree; |
904 | 0 | ethertype_data.trailer_id = hf_avsp_trailer; |
905 | 0 | ethertype_data.fcs_len = 0; |
906 | |
|
907 | 0 | call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, |
908 | 0 | ðertype_data); |
909 | 0 | break; |
910 | | |
911 | 0 | case ARISTA_SUBTYPE_TGEN: |
912 | 0 | proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_tgen_version, tvb, |
913 | 0 | offset, 2, ENC_BIG_ENDIAN, &version); |
914 | 0 | str = try_val_to_str(version, tgen_versions); |
915 | 0 | if (str) { |
916 | 0 | proto_item_append_text(avsp_ti, ", Version: %s", str); |
917 | 0 | } |
918 | 0 | offset += 2; |
919 | |
|
920 | 0 | switch (version) { |
921 | 0 | case ARISTA_TGEN_VER_1: |
922 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Arista TGen Frame"); |
923 | | |
924 | | /* Get TGen Header Control Word. */ |
925 | 0 | ti = proto_tree_add_item(avsp_tree, hf_avsp_tgen_hdr, tvb, offset, 6, |
926 | 0 | ENC_NA); |
927 | 0 | avsp_tgen_hdr = proto_item_add_subtree(ti, ett_avsp_tgen_hdr); |
928 | 0 | proto_tree_add_bitmask_ret_uint64(avsp_tgen_hdr, tvb, offset, |
929 | 0 | hf_avsp_tgen_hdr_ctrl, ett_avsp_tgen_hdr_ctrl, avsp_tgen_ctrl, |
930 | 0 | ENC_BIG_ENDIAN, &tgen_ctrl); |
931 | 0 | proto_item_append_text(ti, ", Control Word: 0x%04" PRIx64, tgen_ctrl); |
932 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Ctrl=0x%04" PRIx64, tgen_ctrl); |
933 | 0 | offset += 2; |
934 | | |
935 | | /* Get TGen Header Sequence Number*/ |
936 | 0 | proto_tree_add_item_ret_uint(avsp_tgen_hdr, hf_avsp_tgen_hdr_seq_num, tvb, |
937 | 0 | offset, 2, ENC_BIG_ENDIAN, &tgen_seq_num); |
938 | 0 | proto_item_append_text(ti, ", Sequence Number: %u", tgen_seq_num); |
939 | 0 | col_append_str_uint(pinfo->cinfo, COL_INFO, "Seq", tgen_seq_num, ", "); |
940 | 0 | offset += 2; |
941 | | |
942 | | /* Get TGen Header Payload Length */ |
943 | 0 | proto_tree_add_item_ret_uint(avsp_tgen_hdr, |
944 | 0 | hf_avsp_tgen_hdr_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, |
945 | 0 | &tgen_payload_len); |
946 | 0 | proto_item_append_text(ti, ", Payload Length: %u", tgen_payload_len); |
947 | 0 | col_append_str_uint(pinfo->cinfo, COL_INFO, "Len", tgen_payload_len, ", "); |
948 | 0 | offset += 2; |
949 | | |
950 | | /* Try to construct a tvbuff containing only |
951 | | the data specified by the tgen_payload_len field. */ |
952 | |
|
953 | 0 | TRY { |
954 | 0 | tgen_payload_tvb = tvb_new_subset_length(tvb, offset, tgen_payload_len); |
955 | 0 | } |
956 | 0 | 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 |
961 | | |
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 | 0 | tgen_payload_tvb = tvb_new_subset_remaining(tvb, offset); |
965 | 0 | } |
966 | 0 | ENDTRY; |
967 | | |
968 | | /* Get the TGen payload captured length. */ |
969 | 0 | uint16_t tgen_payload_captured_len = tvb_captured_length(tgen_payload_tvb); |
970 | | |
971 | | /* Add the TGen payload to the tree, with a heading that displays |
972 | | the TGgen payload captured length. */ |
973 | 0 | ti = proto_tree_add_none_format(avsp_tree, hf_avsp_tgen_payload, |
974 | 0 | tgen_payload_tvb, 0, -1, "TGen Payload (%u byte%s)", |
975 | 0 | tgen_payload_captured_len, |
976 | 0 | plurality(tgen_payload_captured_len, "", "s")); |
977 | 0 | avsp_tgen_payload = proto_item_add_subtree(ti, ett_avsp_tgen_payload); |
978 | 0 | proto_tree_add_item(avsp_tgen_payload, hf_avsp_tgen_payload_data, tgen_payload_tvb, |
979 | 0 | 0, -1, ENC_NA); |
980 | | |
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 | 0 | proto_item_set_len(avsp_ti, offset + tgen_payload_captured_len); |
985 | | |
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. |
989 | | */ |
990 | 0 | set_actual_length(tvb, offset + tgen_payload_captured_len); |
991 | 0 | break; |
992 | | |
993 | 0 | default: |
994 | 0 | expert_add_info_format(pinfo, avsp_ti, &ei_avsp_tgen_unknown_version, |
995 | 0 | "Unknown version: 0x%0x", version); |
996 | 0 | return tvb_captured_length(tvb); |
997 | 0 | } |
998 | 0 | break; |
999 | | |
1000 | 0 | default: |
1001 | 0 | expert_add_info_format(pinfo, avsp_ti, &ei_avsp_unknown_subtype, |
1002 | 0 | "Unknown subtype: 0x%0x", subtype); |
1003 | 0 | return tvb_captured_length(tvb); |
1004 | 0 | } |
1005 | 0 | return tvb_captured_length(tvb); |
1006 | 0 | } |
1007 | | |
1008 | | void proto_reg_handoff_avsp(void) |
1009 | 15 | { |
1010 | 15 | dissector_add_uint("ethertype", ETHERTYPE_AVSP, avsp_handle); |
1011 | 15 | ethertype_handle = find_dissector_add_dependency("ethertype", proto_avsp); |
1012 | 15 | dissector_add_uint("gre.proto", ETHERTYPE_AVSP, avsp_handle); |
1013 | 15 | } |
1014 | | |
1015 | | void proto_register_avsp(void) |
1016 | 15 | { |
1017 | | /* Field Registration */ |
1018 | 15 | static hf_register_info hf[] = { |
1019 | | /* For avsp */ |
1020 | 15 | {&hf_avsp_subtype, |
1021 | 15 | {"Subtype", "avsp.subtype", |
1022 | 15 | FT_UINT16, BASE_HEX, |
1023 | 15 | VALS(arista_subtypes), 0x0, |
1024 | 15 | NULL, HFILL} |
1025 | 15 | }, |
1026 | 15 | {&hf_avsp_ts_version, |
1027 | 15 | {"Version", "avsp.ts.ver", |
1028 | 15 | FT_UINT16, BASE_HEX, |
1029 | 15 | VALS(ts_versions), 0x0, |
1030 | 15 | NULL, HFILL} |
1031 | 15 | }, |
1032 | 15 | {&hf_avsp_ts_64_tai, |
1033 | 15 | {"Timestamp (TAI)", "avsp.ts.64.tai", |
1034 | 15 | FT_NONE, BASE_NONE, |
1035 | 15 | NULL, 0x0, |
1036 | 15 | NULL, HFILL} |
1037 | 15 | }, |
1038 | 15 | {&hf_avsp_ts_64_utc, |
1039 | 15 | {"Timestamp (UTC)", "avsp.ts.64.utc", |
1040 | 15 | FT_NONE, BASE_NONE, |
1041 | 15 | NULL, 0x0, |
1042 | 15 | NULL, HFILL} |
1043 | 15 | }, |
1044 | 15 | {&hf_avsp_ts_64_sec, |
1045 | 15 | {"Seconds", "avsp.ts.64.sec", |
1046 | 15 | FT_UINT32, BASE_DEC, |
1047 | 15 | NULL, 0x0, |
1048 | 15 | NULL, HFILL} |
1049 | 15 | }, |
1050 | 15 | {&hf_avsp_ts_64_ns, |
1051 | 15 | {"Nanoseconds", "avsp.ts.64.ns", |
1052 | 15 | FT_UINT32, BASE_DEC, |
1053 | 15 | NULL, 0x0, |
1054 | 15 | NULL, HFILL} |
1055 | 15 | }, |
1056 | 15 | {&hf_avsp_ts_48_tai, |
1057 | 15 | {"Timestamp (TAI)", "avsp.ts.48.tai", |
1058 | 15 | FT_NONE, BASE_NONE, |
1059 | 15 | NULL, 0x0, |
1060 | 15 | NULL, HFILL} |
1061 | 15 | }, |
1062 | 15 | {&hf_avsp_ts_48_utc, |
1063 | 15 | {"Timestamp (UTC)", "avsp.ts.48.utc", |
1064 | 15 | FT_NONE, BASE_NONE, |
1065 | 15 | NULL, 0x0, |
1066 | 15 | NULL, HFILL} |
1067 | 15 | }, |
1068 | 15 | {&hf_avsp_ts_48_sec, |
1069 | 15 | {"Seconds", "avsp.ts.48.sec", |
1070 | 15 | FT_UINT16, BASE_DEC, |
1071 | 15 | NULL, 0x0, |
1072 | 15 | NULL, HFILL} |
1073 | 15 | }, |
1074 | 15 | {&hf_avsp_ts_48_ns, |
1075 | 15 | {"Nanoseconds", "avsp.ts.48.ns", |
1076 | 15 | FT_UINT32, BASE_DEC, |
1077 | 15 | NULL, 0x0, |
1078 | 15 | NULL, HFILL} |
1079 | 15 | }, |
1080 | 15 | {&hf_avsp_etype, |
1081 | 15 | {"Type", "avsp.etype", |
1082 | 15 | FT_UINT16, BASE_HEX, |
1083 | 15 | VALS(etype_vals), 0x0, |
1084 | 15 | "Ethertype", HFILL} |
1085 | 15 | }, |
1086 | 15 | {&hf_avsp_trailer, |
1087 | 15 | {"Trailer", "avsp.trailer", |
1088 | 15 | FT_BYTES, BASE_NONE, |
1089 | 15 | NULL, 0x0, |
1090 | 15 | "AVSP Trailer", HFILL} |
1091 | 15 | }, |
1092 | 15 | {&hf_avsp_greentap_version, |
1093 | 15 | {"Version", "avsp.greentap.ver", |
1094 | 15 | FT_UINT16, BASE_DEC, |
1095 | 15 | VALS(greentap_versions), 0x0, |
1096 | 15 | NULL, HFILL} |
1097 | 15 | }, |
1098 | 15 | {&hf_avsp_greentap_tai, |
1099 | 15 | {"Timestamp (TAI)", "avsp.greentap.tai", |
1100 | 15 | FT_NONE, BASE_NONE, |
1101 | 15 | NULL, 0x0, |
1102 | 15 | NULL, HFILL} |
1103 | 15 | }, |
1104 | 15 | {&hf_avsp_greentap_utc, |
1105 | 15 | {"Timestamp (UTC)", "avsp.greentap.utc", |
1106 | 15 | FT_NONE, BASE_NONE, |
1107 | 15 | NULL, 0x0, |
1108 | 15 | NULL, HFILL} |
1109 | 15 | }, |
1110 | 15 | {&hf_avsp_greentap_sec, |
1111 | 15 | {"Seconds", "avsp.greentap.sec", |
1112 | 15 | FT_UINT16, BASE_DEC, |
1113 | 15 | NULL, 0x0, |
1114 | 15 | NULL, HFILL} |
1115 | 15 | }, |
1116 | 15 | {&hf_avsp_greentap_ns, |
1117 | 15 | {"Nanoseconds", "avsp.greentap.ns", |
1118 | 15 | FT_UINT32, BASE_DEC, |
1119 | 15 | NULL, 0x0, |
1120 | 15 | NULL, HFILL} |
1121 | 15 | }, |
1122 | 15 | {&hf_avsp_greent_version, |
1123 | 15 | {"Version", "avsp.greent.ver", |
1124 | 15 | FT_UINT16, BASE_DEC, |
1125 | 15 | VALS(greent_versions), 0x0, |
1126 | 15 | NULL, HFILL} |
1127 | 15 | }, |
1128 | 15 | {&hf_avsp_greent_hdr, |
1129 | 15 | {"GREENT Header", "avsp.greent.hdr", |
1130 | 15 | FT_NONE, BASE_NONE, |
1131 | 15 | NULL, 0x0, |
1132 | 15 | NULL, HFILL} |
1133 | 15 | }, |
1134 | 15 | {&hf_avsp_greent_session, |
1135 | 15 | {"Session ID", "avsp.greent.session", |
1136 | 15 | FT_UINT16, BASE_DEC, |
1137 | 15 | NULL, 0x0, |
1138 | 15 | NULL, HFILL} |
1139 | 15 | }, |
1140 | 15 | {&hf_avsp_greent_flags, |
1141 | 15 | {"Flags", "avsp.greent.flags", |
1142 | 15 | FT_UINT8, BASE_HEX, |
1143 | 15 | NULL, 0x0, |
1144 | 15 | NULL, HFILL} |
1145 | 15 | }, |
1146 | 15 | {&hf_avsp_greent_sample_count, |
1147 | 15 | {"Sample Count", "avsp.greent.sample_count", |
1148 | 15 | FT_UINT8, BASE_DEC, |
1149 | 15 | NULL, 0x0, |
1150 | 15 | NULL, HFILL} |
1151 | 15 | }, |
1152 | 15 | {&hf_avsp_greent_sample_hdr, |
1153 | 15 | {"Sample Header", "avsp.greent.sample.hdr", |
1154 | 15 | FT_NONE, BASE_NONE, |
1155 | 15 | NULL, 0x0, |
1156 | 15 | NULL, HFILL} |
1157 | 15 | }, |
1158 | 15 | {&hf_avsp_greent_sample_len, |
1159 | 15 | {"Length", "avsp.greent.sample.len", |
1160 | 15 | FT_UINT16, BASE_DEC, |
1161 | 15 | NULL, 0x0, |
1162 | 15 | NULL, HFILL} |
1163 | 15 | }, |
1164 | 15 | {&hf_avsp_greent_sample_sec, |
1165 | 15 | {"Seconds", "avsp.greent.sample.sec", |
1166 | 15 | FT_UINT16, BASE_DEC, |
1167 | 15 | NULL, 0x0, |
1168 | 15 | NULL, HFILL} |
1169 | 15 | }, |
1170 | 15 | {&hf_avsp_greent_sample_ns, |
1171 | 15 | {"Nanoseconds", "avsp.greent.sample.ns", |
1172 | 15 | FT_UINT32, BASE_DEC, |
1173 | 15 | NULL, 0x0, |
1174 | 15 | NULL, HFILL} |
1175 | 15 | }, |
1176 | 15 | {&hf_avsp_greent_sample_ingress, |
1177 | 15 | {"Ingress Interface", "avsp.greent.sample.ingress", |
1178 | 15 | FT_UINT32, BASE_DEC, |
1179 | 15 | NULL, 0x0, |
1180 | 15 | NULL, HFILL} |
1181 | 15 | }, |
1182 | 15 | {&hf_avsp_greent_sample_egress, |
1183 | 15 | {"Egress Interface", "avsp.greent.sample.egress", |
1184 | 15 | FT_UINT32, BASE_DEC, |
1185 | 15 | NULL, 0x0, |
1186 | 15 | NULL, HFILL} |
1187 | 15 | }, |
1188 | 15 | {&hf_avsp_greent_sample_rate, |
1189 | 15 | {"Rate(*1K)", "avsp.greent.sample.rate", |
1190 | 15 | FT_UINT16, BASE_DEC, |
1191 | 15 | NULL, 0x0, |
1192 | 15 | NULL, HFILL} |
1193 | 15 | }, |
1194 | 15 | {&hf_avsp_greent_sample_sum, |
1195 | 15 | {"Checksum", "avsp.greent.sample.sum", |
1196 | 15 | FT_UINT16, BASE_HEX, |
1197 | 15 | NULL, 0x0, |
1198 | 15 | NULL, HFILL} |
1199 | 15 | }, |
1200 | 15 | {&hf_avsp_greent_sample_data, |
1201 | 15 | {"Header of sampled packet", "avsp.greent.sample.data", |
1202 | 15 | FT_BYTES, BASE_NONE, |
1203 | 15 | NULL, 0x0, |
1204 | 15 | "Data from sampled header", HFILL} |
1205 | 15 | }, |
1206 | 15 | {&hf_avsp_dzgre_a_version, |
1207 | 15 | {"Version", "avsp.dzgre_a.ver", |
1208 | 15 | FT_UINT16, BASE_DEC, |
1209 | 15 | VALS(dzgre_a_versions), 0x0, |
1210 | 15 | NULL, HFILL} |
1211 | 15 | }, |
1212 | 15 | {&hf_avsp_dzgre_a_hdr, |
1213 | 15 | {"DzGRE(A) Header", "avsp.dzgre_a.hdr", |
1214 | 15 | FT_NONE, BASE_NONE, |
1215 | 15 | NULL, 0x0, |
1216 | 15 | NULL, HFILL} |
1217 | 15 | }, |
1218 | 15 | {&hf_avsp_dzgre_a_switch, |
1219 | 15 | {"Switch ID", "avsp.dzgre_a.switch", |
1220 | 15 | FT_UINT16, BASE_DEC, |
1221 | 15 | NULL, 0x0, |
1222 | 15 | NULL, HFILL} |
1223 | 15 | }, |
1224 | 15 | {&hf_avsp_dzgre_a_port, |
1225 | 15 | {"Port ID", "avsp.dzgre_a.port", |
1226 | 15 | FT_UINT16, BASE_DEC, |
1227 | 15 | NULL, 0x0, |
1228 | 15 | NULL, HFILL} |
1229 | 15 | }, |
1230 | 15 | {&hf_avsp_dzgre_a_policy, |
1231 | 15 | {"Policy ID", "avsp.dzgre_a.policy", |
1232 | 15 | FT_UINT16, BASE_DEC, |
1233 | 15 | NULL, 0x0, |
1234 | 15 | NULL, HFILL} |
1235 | 15 | }, |
1236 | 15 | {&hf_avsp_dzgre_a_reserved, |
1237 | 15 | {"Reserved", "avsp.dzgre_a.reserved", |
1238 | 15 | FT_UINT16, BASE_HEX, |
1239 | 15 | NULL, 0x0, |
1240 | 15 | NULL, HFILL} |
1241 | 15 | }, |
1242 | 15 | {&hf_avsp_dzgre_b_version, |
1243 | 15 | {"Version", "avsp.dzgre_b.ver", |
1244 | 15 | FT_UINT16, BASE_DEC, |
1245 | 15 | VALS(dzgre_b_versions), 0x0, |
1246 | 15 | NULL, HFILL} |
1247 | 15 | }, |
1248 | 15 | {&hf_avsp_dzgre_b_hdr, |
1249 | 15 | {"DzGRE(B) Header", "avsp.dzgre_b.hdr", |
1250 | 15 | FT_NONE, BASE_NONE, |
1251 | 15 | NULL, 0x0, |
1252 | 15 | NULL, HFILL} |
1253 | 15 | }, |
1254 | 15 | {&hf_avsp_dzgre_b_port, |
1255 | 15 | {"Port ID", "avsp.dzgre_b.port", |
1256 | 15 | FT_UINT16, BASE_DEC, |
1257 | 15 | NULL, 0x0, |
1258 | 15 | NULL, HFILL} |
1259 | 15 | }, |
1260 | 15 | {&hf_avsp_dzgre_b_policy, |
1261 | 15 | {"Policy ID", "avsp.dzgre_b.policy", |
1262 | 15 | FT_UINT16, BASE_DEC, |
1263 | 15 | NULL, 0x0, |
1264 | 15 | NULL, HFILL} |
1265 | 15 | }, |
1266 | 15 | {&hf_avsp_dzgre_ts_version, |
1267 | 15 | {"Version", "avsp.dzgre_ts.ver", |
1268 | 15 | FT_UINT16, BASE_DEC, |
1269 | 15 | VALS(dzgre_ts_versions), 0x0, |
1270 | 15 | NULL, HFILL} |
1271 | 15 | }, |
1272 | 15 | {&hf_avsp_dzgre_ts_hdr, |
1273 | 15 | {"DzGRE(B) Header", "avsp.dzgre_ts.hdr", |
1274 | 15 | FT_NONE, BASE_NONE, |
1275 | 15 | NULL, 0x0, |
1276 | 15 | NULL, HFILL} |
1277 | 15 | }, |
1278 | 15 | {&hf_avsp_dzgre_ts_switch, |
1279 | 15 | {"Switch ID", "avsp.dzgre_ts.switch", |
1280 | 15 | FT_UINT16, BASE_DEC, |
1281 | 15 | NULL, 0x0, |
1282 | 15 | NULL, HFILL} |
1283 | 15 | }, |
1284 | 15 | {&hf_avsp_dzgre_ts_port, |
1285 | 15 | {"Port ID", "avsp.dzgre_ts.port", |
1286 | 15 | FT_UINT16, BASE_DEC, |
1287 | 15 | NULL, 0x0, |
1288 | 15 | NULL, HFILL} |
1289 | 15 | }, |
1290 | 15 | {&hf_avsp_dzgre_ts_policy, |
1291 | 15 | {"Policy ID", "avsp.dzgre_ts.policy", |
1292 | 15 | FT_UINT16, BASE_DEC, |
1293 | 15 | NULL, 0x0, |
1294 | 15 | NULL, HFILL} |
1295 | 15 | }, |
1296 | 15 | {&hf_avsp_dzgre_ts_reserved, |
1297 | 15 | {"Reserved", "avsp.dzgre_ts.reserved", |
1298 | 15 | FT_UINT16, BASE_HEX, |
1299 | 15 | NULL, 0x0, |
1300 | 15 | NULL, HFILL} |
1301 | 15 | }, |
1302 | 15 | {&hf_avsp_dzgre_ts_tai, |
1303 | 15 | {"Timestamp (TAI)", "avsp.dzgre_ts.tai", |
1304 | 15 | FT_NONE, BASE_NONE, |
1305 | 15 | NULL, 0x0, |
1306 | 15 | NULL, HFILL} |
1307 | 15 | }, |
1308 | 15 | {&hf_avsp_dzgre_ts_utc, |
1309 | 15 | {"Timestamp (UTC)", "avsp.dzgre_ts.utc", |
1310 | 15 | FT_NONE, BASE_NONE, |
1311 | 15 | NULL, 0x0, |
1312 | 15 | NULL, HFILL} |
1313 | 15 | }, |
1314 | 15 | {&hf_avsp_dzgre_ts_sec, |
1315 | 15 | {"Seconds", "avsp.ts.dzgre_ts.sec", |
1316 | 15 | FT_UINT32, BASE_DEC, |
1317 | 15 | NULL, 0x0, |
1318 | 15 | NULL, HFILL} |
1319 | 15 | }, |
1320 | 15 | {&hf_avsp_dzgre_ts_ns, |
1321 | 15 | {"Nanoseconds", "avsp.dzgre_ts.48.ns", |
1322 | 15 | FT_UINT32, BASE_DEC, |
1323 | 15 | NULL, 0x0, |
1324 | 15 | NULL, HFILL} |
1325 | 15 | }, |
1326 | 15 | {&hf_avsp_tgen_version, |
1327 | 15 | {"Version", "avsp.tgen.ver", |
1328 | 15 | FT_UINT16, BASE_DEC, |
1329 | 15 | VALS(tgen_versions), 0x0, |
1330 | 15 | NULL, HFILL} |
1331 | 15 | }, |
1332 | 15 | {&hf_avsp_tgen_hdr, |
1333 | 15 | {"TGen Header", "avsp.tgen.hdr", |
1334 | 15 | FT_NONE, BASE_NONE, |
1335 | 15 | NULL, 0x0, |
1336 | 15 | NULL, HFILL} |
1337 | 15 | }, |
1338 | 15 | {&hf_avsp_tgen_hdr_ctrl, |
1339 | 15 | {"Control Word", "avsp.tgen.hdr.ctrl", |
1340 | 15 | FT_UINT16, BASE_HEX, |
1341 | 15 | NULL, 0x0, |
1342 | 15 | NULL, HFILL} |
1343 | 15 | }, |
1344 | 15 | {&hf_avsp_tgen_hdr_ctrl_fcs_inverted, |
1345 | 15 | {"FCS Inverted", "avsp.tgen.hdr.ctrl.fcs_inverted", |
1346 | 15 | FT_BOOLEAN, 16, |
1347 | 15 | NULL, 0x0001, |
1348 | 15 | NULL, HFILL} |
1349 | 15 | }, |
1350 | 15 | {&hf_avsp_tgen_hdr_ctrl_reserved, |
1351 | 15 | {"Reserved", "avsp.tgen.hdr.ctrl.reserved", |
1352 | 15 | FT_UINT16, BASE_HEX, |
1353 | 15 | NULL, 0xFFFE, |
1354 | 15 | NULL, HFILL} |
1355 | 15 | }, |
1356 | 15 | {&hf_avsp_tgen_hdr_seq_num, |
1357 | 15 | {"Sequence Number", "avsp.tgen.hdr.seq_num", |
1358 | 15 | FT_UINT16, BASE_DEC, |
1359 | 15 | NULL, 0x0, |
1360 | 15 | NULL, HFILL} |
1361 | 15 | }, |
1362 | 15 | {&hf_avsp_tgen_hdr_payload_len, |
1363 | 15 | {"Payload Length", "avsp.tgen.hdr.payload_len", |
1364 | 15 | FT_UINT16, BASE_DEC, |
1365 | 15 | NULL, 0x0, |
1366 | 15 | NULL, HFILL} |
1367 | 15 | }, |
1368 | 15 | { &hf_avsp_tgen_payload, |
1369 | 15 | {"TGen Payload", "avsp.tgen.payload", |
1370 | 15 | FT_NONE, BASE_NONE, |
1371 | 15 | NULL, 0x0, |
1372 | 15 | NULL, HFILL} |
1373 | 15 | }, |
1374 | 15 | { &hf_avsp_tgen_payload_data, |
1375 | 15 | {"Data", "avsp.tgen.payload.data", |
1376 | 15 | FT_BYTES, BASE_NONE, |
1377 | 15 | NULL, 0x0, |
1378 | 15 | NULL, HFILL} |
1379 | 15 | }, |
1380 | 15 | }; |
1381 | | |
1382 | | /* Setup protocol subtree array */ |
1383 | 15 | static int* ett[] = { |
1384 | 15 | &ett_avsp, /* main avsp tree */ |
1385 | 15 | &ett_avsp_ts_48, /* subtree above for 48 bit timestamp */ |
1386 | 15 | &ett_avsp_ts_64, /* subtree above for 64 bit timestamp */ |
1387 | 15 | &ett_avsp_dzgre_a_hdr, /* subtree for DzGRE plan A */ |
1388 | 15 | &ett_avsp_dzgre_b_hdr, /* subtree for DzGRE plan B */ |
1389 | 15 | &ett_avsp_dzgre_ts_hdr, /* subtree for DzGRE with timestamps */ |
1390 | 15 | &ett_avsp_dzgre_ts_tai, /* subtree for DzGRE timestamp */ |
1391 | 15 | &ett_avsp_dzgre_ts_utc, /* subtree for DzGRE timestamp */ |
1392 | 15 | &ett_avsp_greent_hdr, /* subtree for GREENT header */ |
1393 | 15 | &ett_avsp_greent_sample_hdr, /* subtree for GREENT sample header */ |
1394 | 15 | &ett_avsp_greent_sample_data, /* subtree for GREENT sample data */ |
1395 | 15 | &ett_avsp_tgen_hdr, /* subtree for TGen header */ |
1396 | 15 | &ett_avsp_tgen_hdr_ctrl, /* subtree for TGen header control bits */ |
1397 | 15 | &ett_avsp_tgen_payload, /* subtree for TGen payload */ |
1398 | 15 | }; |
1399 | | |
1400 | 15 | static ei_register_info ei[] = { |
1401 | 15 | { &ei_avsp_unknown_subtype, { "avsp.unknown_subtype", PI_SEQUENCE, PI_WARN, "Unknown AVSP subtype", EXPFILL}}, |
1402 | 15 | { &ei_avsp_ts_unknown_version, { "avsp.ts.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown timestamp version", EXPFILL }}, |
1403 | 15 | { &ei_avsp_greentap_unknown_version, { "avsp.greentap.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown GREENTAP version", EXPFILL }}, |
1404 | 15 | { &ei_avsp_greent_unknown_version, { "avsp.greent.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown GREENT version", EXPFILL }}, |
1405 | 15 | { &ei_avsp_dzgre_a_unknown_version, { "avsp.dzgre_a.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown DzGRE(A) version", EXPFILL }}, |
1406 | 15 | { &ei_avsp_dzgre_b_unknown_version, { "avsp.dzgre_b.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown DzGRE(B) version", EXPFILL }}, |
1407 | 15 | { &ei_avsp_dzgre_ts_unknown_version, { "avsp.dzgre_ts.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown DzGRE(timestamped) version", EXPFILL }}, |
1408 | 15 | { &ei_avsp_tgen_unknown_version, { "avsp.tgen.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown TGen version", EXPFILL }}, |
1409 | 15 | }; |
1410 | | |
1411 | | /* Register the AVSP protocol. */ |
1412 | 15 | proto_avsp = proto_register_protocol("Arista Vendor Specific Protocol", "AVSP", "avsp"); |
1413 | | |
1414 | | /* Register header fields and subtrees. */ |
1415 | 15 | proto_register_field_array(proto_avsp, hf, array_length(hf)); |
1416 | | |
1417 | | /* Register subtree types. */ |
1418 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1419 | | |
1420 | | /* Register the expert module. */ |
1421 | 15 | expert_register_field_array(expert_register_protocol(proto_avsp), ei, array_length(ei)); |
1422 | | |
1423 | | /* Register the dissector handle. */ |
1424 | 15 | avsp_handle = register_dissector("avsp", dissect_avsp, proto_avsp); |
1425 | 15 | } |
1426 | | |
1427 | | /* |
1428 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1429 | | * |
1430 | | * Local variables: |
1431 | | * c-basic-offset: 4 |
1432 | | * tab-width: 8 |
1433 | | * indent-tabs-mode: nil |
1434 | | * End: |
1435 | | * |
1436 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1437 | | * :indentSize=4:tabSize=8:noTabs=true: |
1438 | | */ |