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