|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.