121138Sdist /* 221140Sdist * Copyright (c) 1983 Regents of the University of California. 321138Sdist * All rights reserved. The Berkeley software License Agreement 421138Sdist * specifies the terms and conditions for redistribution. 521138Sdist */ 621138Sdist 79197Ssam #ifndef lint 821138Sdist char copyright[] = 921140Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1021138Sdist All rights reserved.\n"; 1121138Sdist #endif not lint 126478Ssam 1321138Sdist #ifndef lint 14*28904Skarels static char sccsid[] = "@(#)implog.c 5.5 (Berkeley) 05/30/86"; 1521138Sdist #endif not lint 1621138Sdist 176478Ssam #include <stdio.h> 186478Ssam #include <signal.h> 196478Ssam #include <sgtty.h> 209195Ssam 2113600Ssam #include <sys/time.h> 226478Ssam #include <sys/types.h> 236478Ssam #include <sys/stat.h> 246478Ssam #include <sys/socket.h> 259195Ssam 269195Ssam #include <netinet/in.h> 276478Ssam #define IMPLEADERS 289195Ssam #include <netimp/if_imp.h> 296478Ssam 306478Ssam #define min(a, b) ((a) < (b) ? (a) : (b)) 316478Ssam 326478Ssam u_char buf[1024]; 336478Ssam int showdata = 1; 346478Ssam int showcontents = 0; 3527727Skarels int rawheader = 0; 366478Ssam int follow = 0; 376478Ssam int link = -1; 386478Ssam int host = -1; 396478Ssam int imp = -1; 406478Ssam int packettype = -1; 416478Ssam extern int errno; 426478Ssam int log; 436478Ssam char *logfile = "/usr/adm/implog"; 446478Ssam 456478Ssam /* 466478Ssam * Socket address, internet style, with 476478Ssam * unused space taken by timestamp and packet 486478Ssam * size. 496478Ssam */ 506478Ssam struct sockstamp { 516478Ssam short sin_family; 526478Ssam u_short sin_port; 536478Ssam struct in_addr sin_addr; 546478Ssam time_t sin_time; 556478Ssam int sin_cc; 566478Ssam }; 576478Ssam struct sockstamp from; 586478Ssam 596478Ssam main(argc, argv) 606478Ssam char *argv[]; 616478Ssam { 626478Ssam struct stat b; 636478Ssam int size; 646478Ssam char *cp; 6522597Skarels int hostfrom, impfrom; 666478Ssam 676478Ssam argc--, argv++; 686478Ssam while (argc > 0 && argv[0][0] == '-') { 696478Ssam if (strcmp(*argv, "-D") == 0) { 706478Ssam showdata = 0; 716478Ssam argv++, argc--; 726478Ssam continue; 736478Ssam } 746478Ssam if (strcmp(*argv, "-f") == 0) { 756478Ssam follow++; 766478Ssam argv++, argc--; 776478Ssam continue; 786478Ssam } 796478Ssam if (strcmp(*argv, "-c") == 0) { 806478Ssam showcontents++; 816478Ssam argv++, argc--; 826478Ssam continue; 836478Ssam } 8427727Skarels if (strcmp(*argv, "-r") == 0) { 8527727Skarels rawheader++; 8627727Skarels argv++, argc--; 8727727Skarels continue; 8827727Skarels } 896478Ssam if (strcmp(*argv, "-l") == 0) { 906478Ssam argc--, argv++; 916478Ssam if (argc > 0) { 926478Ssam link = atoi(*argv); 936478Ssam argc--, argv++; 946478Ssam } else 956478Ssam link = IMPLINK_IP; 966478Ssam continue; 976478Ssam } 986478Ssam if (strcmp(*argv, "-h") == 0) { 996478Ssam argc--, argv++; 1006478Ssam if (argc < 1) { 1016478Ssam printf("-h: missing host #\n"); 1026478Ssam exit(2); 1036478Ssam } 1046478Ssam host = atoi(*argv); 1056478Ssam argv++, argc--; 1066478Ssam continue; 1076478Ssam } 1086478Ssam if (strcmp(*argv, "-i") == 0) { 1096478Ssam argc--, argv++; 1106478Ssam if (argc < 1) { 1116478Ssam printf("-i: missing imp #\n"); 1126478Ssam exit(2); 1136478Ssam } 1146478Ssam imp = atoi(*argv); 1156478Ssam argv++, argc--; 1166478Ssam continue; 1176478Ssam } 1186478Ssam if (strcmp(*argv, "-t") == 0) { 1196478Ssam argc--, argv++;; 1206478Ssam if (argc < 1) { 1216478Ssam printf("-t: missing packet type\n"); 1226478Ssam exit(2); 1236478Ssam } 1246478Ssam packettype = atoi(*argv); 1256478Ssam argv++, argc--;; 1266478Ssam continue; 1276478Ssam } 12827727Skarels printf("usage: implog [ -D ] [ -c ] [ -f ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n"); 1296478Ssam exit(2); 1306478Ssam } 1316478Ssam if (argc > 0) 1326478Ssam logfile = argv[0]; 1336478Ssam log = open(logfile, 0); 1346478Ssam if (log < 0) { 1356478Ssam perror(logfile); 1366478Ssam exit(1); 1376478Ssam } 1386478Ssam fstat(log, &b); 1396478Ssam size = b.st_size; 1406478Ssam again: 1416478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 1426478Ssam if (from.sin_family == 0) { 1436478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time)); 1446478Ssam continue; 1456478Ssam } 14622597Skarels if (host >= 0) { 14722597Skarels long addr = ntohs(from.sin_addr.s_addr); 14822597Skarels 14922597Skarels if (IN_CLASSA(addr)) { 15022597Skarels hostfrom = ((addr>>16) & 0xFF); 15122597Skarels impfrom = addr & 0xFF; 15222597Skarels } else if (IN_CLASSB(addr)) { 15322597Skarels hostfrom = ((addr>>8) & 0xFF); 15422597Skarels impfrom = addr & 0xFF; 15522597Skarels } else { 15622597Skarels hostfrom = ((addr>>4) & 0xF); 15722597Skarels impfrom = addr & 0xF; 15822597Skarels } 15922597Skarels } 16022597Skarels if (host >= 0 && hostfrom != host) { 1616478Ssam lseek(log, from.sin_cc, 1); 1626478Ssam continue; 1636478Ssam } 16422597Skarels if (imp >= 0 && impfrom != imp) { 16522597Skarels lseek(log, from.sin_cc, 1); 16622597Skarels continue; 1676478Ssam } 1686478Ssam process(log, &from); 1696478Ssam } 1706478Ssam while (follow) { 1716478Ssam fflush(stdout); 1726478Ssam sleep(5); 1736478Ssam fstat(log, &b); 1746478Ssam if (b.st_size > size) { 1756478Ssam size = b.st_size; 1766478Ssam goto again; 1776478Ssam } 1786478Ssam } 1796478Ssam } 1806478Ssam 1816478Ssam int impdata(), impbadleader(), impdown(), impnoop(); 1826478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 1836478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 1846478Ssam int impready(), impundef(); 1856478Ssam 1866478Ssam struct messages { 1876478Ssam u_char m_type; /* type of message */ 1886478Ssam int (*m_func)(); /* routine to process message */ 1896478Ssam } mtypes[] = { 1906478Ssam { IMPTYPE_DATA, impdata }, 1916478Ssam { IMPTYPE_BADLEADER, impbadleader }, 1926478Ssam { IMPTYPE_DOWN, impdown }, 1936478Ssam { IMPTYPE_NOOP, impnoop }, 1946478Ssam { IMPTYPE_RFNM, imprfnm }, 1956478Ssam { IMPTYPE_INCOMPLETE, impincomplete }, 1966478Ssam { IMPTYPE_HOSTDEAD, imphostdead }, 1976478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach }, 1986478Ssam { IMPTYPE_BADDATA, impbaddata }, 1996478Ssam { IMPTYPE_RESET, impreset }, 2006478Ssam { IMPTYPE_RETRY, impretry }, 2016478Ssam { IMPTYPE_NOTIFY, impnotify }, 2026478Ssam { IMPTYPE_TRYING, imptrying }, 2036478Ssam { IMPTYPE_READY, impready }, 2046478Ssam { -1, impundef } 2056478Ssam }; 2066478Ssam 2076478Ssam /* 2086478Ssam * Print a packet. 2096478Ssam */ 2106478Ssam process(l, f) 2116478Ssam int l; 2126478Ssam struct sockstamp *f; 2136478Ssam { 2146478Ssam register struct messages *mp; 2156478Ssam struct imp_leader *ip; 21627727Skarels int (*fn)(); 2176478Ssam 2186478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 2196478Ssam perror("read"); 2206478Ssam return; 2216478Ssam } 2226478Ssam ip = (struct imp_leader *)buf; 223*28904Skarels ip->il_imp = ntohs(ip->il_imp); 22427727Skarels if (ip->il_format != IMP_NFF) 22527727Skarels fn = impundef; 22627727Skarels else { 22727727Skarels for (mp = mtypes; mp->m_type != -1; mp++) 22827727Skarels if (mp->m_type == ip->il_mtype) 22927727Skarels break; 23027727Skarels fn = mp->m_func; 23127727Skarels } 23227727Skarels if (ip->il_mtype == IMPTYPE_DATA) { 2336478Ssam if (link >= 0 && ip->il_link != link) 2346478Ssam return; 2356478Ssam if (!showdata) 2366478Ssam return; 2376478Ssam } 23827727Skarels if (packettype >= 0 && ip->il_mtype != packettype) 2396478Ssam return; 2406478Ssam printf("%.24s: ", ctime(&f->sin_time)); 241*28904Skarels if (f->sin_cc < sizeof(struct control_leader)) 242*28904Skarels printf("(truncated header, %d bytes): ", f->sin_cc); 24327727Skarels (*fn)(ip, f->sin_cc); 244*28904Skarels if (rawheader && fn != impundef) { 245*28904Skarels putchar('\t'); 24627727Skarels impundef(ip, f->sin_cc); 247*28904Skarels } 2486478Ssam } 2496478Ssam 2506478Ssam impdata(ip, cc) 2516478Ssam register struct imp_leader *ip; 2526478Ssam { 25327727Skarels printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp); 2546478Ssam if (ip->il_link == IMPLINK_IP) 2556478Ssam printf("ip,"); 2566478Ssam else 2576478Ssam printf("%d,", ip->il_link); 2589195Ssam printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 2596478Ssam if (showcontents) { 2606478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip); 2616478Ssam register int i; 2626478Ssam 2636478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 2646478Ssam cc = min(i, cc); 2656478Ssam printf("data: (%d bytes)", cc); 2666478Ssam for (i = 0; i < cc; i++, cp++) { 2676478Ssam if (i % 25 == 0) 2686478Ssam printf("\n"); 2696478Ssam printf("%02x ", *cp); 2706478Ssam } 2716478Ssam putchar('\n'); 2726478Ssam } 2736478Ssam } 2746478Ssam 2756478Ssam char *badleader[] = { 2766478Ssam "error flip-flop set", 2776478Ssam "message < 80 bits", 2786478Ssam "illegal type field", 2796478Ssam "opposite leader type" 2806478Ssam }; 2816478Ssam 2826478Ssam impbadleader(ip) 2836478Ssam register struct imp_leader *ip; 2846478Ssam { 2856478Ssam printf("bad leader: "); 2866478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE) 2876478Ssam printf("%x\n", ip->il_subtype); 2886478Ssam else 2896478Ssam printf("%s\n", badleader[ip->il_subtype]); 2906478Ssam } 2916478Ssam 2926478Ssam char *down[] = { 2936478Ssam "in 30 secs", 2946478Ssam "for hardware pm", 2956478Ssam "for software reload", 2966478Ssam "for emergency restart" 2976478Ssam }; 2986478Ssam 2996478Ssam impdown(ip) 3006478Ssam register struct imp_leader *ip; 3016478Ssam { 3026478Ssam int tdown, tbackup; 3036478Ssam 3046478Ssam printf("imp going down %s", down[ip->il_link & IMP_DMASK]); 3056478Ssam tdown = ((ip->il_link >> 2) & 0xf) * 5; 3066478Ssam if (ip->il_link & IMP_DMASK) 3076478Ssam printf(" in %d minutes", tdown); 3086478Ssam tbackup = ip->il_subtype * 5; 3096478Ssam printf(": back up "); 3106478Ssam if (tbackup) 3116478Ssam printf("%d minutes\n", tbackup); 3126478Ssam else 3136478Ssam printf("immediately\n"); 3146478Ssam } 3156478Ssam 3166478Ssam impnoop(ip) 3176478Ssam register struct imp_leader *ip; 3186478Ssam { 3199195Ssam printf("noop: host %d, imp %d\n", ip->il_host, 32027727Skarels (u_short)ip->il_imp); 3216478Ssam } 3226478Ssam 3236478Ssam imprfnm(ip) 3246478Ssam register struct imp_leader *ip; 3256478Ssam { 3266478Ssam printf("rfnm: htype=%x, source=%d/%d, link=", 3276478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3286478Ssam if (ip->il_link == IMPLINK_IP) 3296478Ssam printf("ip,"); 3306478Ssam else 33127727Skarels printf("%d,", ip->il_link); 3326478Ssam printf(" subtype=%x\n", ip->il_subtype); 3336478Ssam } 3346478Ssam 3356478Ssam char *hostdead[] = { 3369195Ssam "#0", 3376478Ssam "ready-line negated", 3386478Ssam "tardy receiving messages", 3396478Ssam "ncc doesn't know host", 3406478Ssam "imp software won't allow messages", 3416478Ssam "host down for scheduled pm", 3426478Ssam "host down for hardware work", 3436478Ssam "host down for software work", 3446478Ssam "host down for emergency restart", 3456478Ssam "host down because of power outage", 3466478Ssam "host stopped at a breakpoint", 3476478Ssam "host down due to hardware failure", 3486478Ssam "host not scheduled to be up", 3499195Ssam "#13", 3509195Ssam "#14", 3516478Ssam "host in the process of coming up" 3526478Ssam }; 3536478Ssam 3546478Ssam imphostdead(ip) 3556478Ssam register struct imp_leader *ip; 3566478Ssam { 35727727Skarels printf("host %d/%d dead: ", ip->il_host, ip->il_imp); 3586478Ssam if (ip->il_link & IMP_DMASK) 3596478Ssam printf("down %s, ", down[ip->il_link & IMP_DMASK]); 3606478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP) 3616478Ssam printf("%s\n", hostdead[ip->il_subtype]); 3626478Ssam else 3636478Ssam printf("subtype=%x\n", ip->il_subtype); 3646478Ssam } 3656478Ssam 3666478Ssam char *hostunreach[] = { 3676478Ssam "destination imp can't be reached", 3686478Ssam "destination host isn't up", 3696478Ssam "host doesn't support long leader", 3706478Ssam "communication is prohibited" 3716478Ssam }; 3726478Ssam 3736478Ssam imphostunreach(ip) 3746478Ssam register struct imp_leader *ip; 3756478Ssam { 37627727Skarels printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp); 3776478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED) 3786478Ssam printf("%s\n", hostunreach[ip->il_subtype]); 3796478Ssam else 3806478Ssam printf("subtype=%x\n", ip->il_subtype); 3816478Ssam } 3826478Ssam 3836478Ssam impbaddata(ip) 3846478Ssam register struct imp_leader *ip; 3856478Ssam { 3866478Ssam printf("error in data: htype=%x, source=%d/%d, link=", 3876478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3886478Ssam if (ip->il_link == IMPLINK_IP) 3896478Ssam printf("ip, "); 3906478Ssam else 39127727Skarels printf("%d, ", ip->il_link); 3926478Ssam printf("subtype=%x\n", ip->il_subtype); 3936478Ssam } 3946478Ssam 3956478Ssam char *incomplete[] = { 3966478Ssam "host didn't take data fast enough", 3976478Ssam "message was too long", 3986478Ssam "message transmission time > 15 seconds", 3996478Ssam "imp/circuit failure", 4006478Ssam "no resources within 15 seconds", 4016478Ssam "source imp i/o failure during receipt" 4026478Ssam }; 4036478Ssam 4046478Ssam impincomplete(ip) 4056478Ssam register struct imp_leader *ip; 4066478Ssam { 4076478Ssam printf("incomplete: htype=%x, source=%d/%d, link=", 4086478Ssam ip->il_htype, ip->il_host, ip->il_imp); 4096478Ssam if (ip->il_link == IMPLINK_IP) 4106478Ssam printf("ip,"); 4116478Ssam else 41227727Skarels printf("%d,", ip->il_link); 4136478Ssam if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 4146478Ssam printf(" %s\n", incomplete[ip->il_subtype]); 4156478Ssam else 4166478Ssam printf(" subtype=%x\n", ip->il_subtype); 4176478Ssam } 4186478Ssam 4196478Ssam impreset(ip) 4206478Ssam register struct imp_leader *ip; 4216478Ssam { 4226478Ssam printf("reset complete\n"); 4236478Ssam } 4246478Ssam 4256478Ssam char *retry[] = { 4266478Ssam "imp buffer wasn't available", 4276478Ssam "connection block unavailable" 4286478Ssam }; 4296478Ssam 4306478Ssam impretry(ip) 4316478Ssam register struct imp_leader *ip; 4326478Ssam { 4336478Ssam printf("refused, try again: "); 4346478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK) 4356478Ssam printf("%s\n", retry[ip->il_subtype]); 4366478Ssam else 4376478Ssam printf("subtype=%x\n", ip->il_subtype); 4386478Ssam } 4396478Ssam 4406478Ssam char *notify[] = { 4419195Ssam "#0", 4429195Ssam "#1", 4436478Ssam "connection not available", 4446478Ssam "reassembly space not available at destination", 4456478Ssam "message number not available", 4466478Ssam "transaction block for message not available" 4476478Ssam }; 4486478Ssam 4496478Ssam impnotify(ip) 4506478Ssam register struct imp_leader *ip; 4516478Ssam { 4526478Ssam printf("refused, will notify: "); 4536478Ssam if (ip->il_subtype <= 5) 4546478Ssam printf("%s\n", notify[ip->il_subtype]); 4556478Ssam else 4566478Ssam printf("subtype=%x\n", ip->il_subtype); 4576478Ssam } 4586478Ssam 4596478Ssam imptrying(ip) 4606478Ssam register struct imp_leader *ip; 4616478Ssam { 4626478Ssam printf("refused, still trying\n"); 4636478Ssam } 4646478Ssam 4656478Ssam impready(ip) 4666478Ssam register struct imp_leader *ip; 4676478Ssam { 4686478Ssam printf("ready\n"); 4696478Ssam } 4706478Ssam 471*28904Skarels impundef(ip, len) 4726478Ssam register struct imp_leader *ip; 4736478Ssam { 4746478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 4756478Ssam ip->il_network, ip->il_flags); 476*28904Skarels printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=", 477*28904Skarels ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host, 478*28904Skarels ip->il_imp, ip->il_imp); 4796478Ssam if (ip->il_link == IMPLINK_IP) 4806478Ssam printf("ip,"); 4816478Ssam else 482*28904Skarels printf("%d (x%x),", ip->il_link, ip->il_link); 483*28904Skarels printf(" subtype=%x", ip->il_subtype); 484*28904Skarels if (len >= sizeof(struct imp_leader) && ip->il_length) 485*28904Skarels printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3); 486*28904Skarels printf(">\n"); 4876478Ssam } 488