1 /* $OpenBSD: print-ntp.c,v 1.19 2020/01/24 22:46:37 procter Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * Format and print ntp packets. 24 * By Jeffrey Mogul/DECWRL 25 * loosely based on print-bootp.c 26 */ 27 28 #include <sys/time.h> 29 #include <sys/socket.h> 30 31 struct mbuf; 32 struct rtentry; 33 #include <net/if.h> 34 35 #include <netinet/in.h> 36 #include <netinet/if_ether.h> 37 38 #include <ctype.h> 39 #include <stdio.h> 40 #include <string.h> 41 42 #include "interface.h" 43 #include "addrtoname.h" 44 #ifdef MODEMASK 45 #undef MODEMASK /* Solaris sucks */ 46 #endif 47 #include "ntp.h" 48 49 static void p_sfix(const struct s_fixedpt *); 50 static void p_ntp_time(const struct l_fixedpt *); 51 static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *); 52 53 /* 54 * Print ntp requests 55 */ 56 void 57 ntp_print(const u_char *cp, u_int length) 58 { 59 const struct ntpdata *bp; 60 int mode, version, leapind; 61 62 bp = (struct ntpdata *)cp; 63 /* Note funny sized packets */ 64 if (length != sizeof(struct ntpdata)) 65 printf(" [len=%d]", length); 66 67 TCHECK(bp->status); 68 69 version = (int)(bp->status & VERSIONMASK) >> 3; 70 printf("v%d", version); 71 72 leapind = bp->status & LEAPMASK; 73 switch (leapind) { 74 75 case NO_WARNING: 76 break; 77 78 case ALARM: 79 printf(" alarm"); 80 break; 81 82 case PLUS_SEC: 83 printf(" +1s"); 84 break; 85 86 case MINUS_SEC: 87 printf(" -1s"); 88 break; 89 } 90 91 mode = bp->status & MODEMASK; 92 switch (mode) { 93 94 case MODE_UNSPEC: /* unspecified */ 95 printf(" unspec"); 96 break; 97 98 case MODE_SYM_ACT: /* symmetric active */ 99 printf(" sym_act"); 100 break; 101 102 case MODE_SYM_PAS: /* symmetric passive */ 103 printf(" sym_pas"); 104 break; 105 106 case MODE_CLIENT: /* client */ 107 printf(" client"); 108 break; 109 110 case MODE_SERVER: /* server */ 111 printf(" server"); 112 break; 113 114 case MODE_BROADCAST: /* broadcast */ 115 printf(" bcast"); 116 break; 117 118 case MODE_RES1: /* reserved */ 119 printf(" res1"); 120 break; 121 122 case MODE_RES2: /* reserved */ 123 printf(" res2"); 124 break; 125 126 } 127 128 TCHECK(bp->stratum); 129 printf(" strat %d", bp->stratum); 130 131 TCHECK(bp->ppoll); 132 printf(" poll %d", bp->ppoll); 133 134 /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ 135 TCHECK2(bp->distance, 0); 136 printf(" prec %d", bp->precision); 137 138 if (!vflag) 139 return; 140 141 TCHECK(bp->distance); 142 printf(" dist "); 143 p_sfix(&bp->distance); 144 145 TCHECK(bp->dispersion); 146 printf(" disp "); 147 p_sfix(&bp->dispersion); 148 149 TCHECK(bp->refid); 150 printf(" ref "); 151 /* Interpretation depends on stratum */ 152 switch (bp->stratum) { 153 154 case UNSPECIFIED: 155 printf("(unspec)"); 156 break; 157 158 case PRIM_REF: 159 fn_printn((u_char *)&bp->refid, sizeof(bp->refid), NULL); 160 break; 161 162 case INFO_QUERY: 163 printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); 164 /* this doesn't have more content */ 165 return; 166 167 case INFO_REPLY: 168 printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); 169 /* this is too complex to be worth printing */ 170 return; 171 172 default: 173 printf("%s", ipaddr_string(&(bp->refid))); 174 break; 175 } 176 177 TCHECK(bp->reftime); 178 putchar('@'); 179 p_ntp_time(&(bp->reftime)); 180 181 TCHECK(bp->org); 182 printf(" orig "); 183 p_ntp_time(&(bp->org)); 184 185 TCHECK(bp->rec); 186 printf(" rec "); 187 p_ntp_delta(&(bp->org), &(bp->rec)); 188 189 TCHECK(bp->xmt); 190 printf(" xmt "); 191 p_ntp_delta(&(bp->org), &(bp->xmt)); 192 193 return; 194 195 trunc: 196 printf(" [|ntp]"); 197 } 198 199 static void 200 p_sfix(const struct s_fixedpt *sfp) 201 { 202 int i; 203 int f; 204 float ff; 205 206 i = ntohs(sfp->int_part); 207 f = ntohs(sfp->fraction); 208 ff = f / 65536.0; /* shift radix point by 16 bits */ 209 f = ff * 1000000.0; /* Treat fraction as parts per million */ 210 printf("%d.%06d", i, f); 211 } 212 213 #define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ 214 215 static void 216 p_ntp_time(const struct l_fixedpt *lfp) 217 { 218 int32_t i; 219 u_int32_t uf; 220 u_int32_t f; 221 float ff; 222 223 i = ntohl(lfp->int_part); 224 uf = ntohl(lfp->fraction); 225 ff = uf; 226 if (ff < 0.0) /* some compilers are buggy */ 227 ff += FMAXINT; 228 ff = ff / FMAXINT; /* shift radix point by 32 bits */ 229 f = ff * 1000000000.0; /* treat fraction as parts per billion */ 230 printf("%u.%09d", i, f); 231 } 232 233 /* Prints time difference between *lfp and *olfp */ 234 static void 235 p_ntp_delta(const struct l_fixedpt *olfp, const struct l_fixedpt *lfp) 236 { 237 int32_t i; 238 u_int32_t uf; 239 u_int32_t ouf; 240 u_int32_t f; 241 float ff; 242 int signbit; 243 244 i = ntohl(lfp->int_part) - ntohl(olfp->int_part); 245 246 uf = ntohl(lfp->fraction); 247 ouf = ntohl(olfp->fraction); 248 249 if (i > 0) { /* new is definitely greater than old */ 250 signbit = 0; 251 f = uf - ouf; 252 if (ouf > uf) /* must borrow from high-order bits */ 253 i -= 1; 254 } else if (i < 0) { /* new is definitely less than old */ 255 signbit = 1; 256 f = ouf - uf; 257 if (uf > ouf) /* must carry into the high-order bits */ 258 i += 1; 259 i = -i; 260 } else { /* int_part is zero */ 261 if (uf > ouf) { 262 signbit = 0; 263 f = uf - ouf; 264 } else { 265 signbit = 1; 266 f = ouf - uf; 267 } 268 } 269 270 ff = f; 271 if (ff < 0.0) /* some compilers are buggy */ 272 ff += FMAXINT; 273 ff = ff / FMAXINT; /* shift radix point by 32 bits */ 274 f = ff * 1000000000.0; /* treat fraction as parts per billion */ 275 if (signbit) 276 putchar('-'); 277 else 278 putchar('+'); 279 printf("%d.%09d", i, f); 280 } 281