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 * 21 * Format and print ntp packets. 22 * By Jeffrey Mogul/DECWRL 23 * loosely based on print-bootp.c 24 * 25 * $FreeBSD$ 26 */ 27 28 #ifndef lint 29 static const char rcsid[] _U_ = 30 "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.37.2.2 2003/11/16 08:51:36 guy Exp $ (LBL)"; 31 #endif 32 33 #ifdef HAVE_CONFIG_H 34 #include "config.h" 35 #endif 36 37 #include <tcpdump-stdinc.h> 38 39 #include <stdio.h> 40 #include <string.h> 41 #ifdef HAVE_STRFTIME 42 #include <time.h> 43 #endif 44 45 #include "interface.h" 46 #include "addrtoname.h" 47 #include "extract.h" 48 #ifdef MODEMASK 49 #undef MODEMASK /* Solaris sucks */ 50 #endif 51 #include "ntp.h" 52 53 static void p_sfix(const struct s_fixedpt *); 54 static void p_ntp_time(const struct l_fixedpt *); 55 static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *); 56 57 /* 58 * Print ntp requests 59 */ 60 void 61 ntp_print(register const u_char *cp, u_int length) 62 { 63 register const struct ntpdata *bp; 64 int mode, version, leapind; 65 66 bp = (struct ntpdata *)cp; 67 /* Note funny sized packets */ 68 if (length != sizeof(struct ntpdata)) 69 (void)printf(" [len=%d]", length); 70 71 TCHECK(bp->status); 72 73 version = (int)(bp->status & VERSIONMASK) >> 3; 74 printf("NTPv%d", version); 75 76 leapind = bp->status & LEAPMASK; 77 switch (leapind) { 78 79 case NO_WARNING: 80 break; 81 82 case PLUS_SEC: 83 fputs(" +1s", stdout); 84 break; 85 86 case MINUS_SEC: 87 fputs(" -1s", stdout); 88 break; 89 } 90 91 mode = bp->status & MODEMASK; 92 switch (mode) { 93 94 case MODE_UNSPEC: /* unspecified */ 95 fputs(" unspec", stdout); 96 break; 97 98 case MODE_SYM_ACT: /* symmetric active */ 99 fputs(" sym_act", stdout); 100 break; 101 102 case MODE_SYM_PAS: /* symmetric passive */ 103 fputs(" sym_pas", stdout); 104 break; 105 106 case MODE_CLIENT: /* client */ 107 fputs(" client", stdout); 108 break; 109 110 case MODE_SERVER: /* server */ 111 fputs(" server", stdout); 112 break; 113 114 case MODE_BROADCAST: /* broadcast */ 115 fputs(" bcast", stdout); 116 break; 117 118 case MODE_RES1: /* reserved */ 119 fputs(" res1", stdout); 120 break; 121 122 case MODE_RES2: /* reserved */ 123 fputs(" res2", stdout); 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 fputs(" dist ", stdout); 143 p_sfix(&bp->distance); 144 145 TCHECK(bp->dispersion); 146 fputs(", disp ", stdout); 147 p_sfix(&bp->dispersion); 148 149 TCHECK(bp->refid); 150 fputs(", ref ", stdout); 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), 4, 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 fputs(" orig ", stdout); 183 p_ntp_time(&(bp->org)); 184 185 TCHECK(bp->rec); 186 fputs(" rec ", stdout); 187 p_ntp_delta(&(bp->org), &(bp->rec)); 188 189 TCHECK(bp->xmt); 190 fputs(" xmt ", stdout); 191 p_ntp_delta(&(bp->org), &(bp->xmt)); 192 193 return; 194 195 trunc: 196 fputs(" [|ntp]", stdout); 197 } 198 199 static void 200 p_sfix(register const struct s_fixedpt *sfp) 201 { 202 register int i; 203 register int f; 204 register float ff; 205 206 i = EXTRACT_16BITS(&sfp->int_part); 207 f = EXTRACT_16BITS(&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(register const struct l_fixedpt *lfp) 217 { 218 register int32_t i; 219 register u_int32_t uf; 220 register u_int32_t f; 221 register float ff; 222 223 i = EXTRACT_32BITS(&lfp->int_part); 224 uf = EXTRACT_32BITS(&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 #ifdef HAVE_STRFTIME 233 /* 234 * For extra verbosity, print the time in human-readable format. 235 */ 236 if (vflag > 1 && i) { 237 time_t seconds = i - JAN_1970; 238 struct tm *tm; 239 char time_buf[128]; 240 241 tm = localtime(&seconds); 242 strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm); 243 printf (" (%s)", time_buf); 244 } 245 #endif 246 } 247 248 /* Prints time difference between *lfp and *olfp */ 249 static void 250 p_ntp_delta(register const struct l_fixedpt *olfp, 251 register const struct l_fixedpt *lfp) 252 { 253 register int32_t i; 254 register u_int32_t u, uf; 255 register u_int32_t ou, ouf; 256 register u_int32_t f; 257 register float ff; 258 int signbit; 259 260 u = EXTRACT_32BITS(&lfp->int_part); 261 ou = EXTRACT_32BITS(&olfp->int_part); 262 uf = EXTRACT_32BITS(&lfp->fraction); 263 ouf = EXTRACT_32BITS(&olfp->fraction); 264 if (ou == 0 && ouf == 0) { 265 p_ntp_time(lfp); 266 return; 267 } 268 269 i = u - ou; 270 271 if (i > 0) { /* new is definitely greater than old */ 272 signbit = 0; 273 f = uf - ouf; 274 if (ouf > uf) /* must borrow from high-order bits */ 275 i -= 1; 276 } else if (i < 0) { /* new is definitely less than old */ 277 signbit = 1; 278 f = ouf - uf; 279 if (uf > ouf) /* must carry into the high-order bits */ 280 i += 1; 281 i = -i; 282 } else { /* int_part is zero */ 283 if (uf > ouf) { 284 signbit = 0; 285 f = uf - ouf; 286 } else { 287 signbit = 1; 288 f = ouf - uf; 289 } 290 } 291 292 ff = f; 293 if (ff < 0.0) /* some compilers are buggy */ 294 ff += FMAXINT; 295 ff = ff / FMAXINT; /* shift radix point by 32 bits */ 296 f = ff * 1000000000.0; /* treat fraction as parts per billion */ 297 if (signbit) 298 putchar('-'); 299 else 300 putchar('+'); 301 printf("%d.%09d", i, f); 302 } 303 304