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