NTP: Improve handling of poll and precision fields

The poll and precision fields in timing NTP messages are signed
integers.

Different NTP implementations have different minimum and maximum polling
intervals. Some can be configured even with negative values for
sub-second intervals (e.g. down to -7 for 1/128th of a second).

NTP clocks on modern systems and hardware typically have
a sub-microsecond precision.

Print all poll values. Add the raw precision and change the resolution
of the printed value to nanoseconds.
This commit is contained in:
Miroslav Lichvar 2022-08-16 14:41:21 +02:00 committed by AndersBroman
parent b025c45cf3
commit d892d28481
2 changed files with 22 additions and 26 deletions

View File

@ -1137,7 +1137,7 @@ static void
dissect_ntp_std(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ntp_tree, ntp_conv_info_t *ntp_conv)
{
guint8 stratum;
guint8 ppoll;
gint8 ppoll;
gint8 precision;
guint32 rootdelay;
double rootdelay_double;
@ -1211,21 +1211,17 @@ dissect_ntp_std(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ntp_tree, ntp_con
* between successive messages, in seconds to the nearest
* power of two.
*/
ppoll = tvb_get_guint8(tvb, 2);
if ((ppoll >= 4) && (ppoll <= 17)) {
proto_tree_add_uint_format_value(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
ppoll, "%u (%u seconds)", ppoll, 1 << ppoll);
} else {
proto_tree_add_uint_format_value(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
ppoll, "invalid (%u)", ppoll);
}
ppoll = tvb_get_gint8(tvb, 2);
proto_tree_add_int_format_value(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
ppoll, ppoll >= 0 ? "%d (%.0f seconds)" : "%d (%5.3f seconds)",
ppoll, pow(2, ppoll));
/* Precision, 1 byte field indicating the precision of the
* local clock, in seconds to the nearest power of two.
*/
precision = tvb_get_guint8(tvb, 3);
proto_tree_add_uint_format_value(ntp_tree, hf_ntp_precision, tvb, 3, 1,
(guint8)precision, "%8.6f seconds", pow(2, precision));
precision = tvb_get_gint8(tvb, 3);
proto_tree_add_int_format_value(ntp_tree, hf_ntp_precision, tvb, 3, 1,
precision, "%d (%11.9f seconds)", precision, pow(2, precision));
/* Root Delay is a 32-bit signed fixed-point number indicating
* the total roundtrip delay to the primary reference source,
@ -2646,10 +2642,10 @@ proto_register_ntp(void)
"Peer Clock Stratum", "ntp.stratum", FT_UINT8, BASE_DEC|BASE_RANGE_STRING,
RVALS(stratum_rvals), 0, NULL, HFILL }},
{ &hf_ntp_ppoll, {
"Peer Polling Interval", "ntp.ppoll", FT_UINT8, BASE_DEC,
"Peer Polling Interval", "ntp.ppoll", FT_INT8, BASE_DEC,
NULL, 0, "Maximum interval between successive messages", HFILL }},
{ &hf_ntp_precision, {
"Peer Clock Precision", "ntp.precision", FT_UINT8, BASE_DEC,
"Peer Clock Precision", "ntp.precision", FT_INT8, BASE_DEC,
NULL, 0, "The precision of the system clock", HFILL }},
{ &hf_ntp_rootdelay, {
"Root Delay", "ntp.rootdelay", FT_UINT32, BASE_DEC,

View File

@ -110,51 +110,51 @@ class case_integer(unittest.TestCase):
checkDFilterCount(dfilter, 1)
def test_s_gt_1(self, checkDFilterCount):
dfilter = "ntp.precision > 244"
dfilter = "ntp.precision > -12"
checkDFilterCount(dfilter, 1)
def test_s_gt_2(self, checkDFilterCount):
dfilter = "ntp.precision > 245"
dfilter = "ntp.precision > -11"
checkDFilterCount(dfilter, 0)
def test_s_gt_3(self, checkDFilterCount):
dfilter = "ntp.precision > 246"
dfilter = "ntp.precision > -10"
checkDFilterCount(dfilter, 0)
def test_s_ge_1(self, checkDFilterCount):
dfilter = "ntp.precision >= 244"
dfilter = "ntp.precision >= -12"
checkDFilterCount(dfilter, 1)
def test_s_ge_2(self, checkDFilterCount):
dfilter = "ntp.precision >= 245"
dfilter = "ntp.precision >= -11"
checkDFilterCount(dfilter, 1)
def test_s_ge_3(self, checkDFilterCount):
dfilter = "ntp.precision >= 246"
dfilter = "ntp.precision >= -10"
checkDFilterCount(dfilter, 0)
def test_s_lt_1(self, checkDFilterCount):
dfilter = "ntp.precision < 244"
dfilter = "ntp.precision < -12"
checkDFilterCount(dfilter, 0)
def test_s_lt_2(self, checkDFilterCount):
dfilter = "ntp.precision < 245"
dfilter = "ntp.precision < -11"
checkDFilterCount(dfilter, 0)
def test_s_lt_3(self, checkDFilterCount):
dfilter = "ntp.precision < 246"
dfilter = "ntp.precision < -10"
checkDFilterCount(dfilter, 1)
def test_s_le_1(self, checkDFilterCount):
dfilter = "ntp.precision <= 244"
dfilter = "ntp.precision <= -12"
checkDFilterCount(dfilter, 0)
def test_s_le_2(self, checkDFilterCount):
dfilter = "ntp.precision <= 245"
dfilter = "ntp.precision <= -11"
checkDFilterCount(dfilter, 1)
def test_s_le_3(self, checkDFilterCount):
dfilter = "ntp.precision <= 246"
dfilter = "ntp.precision <= -10"
checkDFilterCount(dfilter, 1)
def test_bool_eq_1(self, checkDFilterCount):