|
|
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.