]>
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 */
9 #include "netdissect-stdinc.h"
11 #include "netdissect.h"
13 #include "addrtoname.h"
19 The Arista timestamp header consists of the following fields:
20 1. The Arista ethertype (0xd28b)
21 2. A 2-byte subtype field; 0x01 indicates the timestamp header
22 3. A 2-byte version field, described below.
23 4. A 48-bit or 64-bit timestamp field, depending on the contents of the version field
25 This header is then followed by the original ethertype and the remainder of the original packet.
28 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
29 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
35 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 | ethertype 0xd28b | subtype 0x1 |
37 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
41 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 The two-byte version value is split into 3 fields:
44 1. The timescale in use. Currently assigned values include:
47 2. The timestamp format and length. Currently assigned values include:
55 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 | timescale | format|hw info|
58 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 #define ARISTA_SUBTYPE_TIMESTAMP 0x0001
63 static const struct tok subtype_str
[] = {
64 { ARISTA_SUBTYPE_TIMESTAMP
, "Timestamp" },
68 static const struct tok ts_timescale_str
[] = {
74 #define FORMAT_64BIT 0x1
75 #define FORMAT_48BIT 0x2
76 static const struct tok ts_format_str
[] = {
77 { FORMAT_64BIT
, "64-bit" },
78 { FORMAT_48BIT
, "48-bit" },
82 static const struct tok hw_info_str
[] = {
89 arista_print_date_hms_time(netdissect_options
*ndo
, uint32_t seconds
,
96 ts
= seconds
+ (nanoseconds
/ 1000000000);
97 nanoseconds
%= 1000000000;
98 if (NULL
== (tm
= gmtime(&ts
)))
99 ND_PRINT("gmtime() error");
100 else if (0 == strftime(buf
, sizeof(buf
), "%Y-%m-%d %H:%M:%S", tm
))
101 ND_PRINT("strftime() error");
103 ND_PRINT("%s.%09u", buf
, nanoseconds
);
107 arista_ethertype_print(netdissect_options
*ndo
, const u_char
*bp
, u_int len _U_
)
110 u_short bytesConsumed
= 0;
112 ndo
->ndo_protocol
= "arista";
114 subTypeId
= GET_BE_U_2(bp
);
118 ND_PRINT("SubType %s (0x%04x), ",
119 tok2str(subtype_str
, "Unknown", subTypeId
),
122 // TapAgg Header Timestamping
123 if (subTypeId
== ARISTA_SUBTYPE_TIMESTAMP
) {
125 uint32_t nanoseconds
;
126 uint8_t ts_timescale
= GET_U_1(bp
);
129 ND_PRINT("Timescale %s (%u), ",
130 tok2str(ts_timescale_str
, "Unknown", ts_timescale
),
133 uint8_t ts_format
= GET_U_1(bp
) >> 4;
134 uint8_t hw_info
= GET_U_1(bp
) & 0x0f;
138 // Timestamp has 32-bit lsb in nanosec and remaining msb in sec
139 ND_PRINT("Format %s (%u), HwInfo %s (%u), Timestamp ",
140 tok2str(ts_format_str
, "Unknown", ts_format
),
142 tok2str(hw_info_str
, "Unknown", hw_info
),
146 seconds
= GET_BE_U_4(bp
);
147 nanoseconds
= GET_BE_U_4(bp
+ 4);
148 arista_print_date_hms_time(ndo
, seconds
, nanoseconds
);
152 seconds
= GET_BE_U_2(bp
);
153 nanoseconds
= GET_BE_U_4(bp
+ 2);
154 seconds
+= nanoseconds
/ 1000000000;
155 nanoseconds
%= 1000000000;
156 ND_PRINT("%" PRIu64
".%09u", seconds
, nanoseconds
);
166 return bytesConsumed
;