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 |
b8c620d6 KB |
25 | static 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 | ||
47 | u_char buf[1024]; | |
48 | int showdata = 1; | |
49 | int showcontents = 0; | |
28026947 | 50 | int rawheader = 0; |
bbb841ef | 51 | int follow = 0; |
8cc7a4f3 | 52 | int skip = 0; |
bbb841ef SL |
53 | int link = -1; |
54 | int host = -1; | |
55 | int imp = -1; | |
56 | int packettype = -1; | |
57 | extern int errno; | |
58 | int log; | |
59 | char *logfile = "/usr/adm/implog"; | |
60 | ||
61 | /* | |
62 | * Socket address, internet style, with | |
63 | * unused space taken by timestamp and packet | |
64 | * size. | |
65 | */ | |
66 | struct 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 | }; | |
73 | struct sockstamp from; | |
74 | ||
75 | main(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 |
164 | again: |
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 | ||
205 | int impdata(), impbadleader(), impdown(), impnoop(); | |
206 | int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); | |
207 | int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); | |
208 | int impready(), impundef(); | |
209 | ||
210 | struct 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 | */ | |
234 | process(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 | ||
274 | impdata(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 | ||
299 | char *badleader[] = { | |
300 | "error flip-flop set", | |
301 | "message < 80 bits", | |
302 | "illegal type field", | |
303 | "opposite leader type" | |
304 | }; | |
305 | ||
306 | impbadleader(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 |
316 | impdown(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 | ||
334 | impnoop(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 | ||
341 | imprfnm(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 | ||
353 | char *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 | ||
372 | imphostdead(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 | ||
384 | char *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 | ||
391 | imphostunreach(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 | ||
401 | impbaddata(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 | ||
413 | char *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 | ||
422 | impincomplete(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 | ||
437 | impreset(ip) | |
438 | register struct imp_leader *ip; | |
439 | { | |
440 | printf("reset complete\n"); | |
441 | } | |
442 | ||
443 | char *retry[] = { | |
444 | "imp buffer wasn't available", | |
445 | "connection block unavailable" | |
446 | }; | |
447 | ||
448 | impretry(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 | ||
458 | char *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 | ||
467 | impnotify(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 | ||
477 | imptrying(ip) | |
478 | register struct imp_leader *ip; | |
479 | { | |
480 | printf("refused, still trying\n"); | |
481 | } | |
482 | ||
483 | impready(ip) | |
484 | register struct imp_leader *ip; | |
485 | { | |
486 | printf("ready\n"); | |
487 | } | |
488 | ||
db434d07 | 489 | impundef(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 | } |