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