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