1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 0 stevel * Common Development and Distribution License, Version 1.0 only 6 0 stevel * (the "License"). You may not use this file except in compliance 7 0 stevel * with the License. 8 0 stevel * 9 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 0 stevel * or http://www.opensolaris.org/os/licensing. 11 0 stevel * See the License for the specific language governing permissions 12 0 stevel * and limitations under the License. 13 0 stevel * 14 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 15 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 0 stevel * If applicable, add the following below this CDDL HEADER, with the 17 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 18 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 19 0 stevel * 20 0 stevel * CDDL HEADER END 21 0 stevel */ 22 0 stevel /* 23 410 kcpoon * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 28 0 stevel 29 0 stevel #include <fcntl.h> 30 0 stevel #include <sys/socket.h> 31 0 stevel #include <sys/sysmacros.h> 32 0 stevel #include <netinet/in.h> 33 0 stevel #include <netdb.h> 34 0 stevel #include <stdio.h> 35 0 stevel #include <string.h> 36 0 stevel #include <tzfile.h> 37 0 stevel #include "snoop.h" 38 0 stevel #include "ntp.h" 39 0 stevel 40 0 stevel /* 41 0 stevel * In verbose mode, how many octets of the control-mode data payload 42 0 stevel * are displayed per line of output. The value 64 fits well on an 43 0 stevel * 80-column screen and, as a power of 2, is easily correlated to 44 0 stevel * hexadecimal output. 45 0 stevel */ 46 0 stevel #define OCTETS_PER_LINE 64 47 0 stevel 48 0 stevel extern char *dlc_header; 49 0 stevel 50 0 stevel static char *show_leap(int); 51 0 stevel static char *show_mode(int); 52 0 stevel static char *show_ref(int, ulong_t); 53 0 stevel static char *show_time(struct l_fixedpt); 54 0 stevel static double s_fixed_to_double(struct s_fixedpt *); 55 0 stevel static char *iso_date_time(time_t); 56 0 stevel static char *show_operation(int); 57 0 stevel 58 0 stevel int 59 0 stevel interpret_ntp(int flags, struct ntpdata *ntp_pkt, int fraglen) 60 0 stevel { 61 0 stevel unsigned int i, j, macbytes; 62 0 stevel unsigned int proto_version; 63 0 stevel unsigned int datalen; 64 0 stevel unsigned int linelen = OCTETS_PER_LINE; 65 0 stevel unsigned int sofar = 0; 66 0 stevel 67 0 stevel char *datap; 68 0 stevel char hbuf[2 * MAC_OCTETS_MAX + 1]; 69 0 stevel static char *hexstr = "0123456789ABCDEF"; 70 0 stevel 71 0 stevel union ntp_pkt_buf { 72 0 stevel struct ntpdata ntp_msg; 73 0 stevel union ntpc_buf { 74 0 stevel struct ntp_control chdr; 75 0 stevel uchar_t data2[NTPC_DATA_MAXLEN - 1]; 76 0 stevel } ntpc_msg; 77 0 stevel union ntpp_buf { 78 0 stevel struct ntp_private phdr; 79 0 stevel uchar_t data2[1]; 80 0 stevel } ntpp_msg; 81 0 stevel } fragbuf; 82 0 stevel 83 0 stevel struct ntpdata *ntp = &fragbuf.ntp_msg; 84 0 stevel struct ntp_control *ntpc = (struct ntp_control *)&fragbuf.ntpc_msg; 85 0 stevel struct ntp_private *ntpp = (struct ntp_private *)&fragbuf.ntpp_msg; 86 0 stevel 87 0 stevel /* 88 0 stevel * Copying packet contents into a local buffer avoids 89 0 stevel * problems of interpretation if the packet is truncated. 90 0 stevel */ 91 0 stevel (void) memcpy(&fragbuf, ntp_pkt, MIN(sizeof (fragbuf), fraglen)); 92 0 stevel 93 0 stevel if (flags & F_SUM) { 94 0 stevel switch (ntp->li_vn_mode & NTPMODEMASK) { 95 0 stevel case MODE_SYM_ACT: 96 0 stevel case MODE_SYM_PAS: 97 0 stevel case MODE_CLIENT: 98 0 stevel case MODE_SERVER: 99 0 stevel case MODE_BROADCAST: 100 0 stevel (void) sprintf(get_sum_line(), 101 0 stevel "NTP %s [st=%hd] (%s)", 102 0 stevel show_mode(ntp->li_vn_mode & NTPMODEMASK), 103 0 stevel ntp->stratum, 104 0 stevel show_time(ntp->xmt)); 105 0 stevel break; 106 0 stevel case MODE_CONTROL: 107 0 stevel (void) sprintf(get_sum_line(), 108 0 stevel "NTP %s " 109 0 stevel "(Flags/op=0x%02x Seq=%hu Status=0x%04hx Assoc=%hu)", 110 0 stevel show_mode(ntpc->li_vn_mode & NTPMODEMASK), 111 0 stevel ntpc->r_m_e_op, 112 0 stevel ntohs(ntpc->sequence), 113 0 stevel ntohs(ntpc->status), 114 0 stevel ntohs(ntpc->associd)); 115 0 stevel break; 116 0 stevel default: 117 0 stevel (void) sprintf(get_sum_line(), 118 0 stevel "NTP %s", 119 0 stevel show_mode(ntpp->rm_vn_mode & NTPMODEMASK)); 120 0 stevel break; 121 0 stevel } 122 0 stevel } 123 0 stevel 124 0 stevel proto_version = (ntp->li_vn_mode & VERSIONMASK) >> 3; 125 0 stevel 126 0 stevel if (flags & F_DTAIL) { 127 0 stevel show_header("NTP: ", "Network Time Protocol", fraglen); 128 0 stevel show_space(); 129 0 stevel switch (ntp->li_vn_mode & NTPMODEMASK) { 130 0 stevel case MODE_SYM_ACT: 131 0 stevel case MODE_SYM_PAS: 132 0 stevel case MODE_CLIENT: 133 0 stevel case MODE_SERVER: 134 0 stevel case MODE_BROADCAST: 135 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 136 0 stevel dlc_header, 1), 137 0 stevel "Leap = 0x%x (%s)", 138 0 stevel (int)(ntp->li_vn_mode & LEAPMASK) >> 6, 139 0 stevel show_leap(ntp->li_vn_mode & LEAPMASK)); 140 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 141 0 stevel dlc_header, 1), 142 0 stevel "Version = %lu", proto_version); 143 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 144 0 stevel dlc_header, 1), 145 0 stevel "Mode = %hu (%s)", 146 0 stevel ntp->li_vn_mode & NTPMODEMASK, 147 0 stevel show_mode(ntp->li_vn_mode & NTPMODEMASK)); 148 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->stratum - 149 0 stevel dlc_header, 1), 150 0 stevel "Stratum = %d (%s)", 151 0 stevel ntp->stratum, 152 0 stevel ntp->stratum == 0 ? "unspecified" : 153 0 stevel ntp->stratum == 1 ? "primary reference" : 154 0 stevel "secondary reference"); 155 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->ppoll - 156 410 kcpoon dlc_header, 1), "Poll = %hu", ntp->ppoll); 157 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->precision - 158 0 stevel dlc_header, 1), 159 0 stevel "Precision = %d seconds", 160 0 stevel ntp->precision); 161 410 kcpoon (void) sprintf(get_line( 162 410 kcpoon (char *)(uintptr_t)ntp->distance.int_part - 163 0 stevel dlc_header, 1), 164 0 stevel "Synchronizing distance = 0x%04x.%04x (%f)", 165 0 stevel ntohs(ntp->distance.int_part), 166 0 stevel ntohs(ntp->distance.fraction), 167 0 stevel s_fixed_to_double(&ntp->distance)); 168 410 kcpoon (void) sprintf(get_line( 169 410 kcpoon (char *)(uintptr_t)ntp->dispersion.int_part - 170 0 stevel dlc_header, 1), 171 0 stevel "Synchronizing dispersion = 0x%04x.%04x (%f)", 172 0 stevel ntohs(ntp->dispersion.int_part), 173 0 stevel ntohs(ntp->dispersion.fraction), 174 0 stevel s_fixed_to_double(&ntp->dispersion)); 175 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->refid - 176 410 kcpoon dlc_header, 1), "Reference clock = %s", 177 0 stevel show_ref(ntp->stratum, ntp->refid)); 178 0 stevel 179 410 kcpoon (void) sprintf(get_line( 180 410 kcpoon (char *)(uintptr_t)ntp->reftime.int_part - dlc_header, 181 410 kcpoon 1), "Reference time = 0x%08lx.%08lx (%s)", 182 0 stevel ntohl(ntp->reftime.int_part), 183 0 stevel ntohl(ntp->reftime.fraction), 184 0 stevel show_time(ntp->reftime)); 185 0 stevel 186 410 kcpoon (void) sprintf(get_line( 187 410 kcpoon (char *)(uintptr_t)ntp->org.int_part - dlc_header, 1), 188 0 stevel "Originate time = 0x%08lx.%08lx (%s)", 189 0 stevel ntohl(ntp->org.int_part), 190 0 stevel ntohl(ntp->org.fraction), 191 0 stevel show_time(ntp->org)); 192 0 stevel 193 410 kcpoon (void) sprintf(get_line( 194 410 kcpoon (char *)(uintptr_t)ntp->rec.int_part - dlc_header, 1), 195 0 stevel "Receive time = 0x%08lx.%08lx (%s)", 196 0 stevel ntohl(ntp->rec.int_part), 197 0 stevel ntohl(ntp->rec.fraction), 198 0 stevel show_time(ntp->rec)); 199 0 stevel 200 410 kcpoon (void) sprintf(get_line( 201 410 kcpoon (char *)(uintptr_t)ntp->xmt.int_part - dlc_header, 1), 202 0 stevel "Transmit time = 0x%08lx.%08lx (%s)", 203 0 stevel ntohl(ntp->xmt.int_part), 204 0 stevel ntohl(ntp->xmt.fraction), 205 0 stevel show_time(ntp->xmt)); 206 0 stevel 207 0 stevel if (proto_version > 3 || 208 0 stevel fraglen < (LEN_PKT_NOMAC + MAC_OCTETS_MIN)) { 209 0 stevel /* 210 0 stevel * A newer protocol version we can't parse, 211 0 stevel * or v3 packet with no valid authentication. 212 0 stevel */ 213 0 stevel break; 214 0 stevel } 215 0 stevel (void) sprintf(get_line((char *)ntp->keyid - 216 0 stevel dlc_header, 1), 217 0 stevel "Key ID = %8lu", ntohl(ntp->keyid)); 218 0 stevel 219 0 stevel macbytes = fraglen - (LEN_PKT_NOMAC + sizeof (uint32_t)); 220 0 stevel 221 0 stevel for (i = 0, j = 0; i < macbytes; i++) { 222 0 stevel hbuf[j++] = hexstr[ntp->mac[i] >> 4 & 0x0f]; 223 0 stevel hbuf[j++] = hexstr[ntp->mac[i] & 0x0f]; 224 0 stevel } 225 0 stevel hbuf[j] = '\0'; 226 0 stevel (void) sprintf(get_line((char *)ntp->mac - 227 0 stevel dlc_header, 1), 228 0 stevel "Authentication code = %s", hbuf); 229 0 stevel break; 230 0 stevel 231 0 stevel case MODE_CONTROL: 232 0 stevel /* NTP Control Message, mode 6 */ 233 0 stevel 234 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 235 0 stevel dlc_header, 1), 236 0 stevel "Leap = 0x%x (%s)", 237 0 stevel (int)(ntp->li_vn_mode & LEAPMASK) >> 6, 238 0 stevel show_leap(ntp->li_vn_mode & LEAPMASK)); 239 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 240 0 stevel dlc_header, 1), 241 0 stevel "Version = %lu", proto_version); 242 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 243 0 stevel dlc_header, 1), 244 0 stevel "Mode = %hu (%s)", 245 0 stevel ntp->li_vn_mode & NTPMODEMASK, 246 0 stevel show_mode(ntp->li_vn_mode & NTPMODEMASK)); 247 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->r_m_e_op - 248 0 stevel dlc_header, 1), 249 0 stevel "Flags and operation code = 0x%02x", 250 0 stevel ntpc->r_m_e_op); 251 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->r_m_e_op - 252 0 stevel dlc_header, 1), 253 0 stevel " %s", 254 0 stevel getflag(ntpc->r_m_e_op, CTL_RESPONSE, "response", 255 0 stevel "request")); 256 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->r_m_e_op - 257 0 stevel dlc_header, 1), 258 0 stevel " %s", 259 0 stevel getflag(ntpc->r_m_e_op, CTL_ERROR, "error", 260 0 stevel "success")); 261 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->r_m_e_op - 262 0 stevel dlc_header, 1), 263 0 stevel " %s", 264 0 stevel getflag(ntpc->r_m_e_op, CTL_MORE, "more", 265 0 stevel "no more")); 266 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->r_m_e_op - 267 0 stevel dlc_header, 1), 268 0 stevel " ...x xxxx = %hd (%s)", 269 0 stevel ntpc->r_m_e_op & CTL_OP_MASK, 270 0 stevel show_operation(ntpc->r_m_e_op & CTL_OP_MASK)); 271 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->sequence - 272 0 stevel dlc_header, 1), 273 0 stevel "Sequence = %hu", 274 0 stevel ntohs(ntpc->sequence)); 275 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->status - 276 0 stevel dlc_header, 1), 277 0 stevel "Status = 0x%04hx", 278 0 stevel ntohs(ntpc->status)); 279 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->associd - 280 0 stevel dlc_header, 1), 281 0 stevel "Assoc ID = %hu", 282 0 stevel ntohs(ntpc->associd)); 283 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->offset - 284 0 stevel dlc_header, 1), 285 0 stevel "Data offset = %hu", 286 0 stevel ntohs(ntpc->offset)); 287 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpc->count - 288 0 stevel dlc_header, 1), 289 0 stevel "Data bytes = %hu", 290 0 stevel ntohs(ntpc->count)); 291 0 stevel datalen = ntohs(ntpc->count); 292 0 stevel if (datalen == 0) { 293 0 stevel break; 294 0 stevel } else if (datalen > NTPC_DATA_MAXLEN) { 295 0 stevel datalen = NTPC_DATA_MAXLEN; 296 0 stevel } 297 0 stevel show_space(); 298 0 stevel datap = (char *)ntpc->data; 299 0 stevel do { 300 0 stevel (void) sprintf(get_line(datap - 301 0 stevel dlc_header, 1), 302 0 stevel "\"%s\"", 303 0 stevel show_string(datap, linelen, datalen)); 304 0 stevel sofar += linelen; 305 0 stevel datap += linelen; 306 0 stevel if ((sofar + linelen) > datalen) { 307 0 stevel linelen = datalen - sofar; 308 0 stevel } 309 0 stevel } while (sofar < datalen); 310 0 stevel show_trailer(); 311 0 stevel break; 312 0 stevel 313 0 stevel case MODE_PRIVATE: 314 0 stevel /* NTP Private Message, mode 7 */ 315 0 stevel 316 410 kcpoon (void) sprintf(get_line( 317 410 kcpoon (char *)(uintptr_t)ntpp->rm_vn_mode - dlc_header, 1), 318 410 kcpoon "Version = %hu", INFO_VERSION(ntpp->rm_vn_mode)); 319 410 kcpoon (void) sprintf(get_line( 320 410 kcpoon (char *)(uintptr_t)ntpp->rm_vn_mode - dlc_header, 1), 321 410 kcpoon "Mode = %hu (%s)", INFO_MODE(ntpp->rm_vn_mode), 322 0 stevel show_mode(INFO_MODE(ntpp->rm_vn_mode))); 323 410 kcpoon (void) sprintf(get_line( 324 410 kcpoon (char *)(uintptr_t)ntpp->rm_vn_mode - dlc_header, 1), 325 410 kcpoon "Flags = 0x%02hx", ntpp->rm_vn_mode); 326 410 kcpoon (void) sprintf(get_line( 327 410 kcpoon (char *)(uintptr_t)ntpp->rm_vn_mode - dlc_header, 1), 328 0 stevel " %s", 329 0 stevel getflag(ntpp->rm_vn_mode, RESP_BIT, "response", 330 0 stevel "request")); 331 410 kcpoon (void) sprintf(get_line( 332 410 kcpoon (char *)(uintptr_t)ntpp->rm_vn_mode - dlc_header, 1), 333 410 kcpoon " %s", 334 410 kcpoon getflag(ntpp->rm_vn_mode, MORE_BIT, "more", "no more")); 335 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpp->auth_seq - 336 0 stevel dlc_header, 1), 337 410 kcpoon "Authentication and sequence = 0x%02x", ntpp->auth_seq); 338 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpp->auth_seq - 339 0 stevel dlc_header, 1), 340 0 stevel " %s", 341 0 stevel getflag(ntpp->auth_seq, AUTH_BIT, "authenticated", 342 0 stevel "unauthenticated")); 343 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpp->auth_seq - 344 0 stevel dlc_header, 1), 345 0 stevel " .xxx xxxx = %hu (sequence number)", 346 0 stevel INFO_SEQ(ntpp->auth_seq)); 347 410 kcpoon (void) sprintf(get_line( 348 410 kcpoon (char *)(uintptr_t)ntpp->implementation - dlc_header, 349 410 kcpoon 1), "Implementation = %hu", ntpp->implementation); 350 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntpp->request - 351 410 kcpoon dlc_header, 1), "Request = %hu", ntpp->request); 352 410 kcpoon (void) sprintf(get_line( 353 410 kcpoon (char *)(uintptr_t)ntpp->err_nitems - dlc_header, 1), 354 410 kcpoon "Error = %hu", INFO_ERR(ntpp->err_nitems)); 355 410 kcpoon (void) sprintf(get_line( 356 410 kcpoon (char *)(uintptr_t)ntpp->err_nitems - dlc_header, 1), 357 410 kcpoon "Items = %hu", INFO_NITEMS(ntpp->err_nitems)); 358 410 kcpoon (void) sprintf(get_line( 359 410 kcpoon (char *)(uintptr_t)ntpp->mbz_itemsize - dlc_header, 1), 360 410 kcpoon "Item size = %hu", INFO_ITEMSIZE(ntpp->mbz_itemsize)); 361 0 stevel break; 362 0 stevel 363 0 stevel default: 364 0 stevel /* Unknown mode */ 365 410 kcpoon (void) sprintf(get_line((char *)(uintptr_t)ntp->li_vn_mode - 366 410 kcpoon dlc_header, 1), "Mode = %hu (%s)", 367 0 stevel ntp->li_vn_mode & NTPMODEMASK, 368 0 stevel show_mode(ntp->li_vn_mode & NTPMODEMASK)); 369 0 stevel break; 370 0 stevel } 371 0 stevel } 372 0 stevel 373 0 stevel return (fraglen); 374 0 stevel } 375 0 stevel 376 0 stevel char * 377 0 stevel show_leap(int leap) 378 0 stevel { 379 0 stevel switch (leap) { 380 0 stevel case NO_WARNING: return ("OK"); 381 0 stevel case PLUS_SEC: return ("add a second (61 seconds)"); 382 0 stevel case MINUS_SEC: return ("minus a second (59 seconds)"); 383 0 stevel case ALARM: return ("alarm condition (clock unsynchronized)"); 384 0 stevel default: return ("unknown"); 385 0 stevel } 386 0 stevel } 387 0 stevel 388 0 stevel char * 389 0 stevel show_mode(int mode) 390 0 stevel { 391 0 stevel switch (mode) { 392 0 stevel case MODE_UNSPEC: return ("unspecified"); 393 0 stevel case MODE_SYM_ACT: return ("symmetric active"); 394 0 stevel case MODE_SYM_PAS: return ("symmetric passive"); 395 0 stevel case MODE_CLIENT: return ("client"); 396 0 stevel case MODE_SERVER: return ("server"); 397 0 stevel case MODE_BROADCAST: return ("broadcast"); 398 0 stevel case MODE_CONTROL: return ("control"); 399 0 stevel case MODE_PRIVATE: return ("private"); 400 0 stevel default: return ("unknown"); 401 0 stevel } 402 0 stevel } 403 0 stevel 404 0 stevel char * 405 0 stevel show_ref(int mode, ulong_t refid) 406 0 stevel { 407 0 stevel static char buff[MAXHOSTNAMELEN + 32]; 408 0 stevel struct in_addr host; 409 0 stevel extern char *inet_ntoa(); 410 0 stevel 411 0 stevel switch (mode) { 412 0 stevel case 0: 413 0 stevel case 1: 414 0 stevel (void) strncpy(buff, (char *)&refid, 4); 415 0 stevel buff[4] = '\0'; 416 0 stevel break; 417 0 stevel 418 0 stevel default: 419 0 stevel host.s_addr = refid; 420 0 stevel (void) sprintf(buff, "%s (%s)", 421 0 stevel inet_ntoa(host), 422 0 stevel addrtoname(AF_INET, &host)); 423 0 stevel break; 424 0 stevel } 425 0 stevel 426 0 stevel return (buff); 427 0 stevel } 428 0 stevel 429 0 stevel /* 430 0 stevel * Here we have to worry about the high order bit being signed 431 0 stevel */ 432 0 stevel double 433 0 stevel s_fixed_to_double(struct s_fixedpt *t) 434 0 stevel { 435 0 stevel double a; 436 0 stevel 437 0 stevel if (ntohs(t->int_part) & 0x8000) { 438 0 stevel a = ntohs((int)(~t->fraction) & 0xFFFF); 439 0 stevel a = a / 65536.0; /* shift dec point over by 16 bits */ 440 0 stevel a += ntohs((int)(~t->int_part) & 0xFFFF); 441 0 stevel a = -a; 442 0 stevel } else { 443 0 stevel a = ntohs(t->fraction); 444 0 stevel a = a / 65536.0; /* shift dec point over by 16 bits */ 445 0 stevel a += ntohs(t->int_part); 446 0 stevel } 447 0 stevel return (a); 448 0 stevel } 449 0 stevel 450 0 stevel /* 451 0 stevel * Consistent with RFC-3339, ISO 8601. 452 0 stevel */ 453 0 stevel char * 454 0 stevel iso_date_time(time_t input_time) 455 0 stevel { 456 0 stevel struct tm *time_parts; 457 0 stevel static char tbuf[sizeof ("yyyy-mm-dd hh:mm:ss")]; 458 0 stevel 459 0 stevel time_parts = localtime(&input_time); 460 0 stevel (void) strftime(tbuf, sizeof (tbuf), "%Y-%m-%d %H:%M:%S", time_parts); 461 0 stevel return (tbuf); 462 0 stevel } 463 0 stevel 464 0 stevel /* 465 0 stevel * The base of NTP timestamps is 1900-01-01 00:00:00.00000 466 0 stevel */ 467 0 stevel char * 468 0 stevel show_time(struct l_fixedpt pkt_time) 469 0 stevel { 470 0 stevel struct l_fixedpt net_time; 471 0 stevel unsigned long fracsec; 472 0 stevel static char buff[32]; 473 0 stevel 474 0 stevel if (pkt_time.int_part == 0) { 475 0 stevel buff[0] = '\0'; 476 0 stevel return (buff); 477 0 stevel } 478 0 stevel 479 0 stevel net_time.int_part = ntohl(pkt_time.int_part) - JAN_1970; 480 0 stevel net_time.fraction = ntohl(pkt_time.fraction); 481 0 stevel 482 0 stevel fracsec = net_time.fraction / 42949; /* fract / (2**32/10**6) */ 483 0 stevel 484 0 stevel (void) strlcpy(buff, iso_date_time(net_time.int_part), sizeof (buff)); 485 0 stevel (void) snprintf(buff, sizeof (buff), "%s.%05lu", buff, fracsec); 486 0 stevel 487 0 stevel return (buff); 488 0 stevel } 489 0 stevel 490 0 stevel char * 491 0 stevel show_operation(int op) 492 0 stevel { 493 0 stevel switch (op) { 494 0 stevel case CTL_OP_UNSPEC: return ("unspecified"); 495 0 stevel case CTL_OP_READSTAT: return ("read stats"); 496 0 stevel case CTL_OP_READVAR: return ("read var"); 497 0 stevel case CTL_OP_WRITEVAR: return ("write var"); 498 0 stevel case CTL_OP_READCLOCK: return ("read clock"); 499 0 stevel case CTL_OP_WRITECLOCK: return ("write clock"); 500 0 stevel case CTL_OP_SETTRAP: return ("set trap"); 501 0 stevel case CTL_OP_ASYNCMSG: return ("async msg"); 502 0 stevel case CTL_OP_UNSETTRAP: return ("unset trap"); 503 0 stevel default: return ("unknown"); 504 0 stevel } 505 0 stevel } 506