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