]>
The Tcpdump Group git mirrors - tcpdump/blob - print-arista.c
1 // Copyright (c) 2018 Arista Networks, Inc. All rights reserved.
3 /* \summary: EtherType protocol for Arista Networks printer */
7 #include "netdissect-stdinc.h"
9 #include "netdissect.h"
11 #include "timeval-operations.h"
17 The Arista timestamp header consists of the following fields:
18 1. The Arista ethertype (0xd28b)
19 2. A 2-byte subtype field; 0x01 indicates the timestamp header
20 3. A 2-byte version field, described below.
21 4. A 48-bit or 64-bit timestamp field, depending on the contents of the version field
23 This header is then followed by the original ethertype and the remainder of the original packet.
26 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
27 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
33 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 | ethertype 0xd28b | subtype 0x1 |
35 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
39 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 The two-byte version value is split into 3 fields:
42 1. The timescale in use. Currently assigned values include:
45 2. The timestamp format and length. Currently assigned values include:
53 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
54 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 | timescale | format|hw info|
56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 See also: https://www.arista.com/assets/data/pdf/Whitepapers/Overview_Arista_Timestamps.pdf
63 #define ARISTA_SUBTYPE_TIMESTAMP 0x0001
64 static const struct tok subtype_str
[] = {
65 { ARISTA_SUBTYPE_TIMESTAMP
, "Timestamp" },
69 static const struct tok ts_timescale_str
[] = {
75 #define FORMAT_64BIT 0x1
76 #define FORMAT_48BIT 0x2
77 static const struct tok ts_format_str
[] = {
78 { FORMAT_64BIT
, "64-bit" },
79 { FORMAT_48BIT
, "48-bit" },
83 static const struct tok hw_info_str
[] = {
90 arista_print_date_hms_time(netdissect_options
*ndo
, const uint32_t seconds
,
91 const uint32_t nanoseconds
)
93 const time_t ts
= seconds
;
94 char buf
[sizeof("-yyyyyyyyyy-mm-dd hh:mm:ss")];
97 nd_format_time(buf
, sizeof(buf
), "%Y-%m-%d %H:%M:%S",
98 gmtime(&ts
)), nanoseconds
);
99 if (nanoseconds
> ND_NANO_PER_SEC
- 1)
100 ND_PRINT(" " ND_INVALID_NANO_SEC_STR
);
104 arista_ethertype_print(netdissect_options
*ndo
, const u_char
*bp
, u_int len _U_
)
107 u_short bytesConsumed
= 0;
109 ndo
->ndo_protocol
= "arista";
111 subTypeId
= GET_BE_U_2(bp
);
115 ND_PRINT("SubType %s (0x%04x), ",
116 tok2str(subtype_str
, "Unknown", subTypeId
),
119 // TapAgg Header Timestamping
120 if (subTypeId
== ARISTA_SUBTYPE_TIMESTAMP
) {
122 uint32_t nanoseconds
;
123 uint8_t ts_timescale
= GET_U_1(bp
);
126 ND_PRINT("Timescale %s (%u), ",
127 tok2str(ts_timescale_str
, "Unknown", ts_timescale
),
130 uint8_t ts_format
= GET_U_1(bp
) >> 4;
131 uint8_t hw_info
= GET_U_1(bp
) & 0x0f;
135 // Timestamp has 32-bit lsb in nanosec and remaining msb in sec
136 ND_PRINT("Format %s (%u), HwInfo %s (%u), Timestamp ",
137 tok2str(ts_format_str
, "Unknown", ts_format
),
139 tok2str(hw_info_str
, "Unknown", hw_info
),
143 seconds
= GET_BE_U_4(bp
);
144 nanoseconds
= GET_BE_U_4(bp
+ 4);
145 arista_print_date_hms_time(ndo
, seconds
, nanoseconds
);
149 seconds
= GET_BE_U_2(bp
);
150 nanoseconds
= GET_BE_U_4(bp
+ 2);
151 ND_PRINT("%u.%09u", seconds
, nanoseconds
);
152 if (nanoseconds
> ND_NANO_PER_SEC
- 1)
153 ND_PRINT(" " ND_INVALID_NANO_SEC_STR
);
163 return bytesConsumed
;