121138Sdist /*
234772Sbostic * Copyright (c) 1983, 1988 Regents of the University of California.
333457Skarels * All rights reserved.
433457Skarels *
542798Sbostic * %sccs.include.redist.c%
621138Sdist */
721138Sdist
89197Ssam #ifndef lint
921138Sdist char copyright[] =
1034772Sbostic "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
1121138Sdist All rights reserved.\n";
1234772Sbostic #endif /* not lint */
136478Ssam
1421138Sdist #ifndef lint
15*47697Sbostic static char sccsid[] = "@(#)implog.c 5.14 (Berkeley) 04/01/91";
1634772Sbostic #endif /* not lint */
1721138Sdist
1837278Sbostic #include <sys/param.h>
1913600Ssam #include <sys/time.h>
2037278Sbostic #include <sys/signal.h>
2134037Skarels #include <sys/file.h>
226478Ssam #include <sys/stat.h>
236478Ssam #include <sys/socket.h>
249195Ssam
2533455Skarels #include <net/if.h>
2633455Skarels
279195Ssam #include <netinet/in.h>
2833455Skarels #define IMPMESSAGES
296478Ssam #define IMPLEADERS
309195Ssam #include <netimp/if_imp.h>
316478Ssam
3237278Sbostic #include <sgtty.h>
3337278Sbostic #include <stdio.h>
3437278Sbostic #include "pathnames.h"
356478Ssam
366478Ssam u_char buf[1024];
376478Ssam int showdata = 1;
386478Ssam int showcontents = 0;
3927727Skarels int rawheader = 0;
406478Ssam int follow = 0;
4134037Skarels int skip = 0;
42*47697Sbostic int linkn = -1;
436478Ssam int host = -1;
446478Ssam int imp = -1;
456478Ssam int packettype = -1;
466478Ssam extern int errno;
476478Ssam int log;
486478Ssam
496478Ssam /*
506478Ssam * Socket address, internet style, with
516478Ssam * unused space taken by timestamp and packet
526478Ssam * size.
536478Ssam */
546478Ssam struct sockstamp {
556478Ssam short sin_family;
566478Ssam u_short sin_port;
576478Ssam struct in_addr sin_addr;
586478Ssam time_t sin_time;
596478Ssam int sin_cc;
606478Ssam };
616478Ssam struct sockstamp from;
626478Ssam
main(argc,argv)636478Ssam main(argc, argv)
6437278Sbostic int argc;
6537278Sbostic char **argv;
666478Ssam {
6737278Sbostic extern int errno, optind;
6837278Sbostic extern char *optarg;
696478Ssam struct stat b;
7037278Sbostic off_t size, lseek();
7137278Sbostic char *logfile, *strerror();
7237278Sbostic int ch;
7337278Sbostic long hostfrom, impfrom;
746478Ssam
7537278Sbostic while ((ch = getopt(argc, argv, "DFLcfh:i:l:rt:")) != EOF)
7637278Sbostic switch(ch) {
7737278Sbostic case 'D':
786478Ssam showdata = 0;
7937278Sbostic break;
8037278Sbostic case 'F':
8134037Skarels skip++;
8237278Sbostic /* FALLTHROUGH */
8337278Sbostic case 'f':
8434037Skarels follow++;
8537278Sbostic break;
8637278Sbostic case 'L':
87*47697Sbostic linkn = IMPLINK_IP;
8837278Sbostic break;
8937278Sbostic case 'c':
906478Ssam showcontents++;
9137278Sbostic break;
9237278Sbostic case 'h':
9337278Sbostic host = atoi(optarg);
9437278Sbostic break;
9537278Sbostic case 'i':
9637278Sbostic imp = atoi(optarg);
9737278Sbostic break;
9837278Sbostic case 'l':
99*47697Sbostic linkn = atoi(optarg);
10037278Sbostic break;
10137278Sbostic case 'r':
10227727Skarels rawheader++;
10337278Sbostic break;
10437278Sbostic case 't':
10537278Sbostic packettype = atoi(optarg);
10637278Sbostic break;
10737278Sbostic case '?':
10837278Sbostic default:
10937278Sbostic fprintf(stderr,
11037278Sbostic "usage: implog [-DFLcfr] [-h host] [-i imp] [-l link] [-t type] [logfile]\n");
11137278Sbostic exit(2);
11227727Skarels }
11337278Sbostic argc -= optind;
11437278Sbostic argv += optind;
11537278Sbostic
11637278Sbostic logfile = argc ? *argv : _PATH_IMPLOG;
11737278Sbostic log = open(logfile, O_RDONLY, 0);
11837278Sbostic if (log < 0 || fstat(log, &b)) {
11937278Sbostic fprintf(stderr, "implog: %s: %s\n", logfile, strerror(errno));
1206478Ssam exit(1);
1216478Ssam }
1226478Ssam size = b.st_size;
12334037Skarels if (skip)
12437278Sbostic (void)lseek(log, size, L_SET);
1256478Ssam again:
1266478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1276478Ssam if (from.sin_family == 0) {
1286478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time));
1296478Ssam continue;
1306478Ssam }
13138002Skarels if (host >= 0 || imp >= 0) {
13238002Skarels long addr = ntohl(from.sin_addr.s_addr);
13322597Skarels
13422597Skarels if (IN_CLASSA(addr)) {
13522597Skarels hostfrom = ((addr>>16) & 0xFF);
13622597Skarels impfrom = addr & 0xFF;
13722597Skarels } else if (IN_CLASSB(addr)) {
13822597Skarels hostfrom = ((addr>>8) & 0xFF);
13922597Skarels impfrom = addr & 0xFF;
14022597Skarels } else {
14122597Skarels hostfrom = ((addr>>4) & 0xF);
14222597Skarels impfrom = addr & 0xF;
14322597Skarels }
14422597Skarels }
14522597Skarels if (host >= 0 && hostfrom != host) {
14637278Sbostic (void)lseek(log, (long)from.sin_cc, L_INCR);
1476478Ssam continue;
1486478Ssam }
14922597Skarels if (imp >= 0 && impfrom != imp) {
15037278Sbostic (void)lseek(log, (long)from.sin_cc, L_INCR);
15122597Skarels continue;
1526478Ssam }
1536478Ssam process(log, &from);
1546478Ssam }
1556478Ssam while (follow) {
15637278Sbostic (void)fflush(stdout);
15737278Sbostic (void)sleep(5);
15837278Sbostic (void)fstat(log, &b);
1596478Ssam if (b.st_size > size) {
1606478Ssam size = b.st_size;
1616478Ssam goto again;
1626478Ssam }
1636478Ssam }
1646478Ssam }
1656478Ssam
1666478Ssam int impdata(), impbadleader(), impdown(), impnoop();
1676478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1686478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1696478Ssam int impready(), impundef();
1706478Ssam
1716478Ssam struct messages {
1726478Ssam u_char m_type; /* type of message */
1736478Ssam int (*m_func)(); /* routine to process message */
1746478Ssam } mtypes[] = {
1756478Ssam { IMPTYPE_DATA, impdata },
1766478Ssam { IMPTYPE_BADLEADER, impbadleader },
1776478Ssam { IMPTYPE_DOWN, impdown },
1786478Ssam { IMPTYPE_NOOP, impnoop },
1796478Ssam { IMPTYPE_RFNM, imprfnm },
1806478Ssam { IMPTYPE_INCOMPLETE, impincomplete },
1816478Ssam { IMPTYPE_HOSTDEAD, imphostdead },
1826478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach },
1836478Ssam { IMPTYPE_BADDATA, impbaddata },
1846478Ssam { IMPTYPE_RESET, impreset },
1856478Ssam { IMPTYPE_RETRY, impretry },
1866478Ssam { IMPTYPE_NOTIFY, impnotify },
1876478Ssam { IMPTYPE_TRYING, imptrying },
1886478Ssam { IMPTYPE_READY, impready },
1896478Ssam { -1, impundef }
1906478Ssam };
1916478Ssam
1926478Ssam /*
1936478Ssam * Print a packet.
1946478Ssam */
process(l,f)1956478Ssam process(l, f)
1966478Ssam int l;
1976478Ssam struct sockstamp *f;
1986478Ssam {
1996478Ssam register struct messages *mp;
2006478Ssam struct imp_leader *ip;
20127727Skarels int (*fn)();
2026478Ssam
2036478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
20437278Sbostic perror("implog: read");
2056478Ssam return;
2066478Ssam }
2076478Ssam ip = (struct imp_leader *)buf;
20828904Skarels ip->il_imp = ntohs(ip->il_imp);
20927727Skarels if (ip->il_format != IMP_NFF)
21027727Skarels fn = impundef;
21127727Skarels else {
21233085Sbostic for (mp = mtypes; mp->m_type != (u_char)-1; mp++)
21327727Skarels if (mp->m_type == ip->il_mtype)
21427727Skarels break;
21527727Skarels fn = mp->m_func;
21627727Skarels }
21727727Skarels if (ip->il_mtype == IMPTYPE_DATA) {
218*47697Sbostic if (linkn >= 0 && ip->il_link != linkn)
2196478Ssam return;
2206478Ssam if (!showdata)
2216478Ssam return;
2226478Ssam }
22327727Skarels if (packettype >= 0 && ip->il_mtype != packettype)
2246478Ssam return;
2256478Ssam printf("%.24s: ", ctime(&f->sin_time));
22628904Skarels if (f->sin_cc < sizeof(struct control_leader))
22728904Skarels printf("(truncated header, %d bytes): ", f->sin_cc);
22827727Skarels (*fn)(ip, f->sin_cc);
22928904Skarels if (rawheader && fn != impundef) {
23028904Skarels putchar('\t');
23127727Skarels impundef(ip, f->sin_cc);
23228904Skarels }
2336478Ssam }
2346478Ssam
impdata(ip,cc)2356478Ssam impdata(ip, cc)
2366478Ssam register struct imp_leader *ip;
23737278Sbostic int cc;
2386478Ssam {
23937278Sbostic printf("<DATA, source=%d/%u, link=", ip->il_host, (u_short)ip->il_imp);
2406478Ssam if (ip->il_link == IMPLINK_IP)
2416478Ssam printf("ip,");
2426478Ssam else
2436478Ssam printf("%d,", ip->il_link);
24437278Sbostic printf(" len=%u bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2456478Ssam if (showcontents) {
2466478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2476478Ssam register int i;
2486478Ssam
2496478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
25037278Sbostic cc = MIN(i, cc);
2516478Ssam printf("data: (%d bytes)", cc);
2526478Ssam for (i = 0; i < cc; i++, cp++) {
2536478Ssam if (i % 25 == 0)
2546478Ssam printf("\n");
2556478Ssam printf("%02x ", *cp);
2566478Ssam }
2576478Ssam putchar('\n');
2586478Ssam }
2596478Ssam }
2606478Ssam
2616478Ssam char *badleader[] = {
2626478Ssam "error flip-flop set",
2636478Ssam "message < 80 bits",
2646478Ssam "illegal type field",
2656478Ssam "opposite leader type"
2666478Ssam };
2676478Ssam
26837278Sbostic /* ARGSUSED */
impbadleader(ip,cc)26937278Sbostic impbadleader(ip, cc)
2706478Ssam register struct imp_leader *ip;
27137278Sbostic int cc;
2726478Ssam {
2736478Ssam printf("bad leader: ");
2746478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE)
2756478Ssam printf("%x\n", ip->il_subtype);
2766478Ssam else
2776478Ssam printf("%s\n", badleader[ip->il_subtype]);
2786478Ssam }
2796478Ssam
28037278Sbostic /* ARGSUSED */
impdown(ip,cc)28137278Sbostic impdown(ip, cc)
2826478Ssam register struct imp_leader *ip;
28337278Sbostic int cc;
2846478Ssam {
2856478Ssam int tdown, tbackup;
2866478Ssam
28733455Skarels printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]);
28833455Skarels tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) *
28933455Skarels IMPDOWN_WHENUNIT;
29033455Skarels if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING)
2916478Ssam printf(" in %d minutes", tdown);
29233455Skarels tbackup = ip->il_subtype * IMPDOWN_WHENUNIT;
2936478Ssam printf(": back up ");
2946478Ssam if (tbackup)
2956478Ssam printf("%d minutes\n", tbackup);
2966478Ssam else
2976478Ssam printf("immediately\n");
2986478Ssam }
2996478Ssam
30037278Sbostic /* ARGSUSED */
impnoop(ip,cc)30137278Sbostic impnoop(ip, cc)
3026478Ssam register struct imp_leader *ip;
30337278Sbostic int cc;
3046478Ssam {
30537278Sbostic printf("noop: host %d, imp %u\n", ip->il_host, ip->il_imp);
3066478Ssam }
3076478Ssam
30837278Sbostic /* ARGSUSED */
imprfnm(ip,cc)30937278Sbostic imprfnm(ip, cc)
3106478Ssam register struct imp_leader *ip;
31137278Sbostic int cc;
3126478Ssam {
31337278Sbostic printf("rfnm: htype=%x, source=%d/%u, link=",
3146478Ssam ip->il_htype, ip->il_host, ip->il_imp);
3156478Ssam if (ip->il_link == IMPLINK_IP)
3166478Ssam printf("ip,");
3176478Ssam else
31827727Skarels printf("%d,", ip->il_link);
3196478Ssam printf(" subtype=%x\n", ip->il_subtype);
3206478Ssam }
3216478Ssam
3226478Ssam char *hostdead[] = {
3239195Ssam "#0",
3246478Ssam "ready-line negated",
3256478Ssam "tardy receiving messages",
3266478Ssam "ncc doesn't know host",
3276478Ssam "imp software won't allow messages",
3286478Ssam "host down for scheduled pm",
3296478Ssam "host down for hardware work",
3306478Ssam "host down for software work",
3316478Ssam "host down for emergency restart",
3326478Ssam "host down because of power outage",
3336478Ssam "host stopped at a breakpoint",
3346478Ssam "host down due to hardware failure",
3356478Ssam "host not scheduled to be up",
3369195Ssam "#13",
3379195Ssam "#14",
3386478Ssam "host in the process of coming up"
3396478Ssam };
3406478Ssam
34137278Sbostic /* ARGSUSED */
imphostdead(ip,cc)34237278Sbostic imphostdead(ip, cc)
3436478Ssam register struct imp_leader *ip;
34437278Sbostic int cc;
3456478Ssam {
34637278Sbostic printf("host %u/%u dead: ", ip->il_host, ip->il_imp);
3476478Ssam if (ip->il_link & IMP_DMASK)
34833455Skarels printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]);
3496478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP)
3506478Ssam printf("%s\n", hostdead[ip->il_subtype]);
3516478Ssam else
3526478Ssam printf("subtype=%x\n", ip->il_subtype);
3536478Ssam }
3546478Ssam
3556478Ssam char *hostunreach[] = {
3566478Ssam "destination imp can't be reached",
3576478Ssam "destination host isn't up",
3586478Ssam "host doesn't support long leader",
3596478Ssam "communication is prohibited"
3606478Ssam };
3616478Ssam
36237278Sbostic /* ARGSUSED */
imphostunreach(ip,cc)36337278Sbostic imphostunreach(ip, cc)
3646478Ssam register struct imp_leader *ip;
36537278Sbostic int cc;
3666478Ssam {
36737278Sbostic printf("host %u/%u unreachable: ", ip->il_host, ip->il_imp);
3686478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED)
3696478Ssam printf("%s\n", hostunreach[ip->il_subtype]);
3706478Ssam else
3716478Ssam printf("subtype=%x\n", ip->il_subtype);
3726478Ssam }
3736478Ssam
37437278Sbostic /* ARGSUSED */
impbaddata(ip,cc)37537278Sbostic impbaddata(ip, cc)
3766478Ssam register struct imp_leader *ip;
37737278Sbostic int cc;
3786478Ssam {
37937278Sbostic printf("error in data: htype=%x, source=%u/%u, link=",
3806478Ssam ip->il_htype, ip->il_host, ip->il_imp);
3816478Ssam if (ip->il_link == IMPLINK_IP)
3826478Ssam printf("ip, ");
3836478Ssam else
38427727Skarels printf("%d, ", ip->il_link);
3856478Ssam printf("subtype=%x\n", ip->il_subtype);
3866478Ssam }
3876478Ssam
3886478Ssam char *incomplete[] = {
3896478Ssam "host didn't take data fast enough",
3906478Ssam "message was too long",
3916478Ssam "message transmission time > 15 seconds",
3926478Ssam "imp/circuit failure",
3936478Ssam "no resources within 15 seconds",
3946478Ssam "source imp i/o failure during receipt"
3956478Ssam };
3966478Ssam
39737278Sbostic /* ARGSUSED */
impincomplete(ip,cc)39837278Sbostic impincomplete(ip, cc)
3996478Ssam register struct imp_leader *ip;
40037278Sbostic int cc;
4016478Ssam {
40237278Sbostic printf("incomplete: htype=%x, source=%u/%u, link=",
4036478Ssam ip->il_htype, ip->il_host, ip->il_imp);
4046478Ssam if (ip->il_link == IMPLINK_IP)
4056478Ssam printf("ip,");
4066478Ssam else
40727727Skarels printf("%d,", ip->il_link);
4086478Ssam if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
4096478Ssam printf(" %s\n", incomplete[ip->il_subtype]);
4106478Ssam else
4116478Ssam printf(" subtype=%x\n", ip->il_subtype);
4126478Ssam }
4136478Ssam
41437278Sbostic /* ARGSUSED */
41537278Sbostic impreset(ip, cc)
41637278Sbostic struct imp_leader *ip;
41737278Sbostic int cc;
4186478Ssam {
4196478Ssam printf("reset complete\n");
4206478Ssam }
4216478Ssam
4226478Ssam char *retry[] = {
4236478Ssam "imp buffer wasn't available",
4246478Ssam "connection block unavailable"
4256478Ssam };
4266478Ssam
42737278Sbostic /* ARGSUSED */
impretry(ip,cc)42837278Sbostic impretry(ip, cc)
4296478Ssam register struct imp_leader *ip;
43037278Sbostic int cc;
4316478Ssam {
4326478Ssam printf("refused, try again: ");
4336478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK)
4346478Ssam printf("%s\n", retry[ip->il_subtype]);
4356478Ssam else
4366478Ssam printf("subtype=%x\n", ip->il_subtype);
4376478Ssam }
4386478Ssam
4396478Ssam char *notify[] = {
4409195Ssam "#0",
4419195Ssam "#1",
4426478Ssam "connection not available",
4436478Ssam "reassembly space not available at destination",
4446478Ssam "message number not available",
4456478Ssam "transaction block for message not available"
4466478Ssam };
4476478Ssam
44837278Sbostic /* ARGSUSED */
impnotify(ip,cc)44937278Sbostic impnotify(ip, cc)
4506478Ssam register struct imp_leader *ip;
45137278Sbostic int cc;
4526478Ssam {
4536478Ssam printf("refused, will notify: ");
4546478Ssam if (ip->il_subtype <= 5)
4556478Ssam printf("%s\n", notify[ip->il_subtype]);
4566478Ssam else
4576478Ssam printf("subtype=%x\n", ip->il_subtype);
4586478Ssam }
4596478Ssam
46037278Sbostic /* ARGSUSED */
46137278Sbostic imptrying(ip, cc)
46237278Sbostic struct imp_leader *ip;
46337278Sbostic int cc;
4646478Ssam {
4656478Ssam printf("refused, still trying\n");
4666478Ssam }
4676478Ssam
46837278Sbostic /* ARGSUSED */
46937278Sbostic impready(ip, cc)
47037278Sbostic struct imp_leader *ip;
47137278Sbostic int cc;
4726478Ssam {
4736478Ssam printf("ready\n");
4746478Ssam }
4756478Ssam
47637278Sbostic /* ARGSUSED */
impundef(ip,cc)47737278Sbostic impundef(ip, cc)
4786478Ssam register struct imp_leader *ip;
47937278Sbostic int cc;
4806478Ssam {
4816478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4826478Ssam ip->il_network, ip->il_flags);
48337278Sbostic printf("%x, htype=%x,\n\t host=%d(x%x), imp=%u(x%x), link=",
48428904Skarels ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
48528904Skarels ip->il_imp, ip->il_imp);
4866478Ssam if (ip->il_link == IMPLINK_IP)
4876478Ssam printf("ip,");
4886478Ssam else
48928904Skarels printf("%d (x%x),", ip->il_link, ip->il_link);
49028904Skarels printf(" subtype=%x", ip->il_subtype);
49137278Sbostic if (cc >= sizeof(struct imp_leader) && ip->il_length)
49237278Sbostic printf(" len=%u bytes", ntohs((u_short)ip->il_length) >> 3);
49328904Skarels printf(">\n");
4946478Ssam }
495