xref: /original-bsd/old/implog/implog.c (revision fbed46ce)
1 /*	implog.c	4.1	82/04/04	*/
2 
3 #include <stdio.h>
4 #include <time.h>
5 #include <signal.h>
6 #include <sgtty.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <sys/socket.h>
10 #include <net/in.h>
11 #define	IMPLEADERS
12 #include <net/if_imp.h>
13 
14 #define	min(a, b)	((a) < (b) ? (a) : (b))
15 
16 u_char	buf[1024];
17 int	showdata = 1;
18 int	showcontents = 0;
19 int	follow = 0;
20 int	link = -1;
21 int	host = -1;
22 int	imp = -1;
23 int	packettype = -1;
24 extern	int errno;
25 int	log;
26 char	*logfile = "/usr/adm/implog";
27 
28 /*
29  * Socket address, internet style, with
30  * unused space taken by timestamp and packet
31  * size.
32  */
33 struct sockstamp {
34 	short	sin_family;
35 	u_short	sin_port;
36 	struct	in_addr sin_addr;
37 	time_t	sin_time;
38 	int	sin_cc;
39 };
40 struct	sockstamp from;
41 
42 main(argc, argv)
43 	char *argv[];
44 {
45 	struct stat b;
46 	int size;
47 	char *cp;
48 
49 	argc--, argv++;
50 	while (argc > 0 && argv[0][0] == '-') {
51 		if (strcmp(*argv, "-D") == 0) {
52 			showdata = 0;
53 			argv++, argc--;
54 			continue;
55 		}
56 		if (strcmp(*argv, "-f") == 0) {
57 			follow++;
58 			argv++, argc--;
59 			continue;
60 		}
61 		if (strcmp(*argv, "-c") == 0) {
62 			showcontents++;
63 			argv++, argc--;
64 			continue;
65 		}
66 		if (strcmp(*argv, "-l") == 0) {
67 			argc--, argv++;
68 			if (argc > 0) {
69 				link = atoi(*argv);
70 				argc--, argv++;
71 			} else
72 				link = IMPLINK_IP;
73 			continue;
74 		}
75 		if (strcmp(*argv, "-h") == 0) {
76 			argc--, argv++;
77 			if (argc < 1) {
78 				printf("-h: missing host #\n");
79 				exit(2);
80 			}
81 			host = atoi(*argv);
82 			argv++, argc--;
83 			continue;
84 		}
85 		if (strcmp(*argv, "-i") == 0) {
86 			argc--, argv++;
87 			if (argc < 1) {
88 				printf("-i: missing imp #\n");
89 				exit(2);
90 			}
91 			imp = atoi(*argv);
92 			argv++, argc--;
93 			continue;
94 		}
95 		if (strcmp(*argv, "-t") == 0) {
96 			argc--, argv++;;
97 			if (argc < 1) {
98 				printf("-t: missing packet type\n");
99 				exit(2);
100 			}
101 			packettype = atoi(*argv);
102 			argv++, argc--;;
103 			continue;
104 		}
105 		printf("usage: prlog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
106 		exit(2);
107 	}
108 	if (argc > 0)
109 		logfile = argv[0];
110 	log = open(logfile, 0);
111 	if (log < 0) {
112 		perror(logfile);
113 		exit(1);
114 	}
115 	fstat(log, &b);
116 	size = b.st_size;
117 again:
118 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
119 		if (from.sin_family == 0) {
120 			printf("restarted: %.24s\n", ctime(&from.sin_time));
121 			continue;
122 		}
123 		if (host >= 0 && from.sin_addr.s_host != host) {
124 			lseek(log, from.sin_cc, 1);
125 			continue;
126 		}
127 		if (imp >= 0) {
128 			from.sin_addr.s_imp = ntohs(from.sin_addr.s_imp);
129 			if (from.sin_addr.s_imp != imp) {
130 				lseek(log, from.sin_cc, 1);
131 				continue;
132 			}
133 		}
134 		process(log, &from);
135 	}
136 	while (follow) {
137 		fflush(stdout);
138 		sleep(5);
139 		fstat(log, &b);
140 		if (b.st_size > size) {
141 			size = b.st_size;
142 			goto again;
143 		}
144 	}
145 }
146 
147 int	impdata(), impbadleader(), impdown(), impnoop();
148 int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
149 int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
150 int	impready(), impundef();
151 
152 struct	messages {
153 	u_char	m_type;		/* type of message */
154 	int	(*m_func)();	/* routine to process message */
155 } mtypes[] = {
156 	{ IMPTYPE_DATA,		impdata },
157 	{ IMPTYPE_BADLEADER,	impbadleader },
158 	{ IMPTYPE_DOWN,		impdown },
159 	{ IMPTYPE_NOOP,		impnoop },
160 	{ IMPTYPE_RFNM,		imprfnm },
161 	{ IMPTYPE_INCOMPLETE,	impincomplete },
162 	{ IMPTYPE_HOSTDEAD,	imphostdead },
163 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
164 	{ IMPTYPE_BADDATA,	impbaddata },
165 	{ IMPTYPE_RESET,	impreset },
166 	{ IMPTYPE_RETRY,	impretry },
167 	{ IMPTYPE_NOTIFY,	impnotify },
168 	{ IMPTYPE_TRYING,	imptrying },
169 	{ IMPTYPE_READY,	impready },
170 	{ -1,			impundef }
171 };
172 
173 /*
174  * Print a packet.
175  */
176 process(l, f)
177 	int l;
178 	struct sockstamp *f;
179 {
180 	register struct messages *mp;
181 	struct imp_leader *ip;
182 
183 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
184 		perror("read");
185 		return;
186 	}
187 	ip = (struct imp_leader *)buf;
188 #if vax
189 	ip->il_imp = ntohs(ip->il_imp);
190 #endif
191 	for (mp = mtypes; mp->m_type != -1; mp++)
192 		if (mp->m_type == ip->il_mtype)
193 			break;
194 	if (mp->m_type == IMPTYPE_DATA) {
195 		if (link >= 0 && ip->il_link != link)
196 			return;
197 		if (!showdata)
198 			return;
199 	}
200 	if (packettype >= 0 && mp->m_type != packettype)
201 		return;
202 	printf("%.24s: ", ctime(&f->sin_time));
203 	(*mp->m_func)(ip, f->sin_cc);
204 }
205 
206 impdata(ip, cc)
207 	register struct imp_leader *ip;
208 {
209 	printf("<%d/%d, DATA, link=", ip->il_host, ntohs(ip->il_imp));
210 	if (ip->il_link == IMPLINK_IP)
211 		printf("ip,");
212 	else
213 		printf("%d,", ip->il_link);
214 	printf(" len=%d bytes>\n", ntohs(ip->il_length) >> 3);
215 	if (showcontents) {
216 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
217 		register int i;
218 
219 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
220 		cc = min(i, cc);
221 		printf("data: (%d bytes)", cc);
222 		for (i = 0; i < cc; i++, cp++) {
223 			if (i % 25 == 0)
224 				printf("\n");
225 			printf("%02x ", *cp);
226 		}
227 		putchar('\n');
228 	}
229 }
230 
231 char *badleader[] = {
232 	"error flip-flop set",
233 	"message < 80 bits",
234 	"illegal type field",
235 	"opposite leader type"
236 };
237 
238 impbadleader(ip)
239 	register struct imp_leader *ip;
240 {
241 	printf("bad leader: ");
242 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
243 		printf("%x\n", ip->il_subtype);
244 	else
245 		printf("%s\n", badleader[ip->il_subtype]);
246 }
247 
248 char *down[] = {
249 	"in 30 secs",
250 	"for hardware pm",
251 	"for software reload",
252 	"for emergency restart"
253 };
254 
255 impdown(ip)
256 	register struct imp_leader *ip;
257 {
258 	int tdown, tbackup;
259 
260 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
261 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
262 	if (ip->il_link & IMP_DMASK)
263 		printf(" in %d minutes", tdown);
264 	tbackup = ip->il_subtype * 5;
265 	printf(": back up ");
266 	if (tbackup)
267 		printf("%d minutes\n", tbackup);
268 	else
269 		printf("immediately\n");
270 }
271 
272 impnoop(ip)
273 	register struct imp_leader *ip;
274 {
275 	printf("noop: host %d, imp %d\n", ip->il_host, ntohs(ip->il_imp));
276 }
277 
278 imprfnm(ip)
279 	register struct imp_leader *ip;
280 {
281 	printf("rfnm: htype=%x, source=%d/%d, link=",
282 		ip->il_htype, ip->il_host, ip->il_imp);
283 	if (ip->il_link == IMPLINK_IP)
284 		printf("ip,");
285 	else
286 		printf("%x,", ip->il_link);
287 	printf(" subtype=%x\n", ip->il_subtype);
288 }
289 
290 char *hostdead[] = {
291 	"???",
292 	"ready-line negated",
293 	"tardy receiving messages",
294 	"ncc doesn't know host",
295 	"imp software won't allow messages",
296 	"host down for scheduled pm",
297 	"host down for hardware work",
298 	"host down for software work",
299 	"host down for emergency restart",
300 	"host down because of power outage",
301 	"host stopped at a breakpoint",
302 	"host down due to hardware failure",
303 	"host not scheduled to be up",
304 	"???",
305 	"???",
306 	"host in the process of coming up"
307 };
308 
309 imphostdead(ip)
310 	register struct imp_leader *ip;
311 {
312 	printf("host dead: ");
313 	if (ip->il_link & IMP_DMASK)
314 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
315 	if (ip->il_subtype <= IMPHOST_COMINGUP)
316 		printf("%s\n", hostdead[ip->il_subtype]);
317 	else
318 		printf("subtype=%x\n", ip->il_subtype);
319 }
320 
321 char *hostunreach[] = {
322 	"destination imp can't be reached",
323 	"destination host isn't up",
324 	"host doesn't support long leader",
325 	"communication is prohibited"
326 };
327 
328 imphostunreach(ip)
329 	register struct imp_leader *ip;
330 {
331 	printf("host unreachable: ");
332 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
333 		printf("%s\n", hostunreach[ip->il_subtype]);
334 	else
335 		printf("subtype=%x\n", ip->il_subtype);
336 }
337 
338 impbaddata(ip)
339 	register struct imp_leader *ip;
340 {
341 	printf("error in data: htype=%x, source=%d/%d, link=",
342 		ip->il_htype, ip->il_host, ip->il_imp);
343 	if (ip->il_link == IMPLINK_IP)
344 		printf("ip, ");
345 	else
346 		printf("%x, ", ip->il_link);
347 	printf("subtype=%x\n", ip->il_subtype);
348 }
349 
350 char *incomplete[] = {
351 	"host didn't take data fast enough",
352 	"message was too long",
353 	"message transmission time > 15 seconds",
354 	"imp/circuit failure",
355 	"no resources within 15 seconds",
356 	"source imp i/o failure during receipt"
357 };
358 
359 impincomplete(ip)
360 	register struct imp_leader *ip;
361 {
362 	printf("incomplete: htype=%x, source=%d/%d, link=",
363 		ip->il_htype, ip->il_host, ip->il_imp);
364 	if (ip->il_link == IMPLINK_IP)
365 		printf("ip,");
366 	else
367 		printf("%x,", ip->il_link);
368 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
369 		printf(" %s\n", incomplete[ip->il_subtype]);
370 	else
371 		printf(" subtype=%x\n", ip->il_subtype);
372 }
373 
374 impreset(ip)
375 	register struct imp_leader *ip;
376 {
377 	printf("reset complete\n");
378 }
379 
380 char *retry[] = {
381 	"imp buffer wasn't available",
382 	"connection block unavailable"
383 };
384 
385 impretry(ip)
386 	register struct imp_leader *ip;
387 {
388 	printf("refused, try again: ");
389 	if (ip->il_subtype <= IMPRETRY_BLOCK)
390 		printf("%s\n", retry[ip->il_subtype]);
391 	else
392 		printf("subtype=%x\n", ip->il_subtype);
393 }
394 
395 char *notify[] = {
396 	"???",
397 	"???",
398 	"connection not available",
399 	"reassembly space not available at destination",
400 	"message number not available",
401 	"transaction block for message not available"
402 };
403 
404 impnotify(ip)
405 	register struct imp_leader *ip;
406 {
407 	printf("refused, will notify: ");
408 	if (ip->il_subtype <= 5)
409 		printf("%s\n", notify[ip->il_subtype]);
410 	else
411 		printf("subtype=%x\n", ip->il_subtype);
412 }
413 
414 imptrying(ip)
415 	register struct imp_leader *ip;
416 {
417 	printf("refused, still trying\n");
418 }
419 
420 impready(ip)
421 	register struct imp_leader *ip;
422 {
423 	printf("ready\n");
424 }
425 
426 impundef(ip)
427 	register struct imp_leader *ip;
428 {
429 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
430 		ip->il_network, ip->il_flags);
431 	printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype,
432 		ip->il_htype, ip->il_host, ip->il_imp);
433 	if (ip->il_link == IMPLINK_IP)
434 		printf("ip,");
435 	else
436 		printf("%x,", ip->il_link);
437 	printf(" subtype=%x>\n", ip->il_subtype);
438 }
439