/*-
* Copyright (c) 1985, 1993 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
i = msg->tsp_type;
return i < TSPTYPENUMBER ? tsptype[i] : "unknown";
}
/* compute the difference between our date and another machine
*/
static int /* difference in days from our time */
daydiff(const char *hostname, const struct sockaddr_in *addr)
{
struct pollfd set[1];
int trials;
/* if we get here, we tried too many times */
warnx("%s will not tell us the date", hostname);
return 0;
}
/*
* Clockdiff computes the difference between the time of the machine on
* which it is called and the time of the machines given as argument.
* The time differences measured by clockdiff are obtained using a sequence
* of ICMP TSTAMP messages which are returned to the sender by the IP module
* in the remote machine.
* In order to compare clocks of machines in different time zones, the time
* is transmitted (as a 32-bit value) in milliseconds since midnight UT.
* If a hosts uses a different time format, it should set the high order
* bit of the 32-bit quantity it transmits.
* However, VMS apparently transmits the time in milliseconds since midnight
* local time (rather than GMT) without setting the high order bit.
* Furthermore, it does not understand daylight-saving time. This makes
* clockdiff behaving inconsistently with hosts running VMS.
*
* In order to reduce the sensitivity to the variance of message transmission
* time, clockdiff sends a sequence of messages. Yet, measures between
* two `distant' hosts can be affected by a small error. The error can,
* however, be reduced by increasing the number of messages sent in each
* measurement.
*/
void
clockdiff(int argc, char *argv[])
{
extern int measure(u_long, u_long, const char *,
const struct sockaddr_in*, int);
in_port_t port;
switch (measure_status) {
case HOSTDOWN:
printf("%s is down\n", hostname);
continue;
case NONSTDTIME:
printf("%s transmits a non-standard time format\n",
hostname);
continue;
case UNREACHABLE:
printf("%s is unreachable\n", hostname);
continue;
}
/*
* Try to get the date only after using ICMP timestamps to
* get the time. This is because the date protocol
* is optional.
*/
if (port != 0) {
avg = daydiff(*argv, &server);
if (avg > SECDAY) {
printf("time on %s is %ld days ahead %s\n",
hostname, avg/SECDAY, myname(CACHED));
continue;
} else if (avg < -SECDAY) {
printf("time on %s is %ld days behind %s\n",
hostname, -avg/SECDAY, myname(CACHED));
continue;
}
}
if (measure_delta > 0) {
printf("time on %s is %d ms. ahead of time on %s\n",
hostname, measure_delta, myname(CACHED));
} else if (measure_delta == 0) {
printf("%s and %s have the same time\n",
hostname, myname(CACHED));
} else {
printf("time on %s is %d ms. behind time on %s\n",
hostname, -measure_delta, myname(CACHED));
}
}
return;
}
/*
* Causes the election timer to expire on the selected hosts
* It sends just one udp message per machine, relying on
* reliability of communication channel.
*/
void
testing(int argc, char *argv[])
{
in_port_t port;