/* * Print NTP time requests and responses */ static void ntp_time_print(netdissect_options *ndo, const struct ntp_time_data *bp, u_int length) { uint8_t stratum; if (length < NTP_TIMEMSG_MINLEN) goto invalid; ND_TCHECK_1(bp->stratum); stratum = EXTRACT_U_1(bp->stratum); ND_PRINT(", Stratum %u (%s)", stratum, tok2str(ntp_stratum_values, (stratum >=2 && stratum<=15) ? "secondary reference" : "reserved", stratum)); ND_TCHECK_1(bp->ppoll); ND_PRINT(", poll %d", EXTRACT_S_1(bp->ppoll)); p_poll(ndo, EXTRACT_S_1(bp->ppoll)); ND_TCHECK_1(bp->precision); ND_PRINT(", precision %d", EXTRACT_S_1(bp->precision)); ND_TCHECK_SIZE(&bp->root_delay); ND_PRINT("\n\tRoot Delay: "); p_sfix(ndo, &bp->root_delay); ND_TCHECK_SIZE(&bp->root_dispersion); ND_PRINT(", Root dispersion: "); p_sfix(ndo, &bp->root_dispersion); ND_TCHECK_4(bp->refid); ND_PRINT(", Reference-ID: "); /* Interpretation depends on stratum */ switch (stratum) { case UNSPECIFIED: ND_PRINT("(unspec)"); break; case PRIM_REF: if (nd_printn(ndo, (const u_char *)&(bp->refid), 4, ndo->ndo_snapend)) goto trunc; break; case INFO_QUERY: ND_PRINT("%s INFO_QUERY", ipaddr_string(ndo, bp->refid)); /* this doesn't have more content */ return; case INFO_REPLY: ND_PRINT("%s INFO_REPLY", ipaddr_string(ndo, bp->refid)); /* this is too complex to be worth printing */ return; default: /* In NTPv4 (RFC 5905) refid is an IPv4 address or first 32 bits of MD5 sum of IPv6 address */ ND_PRINT("0x%08x", EXTRACT_BE_U_4(bp->refid)); break; } ND_TCHECK_SIZE(&bp->ref_timestamp); ND_PRINT("\n\t Reference Timestamp: "); p_ntp_time(ndo, &(bp->ref_timestamp)); ND_TCHECK_SIZE(&bp->org_timestamp); ND_PRINT("\n\t Originator Timestamp: "); p_ntp_time(ndo, &(bp->org_timestamp)); ND_TCHECK_SIZE(&bp->rec_timestamp); ND_PRINT("\n\t Receive Timestamp: "); p_ntp_time(ndo, &(bp->rec_timestamp)); ND_TCHECK_SIZE(&bp->xmt_timestamp); ND_PRINT("\n\t Transmit Timestamp: "); p_ntp_time(ndo, &(bp->xmt_timestamp)); ND_PRINT("\n\t Originator - Receive Timestamp: "); p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->rec_timestamp)); ND_PRINT("\n\t Originator - Transmit Timestamp: "); p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->xmt_timestamp)); /* FIXME: this code is not aware of any extension fields */ if (length == NTP_TIMEMSG_MINLEN + 4) { /* Optional: key-id (crypto-NAK) */ ND_TCHECK_4(bp->key_id); ND_PRINT("\n\tKey id: %u", EXTRACT_BE_U_4(bp->key_id)); } else if (length == NTP_TIMEMSG_MINLEN + 4 + 16) { /* Optional: key-id + 128-bit digest */ ND_TCHECK_4(bp->key_id); ND_PRINT("\n\tKey id: %u", EXTRACT_BE_U_4(bp->key_id)); ND_TCHECK_LEN(bp->message_digest, 16); ND_PRINT("\n\tAuthentication: %08x%08x%08x%08x", EXTRACT_BE_U_4(bp->message_digest), EXTRACT_BE_U_4(bp->message_digest + 4), EXTRACT_BE_U_4(bp->message_digest + 8), EXTRACT_BE_U_4(bp->message_digest + 12)); } else if (length == NTP_TIMEMSG_MINLEN + 4 + 20) { /* Optional: key-id + 160-bit digest */ ND_TCHECK_4(bp->key_id); ND_PRINT("\n\tKey id: %u", EXTRACT_BE_U_4(bp->key_id)); ND_TCHECK_LEN(bp->message_digest, 20); ND_PRINT("\n\tAuthentication: %08x%08x%08x%08x%08x", EXTRACT_BE_U_4(bp->message_digest), EXTRACT_BE_U_4(bp->message_digest + 4), EXTRACT_BE_U_4(bp->message_digest + 8), EXTRACT_BE_U_4(bp->message_digest + 12), EXTRACT_BE_U_4(bp->message_digest + 16)); } else if (length > NTP_TIMEMSG_MINLEN) { ND_PRINT("\n\t(%u more bytes after the header)", length - NTP_TIMEMSG_MINLEN); } return; invalid: nd_print_invalid(ndo); ND_TCHECK_LEN(bp, length); return; trunc: nd_print_trunc(ndo); }
/* * Print ntp requests */ void ntp_print(register const u_char *cp, u_int length) { register const struct ntpdata *bp; int mode, version, leapind; bp = (struct ntpdata *)cp; TCHECK(bp->status); version = (int)(bp->status & VERSIONMASK) >> 3; printf("NTPv%d", version); mode = bp->status & MODEMASK; if (!vflag) { printf (", %s, length %u", tok2str(ntp_mode_values, "Unknown mode", mode), length); return; } printf (", length %u\n\t%s", length, tok2str(ntp_mode_values, "Unknown mode", mode)); leapind = bp->status & LEAPMASK; printf (", Leap indicator: %s (%u)", tok2str(ntp_leapind_values, "Unknown", leapind), leapind); TCHECK(bp->stratum); printf(", Stratum %u (%s)", bp->stratum, tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum)); TCHECK(bp->ppoll); printf(", poll %u (%us)", bp->ppoll, 1 << bp->ppoll); /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ TCHECK2(bp->root_delay, 0); printf(", precision %d", bp->precision); TCHECK(bp->root_delay); fputs("\n\tRoot Delay: ", stdout); p_sfix(&bp->root_delay); TCHECK(bp->root_dispersion); fputs(", Root dispersion: ", stdout); p_sfix(&bp->root_dispersion); TCHECK(bp->refid); fputs(", Reference-ID: ", stdout); /* Interpretation depends on stratum */ switch (bp->stratum) { case UNSPECIFIED: printf("(unspec)"); break; case PRIM_REF: if (fn_printn((u_char *)&(bp->refid), 4, snapend)) goto trunc; break; case INFO_QUERY: printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); /* this doesn't have more content */ return; case INFO_REPLY: printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); /* this is too complex to be worth printing */ return; default: printf("%s", ipaddr_string(&(bp->refid))); break; } TCHECK(bp->ref_timestamp); fputs("\n\t Reference Timestamp: ", stdout); p_ntp_time(&(bp->ref_timestamp)); TCHECK(bp->org_timestamp); fputs("\n\t Originator Timestamp: ", stdout); p_ntp_time(&(bp->org_timestamp)); TCHECK(bp->rec_timestamp); fputs("\n\t Receive Timestamp: ", stdout); p_ntp_time(&(bp->rec_timestamp)); TCHECK(bp->xmt_timestamp); fputs("\n\t Transmit Timestamp: ", stdout); p_ntp_time(&(bp->xmt_timestamp)); fputs("\n\t Originator - Receive Timestamp: ", stdout); p_ntp_delta(&(bp->org_timestamp), &(bp->rec_timestamp)); fputs("\n\t Originator - Transmit Timestamp: ", stdout); p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp)); if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */ TCHECK(bp->key_id); printf("\n\tKey id: %u", bp->key_id); } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */ TCHECK(bp->key_id); printf("\n\tKey id: %u", bp->key_id); TCHECK2(bp->message_digest, sizeof (bp->message_digest)); printf("\n\tAuthentication: %08x%08x%08x%08x", EXTRACT_32BITS(bp->message_digest), EXTRACT_32BITS(bp->message_digest + 4), EXTRACT_32BITS(bp->message_digest + 8), EXTRACT_32BITS(bp->message_digest + 12)); } return; trunc: fputs(" [|ntp]", stdout); }
/* * Print ntp requests */ void ntp_print(register const u_char *cp, u_int length) { register const struct ntpdata *bp; int mode, version, leapind; static char rclock[5]; bp = (struct ntpdata *)cp; /* Note funny sized packets */ if (length != sizeof(struct ntpdata)) (void)printf(" [len=%d]", length); TCHECK(bp->status); version = (int)(bp->status & VERSIONMASK) >> 3; printf(" v%d", version); leapind = bp->status & LEAPMASK; switch (leapind) { case NO_WARNING: break; case PLUS_SEC: fputs(" +1s", stdout); break; case MINUS_SEC: fputs(" -1s", stdout); break; } mode = bp->status & MODEMASK; switch (mode) { case MODE_UNSPEC: /* unspecified */ fputs(" unspec", stdout); break; case MODE_SYM_ACT: /* symmetric active */ fputs(" sym_act", stdout); break; case MODE_SYM_PAS: /* symmetric passive */ fputs(" sym_pas", stdout); break; case MODE_CLIENT: /* client */ fputs(" client", stdout); break; case MODE_SERVER: /* server */ fputs(" server", stdout); break; case MODE_BROADCAST: /* broadcast */ fputs(" bcast", stdout); break; case MODE_RES1: /* reserved */ fputs(" res1", stdout); break; case MODE_RES2: /* reserved */ fputs(" res2", stdout); break; } TCHECK(bp->stratum); printf(" strat %d", bp->stratum); TCHECK(bp->ppoll); printf(" poll %d", bp->ppoll); /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ TCHECK2(bp->distance, 0); printf(" prec %d", bp->precision); if (!vflag) return; TCHECK(bp->distance); fputs(" dist ", stdout); p_sfix(&bp->distance); TCHECK(bp->dispersion); fputs(" disp ", stdout); p_sfix(&bp->dispersion); TCHECK(bp->refid); fputs(" ref ", stdout); /* Interpretation depends on stratum */ switch (bp->stratum) { case UNSPECIFIED: printf("(unspec)"); break; case PRIM_REF: strncpy(rclock, (char *)&(bp->refid), 4); rclock[4] = '\0'; fputs(rclock, stdout); break; case INFO_QUERY: printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); /* this doesn't have more content */ return; case INFO_REPLY: printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); /* this is too complex to be worth printing */ return; default: printf("%s", ipaddr_string(&(bp->refid))); break; } TCHECK(bp->reftime); putchar('@'); p_ntp_time(&(bp->reftime)); TCHECK(bp->org); fputs(" orig ", stdout); p_ntp_time(&(bp->org)); TCHECK(bp->rec); fputs(" rec ", stdout); p_ntp_delta(&(bp->org), &(bp->rec)); TCHECK(bp->xmt); fputs(" xmt ", stdout); p_ntp_delta(&(bp->org), &(bp->xmt)); return; trunc: fputs(" [|ntp]", stdout); }