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