The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 |
| 3 | * The Regents of the University of California. All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that: (1) source code distributions |
| 7 | * retain the above copyright notice and this paragraph in its entirety, (2) |
| 8 | * distributions including binary code include the above copyright notice and |
| 9 | * this paragraph in its entirety in the documentation or other materials |
| 10 | * provided with the distribution, and (3) all advertising materials mentioning |
| 11 | * features or use of this software display the following acknowledgement: |
| 12 | * ``This product includes software developed by the University of California, |
| 13 | * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of |
| 14 | * the University nor the names of its contributors may be used to endorse |
| 15 | * or promote products derived from this software without specific prior |
| 16 | * written permission. |
| 17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
| 18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
| 19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
| 20 | * |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 21 | * By Jeffrey Mogul/DECWRL |
| 22 | * loosely based on print-bootp.c |
| 23 | */ |
| 24 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 25 | /* \summary: Network Time Protocol (NTP) printer */ |
| 26 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 27 | /* |
| 28 | * specification: |
| 29 | * |
| 30 | * RFC 1119 - NTPv2 |
| 31 | * RFC 1305 - NTPv3 |
| 32 | * RFC 5905 - NTPv4 |
| 33 | */ |
| 34 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 35 | #ifdef HAVE_CONFIG_H |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 36 | #include <config.h> |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 37 | #endif |
| 38 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 39 | #include "netdissect-stdinc.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 40 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 41 | #ifdef HAVE_STRFTIME |
| 42 | #include <time.h> |
| 43 | #endif |
| 44 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 45 | #include "netdissect.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 46 | #include "addrtoname.h" |
| 47 | #include "extract.h" |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 48 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 49 | #include "ntp.h" |
| 50 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 51 | /* |
| 52 | * Based on ntp.h from the U of MD implementation |
| 53 | * This file is based on Version 2 of the NTP spec (RFC1119). |
| 54 | */ |
| 55 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 56 | /* rfc2030 |
| 57 | * 1 2 3 |
| 58 | * 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 |
| 59 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 60 | * |LI | VN |Mode | Stratum | Poll | Precision | |
| 61 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 62 | * | Root Delay | |
| 63 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 64 | * | Root Dispersion | |
| 65 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 66 | * | Reference Identifier | |
| 67 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 68 | * | | |
| 69 | * | Reference Timestamp (64) | |
| 70 | * | | |
| 71 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 72 | * | | |
| 73 | * | Originate Timestamp (64) | |
| 74 | * | | |
| 75 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 76 | * | | |
| 77 | * | Receive Timestamp (64) | |
| 78 | * | | |
| 79 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 80 | * | | |
| 81 | * | Transmit Timestamp (64) | |
| 82 | * | | |
| 83 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 84 | * | Key Identifier (optional) (32) | |
| 85 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 86 | * | | |
| 87 | * | | |
| 88 | * | Message Digest (optional) (128) | |
| 89 | * | | |
| 90 | * | | |
| 91 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 92 | */ |
| 93 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 94 | /* Length of the NTP data message with the mandatory fields ("the header") |
| 95 | * and without any optional fields (extension, Key Identifier, |
| 96 | * Message Digest). |
| 97 | */ |
| 98 | #define NTP_TIMEMSG_MINLEN 48U |
| 99 | |
| 100 | struct ntp_time_data { |
| 101 | nd_uint8_t status; /* status of local clock and leap info */ |
| 102 | nd_uint8_t stratum; /* Stratum level */ |
| 103 | nd_int8_t ppoll; /* poll value */ |
| 104 | nd_int8_t precision; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 105 | struct s_fixedpt root_delay; |
| 106 | struct s_fixedpt root_dispersion; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 107 | nd_uint32_t refid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 108 | struct l_fixedpt ref_timestamp; |
| 109 | struct l_fixedpt org_timestamp; |
| 110 | struct l_fixedpt rec_timestamp; |
| 111 | struct l_fixedpt xmt_timestamp; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 112 | nd_uint32_t key_id; |
| 113 | nd_uint8_t message_digest[20]; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 114 | }; |
| 115 | /* |
| 116 | * Leap Second Codes (high order two bits) |
| 117 | */ |
| 118 | #define NO_WARNING 0x00 /* no warning */ |
| 119 | #define PLUS_SEC 0x40 /* add a second (61 seconds) */ |
| 120 | #define MINUS_SEC 0x80 /* minus a second (59 seconds) */ |
| 121 | #define ALARM 0xc0 /* alarm condition (clock unsynchronized) */ |
| 122 | |
| 123 | /* |
| 124 | * Clock Status Bits that Encode Version |
| 125 | */ |
| 126 | #define NTPVERSION_1 0x08 |
| 127 | #define VERSIONMASK 0x38 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 128 | #define VERSIONSHIFT 3 |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 129 | #define LEAPMASK 0xc0 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 130 | #define LEAPSHIFT 6 |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 131 | #ifdef MODEMASK |
| 132 | #undef MODEMASK /* Solaris sucks */ |
| 133 | #endif |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 134 | #define MODEMASK 0x07 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 135 | #define MODESHIFT 0 |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 136 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 137 | /* |
| 138 | * Code values |
| 139 | */ |
| 140 | #define MODE_UNSPEC 0 /* unspecified */ |
| 141 | #define MODE_SYM_ACT 1 /* symmetric active */ |
| 142 | #define MODE_SYM_PAS 2 /* symmetric passive */ |
| 143 | #define MODE_CLIENT 3 /* client */ |
| 144 | #define MODE_SERVER 4 /* server */ |
| 145 | #define MODE_BROADCAST 5 /* broadcast */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 146 | #define MODE_CONTROL 6 /* control message */ |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 147 | #define MODE_RES2 7 /* reserved */ |
| 148 | |
| 149 | /* |
| 150 | * Stratum Definitions |
| 151 | */ |
| 152 | #define UNSPECIFIED 0 |
| 153 | #define PRIM_REF 1 /* radio clock */ |
| 154 | #define INFO_QUERY 62 /* **** THIS implementation dependent **** */ |
| 155 | #define INFO_REPLY 63 /* **** THIS implementation dependent **** */ |
| 156 | |
| 157 | static void p_sfix(netdissect_options *ndo, const struct s_fixedpt *); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 158 | static void p_ntp_delta(netdissect_options *, const struct l_fixedpt *, const struct l_fixedpt *); |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 159 | static void p_poll(netdissect_options *, const int); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 160 | |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 161 | static const struct tok ntp_mode_values[] = { |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 162 | { MODE_UNSPEC, "unspecified" }, |
| 163 | { MODE_SYM_ACT, "symmetric active" }, |
| 164 | { MODE_SYM_PAS, "symmetric passive" }, |
| 165 | { MODE_CLIENT, "Client" }, |
| 166 | { MODE_SERVER, "Server" }, |
| 167 | { MODE_BROADCAST, "Broadcast" }, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 168 | { MODE_CONTROL, "Control Message" }, |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 169 | { MODE_RES2, "Reserved" }, |
| 170 | { 0, NULL } |
| 171 | }; |
| 172 | |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 173 | static const struct tok ntp_leapind_values[] = { |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 174 | { NO_WARNING, "" }, |
| 175 | { PLUS_SEC, "+1s" }, |
| 176 | { MINUS_SEC, "-1s" }, |
| 177 | { ALARM, "clock unsynchronized" }, |
| 178 | { 0, NULL } |
| 179 | }; |
| 180 | |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 181 | static const struct tok ntp_stratum_values[] = { |
| 182 | { UNSPECIFIED, "unspecified" }, |
| 183 | { PRIM_REF, "primary reference" }, |
| 184 | { 0, NULL } |
| 185 | }; |
| 186 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 187 | /* draft-ietf-ntp-mode-6-cmds-02 |
| 188 | * 0 1 2 3 |
| 189 | * 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 |
| 190 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 191 | * |LI | VN |Mode |R|E|M| OpCode | Sequence Number | |
| 192 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 193 | * | Status | Association ID | |
| 194 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 195 | * | Offset | Count | |
| 196 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 197 | * | | |
| 198 | * / Data (up to 468 bytes) / |
| 199 | * | | |
| 200 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 201 | * | Padding (optional) | |
| 202 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 203 | * | | |
| 204 | * / Authenticator (optional, 96 bytes) / |
| 205 | * | | |
| 206 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 207 | * |
| 208 | * Figure 1: NTP Control Message Header |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 209 | */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 210 | |
| 211 | /* Length of the NTP control message with the mandatory fields ("the header") |
| 212 | * and without any optional fields (Data, Padding, Authenticator). |
| 213 | */ |
| 214 | #define NTP_CTRLMSG_MINLEN 12U |
| 215 | |
| 216 | struct ntp_control_data { |
| 217 | nd_uint8_t magic; /* LI, VN, Mode */ |
| 218 | nd_uint8_t control; /* R, E, M, OpCode */ |
| 219 | nd_uint16_t sequence; /* Sequence Number */ |
| 220 | nd_uint16_t status; /* Status */ |
| 221 | nd_uint16_t assoc; /* Association ID */ |
| 222 | nd_uint16_t offset; /* Offset */ |
| 223 | nd_uint16_t count; /* Count */ |
| 224 | nd_uint8_t data[564]; /* Data, [Padding, [Authenticator]] */ |
| 225 | }; |
| 226 | |
| 227 | /* |
| 228 | * Print NTP time requests and responses |
| 229 | */ |
| 230 | static void |
| 231 | ntp_time_print(netdissect_options *ndo, |
| 232 | const struct ntp_time_data *bp, u_int length) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 233 | { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 234 | uint8_t stratum; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 235 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 236 | if (length < NTP_TIMEMSG_MINLEN) |
| 237 | goto invalid; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 238 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 239 | stratum = GET_U_1(bp->stratum); |
| 240 | ND_PRINT(", Stratum %u (%s)", |
| 241 | stratum, |
| 242 | tok2str(ntp_stratum_values, (stratum >=2 && stratum<=15) ? "secondary reference" : "reserved", stratum)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 243 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 244 | ND_PRINT(", poll %d", GET_S_1(bp->ppoll)); |
| 245 | p_poll(ndo, GET_S_1(bp->ppoll)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 246 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 247 | ND_PRINT(", precision %d", GET_S_1(bp->precision)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 248 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 249 | ND_TCHECK_SIZE(&bp->root_delay); |
| 250 | ND_PRINT("\n\tRoot Delay: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 251 | p_sfix(ndo, &bp->root_delay); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 252 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 253 | ND_TCHECK_SIZE(&bp->root_dispersion); |
| 254 | ND_PRINT(", Root dispersion: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 255 | p_sfix(ndo, &bp->root_dispersion); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 256 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 257 | ND_TCHECK_4(bp->refid); |
| 258 | ND_PRINT(", Reference-ID: "); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 259 | /* Interpretation depends on stratum */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 260 | switch (stratum) { |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 261 | |
| 262 | case UNSPECIFIED: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 263 | ND_PRINT("(unspec)"); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 264 | break; |
| 265 | |
| 266 | case PRIM_REF: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 267 | if (nd_printn(ndo, (const u_char *)&(bp->refid), 4, ndo->ndo_snapend)) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 268 | goto trunc; |
| 269 | break; |
| 270 | |
| 271 | case INFO_QUERY: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 272 | ND_PRINT("%s INFO_QUERY", GET_IPADDR_STRING(bp->refid)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 273 | /* this doesn't have more content */ |
| 274 | return; |
| 275 | |
| 276 | case INFO_REPLY: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 277 | ND_PRINT("%s INFO_REPLY", GET_IPADDR_STRING(bp->refid)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 278 | /* this is too complex to be worth printing */ |
| 279 | return; |
| 280 | |
| 281 | default: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 282 | /* In NTPv4 (RFC 5905) refid is an IPv4 address or first 32 bits of |
| 283 | MD5 sum of IPv6 address */ |
| 284 | ND_PRINT("0x%08x", GET_BE_U_4(bp->refid)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 285 | break; |
| 286 | } |
| 287 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 288 | ND_TCHECK_SIZE(&bp->ref_timestamp); |
| 289 | ND_PRINT("\n\t Reference Timestamp: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 290 | p_ntp_time(ndo, &(bp->ref_timestamp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 291 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 292 | ND_TCHECK_SIZE(&bp->org_timestamp); |
| 293 | ND_PRINT("\n\t Originator Timestamp: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 294 | p_ntp_time(ndo, &(bp->org_timestamp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 295 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 296 | ND_TCHECK_SIZE(&bp->rec_timestamp); |
| 297 | ND_PRINT("\n\t Receive Timestamp: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 298 | p_ntp_time(ndo, &(bp->rec_timestamp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 299 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 300 | ND_TCHECK_SIZE(&bp->xmt_timestamp); |
| 301 | ND_PRINT("\n\t Transmit Timestamp: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 302 | p_ntp_time(ndo, &(bp->xmt_timestamp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 303 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 304 | ND_PRINT("\n\t Originator - Receive Timestamp: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 305 | p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->rec_timestamp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 306 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 307 | ND_PRINT("\n\t Originator - Transmit Timestamp: "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 308 | p_ntp_delta(ndo, &(bp->org_timestamp), &(bp->xmt_timestamp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 309 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 310 | /* FIXME: this code is not aware of any extension fields */ |
| 311 | if (length == NTP_TIMEMSG_MINLEN + 4) { /* Optional: key-id (crypto-NAK) */ |
| 312 | ND_PRINT("\n\tKey id: %u", GET_BE_U_4(bp->key_id)); |
| 313 | } else if (length == NTP_TIMEMSG_MINLEN + 4 + 16) { /* Optional: key-id + 128-bit digest */ |
| 314 | ND_PRINT("\n\tKey id: %u", GET_BE_U_4(bp->key_id)); |
| 315 | ND_TCHECK_LEN(bp->message_digest, 16); |
| 316 | ND_PRINT("\n\tAuthentication: %08x%08x%08x%08x", |
| 317 | GET_BE_U_4(bp->message_digest), |
| 318 | GET_BE_U_4(bp->message_digest + 4), |
| 319 | GET_BE_U_4(bp->message_digest + 8), |
| 320 | GET_BE_U_4(bp->message_digest + 12)); |
| 321 | } else if (length == NTP_TIMEMSG_MINLEN + 4 + 20) { /* Optional: key-id + 160-bit digest */ |
| 322 | ND_PRINT("\n\tKey id: %u", GET_BE_U_4(bp->key_id)); |
| 323 | ND_TCHECK_LEN(bp->message_digest, 20); |
| 324 | ND_PRINT("\n\tAuthentication: %08x%08x%08x%08x%08x", |
| 325 | GET_BE_U_4(bp->message_digest), |
| 326 | GET_BE_U_4(bp->message_digest + 4), |
| 327 | GET_BE_U_4(bp->message_digest + 8), |
| 328 | GET_BE_U_4(bp->message_digest + 12), |
| 329 | GET_BE_U_4(bp->message_digest + 16)); |
| 330 | } else if (length > NTP_TIMEMSG_MINLEN) { |
| 331 | ND_PRINT("\n\t(%u more bytes after the header)", length - NTP_TIMEMSG_MINLEN); |
| 332 | } |
| 333 | return; |
| 334 | |
| 335 | invalid: |
| 336 | nd_print_invalid(ndo); |
| 337 | ND_TCHECK_LEN(bp, length); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 338 | return; |
| 339 | |
| 340 | trunc: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 341 | nd_print_trunc(ndo); |
| 342 | } |
| 343 | |
| 344 | /* |
| 345 | * Print NTP control message requests and responses |
| 346 | */ |
| 347 | static void |
| 348 | ntp_control_print(netdissect_options *ndo, |
| 349 | const struct ntp_control_data *cd, u_int length) |
| 350 | { |
| 351 | uint8_t control, R, E, M, opcode; |
| 352 | uint16_t sequence, status, assoc, offset, count; |
| 353 | |
| 354 | if (length < NTP_CTRLMSG_MINLEN) |
| 355 | goto invalid; |
| 356 | |
| 357 | control = GET_U_1(cd->control); |
| 358 | R = (control & 0x80) != 0; |
| 359 | E = (control & 0x40) != 0; |
| 360 | M = (control & 0x20) != 0; |
| 361 | opcode = control & 0x1f; |
| 362 | ND_PRINT(", %s, %s, %s, OpCode=%u\n", |
| 363 | R ? "Response" : "Request", E ? "Error" : "OK", |
| 364 | M ? "More" : "Last", opcode); |
| 365 | |
| 366 | sequence = GET_BE_U_2(cd->sequence); |
| 367 | ND_PRINT("\tSequence=%hu", sequence); |
| 368 | |
| 369 | status = GET_BE_U_2(cd->status); |
| 370 | ND_PRINT(", Status=%#hx", status); |
| 371 | |
| 372 | assoc = GET_BE_U_2(cd->assoc); |
| 373 | ND_PRINT(", Assoc.=%hu", assoc); |
| 374 | |
| 375 | offset = GET_BE_U_2(cd->offset); |
| 376 | ND_PRINT(", Offset=%hu", offset); |
| 377 | |
| 378 | count = GET_BE_U_2(cd->count); |
| 379 | ND_PRINT(", Count=%hu", count); |
| 380 | |
| 381 | if (NTP_CTRLMSG_MINLEN + count > length) |
| 382 | goto invalid; |
| 383 | if (count != 0) { |
| 384 | ND_TCHECK_LEN(cd->data, count); |
| 385 | ND_PRINT("\n\tTO-BE-DONE: data not interpreted"); |
| 386 | } |
| 387 | return; |
| 388 | |
| 389 | invalid: |
| 390 | nd_print_invalid(ndo); |
| 391 | ND_TCHECK_LEN(cd, length); |
| 392 | return; |
| 393 | |
| 394 | trunc: |
| 395 | nd_print_trunc(ndo); |
| 396 | } |
| 397 | |
| 398 | union ntpdata { |
| 399 | struct ntp_time_data td; |
| 400 | struct ntp_control_data cd; |
| 401 | }; |
| 402 | |
| 403 | /* |
| 404 | * Print NTP requests, handling the common VN, LI, and Mode |
| 405 | */ |
| 406 | void |
| 407 | ntp_print(netdissect_options *ndo, |
| 408 | const u_char *cp, u_int length) |
| 409 | { |
| 410 | const union ntpdata *bp = (const union ntpdata *)cp; |
| 411 | u_int mode, version, leapind; |
| 412 | uint8_t status; |
| 413 | |
| 414 | ndo->ndo_protocol = "ntp"; |
| 415 | status = GET_U_1(bp->td.status); |
| 416 | |
| 417 | version = (status & VERSIONMASK) >> VERSIONSHIFT; |
| 418 | ND_PRINT("NTPv%u", version); |
| 419 | |
| 420 | mode = (status & MODEMASK) >> MODESHIFT; |
| 421 | if (!ndo->ndo_vflag) { |
| 422 | ND_PRINT(", %s, length %u", |
| 423 | tok2str(ntp_mode_values, "Unknown mode", mode), |
| 424 | length); |
| 425 | return; |
| 426 | } |
| 427 | |
| 428 | ND_PRINT(", %s, length %u\n", |
| 429 | tok2str(ntp_mode_values, "Unknown mode", mode), length); |
| 430 | |
| 431 | /* leapind = (status & LEAPMASK) >> LEAPSHIFT; */ |
| 432 | leapind = (status & LEAPMASK); |
| 433 | ND_PRINT("\tLeap indicator: %s (%u)", |
| 434 | tok2str(ntp_leapind_values, "Unknown", leapind), |
| 435 | leapind); |
| 436 | |
| 437 | switch (mode) { |
| 438 | |
| 439 | case MODE_UNSPEC: |
| 440 | case MODE_SYM_ACT: |
| 441 | case MODE_SYM_PAS: |
| 442 | case MODE_CLIENT: |
| 443 | case MODE_SERVER: |
| 444 | case MODE_BROADCAST: |
| 445 | ntp_time_print(ndo, &bp->td, length); |
| 446 | break; |
| 447 | |
| 448 | case MODE_CONTROL: |
| 449 | ntp_control_print(ndo, &bp->cd, length); |
| 450 | break; |
| 451 | |
| 452 | default: |
| 453 | break; /* XXX: not implemented! */ |
| 454 | } |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 455 | } |
| 456 | |
| 457 | static void |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 458 | p_sfix(netdissect_options *ndo, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 459 | const struct s_fixedpt *sfp) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 460 | { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 461 | int i; |
| 462 | int f; |
| 463 | double ff; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 464 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 465 | i = GET_BE_U_2(sfp->int_part); |
| 466 | f = GET_BE_U_2(sfp->fraction); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 467 | ff = f / 65536.0; /* shift radix point by 16 bits */ |
| 468 | f = (int)(ff * 1000000.0); /* Treat fraction as parts per million */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 469 | ND_PRINT("%d.%06d", i, f); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 470 | } |
| 471 | |
| 472 | /* Prints time difference between *lfp and *olfp */ |
| 473 | static void |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 474 | p_ntp_delta(netdissect_options *ndo, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 475 | const struct l_fixedpt *olfp, |
| 476 | const struct l_fixedpt *lfp) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 477 | { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 478 | uint32_t u, uf; |
| 479 | uint32_t ou, ouf; |
| 480 | uint32_t i; |
| 481 | uint32_t f; |
| 482 | double ff; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 483 | int signbit; |
| 484 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 485 | u = GET_BE_U_4(lfp->int_part); |
| 486 | ou = GET_BE_U_4(olfp->int_part); |
| 487 | uf = GET_BE_U_4(lfp->fraction); |
| 488 | ouf = GET_BE_U_4(olfp->fraction); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 489 | if (ou == 0 && ouf == 0) { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 490 | p_ntp_time(ndo, lfp); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 491 | return; |
| 492 | } |
| 493 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 494 | if (u > ou) { /* new is definitely greater than old */ |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 495 | signbit = 0; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 496 | i = u - ou; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 497 | f = uf - ouf; |
| 498 | if (ouf > uf) /* must borrow from high-order bits */ |
| 499 | i -= 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 500 | } else if (u < ou) { /* new is definitely less than old */ |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 501 | signbit = 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 502 | i = ou - u; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 503 | f = ouf - uf; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 504 | if (uf > ouf) /* must borrow from the high-order bits */ |
| 505 | i -= 1; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 506 | } else { /* int_part is zero */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 507 | i = 0; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 508 | if (uf > ouf) { |
| 509 | signbit = 0; |
| 510 | f = uf - ouf; |
| 511 | } else { |
| 512 | signbit = 1; |
| 513 | f = ouf - uf; |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | ff = f; |
| 518 | if (ff < 0.0) /* some compilers are buggy */ |
| 519 | ff += FMAXINT; |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 520 | ff = ff / FMAXINT; /* shift radix point by 32 bits */ |
| 521 | f = (uint32_t)(ff * 1000000000.0); /* treat fraction as parts per billion */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 522 | ND_PRINT("%s%u.%09u", signbit ? "-" : "+", i, f); |
| 523 | } |
| 524 | |
| 525 | /* Prints polling interval in log2 as seconds or fraction of second */ |
| 526 | static void |
| 527 | p_poll(netdissect_options *ndo, |
| 528 | const int poll_interval) |
| 529 | { |
| 530 | if (poll_interval <= -32 || poll_interval >= 32) |
| 531 | return; |
| 532 | |
| 533 | if (poll_interval >= 0) |
| 534 | ND_PRINT(" (%us)", 1U << poll_interval); |
| 535 | else |
| 536 | ND_PRINT(" (1/%us)", 1U << -poll_interval); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 537 | } |
| 538 | |