diff options
author | Joseph Mingrone <jrm@FreeBSD.org> | 2023-06-08 17:30:54 +0000 |
---|---|---|
committer | Joseph Mingrone <jrm@FreeBSD.org> | 2023-06-08 17:30:54 +0000 |
commit | ee67461e56828dd1f8de165947ba83f6d9148a87 (patch) | |
tree | 84372978fdb5efead69ae456f5e480a5872ec37b /contrib/tcpdump/print-arista.c | |
parent | f40cd16bfda4f4512033bb9e7212ee5d8b94b9a7 (diff) | |
parent | 51a183021fce3928d24b11c319d2787f5a15ae87 (diff) | |
download | src-ee67461e56828dd1f8de165947ba83f6d9148a87.tar.gz src-ee67461e56828dd1f8de165947ba83f6d9148a87.zip |
tpcdump: Update to 4.99.4
Local changes:
- Update some local modifications to fix build
- Synch config.h with upstream as much as possible
Changelog: https://git.tcpdump.org/tcpdump/blob/55bc126b0216cfe409b8d6bd378f65679d136ddf:/CHANGES
Reviewed by: emaste
Obtained from: https://www.tcpdump.org/release/tcpdump-4.99.4.tar.gz
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib/tcpdump/print-arista.c')
-rw-r--r-- | contrib/tcpdump/print-arista.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/contrib/tcpdump/print-arista.c b/contrib/tcpdump/print-arista.c new file mode 100644 index 000000000000..079ad684bc11 --- /dev/null +++ b/contrib/tcpdump/print-arista.c @@ -0,0 +1,165 @@ +// Copyright (c) 2018 Arista Networks, Inc. All rights reserved. + +/* \summary: EtherType protocol for Arista Networks printer */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "netdissect-stdinc.h" + +#include "netdissect.h" +#include "extract.h" + +/* + +From Bill Fenner: + +The Arista timestamp header consists of the following fields: +1. The Arista ethertype (0xd28b) +2. A 2-byte subtype field; 0x01 indicates the timestamp header +3. A 2-byte version field, described below. +4. A 48-bit or 64-bit timestamp field, depending on the contents of the version field + +This header is then followed by the original ethertype and the remainder of the original packet. + + 0 1 2 3 + 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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| dst mac | ++ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| | | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| src mac | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| ethertype 0xd28b | subtype 0x1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| version | | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| timestamp... | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +The two-byte version value is split into 3 fields: +1. The timescale in use. Currently assigned values include: + 0 = TAI + 1 = UTC +2. The timestamp format and length. Currently assigned values include: + 1 = 64-bit timestamp + 2 = 48-bit timestamp +3. The hardware info + 0 = R/R2 series + 1 = R3 series + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| timescale | format|hw info| ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +See also: https://www.arista.com/assets/data/pdf/Whitepapers/Overview_Arista_Timestamps.pdf + +*/ + +#define ARISTA_SUBTYPE_TIMESTAMP 0x0001 +static const struct tok subtype_str[] = { + { ARISTA_SUBTYPE_TIMESTAMP, "Timestamp" }, + { 0, NULL } +}; + +static const struct tok ts_timescale_str[] = { + { 0, "TAI" }, + { 1, "UTC" }, + { 0, NULL } +}; + +#define FORMAT_64BIT 0x1 +#define FORMAT_48BIT 0x2 +static const struct tok ts_format_str[] = { + { FORMAT_64BIT, "64-bit" }, + { FORMAT_48BIT, "48-bit" }, + { 0, NULL } +}; + +static const struct tok hw_info_str[] = { + { 0, "R/R2" }, + { 1, "R3" }, + { 0, NULL } +}; + +static inline void +arista_print_date_hms_time(netdissect_options *ndo, uint32_t seconds, + uint32_t nanoseconds) +{ + time_t ts; + char buf[sizeof("-yyyyyyyyyy-mm-dd hh:mm:ss")]; + + ts = seconds + (nanoseconds / 1000000000); + nanoseconds %= 1000000000; + ND_PRINT("%s.%09u", + nd_format_time(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", + gmtime(&ts)), nanoseconds); +} + +int +arista_ethertype_print(netdissect_options *ndo, const u_char *bp, u_int len _U_) +{ + uint16_t subTypeId; + u_short bytesConsumed = 0; + + ndo->ndo_protocol = "arista"; + + subTypeId = GET_BE_U_2(bp); + bp += 2; + bytesConsumed += 2; + + ND_PRINT("SubType %s (0x%04x), ", + tok2str(subtype_str, "Unknown", subTypeId), + subTypeId); + + // TapAgg Header Timestamping + if (subTypeId == ARISTA_SUBTYPE_TIMESTAMP) { + uint64_t seconds; + uint32_t nanoseconds; + uint8_t ts_timescale = GET_U_1(bp); + bp += 1; + bytesConsumed += 1; + ND_PRINT("Timescale %s (%u), ", + tok2str(ts_timescale_str, "Unknown", ts_timescale), + ts_timescale); + + uint8_t ts_format = GET_U_1(bp) >> 4; + uint8_t hw_info = GET_U_1(bp) & 0x0f; + bp += 1; + bytesConsumed += 1; + + // Timestamp has 32-bit lsb in nanosec and remaining msb in sec + ND_PRINT("Format %s (%u), HwInfo %s (%u), Timestamp ", + tok2str(ts_format_str, "Unknown", ts_format), + ts_format, + tok2str(hw_info_str, "Unknown", hw_info), + hw_info); + switch (ts_format) { + case FORMAT_64BIT: + seconds = GET_BE_U_4(bp); + nanoseconds = GET_BE_U_4(bp + 4); + arista_print_date_hms_time(ndo, seconds, nanoseconds); + bytesConsumed += 8; + break; + case FORMAT_48BIT: + seconds = GET_BE_U_2(bp); + nanoseconds = GET_BE_U_4(bp + 2); + seconds += nanoseconds / 1000000000; + nanoseconds %= 1000000000; + ND_PRINT("%" PRIu64 ".%09u", seconds, nanoseconds); + bytesConsumed += 6; + break; + default: + return -1; + } + } else { + return -1; + } + ND_PRINT(": "); + return bytesConsumed; +} |