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