1 // Copyright (c) 2018 Arista Networks, Inc. All rights reserved. 2 3 /* \summary: EtherType protocol for Arista Networks printer */ 4 5 #ifdef HAVE_CONFIG_H 6 #include <config.h> 7 #endif 8 9 #include "netdissect-stdinc.h" 10 11 #include "netdissect.h" 12 #include "extract.h" 13 #include "addrtoname.h" 14 15 #define ARISTA_SUBTYPE_TIMESTAMP 0x01 16 17 #define ARISTA_TIMESTAMP_64_TAI 0x0010 18 #define ARISTA_TIMESTAMP_64_UTC 0x0110 19 #define ARISTA_TIMESTAMP_48_TAI 0x0020 20 #define ARISTA_TIMESTAMP_48_UTC 0x0120 21 22 static const struct tok ts_version_name[] = { 23 { ARISTA_TIMESTAMP_64_TAI, "TAI(64-bit)" }, 24 { ARISTA_TIMESTAMP_64_UTC, "UTC(64-bit)" }, 25 { ARISTA_TIMESTAMP_48_TAI, "TAI(48-bit)" }, 26 { ARISTA_TIMESTAMP_48_UTC, "UTC(48-bit)" }, 27 { 0, NULL } 28 }; 29 30 static inline void 31 arista_print_date_hms_time(netdissect_options *ndo, uint32_t seconds, 32 uint32_t nanoseconds) 33 { 34 time_t ts; 35 struct tm *tm; 36 char buf[BUFSIZE]; 37 38 ts = seconds + (nanoseconds / 1000000000); 39 if (NULL == (tm = gmtime(&ts))) 40 ND_PRINT(": gmtime() error"); 41 else if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) 42 ND_PRINT(": strftime() error"); 43 else 44 ND_PRINT(": %s, %09u ns, ", buf, nanoseconds); 45 } 46 47 int 48 arista_ethertype_print(netdissect_options *ndo, const u_char *bp, u_int len _U_) 49 { 50 uint16_t subTypeId; 51 uint16_t version; 52 u_short bytesConsumed = 0; 53 u_short size = 0; 54 uint32_t seconds, nanoseconds; 55 56 ndo->ndo_protocol = "arista"; 57 58 subTypeId = GET_BE_U_2(bp); 59 bp += 2; 60 version = GET_BE_U_2(bp); 61 bp += 2; 62 bytesConsumed += 4; 63 64 ND_PRINT("SubType: 0x%1x, Version: 0x%04x, ", subTypeId, version); 65 66 // TapAgg Header Timestamping 67 if (subTypeId == ARISTA_SUBTYPE_TIMESTAMP) { 68 // Timestamp has 32-bit lsb in nanosec and remaining msb in sec 69 ND_PRINT("Timestamp %s", tok2str(ts_version_name, 70 "Unknown timestamp Version 0x%04x ", version)); 71 switch (version) { 72 case ARISTA_TIMESTAMP_64_TAI: 73 case ARISTA_TIMESTAMP_64_UTC: 74 seconds = GET_BE_U_4(bp); 75 nanoseconds = GET_BE_U_4(bp + 4); 76 arista_print_date_hms_time(ndo, seconds, nanoseconds); 77 bytesConsumed += size + 8; 78 break; 79 case ARISTA_TIMESTAMP_48_TAI: 80 case ARISTA_TIMESTAMP_48_UTC: 81 ND_PRINT(": Seconds %u,", GET_BE_U_2(bp)); 82 ND_PRINT(" Nanoseconds %u, ", GET_BE_U_4(bp + 2)); 83 bytesConsumed += size + 6; 84 break; 85 default: 86 return -1; 87 } 88 } else { 89 return -1; 90 } 91 return bytesConsumed; 92 } 93