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