121138Sdist /* 2*34772Sbostic * 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 6*34772Sbostic * provided that the above copyright notice and this paragraph are 7*34772Sbostic * duplicated in all such forms and that any documentation, 8*34772Sbostic * advertising materials, and other materials related to such 9*34772Sbostic * distribution and use acknowledge that the software was developed 10*34772Sbostic * by the University of California, Berkeley. The name of the 11*34772Sbostic * University may not be used to endorse or promote products derived 12*34772Sbostic * from this software without specific prior written permission. 13*34772Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34772Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34772Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621138Sdist */ 1721138Sdist 189197Ssam #ifndef lint 1921138Sdist char copyright[] = 20*34772Sbostic "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ 2121138Sdist All rights reserved.\n"; 22*34772Sbostic #endif /* not lint */ 236478Ssam 2421138Sdist #ifndef lint 25*34772Sbostic static char sccsid[] = "@(#)implog.c 5.10 (Berkeley) 06/18/88"; 26*34772Sbostic #endif /* not lint */ 2721138Sdist 286478Ssam #include <stdio.h> 296478Ssam #include <signal.h> 306478Ssam #include <sgtty.h> 319195Ssam 3213600Ssam #include <sys/time.h> 336478Ssam #include <sys/types.h> 3434037Skarels #include <sys/file.h> 356478Ssam #include <sys/stat.h> 366478Ssam #include <sys/socket.h> 379195Ssam 3833455Skarels #include <net/if.h> 3933455Skarels 409195Ssam #include <netinet/in.h> 4133455Skarels #define IMPMESSAGES 426478Ssam #define IMPLEADERS 439195Ssam #include <netimp/if_imp.h> 446478Ssam 456478Ssam #define min(a, b) ((a) < (b) ? (a) : (b)) 466478Ssam 476478Ssam u_char buf[1024]; 486478Ssam int showdata = 1; 496478Ssam int showcontents = 0; 5027727Skarels int rawheader = 0; 516478Ssam int follow = 0; 5234037Skarels int skip = 0; 536478Ssam int link = -1; 546478Ssam int host = -1; 556478Ssam int imp = -1; 566478Ssam int packettype = -1; 576478Ssam extern int errno; 586478Ssam int log; 596478Ssam char *logfile = "/usr/adm/implog"; 606478Ssam 616478Ssam /* 626478Ssam * Socket address, internet style, with 636478Ssam * unused space taken by timestamp and packet 646478Ssam * size. 656478Ssam */ 666478Ssam struct sockstamp { 676478Ssam short sin_family; 686478Ssam u_short sin_port; 696478Ssam struct in_addr sin_addr; 706478Ssam time_t sin_time; 716478Ssam int sin_cc; 726478Ssam }; 736478Ssam struct sockstamp from; 746478Ssam 756478Ssam main(argc, argv) 766478Ssam char *argv[]; 776478Ssam { 786478Ssam struct stat b; 7934037Skarels off_t size; 806478Ssam char *cp; 8122597Skarels int hostfrom, impfrom; 826478Ssam 836478Ssam argc--, argv++; 846478Ssam while (argc > 0 && argv[0][0] == '-') { 856478Ssam if (strcmp(*argv, "-D") == 0) { 866478Ssam showdata = 0; 876478Ssam argv++, argc--; 886478Ssam continue; 896478Ssam } 906478Ssam if (strcmp(*argv, "-f") == 0) { 916478Ssam follow++; 926478Ssam argv++, argc--; 936478Ssam continue; 946478Ssam } 9534037Skarels if (strcmp(*argv, "-F") == 0) { 9634037Skarels skip++; 9734037Skarels follow++; 9834037Skarels argv++, argc--; 9934037Skarels continue; 10034037Skarels } 1016478Ssam if (strcmp(*argv, "-c") == 0) { 1026478Ssam showcontents++; 1036478Ssam argv++, argc--; 1046478Ssam continue; 1056478Ssam } 10627727Skarels if (strcmp(*argv, "-r") == 0) { 10727727Skarels rawheader++; 10827727Skarels argv++, argc--; 10927727Skarels continue; 11027727Skarels } 1116478Ssam if (strcmp(*argv, "-l") == 0) { 1126478Ssam argc--, argv++; 1136478Ssam if (argc > 0) { 1146478Ssam link = atoi(*argv); 1156478Ssam argc--, argv++; 1166478Ssam } else 1176478Ssam link = IMPLINK_IP; 1186478Ssam continue; 1196478Ssam } 1206478Ssam if (strcmp(*argv, "-h") == 0) { 1216478Ssam argc--, argv++; 1226478Ssam if (argc < 1) { 1236478Ssam printf("-h: missing host #\n"); 1246478Ssam exit(2); 1256478Ssam } 1266478Ssam host = atoi(*argv); 1276478Ssam argv++, argc--; 1286478Ssam continue; 1296478Ssam } 1306478Ssam if (strcmp(*argv, "-i") == 0) { 1316478Ssam argc--, argv++; 1326478Ssam if (argc < 1) { 1336478Ssam printf("-i: missing imp #\n"); 1346478Ssam exit(2); 1356478Ssam } 1366478Ssam imp = atoi(*argv); 1376478Ssam argv++, argc--; 1386478Ssam continue; 1396478Ssam } 1406478Ssam if (strcmp(*argv, "-t") == 0) { 1416478Ssam argc--, argv++;; 1426478Ssam if (argc < 1) { 1436478Ssam printf("-t: missing packet type\n"); 1446478Ssam exit(2); 1456478Ssam } 1466478Ssam packettype = atoi(*argv); 1476478Ssam argv++, argc--;; 1486478Ssam continue; 1496478Ssam } 15034037Skarels printf("usage: implog [ -D ] [ -c ] [ -f ] [ -F ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n"); 1516478Ssam exit(2); 1526478Ssam } 1536478Ssam if (argc > 0) 1546478Ssam logfile = argv[0]; 1556478Ssam log = open(logfile, 0); 1566478Ssam if (log < 0) { 1576478Ssam perror(logfile); 1586478Ssam exit(1); 1596478Ssam } 1606478Ssam fstat(log, &b); 1616478Ssam size = b.st_size; 16234037Skarels if (skip) 16334037Skarels (void) lseek(log, size, L_SET); 1646478Ssam again: 1656478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 1666478Ssam if (from.sin_family == 0) { 1676478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time)); 1686478Ssam continue; 1696478Ssam } 17022597Skarels if (host >= 0) { 17122597Skarels long addr = ntohs(from.sin_addr.s_addr); 17222597Skarels 17322597Skarels if (IN_CLASSA(addr)) { 17422597Skarels hostfrom = ((addr>>16) & 0xFF); 17522597Skarels impfrom = addr & 0xFF; 17622597Skarels } else if (IN_CLASSB(addr)) { 17722597Skarels hostfrom = ((addr>>8) & 0xFF); 17822597Skarels impfrom = addr & 0xFF; 17922597Skarels } else { 18022597Skarels hostfrom = ((addr>>4) & 0xF); 18122597Skarels impfrom = addr & 0xF; 18222597Skarels } 18322597Skarels } 18422597Skarels if (host >= 0 && hostfrom != host) { 1856478Ssam lseek(log, from.sin_cc, 1); 1866478Ssam continue; 1876478Ssam } 18822597Skarels if (imp >= 0 && impfrom != imp) { 18922597Skarels lseek(log, from.sin_cc, 1); 19022597Skarels continue; 1916478Ssam } 1926478Ssam process(log, &from); 1936478Ssam } 1946478Ssam while (follow) { 1956478Ssam fflush(stdout); 1966478Ssam sleep(5); 1976478Ssam fstat(log, &b); 1986478Ssam if (b.st_size > size) { 1996478Ssam size = b.st_size; 2006478Ssam goto again; 2016478Ssam } 2026478Ssam } 2036478Ssam } 2046478Ssam 2056478Ssam int impdata(), impbadleader(), impdown(), impnoop(); 2066478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 2076478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 2086478Ssam int impready(), impundef(); 2096478Ssam 2106478Ssam struct messages { 2116478Ssam u_char m_type; /* type of message */ 2126478Ssam int (*m_func)(); /* routine to process message */ 2136478Ssam } mtypes[] = { 2146478Ssam { IMPTYPE_DATA, impdata }, 2156478Ssam { IMPTYPE_BADLEADER, impbadleader }, 2166478Ssam { IMPTYPE_DOWN, impdown }, 2176478Ssam { IMPTYPE_NOOP, impnoop }, 2186478Ssam { IMPTYPE_RFNM, imprfnm }, 2196478Ssam { IMPTYPE_INCOMPLETE, impincomplete }, 2206478Ssam { IMPTYPE_HOSTDEAD, imphostdead }, 2216478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach }, 2226478Ssam { IMPTYPE_BADDATA, impbaddata }, 2236478Ssam { IMPTYPE_RESET, impreset }, 2246478Ssam { IMPTYPE_RETRY, impretry }, 2256478Ssam { IMPTYPE_NOTIFY, impnotify }, 2266478Ssam { IMPTYPE_TRYING, imptrying }, 2276478Ssam { IMPTYPE_READY, impready }, 2286478Ssam { -1, impundef } 2296478Ssam }; 2306478Ssam 2316478Ssam /* 2326478Ssam * Print a packet. 2336478Ssam */ 2346478Ssam process(l, f) 2356478Ssam int l; 2366478Ssam struct sockstamp *f; 2376478Ssam { 2386478Ssam register struct messages *mp; 2396478Ssam struct imp_leader *ip; 24027727Skarels int (*fn)(); 2416478Ssam 2426478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 2436478Ssam perror("read"); 2446478Ssam return; 2456478Ssam } 2466478Ssam ip = (struct imp_leader *)buf; 24728904Skarels ip->il_imp = ntohs(ip->il_imp); 24827727Skarels if (ip->il_format != IMP_NFF) 24927727Skarels fn = impundef; 25027727Skarels else { 25133085Sbostic for (mp = mtypes; mp->m_type != (u_char)-1; mp++) 25227727Skarels if (mp->m_type == ip->il_mtype) 25327727Skarels break; 25427727Skarels fn = mp->m_func; 25527727Skarels } 25627727Skarels if (ip->il_mtype == IMPTYPE_DATA) { 2576478Ssam if (link >= 0 && ip->il_link != link) 2586478Ssam return; 2596478Ssam if (!showdata) 2606478Ssam return; 2616478Ssam } 26227727Skarels if (packettype >= 0 && ip->il_mtype != packettype) 2636478Ssam return; 2646478Ssam printf("%.24s: ", ctime(&f->sin_time)); 26528904Skarels if (f->sin_cc < sizeof(struct control_leader)) 26628904Skarels printf("(truncated header, %d bytes): ", f->sin_cc); 26727727Skarels (*fn)(ip, f->sin_cc); 26828904Skarels if (rawheader && fn != impundef) { 26928904Skarels putchar('\t'); 27027727Skarels impundef(ip, f->sin_cc); 27128904Skarels } 2726478Ssam } 2736478Ssam 2746478Ssam impdata(ip, cc) 2756478Ssam register struct imp_leader *ip; 2766478Ssam { 27727727Skarels printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp); 2786478Ssam if (ip->il_link == IMPLINK_IP) 2796478Ssam printf("ip,"); 2806478Ssam else 2816478Ssam printf("%d,", ip->il_link); 2829195Ssam printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 2836478Ssam if (showcontents) { 2846478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip); 2856478Ssam register int i; 2866478Ssam 2876478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 2886478Ssam cc = min(i, cc); 2896478Ssam printf("data: (%d bytes)", cc); 2906478Ssam for (i = 0; i < cc; i++, cp++) { 2916478Ssam if (i % 25 == 0) 2926478Ssam printf("\n"); 2936478Ssam printf("%02x ", *cp); 2946478Ssam } 2956478Ssam putchar('\n'); 2966478Ssam } 2976478Ssam } 2986478Ssam 2996478Ssam char *badleader[] = { 3006478Ssam "error flip-flop set", 3016478Ssam "message < 80 bits", 3026478Ssam "illegal type field", 3036478Ssam "opposite leader type" 3046478Ssam }; 3056478Ssam 3066478Ssam impbadleader(ip) 3076478Ssam register struct imp_leader *ip; 3086478Ssam { 3096478Ssam printf("bad leader: "); 3106478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE) 3116478Ssam printf("%x\n", ip->il_subtype); 3126478Ssam else 3136478Ssam printf("%s\n", badleader[ip->il_subtype]); 3146478Ssam } 3156478Ssam 3166478Ssam impdown(ip) 3176478Ssam register struct imp_leader *ip; 3186478Ssam { 3196478Ssam int tdown, tbackup; 3206478Ssam 32133455Skarels printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]); 32233455Skarels tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) * 32333455Skarels IMPDOWN_WHENUNIT; 32433455Skarels if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING) 3256478Ssam printf(" in %d minutes", tdown); 32633455Skarels tbackup = ip->il_subtype * IMPDOWN_WHENUNIT; 3276478Ssam printf(": back up "); 3286478Ssam if (tbackup) 3296478Ssam printf("%d minutes\n", tbackup); 3306478Ssam else 3316478Ssam printf("immediately\n"); 3326478Ssam } 3336478Ssam 3346478Ssam impnoop(ip) 3356478Ssam register struct imp_leader *ip; 3366478Ssam { 3379195Ssam printf("noop: host %d, imp %d\n", ip->il_host, 33827727Skarels (u_short)ip->il_imp); 3396478Ssam } 3406478Ssam 3416478Ssam imprfnm(ip) 3426478Ssam register struct imp_leader *ip; 3436478Ssam { 3446478Ssam printf("rfnm: htype=%x, source=%d/%d, link=", 3456478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3466478Ssam if (ip->il_link == IMPLINK_IP) 3476478Ssam printf("ip,"); 3486478Ssam else 34927727Skarels printf("%d,", ip->il_link); 3506478Ssam printf(" subtype=%x\n", ip->il_subtype); 3516478Ssam } 3526478Ssam 3536478Ssam char *hostdead[] = { 3549195Ssam "#0", 3556478Ssam "ready-line negated", 3566478Ssam "tardy receiving messages", 3576478Ssam "ncc doesn't know host", 3586478Ssam "imp software won't allow messages", 3596478Ssam "host down for scheduled pm", 3606478Ssam "host down for hardware work", 3616478Ssam "host down for software work", 3626478Ssam "host down for emergency restart", 3636478Ssam "host down because of power outage", 3646478Ssam "host stopped at a breakpoint", 3656478Ssam "host down due to hardware failure", 3666478Ssam "host not scheduled to be up", 3679195Ssam "#13", 3689195Ssam "#14", 3696478Ssam "host in the process of coming up" 3706478Ssam }; 3716478Ssam 3726478Ssam imphostdead(ip) 3736478Ssam register struct imp_leader *ip; 3746478Ssam { 37527727Skarels printf("host %d/%d dead: ", ip->il_host, ip->il_imp); 3766478Ssam if (ip->il_link & IMP_DMASK) 37733455Skarels printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]); 3786478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP) 3796478Ssam printf("%s\n", hostdead[ip->il_subtype]); 3806478Ssam else 3816478Ssam printf("subtype=%x\n", ip->il_subtype); 3826478Ssam } 3836478Ssam 3846478Ssam char *hostunreach[] = { 3856478Ssam "destination imp can't be reached", 3866478Ssam "destination host isn't up", 3876478Ssam "host doesn't support long leader", 3886478Ssam "communication is prohibited" 3896478Ssam }; 3906478Ssam 3916478Ssam imphostunreach(ip) 3926478Ssam register struct imp_leader *ip; 3936478Ssam { 39427727Skarels printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp); 3956478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED) 3966478Ssam printf("%s\n", hostunreach[ip->il_subtype]); 3976478Ssam else 3986478Ssam printf("subtype=%x\n", ip->il_subtype); 3996478Ssam } 4006478Ssam 4016478Ssam impbaddata(ip) 4026478Ssam register struct imp_leader *ip; 4036478Ssam { 4046478Ssam printf("error in data: htype=%x, source=%d/%d, link=", 4056478Ssam ip->il_htype, ip->il_host, ip->il_imp); 4066478Ssam if (ip->il_link == IMPLINK_IP) 4076478Ssam printf("ip, "); 4086478Ssam else 40927727Skarels printf("%d, ", ip->il_link); 4106478Ssam printf("subtype=%x\n", ip->il_subtype); 4116478Ssam } 4126478Ssam 4136478Ssam char *incomplete[] = { 4146478Ssam "host didn't take data fast enough", 4156478Ssam "message was too long", 4166478Ssam "message transmission time > 15 seconds", 4176478Ssam "imp/circuit failure", 4186478Ssam "no resources within 15 seconds", 4196478Ssam "source imp i/o failure during receipt" 4206478Ssam }; 4216478Ssam 4226478Ssam impincomplete(ip) 4236478Ssam register struct imp_leader *ip; 4246478Ssam { 4256478Ssam printf("incomplete: htype=%x, source=%d/%d, link=", 4266478Ssam ip->il_htype, ip->il_host, ip->il_imp); 4276478Ssam if (ip->il_link == IMPLINK_IP) 4286478Ssam printf("ip,"); 4296478Ssam else 43027727Skarels printf("%d,", ip->il_link); 4316478Ssam if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 4326478Ssam printf(" %s\n", incomplete[ip->il_subtype]); 4336478Ssam else 4346478Ssam printf(" subtype=%x\n", ip->il_subtype); 4356478Ssam } 4366478Ssam 4376478Ssam impreset(ip) 4386478Ssam register struct imp_leader *ip; 4396478Ssam { 4406478Ssam printf("reset complete\n"); 4416478Ssam } 4426478Ssam 4436478Ssam char *retry[] = { 4446478Ssam "imp buffer wasn't available", 4456478Ssam "connection block unavailable" 4466478Ssam }; 4476478Ssam 4486478Ssam impretry(ip) 4496478Ssam register struct imp_leader *ip; 4506478Ssam { 4516478Ssam printf("refused, try again: "); 4526478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK) 4536478Ssam printf("%s\n", retry[ip->il_subtype]); 4546478Ssam else 4556478Ssam printf("subtype=%x\n", ip->il_subtype); 4566478Ssam } 4576478Ssam 4586478Ssam char *notify[] = { 4599195Ssam "#0", 4609195Ssam "#1", 4616478Ssam "connection not available", 4626478Ssam "reassembly space not available at destination", 4636478Ssam "message number not available", 4646478Ssam "transaction block for message not available" 4656478Ssam }; 4666478Ssam 4676478Ssam impnotify(ip) 4686478Ssam register struct imp_leader *ip; 4696478Ssam { 4706478Ssam printf("refused, will notify: "); 4716478Ssam if (ip->il_subtype <= 5) 4726478Ssam printf("%s\n", notify[ip->il_subtype]); 4736478Ssam else 4746478Ssam printf("subtype=%x\n", ip->il_subtype); 4756478Ssam } 4766478Ssam 4776478Ssam imptrying(ip) 4786478Ssam register struct imp_leader *ip; 4796478Ssam { 4806478Ssam printf("refused, still trying\n"); 4816478Ssam } 4826478Ssam 4836478Ssam impready(ip) 4846478Ssam register struct imp_leader *ip; 4856478Ssam { 4866478Ssam printf("ready\n"); 4876478Ssam } 4886478Ssam 48928904Skarels impundef(ip, len) 4906478Ssam register struct imp_leader *ip; 4916478Ssam { 4926478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 4936478Ssam ip->il_network, ip->il_flags); 49428904Skarels printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=", 49528904Skarels ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host, 49628904Skarels ip->il_imp, ip->il_imp); 4976478Ssam if (ip->il_link == IMPLINK_IP) 4986478Ssam printf("ip,"); 4996478Ssam else 50028904Skarels printf("%d (x%x),", ip->il_link, ip->il_link); 50128904Skarels printf(" subtype=%x", ip->il_subtype); 50228904Skarels if (len >= sizeof(struct imp_leader) && ip->il_length) 50328904Skarels printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3); 50428904Skarels printf(">\n"); 5056478Ssam } 506