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