Home | History | Annotate | Download | only in snoop
      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