1: #if !defined(lint) && defined(DOSCCS)
   2: static char *RCSid = "$Source: /usr/src/new/ntp/ntpdc.c,v $ $Revision: 3.4.1.8 $ $Date: 95/01/27 17:31:26 $";
   3: #endif
   4: 
   5: /*
   6:  * $Log:	ntpdc.c,v $
   7:  * Revision 3.4.1.8  95/01/27  17:31:26  sms
   8:  * Fix name clockinfo name collision with sysctl.h
   9:  *
  10:  * Revision 3.4.1.7  89/05/18  18:31:26  louie
  11:  * A few cosmetic changes for ntpd.c
  12:  *
  13:  * Revision 3.4.1.6  89/05/03  15:17:27  louie
  14:  * ntpdc now will display addional peer flags which indicate how far through
  15:  * the clock selection process a peer was considered.
  16:  *
  17:  * Revision 3.4.1.5  89/04/08  10:38:06  louie
  18:  * Minor cosmetic changes and removed dead debug code from ntpd.c
  19:  *
  20:  * Revision 3.4.1.4  89/03/29  12:41:56  louie
  21:  * Check for success sending query before trying to listen for answers.  Will
  22:  * catch case of no server running and an ICMP port unreachable being returned.
  23:  *
  24:  * Revision 3.4.1.3  89/03/22  18:29:53  louie
  25:  * patch3: Use new RCS headers.
  26:  *
  27:  * Revision 3.4.1.2  89/03/22  18:04:18  louie
  28:  * Display dispersion in milliseconds.  The peer->refid field was being ntohl()'ed
  29:  * when it should have stayed in network byte order.
  30:  *
  31:  * Revision 3.4.1.1  89/03/20  00:13:41  louie
  32:  * patch1: Delete unused variables.  Display interface address in numeric form
  33:  * patch1: for local address, rather than symbolically.  For multiple host
  34:  * patch1: queries, the name of the host is emitted prior to the data for that
  35:  * patch1: host.
  36:  *
  37:  * Revision 3.4  89/03/17  18:37:16  louie
  38:  * Latest test release.
  39:  *
  40:  * Revision 3.3.1.1  89/03/17  18:27:43  louie
  41:  * Fix version number mismatch error message.
  42:  *
  43:  * Revision 3.3  89/03/15  14:20:00  louie
  44:  * New baseline for next release.
  45:  *
  46:  * Revision 3.2.1.2  89/03/15  14:03:02  louie
  47:  * The logical used to receive replies has been revised considerably.  Each packet
  48:  * in the reply from the ntpd program carries the total number of packets in the
  49:  * reply as well as a sequence number for this packet.  Thus, we know how many
  50:  * packets to expect, and which one's we're received already.  A new UDP socket
  51:  * is used for each host to prevent the replies from being mixed.  This was
  52:  * a problem when querying an old ntpd which returned 7 bad version packets..
  53:  * Use "%f" rather than "%lf" in format strings.
  54:  *
  55:  * Revision 3.2.1.1  89/03/10  12:28:24  louie
  56:  * Clean up output fomatting somewhat.
  57:  *
  58:  * Revision 3.2  89/03/07  18:27:52  louie
  59:  * Cosmetic changes and bug fixes.  Note that this version is likely to be
  60:  * slightly incompatible with previous versions because the definitions of
  61:  * the flage bits (PEER_FL_*) in ntp.h have changed.
  62:  *
  63:  * A future version of this program will have a considerably different
  64:  * packet format when Version 2 support is added.
  65:  *
  66:  * Revision 3.1.1.1  89/02/15  09:01:39  louie
  67:  * Bugfixes to previous release version.
  68:  *
  69:  *
  70:  * Revision 3.1  89/01/30  14:43:16  louie
  71:  * Second UNIX NTP test release.
  72:  *
  73:  * Revision 3.0  88/12/12  15:57:28  louie
  74:  * Test release of new UNIX NTP software.  This version should conform to the
  75:  * revised NTP protocol specification.
  76:  *
  77:  */
  78: 
  79: #include <sys/types.h>
  80: #include <sys/param.h>
  81: #include <signal.h>
  82: #include <sys/uio.h>
  83: #include <sys/socket.h>
  84: #include <sys/time.h>
  85: #include <netinet/in.h>
  86: #include <netinet/udp.h>
  87: #include <errno.h>
  88: #include <stdio.h>
  89: #include <netdb.h>
  90: #include <strings.h>
  91: #include <arpa/inet.h>
  92: #include "ntp.h"
  93: 
  94: #define WTIME   10      /* Time to wait for all responses */
  95: #define STIME   500000      /* usec to wait for another response */
  96: #define MAXPACKETSIZE 1500
  97: 
  98: extern int errno;
  99: int debug;
 100: int s;
 101: int timedout, timeout();
 102: int nflag, vflag, tflag;
 103: 
 104: struct sockaddr_in sin = {AF_INET};
 105: 
 106: char packet[MAXPACKETSIZE];
 107: #ifndef MAXHOSTNAMELEN
 108: #define MAXHOSTNAMELEN  64
 109: #endif
 110: char    LocalHostName[MAXHOSTNAMELEN+1];    /* our hostname */
 111: char    *LocalDomain;       /* our local domain name */
 112: 
 113: 
 114: main(argc, argv)
 115:     int argc;
 116:     char *argv[];
 117: {
 118:     char *p;
 119: #ifdef  pdp11
 120:     int on = 4*1024;
 121: #else
 122:     int on = 48*1024;
 123: #endif
 124: 
 125:     (void) gethostname(LocalHostName, sizeof LocalHostName);
 126:     if (p = index(LocalHostName, '.')) {
 127:         *p++ = '\0';
 128:         LocalDomain = p;
 129:     }
 130:     else
 131:         LocalDomain = "";
 132: 
 133:     if (argc < 2) {
 134: usage:
 135:         printf("usage: %s [ -v ][ -n ] hosts...\n", argv[0]);
 136:         exit(1);
 137:     }
 138: 
 139:     argv++, argc--;
 140:     if (*argv[0] == '-') {
 141:         switch (argv[0][1]) {
 142:         case 'n':
 143:             nflag++;
 144:             break;
 145:         case 't':
 146:             tflag++;
 147:             break;
 148:         case 'v':
 149:             vflag++;
 150:             break;
 151:         default:
 152:             goto usage;
 153:         }
 154:         argc--, argv++;
 155:     }
 156:     if (argc > 1)
 157:         printf("--- %s ---\n", *argv);
 158: 
 159:     while (argc > 0) {
 160:         /*
 161: 		 * Get a new socket each time - this will cause us to ignore
 162: 		 * packets from the previously queried host.
 163: 		 */
 164:         s = socket(AF_INET, SOCK_DGRAM, 0);
 165:         if (s < 0) {
 166:             perror("socket");
 167:             exit(2);
 168:         }
 169: #ifdef  SO_RCVBUF
 170:         if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0) {
 171:             fprintf(stderr, "setsockopt SO_RCVBUF\n");
 172:         }
 173: #endif
 174:         if (query(*argv))
 175:             answer(*argv);
 176:         close(s);
 177:         argv++;
 178:         if (argc-- > 1)
 179:             printf("--- %s ---\n", *argv);
 180:     }
 181: 
 182: }
 183: 
 184: answer(host)
 185:     char *host;
 186: {
 187:     register struct ntpinfo *msg = (struct ntpinfo *) packet;
 188:     register struct xclockinfo *n;
 189:     struct sockaddr_in from;
 190:     int fromlen = sizeof(from);
 191:     int count, cc;
 192:     fd_set bits;
 193:     struct timeval shorttime;
 194:     int first = 1;
 195:     long replies = 0;
 196: 
 197:     /*
 198: 	 * Listen for returning packets; may be more than one packet per
 199: 	 * host.
 200: 	 */
 201:     FD_ZERO(&bits);
 202:     FD_SET(s, &bits);
 203:     shorttime.tv_sec = 0;
 204:     shorttime.tv_usec = STIME;
 205:     (void) signal(SIGALRM, timeout);
 206:     (void) alarm(WTIME);
 207:     timedout = 0;
 208:     while ((first || replies) &&
 209:            (!timedout || select(FD_SETSIZE, &bits, (fd_set *) 0,
 210:                     (fd_set *) 0, &shorttime) > 0)) {
 211:         if ((cc = recvfrom(s, packet, sizeof(packet), 0,
 212:                  (struct sockaddr *)&from, &fromlen)) <= 0) {
 213:             if (cc == 0 || errno == EINTR)
 214:                 continue;
 215:             fflush(stdout);
 216:             perror(host);
 217:             (void) close(s);
 218:             return;
 219:         }
 220:         FD_SET(s, &bits);
 221: 
 222:         if (msg->type != INFO_REPLY)
 223:             return;
 224: 
 225:         if (msg->version != NTPDC_VERSION) {
 226:             printf("ntpd(%d) - ntpdc(%d) version mismatch\n",
 227:                    msg->version, NTPDC_VERSION);
 228:             alarm(0);
 229:             return;
 230:         }
 231: 
 232:         if (first) {
 233:             first = 0;
 234:             replies = (1L << msg->npkts) - 1;
 235:             if (!vflag) {
 236:                 if (tflag)
 237:                     printf("    Address      Reference     Strat Poll Reach    Delay   Offset    Disp\n");
 238:                 else
 239:                     printf("   (rem)  Address   (lcl)      Strat Poll Reach    Delay   Offset    Disp\n");
 240:                 printf("==========================================================================\n");
 241:             }
 242:         }
 243:         replies &= ~(1L << msg->seq);
 244:         n = (struct xclockinfo *)&msg[1];
 245:         for (count = msg->count; count > 0; count--) {
 246:             if(vflag)
 247:                 print_verbose(n);
 248:             else
 249:                 print_terse(n);
 250:             n++;
 251:         }
 252:     }
 253:     alarm(0);
 254:     if (replies)
 255:         printf("Timed out waiting for replies\n");
 256: }
 257: 
 258: int
 259: query(host)
 260:     char *host;
 261: {
 262:     struct sockaddr_in watcher;
 263:     register struct ntpdata *msg = (struct ntpdata *) packet;
 264:     struct hostent *hp;
 265:     static struct servent *sp = NULL;
 266:     long HostAddr;
 267: 
 268:     bzero((char *) &watcher, sizeof(watcher));
 269:     watcher.sin_family = AF_INET;
 270:     HostAddr = inet_addr(host);
 271:     watcher.sin_addr.s_addr = (u_long) HostAddr;
 272:     if (HostAddr == -1) {
 273:         hp = gethostbyname(host);
 274:         if (hp == 0) {
 275:             fprintf(stderr,"%s: unknown\n", host);
 276:             return 0;
 277:         }
 278:         bcopy(hp->h_addr, (char *) &watcher.sin_addr, hp->h_length);
 279:     }
 280:     sp = getservbyname("ntp", "udp");
 281:     if (sp == 0) {
 282:         fprintf(stderr,"udp/ntp: service unknown, using default %d\n",
 283:             NTP_PORT);
 284:         watcher.sin_port = htons(NTP_PORT);
 285:     } else
 286:         watcher.sin_port = sp->s_port;
 287:     msg->status = NTPVERSION_1;
 288:     msg->stratum = INFO_QUERY;
 289:     if (connect(s, (struct sockaddr *) &watcher, sizeof(watcher))) {
 290:         perror("connect");
 291:         return 0;
 292:     }
 293:     if (send(s, packet, sizeof(struct ntpdata), 0) < 0) {
 294:         perror("send");
 295:         return 0;
 296:     }
 297:     return 1;
 298: }
 299: 
 300: timeout()
 301: {
 302:     timedout = 1;
 303: }
 304: 
 305: print_terse (n)
 306:     struct xclockinfo *n;
 307: {
 308:     int i;
 309:     double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;
 310:     char c;
 311:     char *cvthname();
 312:     int flags;
 313: 
 314:     sin.sin_addr.s_addr = n->net_address;
 315:     for (i = 0; i < PEER_SHIFT; i++) {
 316:         delay[i] = (double) ((long) (ntohl(n->info_filter.delay[i])/1000.0));
 317:         offset[i] = (double) ((long) (ntohl(n->info_filter.offset[i])/1000.0));
 318:     }
 319:     dsp = (long) ntohl(n->estdisp);     /* leave in milliseconds */
 320:     del = (long) ntohl(n->estdelay);    /* leave in milliseconds */
 321:     off = (long) ntohl(n->estoffset);   /* leave in milliseconds */
 322:     c = ' ';
 323:     flags = ntohs(n->flags);
 324:     if (flags & PEER_FL_CONFIG)
 325:         c = '-';        /* mark pre-configured */
 326:     if (flags & PEER_FL_SANE)
 327:         c = '.';        /* passed sanity check */
 328:     if (flags & PEER_FL_CANDIDATE)
 329:         c = '+';        /* made candidate list */
 330:     if (flags & PEER_FL_SELECTED)
 331:         c = '*';        /* mark peer selection */
 332:     sin.sin_addr.s_addr = n->net_address;
 333:     printf("%c%-15.15s ", c, cvthname(&sin));
 334:     if (tflag) {
 335:         if (n->stratum == 1 || n->stratum == 0) {
 336:             printf("%-4.4s             ", (char *) &n->refid);
 337:         } else {
 338:             sin.sin_addr.s_addr = (u_long) n->refid;
 339:             printf("%-16.16s ", cvthname(&sin));
 340:         }
 341:     } else {
 342:         sin.sin_addr.s_addr = n->my_address;
 343:         printf("%-16.16s ", sin.sin_addr.s_addr ?
 344:                inet_ntoa(sin.sin_addr) : "wildcard");
 345:     }
 346:     printf("%2d %4d  %03o  %8.1f %8.1f %8.1f\n",
 347:            n->stratum, (int)ntohl((u_long)n->timer),
 348:            ntohs(n->reach) & SHIFT_MASK, del, off, dsp);
 349: }
 350: 
 351: print_verbose(n)
 352:     struct xclockinfo *n;
 353: {
 354:     int i;
 355:     struct in_addr clock_host;
 356:     double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;
 357:     char *cvthname();
 358: 
 359:     sin.sin_addr.s_addr = n->net_address;
 360:     for (i = 0; i < PEER_SHIFT; i++) {
 361:         delay[i] = (double) (long) ntohl(n->info_filter.delay[i]);
 362:         offset[i] = (double) (long) ntohl(n->info_filter.offset[i]);
 363:     }
 364:     dsp = (double) ((long) ntohl(n->estdisp));  /* in milliseconds */
 365:     del = (double) ((long) ntohl(n->estdelay)); /* in milliseconds */
 366:     off = (double) ((long) ntohl(n->estoffset));    /* in milliseconds */
 367:     printf("Neighbor address %s port:%d",
 368:            inet_ntoa(sin.sin_addr), (int)ntohs(n->port));
 369:     sin.sin_addr.s_addr = n->my_address;
 370:     printf("  local address %s\n", inet_ntoa(sin.sin_addr));
 371:     printf("Reach: 0%o stratum: %d, precision: %d\n",
 372:            ntohs(n->reach) & SHIFT_MASK, n->stratum, n->precision);
 373:     printf("dispersion: %f, flags: %x, leap: %x\n",
 374:            dsp,
 375:            ntohs(n->flags),
 376:            n->leap);
 377:     if (n->stratum == 1 || n->stratum == 0) {
 378:         printf("Reference clock ID: %.4s", (char *)&n->refid);
 379:     } else {
 380:         clock_host.s_addr = (u_long) n->refid;
 381:         printf("Reference clock ID: [%s]", inet_ntoa(clock_host));
 382:     }
 383:     printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part),
 384:            ntohl(n->reftime.fraction));
 385: 
 386:     printf("hpoll: %d, ppoll: %d, timer: %d, sent: %d received: %d\n",
 387:            n->hpoll, n->ppoll,
 388:            (int)ntohl((u_long)n->timer),
 389:            (int)ntohl(n->pkt_sent),
 390:            (int)ntohl(n->pkt_rcvd));
 391:     printf("Delay(ms)  ");
 392:     for (i = 0; i < PEER_SHIFT; i++)
 393:         printf("%7.2f ", delay[i]);
 394:     printf("\n");
 395:     printf("Offset(ms) ");
 396:     for (i = 0; i < PEER_SHIFT; i++)
 397:         printf("%7.2f ", offset[i]);
 398:     printf("\n");
 399:     printf("\n\tdelay: %f offset: %f dsp %f\n", del, off, dsp);
 400:     printf("\n");
 401: }
 402: /*
 403:  * Return a printable representation of a host address.
 404:  */
 405: char *
 406: cvthname(f)
 407:     struct sockaddr_in *f;
 408: {
 409:     struct hostent *hp;
 410:     register char *p;
 411:     extern char *inet_ntoa();
 412: 
 413:     if (f->sin_family != AF_INET) {
 414:         printf("Malformed from address\n");
 415:         return ("???");
 416:     }
 417:     if (!nflag)
 418:         hp = gethostbyaddr(&f->sin_addr, sizeof(struct in_addr),
 419:                    f->sin_family);
 420:     else
 421:         return (inet_ntoa(f->sin_addr));
 422: 
 423:     if (hp == 0)
 424:         return (inet_ntoa(f->sin_addr));
 425: 
 426:     if ((p = index(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
 427:         *p = '\0';
 428:     return (hp->h_name);
 429: }

Defined functions

answer defined in line 184; used 1 times
cvthname defined in line 405; used 4 times
main defined in line 114; never used
print_terse defined in line 305; used 1 times
print_verbose defined in line 351; used 1 times
query defined in line 258; used 1 times
timeout defined in line 300; used 2 times

Defined variables

LocalDomain defined in line 111; used 3 times
LocalHostName defined in line 110; used 3 times
RCSid defined in line 2; never used
debug defined in line 99; never used
nflag defined in line 102; used 2 times
packet defined in line 106; used 5 times
s defined in line 100; used 10 times
sin defined in line 104; used 12 times
tflag defined in line 102; used 3 times
timedout defined in line 101; used 3 times
vflag defined in line 102; used 3 times

Defined macros

MAXHOSTNAMELEN defined in line 108; used 2 times
MAXPACKETSIZE defined in line 96; used 1 times
STIME defined in line 95; used 1 times
WTIME defined in line 94; used 1 times
Last modified: 1995-01-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4458
Valid CSS Valid XHTML 1.0 Strict