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*22597Skarels static char sccsid[] = "@(#)implog.c 5.3 (Berkeley) 06/06/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; 64*22597Skarels int hostfrom, impfrom; 656478Ssam 666478Ssam argc--, argv++; 676478Ssam while (argc > 0 && argv[0][0] == '-') { 686478Ssam if (strcmp(*argv, "-D") == 0) { 696478Ssam showdata = 0; 706478Ssam argv++, argc--; 716478Ssam continue; 726478Ssam } 736478Ssam if (strcmp(*argv, "-f") == 0) { 746478Ssam follow++; 756478Ssam argv++, argc--; 766478Ssam continue; 776478Ssam } 786478Ssam if (strcmp(*argv, "-c") == 0) { 796478Ssam showcontents++; 806478Ssam argv++, argc--; 816478Ssam continue; 826478Ssam } 836478Ssam if (strcmp(*argv, "-l") == 0) { 846478Ssam argc--, argv++; 856478Ssam if (argc > 0) { 866478Ssam link = atoi(*argv); 876478Ssam argc--, argv++; 886478Ssam } else 896478Ssam link = IMPLINK_IP; 906478Ssam continue; 916478Ssam } 926478Ssam if (strcmp(*argv, "-h") == 0) { 936478Ssam argc--, argv++; 946478Ssam if (argc < 1) { 956478Ssam printf("-h: missing host #\n"); 966478Ssam exit(2); 976478Ssam } 986478Ssam host = atoi(*argv); 996478Ssam argv++, argc--; 1006478Ssam continue; 1016478Ssam } 1026478Ssam if (strcmp(*argv, "-i") == 0) { 1036478Ssam argc--, argv++; 1046478Ssam if (argc < 1) { 1056478Ssam printf("-i: missing imp #\n"); 1066478Ssam exit(2); 1076478Ssam } 1086478Ssam imp = atoi(*argv); 1096478Ssam argv++, argc--; 1106478Ssam continue; 1116478Ssam } 1126478Ssam if (strcmp(*argv, "-t") == 0) { 1136478Ssam argc--, argv++;; 1146478Ssam if (argc < 1) { 1156478Ssam printf("-t: missing packet type\n"); 1166478Ssam exit(2); 1176478Ssam } 1186478Ssam packettype = atoi(*argv); 1196478Ssam argv++, argc--;; 1206478Ssam continue; 1216478Ssam } 1229195Ssam printf("usage: implog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n"); 1236478Ssam exit(2); 1246478Ssam } 1256478Ssam if (argc > 0) 1266478Ssam logfile = argv[0]; 1276478Ssam log = open(logfile, 0); 1286478Ssam if (log < 0) { 1296478Ssam perror(logfile); 1306478Ssam exit(1); 1316478Ssam } 1326478Ssam fstat(log, &b); 1336478Ssam size = b.st_size; 1346478Ssam again: 1356478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 1366478Ssam if (from.sin_family == 0) { 1376478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time)); 1386478Ssam continue; 1396478Ssam } 140*22597Skarels if (host >= 0) { 141*22597Skarels long addr = ntohs(from.sin_addr.s_addr); 142*22597Skarels 143*22597Skarels if (IN_CLASSA(addr)) { 144*22597Skarels hostfrom = ((addr>>16) & 0xFF); 145*22597Skarels impfrom = addr & 0xFF; 146*22597Skarels } else if (IN_CLASSB(addr)) { 147*22597Skarels hostfrom = ((addr>>8) & 0xFF); 148*22597Skarels impfrom = addr & 0xFF; 149*22597Skarels } else { 150*22597Skarels hostfrom = ((addr>>4) & 0xF); 151*22597Skarels impfrom = addr & 0xF; 152*22597Skarels } 153*22597Skarels } 154*22597Skarels if (host >= 0 && hostfrom != host) { 1556478Ssam lseek(log, from.sin_cc, 1); 1566478Ssam continue; 1576478Ssam } 158*22597Skarels if (imp >= 0 && impfrom != imp) { 159*22597Skarels lseek(log, from.sin_cc, 1); 160*22597Skarels continue; 1616478Ssam } 1626478Ssam process(log, &from); 1636478Ssam } 1646478Ssam while (follow) { 1656478Ssam fflush(stdout); 1666478Ssam sleep(5); 1676478Ssam fstat(log, &b); 1686478Ssam if (b.st_size > size) { 1696478Ssam size = b.st_size; 1706478Ssam goto again; 1716478Ssam } 1726478Ssam } 1736478Ssam } 1746478Ssam 1756478Ssam int impdata(), impbadleader(), impdown(), impnoop(); 1766478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 1776478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 1786478Ssam int impready(), impundef(); 1796478Ssam 1806478Ssam struct messages { 1816478Ssam u_char m_type; /* type of message */ 1826478Ssam int (*m_func)(); /* routine to process message */ 1836478Ssam } mtypes[] = { 1846478Ssam { IMPTYPE_DATA, impdata }, 1856478Ssam { IMPTYPE_BADLEADER, impbadleader }, 1866478Ssam { IMPTYPE_DOWN, impdown }, 1876478Ssam { IMPTYPE_NOOP, impnoop }, 1886478Ssam { IMPTYPE_RFNM, imprfnm }, 1896478Ssam { IMPTYPE_INCOMPLETE, impincomplete }, 1906478Ssam { IMPTYPE_HOSTDEAD, imphostdead }, 1916478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach }, 1926478Ssam { IMPTYPE_BADDATA, impbaddata }, 1936478Ssam { IMPTYPE_RESET, impreset }, 1946478Ssam { IMPTYPE_RETRY, impretry }, 1956478Ssam { IMPTYPE_NOTIFY, impnotify }, 1966478Ssam { IMPTYPE_TRYING, imptrying }, 1976478Ssam { IMPTYPE_READY, impready }, 1986478Ssam { -1, impundef } 1996478Ssam }; 2006478Ssam 2016478Ssam /* 2026478Ssam * Print a packet. 2036478Ssam */ 2046478Ssam process(l, f) 2056478Ssam int l; 2066478Ssam struct sockstamp *f; 2076478Ssam { 2086478Ssam register struct messages *mp; 2096478Ssam struct imp_leader *ip; 2106478Ssam 2116478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 2126478Ssam perror("read"); 2136478Ssam return; 2146478Ssam } 2156478Ssam ip = (struct imp_leader *)buf; 2169195Ssam ip->il_imp = ntohs((u_short)ip->il_imp); 2176478Ssam for (mp = mtypes; mp->m_type != -1; mp++) 2186478Ssam if (mp->m_type == ip->il_mtype) 2196478Ssam break; 2206478Ssam if (mp->m_type == IMPTYPE_DATA) { 2216478Ssam if (link >= 0 && ip->il_link != link) 2226478Ssam return; 2236478Ssam if (!showdata) 2246478Ssam return; 2256478Ssam } 2266478Ssam if (packettype >= 0 && mp->m_type != packettype) 2276478Ssam return; 2286478Ssam printf("%.24s: ", ctime(&f->sin_time)); 2296478Ssam (*mp->m_func)(ip, f->sin_cc); 2306478Ssam } 2316478Ssam 2326478Ssam impdata(ip, cc) 2336478Ssam register struct imp_leader *ip; 2346478Ssam { 2359195Ssam printf("<%d/%d, DATA, link=", ip->il_host, ntohs((u_short)ip->il_imp)); 2366478Ssam if (ip->il_link == IMPLINK_IP) 2376478Ssam printf("ip,"); 2386478Ssam else 2396478Ssam printf("%d,", ip->il_link); 2409195Ssam printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 2416478Ssam if (showcontents) { 2426478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip); 2436478Ssam register int i; 2446478Ssam 2456478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 2466478Ssam cc = min(i, cc); 2476478Ssam printf("data: (%d bytes)", cc); 2486478Ssam for (i = 0; i < cc; i++, cp++) { 2496478Ssam if (i % 25 == 0) 2506478Ssam printf("\n"); 2516478Ssam printf("%02x ", *cp); 2526478Ssam } 2536478Ssam putchar('\n'); 2546478Ssam } 2556478Ssam } 2566478Ssam 2576478Ssam char *badleader[] = { 2586478Ssam "error flip-flop set", 2596478Ssam "message < 80 bits", 2606478Ssam "illegal type field", 2616478Ssam "opposite leader type" 2626478Ssam }; 2636478Ssam 2646478Ssam impbadleader(ip) 2656478Ssam register struct imp_leader *ip; 2666478Ssam { 2676478Ssam printf("bad leader: "); 2686478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE) 2696478Ssam printf("%x\n", ip->il_subtype); 2706478Ssam else 2716478Ssam printf("%s\n", badleader[ip->il_subtype]); 2726478Ssam } 2736478Ssam 2746478Ssam char *down[] = { 2756478Ssam "in 30 secs", 2766478Ssam "for hardware pm", 2776478Ssam "for software reload", 2786478Ssam "for emergency restart" 2796478Ssam }; 2806478Ssam 2816478Ssam impdown(ip) 2826478Ssam register struct imp_leader *ip; 2836478Ssam { 2846478Ssam int tdown, tbackup; 2856478Ssam 2866478Ssam printf("imp going down %s", down[ip->il_link & IMP_DMASK]); 2876478Ssam tdown = ((ip->il_link >> 2) & 0xf) * 5; 2886478Ssam if (ip->il_link & IMP_DMASK) 2896478Ssam printf(" in %d minutes", tdown); 2906478Ssam tbackup = ip->il_subtype * 5; 2916478Ssam printf(": back up "); 2926478Ssam if (tbackup) 2936478Ssam printf("%d minutes\n", tbackup); 2946478Ssam else 2956478Ssam printf("immediately\n"); 2966478Ssam } 2976478Ssam 2986478Ssam impnoop(ip) 2996478Ssam register struct imp_leader *ip; 3006478Ssam { 3019195Ssam printf("noop: host %d, imp %d\n", ip->il_host, 3029195Ssam ntohs((u_short)ip->il_imp)); 3036478Ssam } 3046478Ssam 3056478Ssam imprfnm(ip) 3066478Ssam register struct imp_leader *ip; 3076478Ssam { 3086478Ssam printf("rfnm: htype=%x, source=%d/%d, link=", 3096478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3106478Ssam if (ip->il_link == IMPLINK_IP) 3116478Ssam printf("ip,"); 3126478Ssam else 3136478Ssam printf("%x,", ip->il_link); 3146478Ssam printf(" subtype=%x\n", ip->il_subtype); 3156478Ssam } 3166478Ssam 3176478Ssam char *hostdead[] = { 3189195Ssam "#0", 3196478Ssam "ready-line negated", 3206478Ssam "tardy receiving messages", 3216478Ssam "ncc doesn't know host", 3226478Ssam "imp software won't allow messages", 3236478Ssam "host down for scheduled pm", 3246478Ssam "host down for hardware work", 3256478Ssam "host down for software work", 3266478Ssam "host down for emergency restart", 3276478Ssam "host down because of power outage", 3286478Ssam "host stopped at a breakpoint", 3296478Ssam "host down due to hardware failure", 3306478Ssam "host not scheduled to be up", 3319195Ssam "#13", 3329195Ssam "#14", 3336478Ssam "host in the process of coming up" 3346478Ssam }; 3356478Ssam 3366478Ssam imphostdead(ip) 3376478Ssam register struct imp_leader *ip; 3386478Ssam { 3396478Ssam printf("host dead: "); 3406478Ssam if (ip->il_link & IMP_DMASK) 3416478Ssam printf("down %s, ", down[ip->il_link & IMP_DMASK]); 3426478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP) 3436478Ssam printf("%s\n", hostdead[ip->il_subtype]); 3446478Ssam else 3456478Ssam printf("subtype=%x\n", ip->il_subtype); 3466478Ssam } 3476478Ssam 3486478Ssam char *hostunreach[] = { 3496478Ssam "destination imp can't be reached", 3506478Ssam "destination host isn't up", 3516478Ssam "host doesn't support long leader", 3526478Ssam "communication is prohibited" 3536478Ssam }; 3546478Ssam 3556478Ssam imphostunreach(ip) 3566478Ssam register struct imp_leader *ip; 3576478Ssam { 3586478Ssam printf("host unreachable: "); 3596478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED) 3606478Ssam printf("%s\n", hostunreach[ip->il_subtype]); 3616478Ssam else 3626478Ssam printf("subtype=%x\n", ip->il_subtype); 3636478Ssam } 3646478Ssam 3656478Ssam impbaddata(ip) 3666478Ssam register struct imp_leader *ip; 3676478Ssam { 3686478Ssam printf("error in data: htype=%x, source=%d/%d, link=", 3696478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3706478Ssam if (ip->il_link == IMPLINK_IP) 3716478Ssam printf("ip, "); 3726478Ssam else 3736478Ssam printf("%x, ", ip->il_link); 3746478Ssam printf("subtype=%x\n", ip->il_subtype); 3756478Ssam } 3766478Ssam 3776478Ssam char *incomplete[] = { 3786478Ssam "host didn't take data fast enough", 3796478Ssam "message was too long", 3806478Ssam "message transmission time > 15 seconds", 3816478Ssam "imp/circuit failure", 3826478Ssam "no resources within 15 seconds", 3836478Ssam "source imp i/o failure during receipt" 3846478Ssam }; 3856478Ssam 3866478Ssam impincomplete(ip) 3876478Ssam register struct imp_leader *ip; 3886478Ssam { 3896478Ssam printf("incomplete: htype=%x, source=%d/%d, link=", 3906478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3916478Ssam if (ip->il_link == IMPLINK_IP) 3926478Ssam printf("ip,"); 3936478Ssam else 3946478Ssam printf("%x,", ip->il_link); 3956478Ssam if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 3966478Ssam printf(" %s\n", incomplete[ip->il_subtype]); 3976478Ssam else 3986478Ssam printf(" subtype=%x\n", ip->il_subtype); 3996478Ssam } 4006478Ssam 4016478Ssam impreset(ip) 4026478Ssam register struct imp_leader *ip; 4036478Ssam { 4046478Ssam printf("reset complete\n"); 4056478Ssam } 4066478Ssam 4076478Ssam char *retry[] = { 4086478Ssam "imp buffer wasn't available", 4096478Ssam "connection block unavailable" 4106478Ssam }; 4116478Ssam 4126478Ssam impretry(ip) 4136478Ssam register struct imp_leader *ip; 4146478Ssam { 4156478Ssam printf("refused, try again: "); 4166478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK) 4176478Ssam printf("%s\n", retry[ip->il_subtype]); 4186478Ssam else 4196478Ssam printf("subtype=%x\n", ip->il_subtype); 4206478Ssam } 4216478Ssam 4226478Ssam char *notify[] = { 4239195Ssam "#0", 4249195Ssam "#1", 4256478Ssam "connection not available", 4266478Ssam "reassembly space not available at destination", 4276478Ssam "message number not available", 4286478Ssam "transaction block for message not available" 4296478Ssam }; 4306478Ssam 4316478Ssam impnotify(ip) 4326478Ssam register struct imp_leader *ip; 4336478Ssam { 4346478Ssam printf("refused, will notify: "); 4356478Ssam if (ip->il_subtype <= 5) 4366478Ssam printf("%s\n", notify[ip->il_subtype]); 4376478Ssam else 4386478Ssam printf("subtype=%x\n", ip->il_subtype); 4396478Ssam } 4406478Ssam 4416478Ssam imptrying(ip) 4426478Ssam register struct imp_leader *ip; 4436478Ssam { 4446478Ssam printf("refused, still trying\n"); 4456478Ssam } 4466478Ssam 4476478Ssam impready(ip) 4486478Ssam register struct imp_leader *ip; 4496478Ssam { 4506478Ssam printf("ready\n"); 4516478Ssam } 4526478Ssam 4536478Ssam impundef(ip) 4546478Ssam register struct imp_leader *ip; 4556478Ssam { 4566478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 4576478Ssam ip->il_network, ip->il_flags); 4586478Ssam printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype, 4596478Ssam ip->il_htype, ip->il_host, ip->il_imp); 4606478Ssam if (ip->il_link == IMPLINK_IP) 4616478Ssam printf("ip,"); 4626478Ssam else 4636478Ssam printf("%x,", ip->il_link); 4646478Ssam printf(" subtype=%x>\n", ip->il_subtype); 4656478Ssam } 466