19197Ssam #ifndef lint 2*13600Ssam static char sccsid[] = "@(#)implog.c 4.4 (Berkeley) 07/01/83"; 39197Ssam #endif 46478Ssam 56478Ssam #include <stdio.h> 66478Ssam #include <signal.h> 76478Ssam #include <sgtty.h> 89195Ssam 9*13600Ssam #include <sys/time.h> 106478Ssam #include <sys/types.h> 116478Ssam #include <sys/stat.h> 126478Ssam #include <sys/socket.h> 139195Ssam 149195Ssam #include <netinet/in.h> 156478Ssam #define IMPLEADERS 169195Ssam #include <netimp/if_imp.h> 176478Ssam 186478Ssam #define min(a, b) ((a) < (b) ? (a) : (b)) 196478Ssam 206478Ssam u_char buf[1024]; 216478Ssam int showdata = 1; 226478Ssam int showcontents = 0; 236478Ssam int follow = 0; 246478Ssam int link = -1; 256478Ssam int host = -1; 266478Ssam int imp = -1; 276478Ssam int packettype = -1; 286478Ssam extern int errno; 296478Ssam int log; 306478Ssam char *logfile = "/usr/adm/implog"; 316478Ssam 326478Ssam /* 336478Ssam * Socket address, internet style, with 346478Ssam * unused space taken by timestamp and packet 356478Ssam * size. 366478Ssam */ 376478Ssam struct sockstamp { 386478Ssam short sin_family; 396478Ssam u_short sin_port; 406478Ssam struct in_addr sin_addr; 416478Ssam time_t sin_time; 426478Ssam int sin_cc; 436478Ssam }; 446478Ssam struct sockstamp from; 456478Ssam 466478Ssam main(argc, argv) 476478Ssam char *argv[]; 486478Ssam { 496478Ssam struct stat b; 506478Ssam int size; 516478Ssam char *cp; 526478Ssam 536478Ssam argc--, argv++; 546478Ssam while (argc > 0 && argv[0][0] == '-') { 556478Ssam if (strcmp(*argv, "-D") == 0) { 566478Ssam showdata = 0; 576478Ssam argv++, argc--; 586478Ssam continue; 596478Ssam } 606478Ssam if (strcmp(*argv, "-f") == 0) { 616478Ssam follow++; 626478Ssam argv++, argc--; 636478Ssam continue; 646478Ssam } 656478Ssam if (strcmp(*argv, "-c") == 0) { 666478Ssam showcontents++; 676478Ssam argv++, argc--; 686478Ssam continue; 696478Ssam } 706478Ssam if (strcmp(*argv, "-l") == 0) { 716478Ssam argc--, argv++; 726478Ssam if (argc > 0) { 736478Ssam link = atoi(*argv); 746478Ssam argc--, argv++; 756478Ssam } else 766478Ssam link = IMPLINK_IP; 776478Ssam continue; 786478Ssam } 796478Ssam if (strcmp(*argv, "-h") == 0) { 806478Ssam argc--, argv++; 816478Ssam if (argc < 1) { 826478Ssam printf("-h: missing host #\n"); 836478Ssam exit(2); 846478Ssam } 856478Ssam host = atoi(*argv); 866478Ssam argv++, argc--; 876478Ssam continue; 886478Ssam } 896478Ssam if (strcmp(*argv, "-i") == 0) { 906478Ssam argc--, argv++; 916478Ssam if (argc < 1) { 926478Ssam printf("-i: missing imp #\n"); 936478Ssam exit(2); 946478Ssam } 956478Ssam imp = atoi(*argv); 966478Ssam argv++, argc--; 976478Ssam continue; 986478Ssam } 996478Ssam if (strcmp(*argv, "-t") == 0) { 1006478Ssam argc--, argv++;; 1016478Ssam if (argc < 1) { 1026478Ssam printf("-t: missing packet type\n"); 1036478Ssam exit(2); 1046478Ssam } 1056478Ssam packettype = atoi(*argv); 1066478Ssam argv++, argc--;; 1076478Ssam continue; 1086478Ssam } 1099195Ssam printf("usage: implog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n"); 1106478Ssam exit(2); 1116478Ssam } 1126478Ssam if (argc > 0) 1136478Ssam logfile = argv[0]; 1146478Ssam log = open(logfile, 0); 1156478Ssam if (log < 0) { 1166478Ssam perror(logfile); 1176478Ssam exit(1); 1186478Ssam } 1196478Ssam fstat(log, &b); 1206478Ssam size = b.st_size; 1216478Ssam again: 1226478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 1236478Ssam if (from.sin_family == 0) { 1246478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time)); 1256478Ssam continue; 1266478Ssam } 1276478Ssam if (host >= 0 && from.sin_addr.s_host != host) { 1286478Ssam lseek(log, from.sin_cc, 1); 1296478Ssam continue; 1306478Ssam } 1316478Ssam if (imp >= 0) { 1326478Ssam from.sin_addr.s_imp = ntohs(from.sin_addr.s_imp); 1336478Ssam if (from.sin_addr.s_imp != imp) { 1346478Ssam lseek(log, from.sin_cc, 1); 1356478Ssam continue; 1366478Ssam } 1376478Ssam } 1386478Ssam process(log, &from); 1396478Ssam } 1406478Ssam while (follow) { 1416478Ssam fflush(stdout); 1426478Ssam sleep(5); 1436478Ssam fstat(log, &b); 1446478Ssam if (b.st_size > size) { 1456478Ssam size = b.st_size; 1466478Ssam goto again; 1476478Ssam } 1486478Ssam } 1496478Ssam } 1506478Ssam 1516478Ssam int impdata(), impbadleader(), impdown(), impnoop(); 1526478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 1536478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 1546478Ssam int impready(), impundef(); 1556478Ssam 1566478Ssam struct messages { 1576478Ssam u_char m_type; /* type of message */ 1586478Ssam int (*m_func)(); /* routine to process message */ 1596478Ssam } mtypes[] = { 1606478Ssam { IMPTYPE_DATA, impdata }, 1616478Ssam { IMPTYPE_BADLEADER, impbadleader }, 1626478Ssam { IMPTYPE_DOWN, impdown }, 1636478Ssam { IMPTYPE_NOOP, impnoop }, 1646478Ssam { IMPTYPE_RFNM, imprfnm }, 1656478Ssam { IMPTYPE_INCOMPLETE, impincomplete }, 1666478Ssam { IMPTYPE_HOSTDEAD, imphostdead }, 1676478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach }, 1686478Ssam { IMPTYPE_BADDATA, impbaddata }, 1696478Ssam { IMPTYPE_RESET, impreset }, 1706478Ssam { IMPTYPE_RETRY, impretry }, 1716478Ssam { IMPTYPE_NOTIFY, impnotify }, 1726478Ssam { IMPTYPE_TRYING, imptrying }, 1736478Ssam { IMPTYPE_READY, impready }, 1746478Ssam { -1, impundef } 1756478Ssam }; 1766478Ssam 1776478Ssam /* 1786478Ssam * Print a packet. 1796478Ssam */ 1806478Ssam process(l, f) 1816478Ssam int l; 1826478Ssam struct sockstamp *f; 1836478Ssam { 1846478Ssam register struct messages *mp; 1856478Ssam struct imp_leader *ip; 1866478Ssam 1876478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 1886478Ssam perror("read"); 1896478Ssam return; 1906478Ssam } 1916478Ssam ip = (struct imp_leader *)buf; 1929195Ssam ip->il_imp = ntohs((u_short)ip->il_imp); 1936478Ssam for (mp = mtypes; mp->m_type != -1; mp++) 1946478Ssam if (mp->m_type == ip->il_mtype) 1956478Ssam break; 1966478Ssam if (mp->m_type == IMPTYPE_DATA) { 1976478Ssam if (link >= 0 && ip->il_link != link) 1986478Ssam return; 1996478Ssam if (!showdata) 2006478Ssam return; 2016478Ssam } 2026478Ssam if (packettype >= 0 && mp->m_type != packettype) 2036478Ssam return; 2046478Ssam printf("%.24s: ", ctime(&f->sin_time)); 2056478Ssam (*mp->m_func)(ip, f->sin_cc); 2066478Ssam } 2076478Ssam 2086478Ssam impdata(ip, cc) 2096478Ssam register struct imp_leader *ip; 2106478Ssam { 2119195Ssam printf("<%d/%d, DATA, link=", ip->il_host, ntohs((u_short)ip->il_imp)); 2126478Ssam if (ip->il_link == IMPLINK_IP) 2136478Ssam printf("ip,"); 2146478Ssam else 2156478Ssam printf("%d,", ip->il_link); 2169195Ssam printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 2176478Ssam if (showcontents) { 2186478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip); 2196478Ssam register int i; 2206478Ssam 2216478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 2226478Ssam cc = min(i, cc); 2236478Ssam printf("data: (%d bytes)", cc); 2246478Ssam for (i = 0; i < cc; i++, cp++) { 2256478Ssam if (i % 25 == 0) 2266478Ssam printf("\n"); 2276478Ssam printf("%02x ", *cp); 2286478Ssam } 2296478Ssam putchar('\n'); 2306478Ssam } 2316478Ssam } 2326478Ssam 2336478Ssam char *badleader[] = { 2346478Ssam "error flip-flop set", 2356478Ssam "message < 80 bits", 2366478Ssam "illegal type field", 2376478Ssam "opposite leader type" 2386478Ssam }; 2396478Ssam 2406478Ssam impbadleader(ip) 2416478Ssam register struct imp_leader *ip; 2426478Ssam { 2436478Ssam printf("bad leader: "); 2446478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE) 2456478Ssam printf("%x\n", ip->il_subtype); 2466478Ssam else 2476478Ssam printf("%s\n", badleader[ip->il_subtype]); 2486478Ssam } 2496478Ssam 2506478Ssam char *down[] = { 2516478Ssam "in 30 secs", 2526478Ssam "for hardware pm", 2536478Ssam "for software reload", 2546478Ssam "for emergency restart" 2556478Ssam }; 2566478Ssam 2576478Ssam impdown(ip) 2586478Ssam register struct imp_leader *ip; 2596478Ssam { 2606478Ssam int tdown, tbackup; 2616478Ssam 2626478Ssam printf("imp going down %s", down[ip->il_link & IMP_DMASK]); 2636478Ssam tdown = ((ip->il_link >> 2) & 0xf) * 5; 2646478Ssam if (ip->il_link & IMP_DMASK) 2656478Ssam printf(" in %d minutes", tdown); 2666478Ssam tbackup = ip->il_subtype * 5; 2676478Ssam printf(": back up "); 2686478Ssam if (tbackup) 2696478Ssam printf("%d minutes\n", tbackup); 2706478Ssam else 2716478Ssam printf("immediately\n"); 2726478Ssam } 2736478Ssam 2746478Ssam impnoop(ip) 2756478Ssam register struct imp_leader *ip; 2766478Ssam { 2779195Ssam printf("noop: host %d, imp %d\n", ip->il_host, 2789195Ssam ntohs((u_short)ip->il_imp)); 2796478Ssam } 2806478Ssam 2816478Ssam imprfnm(ip) 2826478Ssam register struct imp_leader *ip; 2836478Ssam { 2846478Ssam printf("rfnm: htype=%x, source=%d/%d, link=", 2856478Ssam ip->il_htype, ip->il_host, ip->il_imp); 2866478Ssam if (ip->il_link == IMPLINK_IP) 2876478Ssam printf("ip,"); 2886478Ssam else 2896478Ssam printf("%x,", ip->il_link); 2906478Ssam printf(" subtype=%x\n", ip->il_subtype); 2916478Ssam } 2926478Ssam 2936478Ssam char *hostdead[] = { 2949195Ssam "#0", 2956478Ssam "ready-line negated", 2966478Ssam "tardy receiving messages", 2976478Ssam "ncc doesn't know host", 2986478Ssam "imp software won't allow messages", 2996478Ssam "host down for scheduled pm", 3006478Ssam "host down for hardware work", 3016478Ssam "host down for software work", 3026478Ssam "host down for emergency restart", 3036478Ssam "host down because of power outage", 3046478Ssam "host stopped at a breakpoint", 3056478Ssam "host down due to hardware failure", 3066478Ssam "host not scheduled to be up", 3079195Ssam "#13", 3089195Ssam "#14", 3096478Ssam "host in the process of coming up" 3106478Ssam }; 3116478Ssam 3126478Ssam imphostdead(ip) 3136478Ssam register struct imp_leader *ip; 3146478Ssam { 3156478Ssam printf("host dead: "); 3166478Ssam if (ip->il_link & IMP_DMASK) 3176478Ssam printf("down %s, ", down[ip->il_link & IMP_DMASK]); 3186478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP) 3196478Ssam printf("%s\n", hostdead[ip->il_subtype]); 3206478Ssam else 3216478Ssam printf("subtype=%x\n", ip->il_subtype); 3226478Ssam } 3236478Ssam 3246478Ssam char *hostunreach[] = { 3256478Ssam "destination imp can't be reached", 3266478Ssam "destination host isn't up", 3276478Ssam "host doesn't support long leader", 3286478Ssam "communication is prohibited" 3296478Ssam }; 3306478Ssam 3316478Ssam imphostunreach(ip) 3326478Ssam register struct imp_leader *ip; 3336478Ssam { 3346478Ssam printf("host unreachable: "); 3356478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED) 3366478Ssam printf("%s\n", hostunreach[ip->il_subtype]); 3376478Ssam else 3386478Ssam printf("subtype=%x\n", ip->il_subtype); 3396478Ssam } 3406478Ssam 3416478Ssam impbaddata(ip) 3426478Ssam register struct imp_leader *ip; 3436478Ssam { 3446478Ssam printf("error in data: 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 3496478Ssam printf("%x, ", ip->il_link); 3506478Ssam printf("subtype=%x\n", ip->il_subtype); 3516478Ssam } 3526478Ssam 3536478Ssam char *incomplete[] = { 3546478Ssam "host didn't take data fast enough", 3556478Ssam "message was too long", 3566478Ssam "message transmission time > 15 seconds", 3576478Ssam "imp/circuit failure", 3586478Ssam "no resources within 15 seconds", 3596478Ssam "source imp i/o failure during receipt" 3606478Ssam }; 3616478Ssam 3626478Ssam impincomplete(ip) 3636478Ssam register struct imp_leader *ip; 3646478Ssam { 3656478Ssam printf("incomplete: htype=%x, source=%d/%d, link=", 3666478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3676478Ssam if (ip->il_link == IMPLINK_IP) 3686478Ssam printf("ip,"); 3696478Ssam else 3706478Ssam printf("%x,", ip->il_link); 3716478Ssam if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 3726478Ssam printf(" %s\n", incomplete[ip->il_subtype]); 3736478Ssam else 3746478Ssam printf(" subtype=%x\n", ip->il_subtype); 3756478Ssam } 3766478Ssam 3776478Ssam impreset(ip) 3786478Ssam register struct imp_leader *ip; 3796478Ssam { 3806478Ssam printf("reset complete\n"); 3816478Ssam } 3826478Ssam 3836478Ssam char *retry[] = { 3846478Ssam "imp buffer wasn't available", 3856478Ssam "connection block unavailable" 3866478Ssam }; 3876478Ssam 3886478Ssam impretry(ip) 3896478Ssam register struct imp_leader *ip; 3906478Ssam { 3916478Ssam printf("refused, try again: "); 3926478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK) 3936478Ssam printf("%s\n", retry[ip->il_subtype]); 3946478Ssam else 3956478Ssam printf("subtype=%x\n", ip->il_subtype); 3966478Ssam } 3976478Ssam 3986478Ssam char *notify[] = { 3999195Ssam "#0", 4009195Ssam "#1", 4016478Ssam "connection not available", 4026478Ssam "reassembly space not available at destination", 4036478Ssam "message number not available", 4046478Ssam "transaction block for message not available" 4056478Ssam }; 4066478Ssam 4076478Ssam impnotify(ip) 4086478Ssam register struct imp_leader *ip; 4096478Ssam { 4106478Ssam printf("refused, will notify: "); 4116478Ssam if (ip->il_subtype <= 5) 4126478Ssam printf("%s\n", notify[ip->il_subtype]); 4136478Ssam else 4146478Ssam printf("subtype=%x\n", ip->il_subtype); 4156478Ssam } 4166478Ssam 4176478Ssam imptrying(ip) 4186478Ssam register struct imp_leader *ip; 4196478Ssam { 4206478Ssam printf("refused, still trying\n"); 4216478Ssam } 4226478Ssam 4236478Ssam impready(ip) 4246478Ssam register struct imp_leader *ip; 4256478Ssam { 4266478Ssam printf("ready\n"); 4276478Ssam } 4286478Ssam 4296478Ssam impundef(ip) 4306478Ssam register struct imp_leader *ip; 4316478Ssam { 4326478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 4336478Ssam ip->il_network, ip->il_flags); 4346478Ssam printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype, 4356478Ssam ip->il_htype, ip->il_host, ip->il_imp); 4366478Ssam if (ip->il_link == IMPLINK_IP) 4376478Ssam printf("ip,"); 4386478Ssam else 4396478Ssam printf("%x,", ip->il_link); 4406478Ssam printf(" subtype=%x>\n", ip->il_subtype); 4416478Ssam } 442