X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/febd0bc5aa33b3de9b5864e8c5565fe7b63f519f..db8c799f6dfc68765c9451fcbfca06e662f5bd5f:/print-ntp.c diff --git a/print-ntp.c b/print-ntp.c index a7d32bdf..63a35091 100644 --- a/print-ntp.c +++ b/print-ntp.c @@ -68,13 +68,13 @@ static const char tstr[] = " [|ntp]"; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct l_fixedpt { - uint32_t int_part; - uint32_t fraction; + nd_uint32_t int_part; + nd_uint32_t fraction; }; struct s_fixedpt { - uint16_t int_part; - uint16_t fraction; + nd_uint16_t int_part; + nd_uint16_t fraction; }; /* rfc2030 @@ -115,26 +115,26 @@ struct s_fixedpt { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -/* Length of the NTP message with the mandatory fields ("the header") +/* Length of the NTP data message with the mandatory fields ("the header") * and without any optional fields (extension, Key Identifier, * Message Digest). */ -#define NTP_MSG_MINLEN 48 +#define NTP_TIMEMSG_MINLEN 48U struct ntp_time_data { - u_char status; /* status of local clock and leap info */ - u_char stratum; /* Stratum level */ - int ppoll:8; /* poll value */ - int precision:8; + nd_uint8_t status; /* status of local clock and leap info */ + nd_uint8_t stratum; /* Stratum level */ + nd_int8_t ppoll; /* poll value */ + nd_int8_t precision; struct s_fixedpt root_delay; struct s_fixedpt root_dispersion; - uint32_t refid; + nd_uint32_t refid; struct l_fixedpt ref_timestamp; struct l_fixedpt org_timestamp; struct l_fixedpt rec_timestamp; struct l_fixedpt xmt_timestamp; - uint32_t key_id; - uint8_t message_digest[20]; + nd_uint32_t key_id; + nd_uint8_t message_digest[20]; }; /* * Leap Second Codes (high order two bits) @@ -232,15 +232,21 @@ static const struct tok ntp_stratum_values[] = { * * Figure 1: NTP Control Message Header */ + +/* Length of the NTP control message with the mandatory fields ("the header") + * and without any optional fields (Data, Padding, Authenticator). + */ +#define NTP_CTRLMSG_MINLEN 12U + struct ntp_control_data { - u_char magic; /* LI, VN, Mode */ - u_char control; /* R, E, M, OpCode */ - uint16_t sequence; /* Sequence Number */ - uint16_t status; /* Status */ - uint16_t assoc; /* Association ID */ - uint16_t offset; /* Offset */ - uint16_t count; /* Count */ - u_char data[564]; /* Data, [Padding, [Authenticator]] */ + nd_uint8_t magic; /* LI, VN, Mode */ + nd_uint8_t control; /* R, E, M, OpCode */ + nd_uint16_t sequence; /* Sequence Number */ + nd_uint16_t status; /* Status */ + nd_uint16_t assoc; /* Association ID */ + nd_uint16_t offset; /* Offset */ + nd_uint16_t count; /* Count */ + nd_uint8_t data[564]; /* Data, [Padding, [Authenticator]] */ }; /* @@ -252,10 +258,8 @@ ntp_time_print(netdissect_options *ndo, { int mode, version, leapind; - if (length < NTP_MSG_MINLEN) { - ND_PRINT((ndo, "NTP, length %u", length)); + if (length < NTP_TIMEMSG_MINLEN) goto invalid; - } ND_TCHECK(bp->status); @@ -284,13 +288,11 @@ ntp_time_print(netdissect_options *ndo, bp->stratum, tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum))); - /* Can't ND_TCHECK bp->ppoll bitfield so bp->stratum + 2 instead */ - ND_TCHECK2(bp->stratum, 2); + ND_TCHECK(bp->ppoll); ND_PRINT((ndo, ", poll %d", bp->ppoll)); p_poll(ndo, bp->ppoll); - /* Can't ND_TCHECK bp->precision bitfield so bp->distance + 0 instead */ - ND_TCHECK2(bp->root_delay, 0); + ND_TCHECK(bp->precision); ND_PRINT((ndo, ", precision %d", bp->precision)); ND_TCHECK(bp->root_delay); @@ -355,10 +357,10 @@ ntp_time_print(netdissect_options *ndo, p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->xmt_timestamp)); /* FIXME: this code is not aware of any extension fields */ - if (length == NTP_MSG_MINLEN + 4) { /* Optional: key-id (crypto-NAK) */ + if (length == NTP_TIMEMSG_MINLEN + 4) { /* Optional: key-id (crypto-NAK) */ ND_TCHECK(bp->key_id); ND_PRINT((ndo, "\n\tKey id: %u", EXTRACT_32BITS(&bp->key_id))); - } else if (length == NTP_MSG_MINLEN + 4 + 16) { /* Optional: key-id + 128-bit digest */ + } else if (length == NTP_TIMEMSG_MINLEN + 4 + 16) { /* Optional: key-id + 128-bit digest */ ND_TCHECK(bp->key_id); ND_PRINT((ndo, "\n\tKey id: %u", EXTRACT_32BITS(&bp->key_id))); ND_TCHECK2(bp->message_digest, 16); @@ -367,7 +369,7 @@ ntp_time_print(netdissect_options *ndo, EXTRACT_32BITS(bp->message_digest + 4), EXTRACT_32BITS(bp->message_digest + 8), EXTRACT_32BITS(bp->message_digest + 12))); - } else if (length == NTP_MSG_MINLEN + 4 + 20) { /* Optional: key-id + 160-bit digest */ + } else if (length == NTP_TIMEMSG_MINLEN + 4 + 20) { /* Optional: key-id + 160-bit digest */ ND_TCHECK(bp->key_id); ND_PRINT((ndo, "\n\tKey id: %u", EXTRACT_32BITS(&bp->key_id))); ND_TCHECK2(bp->message_digest, 20); @@ -377,8 +379,8 @@ ntp_time_print(netdissect_options *ndo, EXTRACT_32BITS(bp->message_digest + 8), EXTRACT_32BITS(bp->message_digest + 12), EXTRACT_32BITS(bp->message_digest + 16))); - } else if (length > NTP_MSG_MINLEN) { - ND_PRINT((ndo, "\n\t(%u more bytes after the header)", length - NTP_MSG_MINLEN)); + } else if (length > NTP_TIMEMSG_MINLEN) { + ND_PRINT((ndo, "\n\t(%u more bytes after the header)", length - NTP_TIMEMSG_MINLEN)); } return; @@ -401,6 +403,10 @@ ntp_control_print(netdissect_options *ndo, u_char R, E, M, opcode; uint16_t sequence, status, assoc, offset, count; + if (length < NTP_CTRLMSG_MINLEN) + goto invalid; + + ND_TCHECK(cd->control); R = (cd->control & 0x80) != 0; E = (cd->control & 0x40) != 0; M = (cd->control & 0x20) != 0; @@ -409,25 +415,37 @@ ntp_control_print(netdissect_options *ndo, R ? "Response" : "Request", E ? "Error" : "OK", M ? "More" : "Last", (unsigned)opcode)); + ND_TCHECK(cd->sequence); sequence = EXTRACT_16BITS(&cd->sequence); ND_PRINT((ndo, "\tSequence=%hu", sequence)); + ND_TCHECK(cd->status); status = EXTRACT_16BITS(&cd->status); ND_PRINT((ndo, ", Status=%#hx", status)); + ND_TCHECK(cd->assoc); assoc = EXTRACT_16BITS(&cd->assoc); ND_PRINT((ndo, ", Assoc.=%hu", assoc)); + ND_TCHECK(cd->offset); offset = EXTRACT_16BITS(&cd->offset); ND_PRINT((ndo, ", Offset=%hu", offset)); + ND_TCHECK(cd->count); count = EXTRACT_16BITS(&cd->count); ND_PRINT((ndo, ", Count=%hu", count)); - if ((cd->data - (const u_char *)cd) + count > length) - goto trunc; - if (count != 0) + if (NTP_CTRLMSG_MINLEN + count > length) + goto invalid; + if (count != 0) { + ND_TCHECK2(cd->data, count); ND_PRINT((ndo, "\n\tTO-BE-DONE: data not interpreted")); + } + return; + +invalid: + ND_PRINT((ndo, " %s", istr)); + ND_TCHECK2(*cd, length); return; trunc: