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