1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)cmds.c	2.2 (Berkeley) 4/21/86";
   9: #endif not lint
  10: 
  11: #include "timedc.h"
  12: #include <netinet/in_systm.h>
  13: #include <netinet/ip.h>
  14: #include <netinet/ip_icmp.h>
  15: #define TSPTYPES
  16: #include <protocols/timed.h>
  17: #include <sys/file.h>
  18: 
  19: int id;
  20: int sock;
  21: int sock_raw;
  22: char hostname[MAXHOSTNAMELEN];
  23: struct hostent *hp, *gethostbyname();
  24: struct sockaddr_in server;
  25: extern int measure_delta;
  26: int bytenetorder(), bytehostorder();
  27: char *strcpy();
  28: 
  29: /*
  30:  * Clockdiff computes the difference between the time of the machine on
  31:  * which it is called and the time of the machines given as argument.
  32:  * The time differences measured by clockdiff are obtained using a sequence
  33:  * of ICMP TSTAMP messages which are returned to the sender by the IP module
  34:  * in the remote machine.
  35:  * In order to compare clocks of machines in different time zones, the time
  36:  * is transmitted (as a 32-bit value) in milliseconds since midnight UT.
  37:  * If a hosts uses a different time format, it should set the high order
  38:  * bit of the 32-bit quantity it transmits.
  39:  * However, VMS apparently transmits the time in milliseconds since midnight
  40:  * local time (rather than GMT) without setting the high order bit.
  41:  * Furthermore, it does not understand daylight-saving time.  This makes
  42:  * clockdiff behaving inconsistently with hosts running VMS.
  43:  *
  44:  * In order to reduce the sensitivity to the variance of message transmission
  45:  * time, clockdiff sends a sequence of messages.  Yet, measures between
  46:  * two `distant' hosts can be affected by a small error. The error can, however,
  47:  * be reduced by increasing the number of messages sent in each measurement.
  48:  */
  49: 
  50: clockdiff(argc, argv)
  51: int argc;
  52: char *argv[];
  53: {
  54:     int measure_status;
  55:     struct timeval ack;
  56:     int measure();
  57: 
  58:     if(argc < 2)  {
  59:         printf("Usage: clockdiff host ... \n");
  60:         return;
  61:     }
  62: 
  63:     id = getpid();
  64:     (void)gethostname(hostname,sizeof(hostname));
  65: 
  66:     while (argc > 1) {
  67:         argc--; argv++;
  68:         hp = gethostbyname(*argv);
  69:         if (hp == NULL) {
  70:             printf("%s: unknown host\n", *argv);
  71:             continue;
  72:         }
  73:         server.sin_family = hp->h_addrtype;
  74:         bcopy(hp->h_addr, &(server.sin_addr.s_addr), hp->h_length);
  75:         ack.tv_sec = 10;
  76:         ack.tv_usec = 0;
  77:         if ((measure_status = measure(&ack, &server)) < 0) {
  78:             perror("measure");
  79:             return;
  80:         }
  81:         switch (measure_status) {
  82: 
  83:         case HOSTDOWN:
  84:             printf("%s is down\n", hp->h_name);
  85:             continue;
  86:             break;
  87:         case NONSTDTIME:
  88:             printf("%s time transmitted in a non-standard format\n",                         hp->h_name);
  89:             continue;
  90:             break;
  91:         case UNREACHABLE:
  92:             printf("%s is unreachable\n", hp->h_name);
  93:             continue;
  94:             break;
  95:         default:
  96:             break;
  97:         }
  98: 
  99:         if (measure_delta > 0)
 100:             printf("time on %s is %d ms. ahead of time on %s\n",
 101:                         hp->h_name, measure_delta,
 102:                         hostname);
 103:         else
 104:             if (measure_delta == 0)
 105:                     printf("%s and %s have the same time\n",
 106:                         hp->h_name, hostname);
 107:             else
 108:                      printf("time on %s is %d ms. behind time on %s\n",
 109:                     hp->h_name, -measure_delta, hostname);
 110:     }
 111:     return;
 112: }
 113: /*
 114:  * finds location of master timedaemon
 115:  */
 116: 
 117: msite(argc)
 118: int argc;
 119: {
 120:     int length;
 121:     int cc;
 122:     fd_set ready;
 123:     struct sockaddr_in dest;
 124:     struct timeval tout;
 125:     struct sockaddr_in from;
 126:     struct tsp msg;
 127:     struct servent *srvp;
 128: 
 129:     if (argc != 1) {
 130:         printf("Usage: msite\n");
 131:         return;
 132:     }
 133: 
 134:     srvp = getservbyname("timed", "udp");
 135:     if (srvp == 0) {
 136:         fprintf(stderr, "udp/timed: unknown service\n");
 137:         return;
 138:     }
 139:     dest.sin_port = srvp->s_port;
 140:     dest.sin_family = AF_INET;
 141: 
 142:     (void)gethostname(hostname,sizeof(hostname));
 143:     hp = gethostbyname(hostname);
 144:     if (hp == NULL) {
 145:         perror("gethostbyname");
 146:         return;
 147:     }
 148:     bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
 149: 
 150:     (void)strcpy(msg.tsp_name, hostname);
 151:     msg.tsp_type = TSP_MSITE;
 152:     msg.tsp_vers = TSPVERSION;
 153:     bytenetorder(&msg);
 154:     length = sizeof(struct sockaddr_in);
 155:     if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
 156:                         &dest, length) < 0) {
 157:         perror("sendto");
 158:         return;
 159:     }
 160: 
 161:     tout.tv_sec = 15;
 162:     tout.tv_usec = 0;
 163:     FD_ZERO(&ready);
 164:     FD_SET(sock, &ready);
 165:     if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
 166:         length = sizeof(struct sockaddr_in);
 167:         cc = recvfrom(sock, (char *)&msg, sizeof(struct tsp), 0,
 168:                             &from, &length);
 169:         if (cc < 0) {
 170:             perror("recvfrom");
 171:             return;
 172:         }
 173:         bytehostorder(&msg);
 174:         if (msg.tsp_type == TSP_ACK)
 175:             printf("master timedaemon runs on %s\n", msg.tsp_name);
 176:         else
 177:             printf("received wrong ack: %s\n",
 178:                         tsptype[msg.tsp_type]);
 179:     } else
 180:         printf("communication error\n");
 181: }
 182: 
 183: /*
 184:  * quits timedc
 185:  */
 186: 
 187: quit()
 188: {
 189:     exit(0);
 190: }
 191: 
 192: #define MAXH    4   /* max no. of hosts where election can occur */
 193: 
 194: /*
 195:  * Causes the election timer to expire on the selected hosts
 196:  * It sends just one udp message per machine, relying on
 197:  * reliability of communication channel.
 198:  */
 199: 
 200: testing(argc, argv)
 201: int argc;
 202: char *argv[];
 203: {
 204:     int length;
 205:     int nhosts;
 206:     struct servent *srvp;
 207:     struct sockaddr_in sin[MAXH];
 208:     struct tsp msg;
 209: 
 210:     if(argc < 2)  {
 211:         printf("Usage: testing host ...\n");
 212:         return;
 213:     }
 214: 
 215:     srvp = getservbyname("timed", "udp");
 216:     if (srvp == 0) {
 217:         fprintf(stderr, "udp/timed: unknown service\n");
 218:         return;
 219:     }
 220: 
 221:     nhosts = 0;
 222:     while (argc > 1) {
 223:         argc--; argv++;
 224:         hp = gethostbyname(*argv);
 225:         if (hp == NULL) {
 226:             printf("%s: unknown host %s\n", *argv);
 227:             argc--; argv++;
 228:             continue;
 229:         }
 230:         sin[nhosts].sin_port = srvp->s_port;
 231:         sin[nhosts].sin_family = hp->h_addrtype;
 232:         bcopy(hp->h_addr, &(sin[nhosts].sin_addr.s_addr), hp->h_length);
 233:         if (++nhosts == MAXH)
 234:             break;
 235:     }
 236: 
 237:     msg.tsp_type = TSP_TEST;
 238:     msg.tsp_vers = TSPVERSION;
 239:     (void)gethostname(hostname, sizeof(hostname));
 240:     (void)strcpy(msg.tsp_name, hostname);
 241:     bytenetorder(&msg); /* it is not really necessary here */
 242:     while (nhosts-- > 0) {
 243:         length = sizeof(struct sockaddr_in);
 244:         if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
 245:                         &sin[nhosts], length) < 0) {
 246:             perror("sendto");
 247:             return;
 248:         }
 249:     }
 250: }
 251: 
 252: /*
 253:  * Enables or disables tracing on local timedaemon
 254:  */
 255: 
 256: tracing(argc, argv)
 257: int argc;
 258: char *argv[];
 259: {
 260:     int onflag;
 261:     int length;
 262:     int cc;
 263:     fd_set ready;
 264:     struct sockaddr_in dest;
 265:     struct timeval tout;
 266:     struct sockaddr_in from;
 267:     struct tsp msg;
 268:     struct servent *srvp;
 269: 
 270:     if (argc != 2) {
 271:         printf("Usage: tracing { on | off }\n");
 272:         return;
 273:     }
 274: 
 275:     srvp = getservbyname("timed", "udp");
 276:     if (srvp == 0) {
 277:         fprintf(stderr, "udp/timed: unknown service\n");
 278:         return;
 279:     }
 280:     dest.sin_port = srvp->s_port;
 281:     dest.sin_family = AF_INET;
 282: 
 283:     (void)gethostname(hostname,sizeof(hostname));
 284:     hp = gethostbyname(hostname);
 285:     bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
 286: 
 287:     if (strcmp(argv[1], "on") == 0) {
 288:         msg.tsp_type = TSP_TRACEON;
 289:         onflag = ON;
 290:     } else {
 291:         msg.tsp_type = TSP_TRACEOFF;
 292:         onflag = OFF;
 293:     }
 294: 
 295:     (void)strcpy(msg.tsp_name, hostname);
 296:     msg.tsp_vers = TSPVERSION;
 297:     bytenetorder(&msg);
 298:     length = sizeof(struct sockaddr_in);
 299:     if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
 300:                         &dest, length) < 0) {
 301:         perror("sendto");
 302:         return;
 303:     }
 304: 
 305:     tout.tv_sec = 5;
 306:     tout.tv_usec = 0;
 307:     FD_ZERO(&ready);
 308:     FD_SET(sock, &ready);
 309:     if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
 310:         length = sizeof(struct sockaddr_in);
 311:         cc = recvfrom(sock, (char *)&msg, sizeof(struct tsp), 0,
 312:                             &from, &length);
 313:         if (cc < 0) {
 314:             perror("recvfrom");
 315:             return;
 316:         }
 317:         bytehostorder(&msg);
 318:         if (msg.tsp_type == TSP_ACK)
 319:             if (onflag)
 320:                 printf("timed tracing enabled\n");
 321:             else
 322:                 printf("timed tracing disabled\n");
 323:         else
 324:             printf("wrong ack received: %s\n",
 325:                         tsptype[msg.tsp_type]);
 326:     } else
 327:         printf("communication error\n");
 328: }
 329: 
 330: priv_resources()
 331: {
 332:     int port;
 333:     struct sockaddr_in sin;
 334: 
 335:     sock = socket(AF_INET, SOCK_DGRAM, 0);
 336:     if (sock < 0) {
 337:         perror("opening socket");
 338:         return(-1);
 339:     }
 340: 
 341:     sin.sin_family = AF_INET;
 342:     sin.sin_addr.s_addr = 0;
 343:     for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
 344:         sin.sin_port = htons((u_short)port);
 345:         if (bind(sock, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
 346:             break;
 347:         if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
 348:             perror("bind");
 349:             (void) close(sock);
 350:             return(-1);
 351:         }
 352:     }
 353:     if (port == IPPORT_RESERVED / 2) {
 354:         fprintf(stderr, "all reserved ports in use\n");
 355:         (void) close(sock);
 356:         return(-1);
 357:     }
 358: 
 359:     sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
 360:     if (sock_raw < 0)  {
 361:         perror("opening raw socket");
 362:         (void) close(sock_raw);
 363:         return(-1);
 364:     }
 365:     return(1);
 366: }

Defined functions

clockdiff defined in line 50; used 2 times
msite defined in line 117; used 2 times
priv_resources defined in line 330; used 2 times
quit defined in line 187; used 3 times
testing defined in line 200; used 2 times
tracing defined in line 256; used 2 times

Defined variables

hostname defined in line 22; used 46 times
hp defined in line 23; used 52 times
id defined in line 19; used 3 times
sccsid defined in line 8; never used
server defined in line 24; used 3 times
sock defined in line 20; used 39 times
sock_raw defined in line 21; used 8 times

Defined macros

MAXH defined in line 192; used 2 times
TSPTYPES defined in line 15; never used
Last modified: 1986-04-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1875
Valid CSS Valid XHTML 1.0 Strict