2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #include <sys/types.h>
16 #include <sys/param.h>
19 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netinet/udp.h>
27 #include <arpa/inet.h>
30 #include <sys/select.h>
35 #define WTIME 10 /* Time to wait for all responses */
36 #define STIME 500000 /* usec to wait for another response */
37 #define MAXPACKETSIZE 1500
46 struct sockaddr_in sin = {AF_INET};
48 char packet[MAXPACKETSIZE];
49 #ifndef MAXHOSTNAMELEN
50 #define MAXHOSTNAMELEN 64
52 char LocalHostName[MAXHOSTNAMELEN+1]; /* our hostname */
53 char *LocalDomain; /* our local domain name */
55 #include "AFS_component_version_number.c"
66 * The following signal action for AIX is necessary so that in case of a
67 * crash (i.e. core is generated) we can include the user's data section
68 * in the core dump. Unfortunately, by default, only a partial core is
69 * generated which, in many cases, isn't too useful.
73 sigemptyset(&nsa.sa_mask);
74 nsa.sa_handler = SIG_DFL;
75 nsa.sa_flags = SA_FULLDUMP;
76 sigaction(SIGSEGV, &nsa, NULL);
78 (void) gethostname(LocalHostName, sizeof LocalHostName);
79 if (p = strchr(LocalHostName, '.')) {
88 printf("usage: %s [ -v ][ -n ] hosts...\n", argv[0]);
93 if (*argv[0] == '-') {
107 printf("--- %s ---\n", *argv);
111 * Get a new socket each time - this will cause us to ignore
112 * packets from the previously queried host.
114 s = socket(AF_INET, SOCK_DGRAM, 0);
120 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
121 (char *) &on, sizeof (on)) < 0) {
122 fprintf(stderr, "setsockopt SO_RCVBUF\n");
130 printf("--- %s ---\n", *argv);
138 register struct ntpinfo *msg = (struct ntpinfo *) packet;
139 register struct clockinfo *n;
140 struct sockaddr_in from;
141 int fromlen = sizeof(from);
144 struct timeval shorttime;
146 afs_int32 replies = 0;
149 * Listen for returning packets; may be more than one packet per
154 shorttime.tv_sec = 0;
155 shorttime.tv_usec = STIME;
156 (void) signal(SIGALRM, timeout);
159 while ((first || replies) &&
160 (!timedout || select(FD_SETSIZE, &bits, (fd_set *) 0,
161 (fd_set *) 0, &shorttime) > 0)) {
162 if ((cc = recvfrom(s, packet, sizeof(packet), 0,
163 (struct sockaddr *)&from, &fromlen)) <= 0) {
164 if (cc == 0 || errno == EINTR)
173 if (msg->type != INFO_REPLY)
176 if (msg->version != NTPDC_VERSION) {
177 printf("ntpd(%d) - ntpdc(%d) version mismatch\n",
178 msg->version, NTPDC_VERSION);
185 replies = (1L << msg->npkts) - 1;
187 printf(" (rem) Address (lcl) Strat Poll Reach Delay Offset Disp\n");
188 printf("==========================================================================\n");
191 replies &= ~(1L << msg->seq);
192 n = (struct clockinfo *)&msg[1];
193 for (count = msg->count; count > 0; count--) {
203 printf("Timed out waiting for replies\n");
210 struct sockaddr_in watcher;
211 register struct ntpdata *msg = (struct ntpdata *) packet;
213 static struct servent *sp = NULL;
216 memset((char *) &watcher, 0, sizeof(watcher));
217 watcher.sin_family = AF_INET;
218 HostAddr = inet_addr(host);
219 watcher.sin_addr.s_addr = (afs_uint32) HostAddr;
220 if (HostAddr == -1) {
221 hp = gethostbyname(host);
223 fprintf(stderr,"%s: unknown\n", host);
226 memcpy((char *) &watcher.sin_addr, hp->h_addr, hp->h_length);
228 sp = getservbyname("ntp", "udp");
230 fprintf(stderr,"udp/ntp: service unknown, using default %d\n",
232 watcher.sin_port = htons(NTP_PORT);
234 watcher.sin_port = sp->s_port;
235 msg->status = NTPVERSION_1;
236 msg->stratum = INFO_QUERY;
237 if (connect(s, (struct sockaddr *) &watcher, sizeof(watcher))) {
241 if (send(s, packet, sizeof(struct ntpdata), 0) < 0) {
257 double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;
262 sin.sin_addr.s_addr = n->net_address;
263 for (i = 0; i < PEER_SHIFT; i++) {
264 delay[i] = (double) ((afs_int32) (ntohl(n->info_filter.delay[i])/1000.0));
265 offset[i] = (double) ((afs_int32) (ntohl(n->info_filter.offset[i])/1000.0));
267 dsp = (afs_int32) ntohl(n->estdisp); /* leave in milliseconds */
268 del = (afs_int32) ntohl(n->estdelay); /* leave in milliseconds */
269 off = (afs_int32) ntohl(n->estoffset); /* leave in milliseconds */
271 flags = ntohs(n->flags);
272 if (flags & PEER_FL_CONFIG)
273 c = '-'; /* mark pre-configured */
274 if (flags & PEER_FL_SANE)
275 c = '.'; /* passed sanity check */
276 if (flags & PEER_FL_CANDIDATE)
277 c = '+'; /* made candidate list */
278 if (flags & PEER_FL_SELECTED)
279 c = '*'; /* mark peer selection */
280 sin.sin_addr.s_addr = n->net_address;
281 printf("%c%-15.15s ", c, cvthname(&sin));
282 sin.sin_addr.s_addr = n->my_address;
283 printf("%-16.16s %2d %4d %03o %8.1f %8.1f %8.1f\n",
284 sin.sin_addr.s_addr ? inet_ntoa(sin.sin_addr) : "wildcard",
285 n->stratum, (int)ntohl((afs_uint32)n->timer),
286 ntohs(n->reach) & SHIFT_MASK, del, off, dsp);
293 struct in_addr clock_host;
294 double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;
297 sin.sin_addr.s_addr = n->net_address;
298 for (i = 0; i < PEER_SHIFT; i++) {
299 delay[i] = (double) (afs_int32) ntohl(n->info_filter.delay[i]);
300 offset[i] = (double) (afs_int32) ntohl(n->info_filter.offset[i]);
302 dsp = (double) ((afs_int32) ntohl(n->estdisp)); /* in milliseconds */
303 del = (double) ((afs_int32) ntohl(n->estdelay)); /* in milliseconds */
304 off = (double) ((afs_int32) ntohl(n->estoffset)); /* in milliseconds */
305 printf("Neighbor address %s port:%d",
306 inet_ntoa(sin.sin_addr), (int)ntohs(n->port));
307 sin.sin_addr.s_addr = n->my_address;
308 printf(" local address %s\n", inet_ntoa(sin.sin_addr));
309 printf("Reach: 0%o stratum: %d, precision: %d\n",
310 ntohs(n->reach) & SHIFT_MASK, n->stratum, n->precision);
311 printf("dispersion: %f, flags: %x, leap: %x\n",
315 if (n->stratum == 1 || n->stratum == 0) {
316 printf("Reference clock ID: %.4s", (char *)&n->refid);
318 clock_host.s_addr = (afs_uint32) n->refid;
319 printf("Reference clock ID: [%s]", inet_ntoa(clock_host));
321 printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part),
322 ntohl(n->reftime.fraction));
324 printf("hpoll: %d, ppoll: %d, timer: %d, sent: %d received: %d dropped: %d\n",
326 (int)ntohl((afs_uint32)n->timer),
327 (int)ntohl(n->pkt_sent),
328 (int)ntohl(n->pkt_rcvd),
329 (int)ntohl(n->pkt_dropped));
330 printf("Delay(ms) ");
331 for (i = 0; i < PEER_SHIFT; i++)
332 printf("%7.2f ", delay[i]);
334 printf("Offset(ms) ");
335 for (i = 0; i < PEER_SHIFT; i++)
336 printf("%7.2f ", offset[i]);
338 printf("\n\tdelay: %f offset: %f dsp %f\n", del, off, dsp);
342 * Return a printable representation of a host address.
346 struct sockaddr_in *f;
350 extern char *inet_ntoa();
352 if (f->sin_family != AF_INET) {
353 printf("Malformed from address\n");
357 hp = gethostbyaddr((char *) &f->sin_addr,
358 sizeof(struct in_addr),
361 return (inet_ntoa(f->sin_addr));
364 return (inet_ntoa(f->sin_addr));
366 if ((p = strchr(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)