121138Sdist /* 234772Sbostic * Copyright (c) 1983, 1988 Regents of the University of California. 333457Skarels * All rights reserved. 433457Skarels * 533457Skarels * Redistribution and use in source and binary forms are permitted 634772Sbostic * provided that the above copyright notice and this paragraph are 734772Sbostic * duplicated in all such forms and that any documentation, 834772Sbostic * advertising materials, and other materials related to such 934772Sbostic * distribution and use acknowledge that the software was developed 1034772Sbostic * by the University of California, Berkeley. The name of the 1134772Sbostic * University may not be used to endorse or promote products derived 1234772Sbostic * from this software without specific prior written permission. 1334772Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434772Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534772Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621138Sdist */ 1721138Sdist 189197Ssam #ifndef lint 1921138Sdist char copyright[] = 2034772Sbostic "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ 2121138Sdist All rights reserved.\n"; 2234772Sbostic #endif /* not lint */ 236478Ssam 2421138Sdist #ifndef lint 25*38002Skarels static char sccsid[] = "@(#)implog.c 5.12 (Berkeley) 05/13/89"; 2634772Sbostic #endif /* not lint */ 2721138Sdist 2837278Sbostic #include <sys/param.h> 2913600Ssam #include <sys/time.h> 3037278Sbostic #include <sys/signal.h> 3134037Skarels #include <sys/file.h> 326478Ssam #include <sys/stat.h> 336478Ssam #include <sys/socket.h> 349195Ssam 3533455Skarels #include <net/if.h> 3633455Skarels 379195Ssam #include <netinet/in.h> 3833455Skarels #define IMPMESSAGES 396478Ssam #define IMPLEADERS 409195Ssam #include <netimp/if_imp.h> 416478Ssam 4237278Sbostic #include <sgtty.h> 4337278Sbostic #include <stdio.h> 4437278Sbostic #include "pathnames.h" 456478Ssam 466478Ssam u_char buf[1024]; 476478Ssam int showdata = 1; 486478Ssam int showcontents = 0; 4927727Skarels int rawheader = 0; 506478Ssam int follow = 0; 5134037Skarels int skip = 0; 526478Ssam int link = -1; 536478Ssam int host = -1; 546478Ssam int imp = -1; 556478Ssam int packettype = -1; 566478Ssam extern int errno; 576478Ssam int log; 586478Ssam 596478Ssam /* 606478Ssam * Socket address, internet style, with 616478Ssam * unused space taken by timestamp and packet 626478Ssam * size. 636478Ssam */ 646478Ssam struct sockstamp { 656478Ssam short sin_family; 666478Ssam u_short sin_port; 676478Ssam struct in_addr sin_addr; 686478Ssam time_t sin_time; 696478Ssam int sin_cc; 706478Ssam }; 716478Ssam struct sockstamp from; 726478Ssam 736478Ssam main(argc, argv) 7437278Sbostic int argc; 7537278Sbostic char **argv; 766478Ssam { 7737278Sbostic extern int errno, optind; 7837278Sbostic extern char *optarg; 796478Ssam struct stat b; 8037278Sbostic off_t size, lseek(); 8137278Sbostic char *logfile, *strerror(); 8237278Sbostic int ch; 8337278Sbostic long hostfrom, impfrom; 846478Ssam 8537278Sbostic while ((ch = getopt(argc, argv, "DFLcfh:i:l:rt:")) != EOF) 8637278Sbostic switch(ch) { 8737278Sbostic case 'D': 886478Ssam showdata = 0; 8937278Sbostic break; 9037278Sbostic case 'F': 9134037Skarels skip++; 9237278Sbostic /* FALLTHROUGH */ 9337278Sbostic case 'f': 9434037Skarels follow++; 9537278Sbostic break; 9637278Sbostic case 'L': 9737278Sbostic link = IMPLINK_IP; 9837278Sbostic break; 9937278Sbostic case 'c': 1006478Ssam showcontents++; 10137278Sbostic break; 10237278Sbostic case 'h': 10337278Sbostic host = atoi(optarg); 10437278Sbostic break; 10537278Sbostic case 'i': 10637278Sbostic imp = atoi(optarg); 10737278Sbostic break; 10837278Sbostic case 'l': 10937278Sbostic link = atoi(optarg); 11037278Sbostic break; 11137278Sbostic case 'r': 11227727Skarels rawheader++; 11337278Sbostic break; 11437278Sbostic case 't': 11537278Sbostic packettype = atoi(optarg); 11637278Sbostic break; 11737278Sbostic case '?': 11837278Sbostic default: 11937278Sbostic fprintf(stderr, 12037278Sbostic "usage: implog [-DFLcfr] [-h host] [-i imp] [-l link] [-t type] [logfile]\n"); 12137278Sbostic exit(2); 12227727Skarels } 12337278Sbostic argc -= optind; 12437278Sbostic argv += optind; 12537278Sbostic 12637278Sbostic logfile = argc ? *argv : _PATH_IMPLOG; 12737278Sbostic log = open(logfile, O_RDONLY, 0); 12837278Sbostic if (log < 0 || fstat(log, &b)) { 12937278Sbostic fprintf(stderr, "implog: %s: %s\n", logfile, strerror(errno)); 1306478Ssam exit(1); 1316478Ssam } 1326478Ssam size = b.st_size; 13334037Skarels if (skip) 13437278Sbostic (void)lseek(log, size, L_SET); 1356478Ssam again: 1366478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 1376478Ssam if (from.sin_family == 0) { 1386478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time)); 1396478Ssam continue; 1406478Ssam } 141*38002Skarels if (host >= 0 || imp >= 0) { 142*38002Skarels long addr = ntohl(from.sin_addr.s_addr); 14322597Skarels 14422597Skarels if (IN_CLASSA(addr)) { 14522597Skarels hostfrom = ((addr>>16) & 0xFF); 14622597Skarels impfrom = addr & 0xFF; 14722597Skarels } else if (IN_CLASSB(addr)) { 14822597Skarels hostfrom = ((addr>>8) & 0xFF); 14922597Skarels impfrom = addr & 0xFF; 15022597Skarels } else { 15122597Skarels hostfrom = ((addr>>4) & 0xF); 15222597Skarels impfrom = addr & 0xF; 15322597Skarels } 15422597Skarels } 15522597Skarels if (host >= 0 && hostfrom != host) { 15637278Sbostic (void)lseek(log, (long)from.sin_cc, L_INCR); 1576478Ssam continue; 1586478Ssam } 15922597Skarels if (imp >= 0 && impfrom != imp) { 16037278Sbostic (void)lseek(log, (long)from.sin_cc, L_INCR); 16122597Skarels continue; 1626478Ssam } 1636478Ssam process(log, &from); 1646478Ssam } 1656478Ssam while (follow) { 16637278Sbostic (void)fflush(stdout); 16737278Sbostic (void)sleep(5); 16837278Sbostic (void)fstat(log, &b); 1696478Ssam if (b.st_size > size) { 1706478Ssam size = b.st_size; 1716478Ssam goto again; 1726478Ssam } 1736478Ssam } 1746478Ssam } 1756478Ssam 1766478Ssam int impdata(), impbadleader(), impdown(), impnoop(); 1776478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 1786478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 1796478Ssam int impready(), impundef(); 1806478Ssam 1816478Ssam struct messages { 1826478Ssam u_char m_type; /* type of message */ 1836478Ssam int (*m_func)(); /* routine to process message */ 1846478Ssam } mtypes[] = { 1856478Ssam { IMPTYPE_DATA, impdata }, 1866478Ssam { IMPTYPE_BADLEADER, impbadleader }, 1876478Ssam { IMPTYPE_DOWN, impdown }, 1886478Ssam { IMPTYPE_NOOP, impnoop }, 1896478Ssam { IMPTYPE_RFNM, imprfnm }, 1906478Ssam { IMPTYPE_INCOMPLETE, impincomplete }, 1916478Ssam { IMPTYPE_HOSTDEAD, imphostdead }, 1926478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach }, 1936478Ssam { IMPTYPE_BADDATA, impbaddata }, 1946478Ssam { IMPTYPE_RESET, impreset }, 1956478Ssam { IMPTYPE_RETRY, impretry }, 1966478Ssam { IMPTYPE_NOTIFY, impnotify }, 1976478Ssam { IMPTYPE_TRYING, imptrying }, 1986478Ssam { IMPTYPE_READY, impready }, 1996478Ssam { -1, impundef } 2006478Ssam }; 2016478Ssam 2026478Ssam /* 2036478Ssam * Print a packet. 2046478Ssam */ 2056478Ssam process(l, f) 2066478Ssam int l; 2076478Ssam struct sockstamp *f; 2086478Ssam { 2096478Ssam register struct messages *mp; 2106478Ssam struct imp_leader *ip; 21127727Skarels int (*fn)(); 2126478Ssam 2136478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 21437278Sbostic perror("implog: read"); 2156478Ssam return; 2166478Ssam } 2176478Ssam ip = (struct imp_leader *)buf; 21828904Skarels ip->il_imp = ntohs(ip->il_imp); 21927727Skarels if (ip->il_format != IMP_NFF) 22027727Skarels fn = impundef; 22127727Skarels else { 22233085Sbostic for (mp = mtypes; mp->m_type != (u_char)-1; mp++) 22327727Skarels if (mp->m_type == ip->il_mtype) 22427727Skarels break; 22527727Skarels fn = mp->m_func; 22627727Skarels } 22727727Skarels if (ip->il_mtype == IMPTYPE_DATA) { 2286478Ssam if (link >= 0 && ip->il_link != link) 2296478Ssam return; 2306478Ssam if (!showdata) 2316478Ssam return; 2326478Ssam } 23327727Skarels if (packettype >= 0 && ip->il_mtype != packettype) 2346478Ssam return; 2356478Ssam printf("%.24s: ", ctime(&f->sin_time)); 23628904Skarels if (f->sin_cc < sizeof(struct control_leader)) 23728904Skarels printf("(truncated header, %d bytes): ", f->sin_cc); 23827727Skarels (*fn)(ip, f->sin_cc); 23928904Skarels if (rawheader && fn != impundef) { 24028904Skarels putchar('\t'); 24127727Skarels impundef(ip, f->sin_cc); 24228904Skarels } 2436478Ssam } 2446478Ssam 2456478Ssam impdata(ip, cc) 2466478Ssam register struct imp_leader *ip; 24737278Sbostic int cc; 2486478Ssam { 24937278Sbostic printf("<DATA, source=%d/%u, link=", ip->il_host, (u_short)ip->il_imp); 2506478Ssam if (ip->il_link == IMPLINK_IP) 2516478Ssam printf("ip,"); 2526478Ssam else 2536478Ssam printf("%d,", ip->il_link); 25437278Sbostic printf(" len=%u bytes>\n", ntohs((u_short)ip->il_length) >> 3); 2556478Ssam if (showcontents) { 2566478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip); 2576478Ssam register int i; 2586478Ssam 2596478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 26037278Sbostic cc = MIN(i, cc); 2616478Ssam printf("data: (%d bytes)", cc); 2626478Ssam for (i = 0; i < cc; i++, cp++) { 2636478Ssam if (i % 25 == 0) 2646478Ssam printf("\n"); 2656478Ssam printf("%02x ", *cp); 2666478Ssam } 2676478Ssam putchar('\n'); 2686478Ssam } 2696478Ssam } 2706478Ssam 2716478Ssam char *badleader[] = { 2726478Ssam "error flip-flop set", 2736478Ssam "message < 80 bits", 2746478Ssam "illegal type field", 2756478Ssam "opposite leader type" 2766478Ssam }; 2776478Ssam 27837278Sbostic /* ARGSUSED */ 27937278Sbostic impbadleader(ip, cc) 2806478Ssam register struct imp_leader *ip; 28137278Sbostic int cc; 2826478Ssam { 2836478Ssam printf("bad leader: "); 2846478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE) 2856478Ssam printf("%x\n", ip->il_subtype); 2866478Ssam else 2876478Ssam printf("%s\n", badleader[ip->il_subtype]); 2886478Ssam } 2896478Ssam 29037278Sbostic /* ARGSUSED */ 29137278Sbostic impdown(ip, cc) 2926478Ssam register struct imp_leader *ip; 29337278Sbostic int cc; 2946478Ssam { 2956478Ssam int tdown, tbackup; 2966478Ssam 29733455Skarels printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]); 29833455Skarels tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) * 29933455Skarels IMPDOWN_WHENUNIT; 30033455Skarels if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING) 3016478Ssam printf(" in %d minutes", tdown); 30233455Skarels tbackup = ip->il_subtype * IMPDOWN_WHENUNIT; 3036478Ssam printf(": back up "); 3046478Ssam if (tbackup) 3056478Ssam printf("%d minutes\n", tbackup); 3066478Ssam else 3076478Ssam printf("immediately\n"); 3086478Ssam } 3096478Ssam 31037278Sbostic /* ARGSUSED */ 31137278Sbostic impnoop(ip, cc) 3126478Ssam register struct imp_leader *ip; 31337278Sbostic int cc; 3146478Ssam { 31537278Sbostic printf("noop: host %d, imp %u\n", ip->il_host, ip->il_imp); 3166478Ssam } 3176478Ssam 31837278Sbostic /* ARGSUSED */ 31937278Sbostic imprfnm(ip, cc) 3206478Ssam register struct imp_leader *ip; 32137278Sbostic int cc; 3226478Ssam { 32337278Sbostic printf("rfnm: htype=%x, source=%d/%u, link=", 3246478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3256478Ssam if (ip->il_link == IMPLINK_IP) 3266478Ssam printf("ip,"); 3276478Ssam else 32827727Skarels printf("%d,", ip->il_link); 3296478Ssam printf(" subtype=%x\n", ip->il_subtype); 3306478Ssam } 3316478Ssam 3326478Ssam char *hostdead[] = { 3339195Ssam "#0", 3346478Ssam "ready-line negated", 3356478Ssam "tardy receiving messages", 3366478Ssam "ncc doesn't know host", 3376478Ssam "imp software won't allow messages", 3386478Ssam "host down for scheduled pm", 3396478Ssam "host down for hardware work", 3406478Ssam "host down for software work", 3416478Ssam "host down for emergency restart", 3426478Ssam "host down because of power outage", 3436478Ssam "host stopped at a breakpoint", 3446478Ssam "host down due to hardware failure", 3456478Ssam "host not scheduled to be up", 3469195Ssam "#13", 3479195Ssam "#14", 3486478Ssam "host in the process of coming up" 3496478Ssam }; 3506478Ssam 35137278Sbostic /* ARGSUSED */ 35237278Sbostic imphostdead(ip, cc) 3536478Ssam register struct imp_leader *ip; 35437278Sbostic int cc; 3556478Ssam { 35637278Sbostic printf("host %u/%u dead: ", ip->il_host, ip->il_imp); 3576478Ssam if (ip->il_link & IMP_DMASK) 35833455Skarels printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]); 3596478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP) 3606478Ssam printf("%s\n", hostdead[ip->il_subtype]); 3616478Ssam else 3626478Ssam printf("subtype=%x\n", ip->il_subtype); 3636478Ssam } 3646478Ssam 3656478Ssam char *hostunreach[] = { 3666478Ssam "destination imp can't be reached", 3676478Ssam "destination host isn't up", 3686478Ssam "host doesn't support long leader", 3696478Ssam "communication is prohibited" 3706478Ssam }; 3716478Ssam 37237278Sbostic /* ARGSUSED */ 37337278Sbostic imphostunreach(ip, cc) 3746478Ssam register struct imp_leader *ip; 37537278Sbostic int cc; 3766478Ssam { 37737278Sbostic printf("host %u/%u unreachable: ", ip->il_host, ip->il_imp); 3786478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED) 3796478Ssam printf("%s\n", hostunreach[ip->il_subtype]); 3806478Ssam else 3816478Ssam printf("subtype=%x\n", ip->il_subtype); 3826478Ssam } 3836478Ssam 38437278Sbostic /* ARGSUSED */ 38537278Sbostic impbaddata(ip, cc) 3866478Ssam register struct imp_leader *ip; 38737278Sbostic int cc; 3886478Ssam { 38937278Sbostic printf("error in data: htype=%x, source=%u/%u, link=", 3906478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3916478Ssam if (ip->il_link == IMPLINK_IP) 3926478Ssam printf("ip, "); 3936478Ssam else 39427727Skarels printf("%d, ", ip->il_link); 3956478Ssam printf("subtype=%x\n", ip->il_subtype); 3966478Ssam } 3976478Ssam 3986478Ssam char *incomplete[] = { 3996478Ssam "host didn't take data fast enough", 4006478Ssam "message was too long", 4016478Ssam "message transmission time > 15 seconds", 4026478Ssam "imp/circuit failure", 4036478Ssam "no resources within 15 seconds", 4046478Ssam "source imp i/o failure during receipt" 4056478Ssam }; 4066478Ssam 40737278Sbostic /* ARGSUSED */ 40837278Sbostic impincomplete(ip, cc) 4096478Ssam register struct imp_leader *ip; 41037278Sbostic int cc; 4116478Ssam { 41237278Sbostic printf("incomplete: htype=%x, source=%u/%u, link=", 4136478Ssam ip->il_htype, ip->il_host, ip->il_imp); 4146478Ssam if (ip->il_link == IMPLINK_IP) 4156478Ssam printf("ip,"); 4166478Ssam else 41727727Skarels printf("%d,", ip->il_link); 4186478Ssam if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 4196478Ssam printf(" %s\n", incomplete[ip->il_subtype]); 4206478Ssam else 4216478Ssam printf(" subtype=%x\n", ip->il_subtype); 4226478Ssam } 4236478Ssam 42437278Sbostic /* ARGSUSED */ 42537278Sbostic impreset(ip, cc) 42637278Sbostic struct imp_leader *ip; 42737278Sbostic int cc; 4286478Ssam { 4296478Ssam printf("reset complete\n"); 4306478Ssam } 4316478Ssam 4326478Ssam char *retry[] = { 4336478Ssam "imp buffer wasn't available", 4346478Ssam "connection block unavailable" 4356478Ssam }; 4366478Ssam 43737278Sbostic /* ARGSUSED */ 43837278Sbostic impretry(ip, cc) 4396478Ssam register struct imp_leader *ip; 44037278Sbostic int cc; 4416478Ssam { 4426478Ssam printf("refused, try again: "); 4436478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK) 4446478Ssam printf("%s\n", retry[ip->il_subtype]); 4456478Ssam else 4466478Ssam printf("subtype=%x\n", ip->il_subtype); 4476478Ssam } 4486478Ssam 4496478Ssam char *notify[] = { 4509195Ssam "#0", 4519195Ssam "#1", 4526478Ssam "connection not available", 4536478Ssam "reassembly space not available at destination", 4546478Ssam "message number not available", 4556478Ssam "transaction block for message not available" 4566478Ssam }; 4576478Ssam 45837278Sbostic /* ARGSUSED */ 45937278Sbostic impnotify(ip, cc) 4606478Ssam register struct imp_leader *ip; 46137278Sbostic int cc; 4626478Ssam { 4636478Ssam printf("refused, will notify: "); 4646478Ssam if (ip->il_subtype <= 5) 4656478Ssam printf("%s\n", notify[ip->il_subtype]); 4666478Ssam else 4676478Ssam printf("subtype=%x\n", ip->il_subtype); 4686478Ssam } 4696478Ssam 47037278Sbostic /* ARGSUSED */ 47137278Sbostic imptrying(ip, cc) 47237278Sbostic struct imp_leader *ip; 47337278Sbostic int cc; 4746478Ssam { 4756478Ssam printf("refused, still trying\n"); 4766478Ssam } 4776478Ssam 47837278Sbostic /* ARGSUSED */ 47937278Sbostic impready(ip, cc) 48037278Sbostic struct imp_leader *ip; 48137278Sbostic int cc; 4826478Ssam { 4836478Ssam printf("ready\n"); 4846478Ssam } 4856478Ssam 48637278Sbostic /* ARGSUSED */ 48737278Sbostic impundef(ip, cc) 4886478Ssam register struct imp_leader *ip; 48937278Sbostic int cc; 4906478Ssam { 4916478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 4926478Ssam ip->il_network, ip->il_flags); 49337278Sbostic printf("%x, htype=%x,\n\t host=%d(x%x), imp=%u(x%x), link=", 49428904Skarels ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host, 49528904Skarels ip->il_imp, ip->il_imp); 4966478Ssam if (ip->il_link == IMPLINK_IP) 4976478Ssam printf("ip,"); 4986478Ssam else 49928904Skarels printf("%d (x%x),", ip->il_link, ip->il_link); 50028904Skarels printf(" subtype=%x", ip->il_subtype); 50137278Sbostic if (cc >= sizeof(struct imp_leader) && ip->il_length) 50237278Sbostic printf(" len=%u bytes", ntohs((u_short)ip->il_length) >> 3); 50328904Skarels printf(">\n"); 5046478Ssam } 505