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