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*33455Skarels static char sccsid[] = "@(#)implog.c 5.7 (Berkeley) 02/08/88"; 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 26*33455Skarels #include <net/if.h> 27*33455Skarels 289195Ssam #include <netinet/in.h> 29*33455Skarels #define IMPMESSAGES 306478Ssam #define IMPLEADERS 319195Ssam #include <netimp/if_imp.h> 326478Ssam 336478Ssam #define min(a, b) ((a) < (b) ? (a) : (b)) 346478Ssam 356478Ssam u_char buf[1024]; 366478Ssam int showdata = 1; 376478Ssam int showcontents = 0; 3827727Skarels int rawheader = 0; 396478Ssam int follow = 0; 406478Ssam int link = -1; 416478Ssam int host = -1; 426478Ssam int imp = -1; 436478Ssam int packettype = -1; 446478Ssam extern int errno; 456478Ssam int log; 466478Ssam char *logfile = "/usr/adm/implog"; 476478Ssam 486478Ssam /* 496478Ssam * Socket address, internet style, with 506478Ssam * unused space taken by timestamp and packet 516478Ssam * size. 526478Ssam */ 536478Ssam struct sockstamp { 546478Ssam short sin_family; 556478Ssam u_short sin_port; 566478Ssam struct in_addr sin_addr; 576478Ssam time_t sin_time; 586478Ssam int sin_cc; 596478Ssam }; 606478Ssam struct sockstamp from; 616478Ssam 626478Ssam main(argc, argv) 636478Ssam char *argv[]; 646478Ssam { 656478Ssam struct stat b; 666478Ssam int size; 676478Ssam char *cp; 6822597Skarels int hostfrom, impfrom; 696478Ssam 706478Ssam argc--, argv++; 716478Ssam while (argc > 0 && argv[0][0] == '-') { 726478Ssam if (strcmp(*argv, "-D") == 0) { 736478Ssam showdata = 0; 746478Ssam argv++, argc--; 756478Ssam continue; 766478Ssam } 776478Ssam if (strcmp(*argv, "-f") == 0) { 786478Ssam follow++; 796478Ssam argv++, argc--; 806478Ssam continue; 816478Ssam } 826478Ssam if (strcmp(*argv, "-c") == 0) { 836478Ssam showcontents++; 846478Ssam argv++, argc--; 856478Ssam continue; 866478Ssam } 8727727Skarels if (strcmp(*argv, "-r") == 0) { 8827727Skarels rawheader++; 8927727Skarels argv++, argc--; 9027727Skarels continue; 9127727Skarels } 926478Ssam if (strcmp(*argv, "-l") == 0) { 936478Ssam argc--, argv++; 946478Ssam if (argc > 0) { 956478Ssam link = atoi(*argv); 966478Ssam argc--, argv++; 976478Ssam } else 986478Ssam link = IMPLINK_IP; 996478Ssam continue; 1006478Ssam } 1016478Ssam if (strcmp(*argv, "-h") == 0) { 1026478Ssam argc--, argv++; 1036478Ssam if (argc < 1) { 1046478Ssam printf("-h: missing host #\n"); 1056478Ssam exit(2); 1066478Ssam } 1076478Ssam host = atoi(*argv); 1086478Ssam argv++, argc--; 1096478Ssam continue; 1106478Ssam } 1116478Ssam if (strcmp(*argv, "-i") == 0) { 1126478Ssam argc--, argv++; 1136478Ssam if (argc < 1) { 1146478Ssam printf("-i: missing imp #\n"); 1156478Ssam exit(2); 1166478Ssam } 1176478Ssam imp = atoi(*argv); 1186478Ssam argv++, argc--; 1196478Ssam continue; 1206478Ssam } 1216478Ssam if (strcmp(*argv, "-t") == 0) { 1226478Ssam argc--, argv++;; 1236478Ssam if (argc < 1) { 1246478Ssam printf("-t: missing packet type\n"); 1256478Ssam exit(2); 1266478Ssam } 1276478Ssam packettype = atoi(*argv); 1286478Ssam argv++, argc--;; 1296478Ssam continue; 1306478Ssam } 13127727Skarels printf("usage: implog [ -D ] [ -c ] [ -f ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n"); 1326478Ssam exit(2); 1336478Ssam } 1346478Ssam if (argc > 0) 1356478Ssam logfile = argv[0]; 1366478Ssam log = open(logfile, 0); 1376478Ssam if (log < 0) { 1386478Ssam perror(logfile); 1396478Ssam exit(1); 1406478Ssam } 1416478Ssam fstat(log, &b); 1426478Ssam size = b.st_size; 1436478Ssam again: 1446478Ssam while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 1456478Ssam if (from.sin_family == 0) { 1466478Ssam printf("restarted: %.24s\n", ctime(&from.sin_time)); 1476478Ssam continue; 1486478Ssam } 14922597Skarels if (host >= 0) { 15022597Skarels long addr = ntohs(from.sin_addr.s_addr); 15122597Skarels 15222597Skarels if (IN_CLASSA(addr)) { 15322597Skarels hostfrom = ((addr>>16) & 0xFF); 15422597Skarels impfrom = addr & 0xFF; 15522597Skarels } else if (IN_CLASSB(addr)) { 15622597Skarels hostfrom = ((addr>>8) & 0xFF); 15722597Skarels impfrom = addr & 0xFF; 15822597Skarels } else { 15922597Skarels hostfrom = ((addr>>4) & 0xF); 16022597Skarels impfrom = addr & 0xF; 16122597Skarels } 16222597Skarels } 16322597Skarels if (host >= 0 && hostfrom != host) { 1646478Ssam lseek(log, from.sin_cc, 1); 1656478Ssam continue; 1666478Ssam } 16722597Skarels if (imp >= 0 && impfrom != imp) { 16822597Skarels lseek(log, from.sin_cc, 1); 16922597Skarels continue; 1706478Ssam } 1716478Ssam process(log, &from); 1726478Ssam } 1736478Ssam while (follow) { 1746478Ssam fflush(stdout); 1756478Ssam sleep(5); 1766478Ssam fstat(log, &b); 1776478Ssam if (b.st_size > size) { 1786478Ssam size = b.st_size; 1796478Ssam goto again; 1806478Ssam } 1816478Ssam } 1826478Ssam } 1836478Ssam 1846478Ssam int impdata(), impbadleader(), impdown(), impnoop(); 1856478Ssam int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 1866478Ssam int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 1876478Ssam int impready(), impundef(); 1886478Ssam 1896478Ssam struct messages { 1906478Ssam u_char m_type; /* type of message */ 1916478Ssam int (*m_func)(); /* routine to process message */ 1926478Ssam } mtypes[] = { 1936478Ssam { IMPTYPE_DATA, impdata }, 1946478Ssam { IMPTYPE_BADLEADER, impbadleader }, 1956478Ssam { IMPTYPE_DOWN, impdown }, 1966478Ssam { IMPTYPE_NOOP, impnoop }, 1976478Ssam { IMPTYPE_RFNM, imprfnm }, 1986478Ssam { IMPTYPE_INCOMPLETE, impincomplete }, 1996478Ssam { IMPTYPE_HOSTDEAD, imphostdead }, 2006478Ssam { IMPTYPE_HOSTUNREACH, imphostunreach }, 2016478Ssam { IMPTYPE_BADDATA, impbaddata }, 2026478Ssam { IMPTYPE_RESET, impreset }, 2036478Ssam { IMPTYPE_RETRY, impretry }, 2046478Ssam { IMPTYPE_NOTIFY, impnotify }, 2056478Ssam { IMPTYPE_TRYING, imptrying }, 2066478Ssam { IMPTYPE_READY, impready }, 2076478Ssam { -1, impundef } 2086478Ssam }; 2096478Ssam 2106478Ssam /* 2116478Ssam * Print a packet. 2126478Ssam */ 2136478Ssam process(l, f) 2146478Ssam int l; 2156478Ssam struct sockstamp *f; 2166478Ssam { 2176478Ssam register struct messages *mp; 2186478Ssam struct imp_leader *ip; 21927727Skarels int (*fn)(); 2206478Ssam 2216478Ssam if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 2226478Ssam perror("read"); 2236478Ssam return; 2246478Ssam } 2256478Ssam ip = (struct imp_leader *)buf; 22628904Skarels ip->il_imp = ntohs(ip->il_imp); 22727727Skarels if (ip->il_format != IMP_NFF) 22827727Skarels fn = impundef; 22927727Skarels else { 23033085Sbostic for (mp = mtypes; mp->m_type != (u_char)-1; mp++) 23127727Skarels if (mp->m_type == ip->il_mtype) 23227727Skarels break; 23327727Skarels fn = mp->m_func; 23427727Skarels } 23527727Skarels if (ip->il_mtype == IMPTYPE_DATA) { 2366478Ssam if (link >= 0 && ip->il_link != link) 2376478Ssam return; 2386478Ssam if (!showdata) 2396478Ssam return; 2406478Ssam } 24127727Skarels if (packettype >= 0 && ip->il_mtype != packettype) 2426478Ssam return; 2436478Ssam printf("%.24s: ", ctime(&f->sin_time)); 24428904Skarels if (f->sin_cc < sizeof(struct control_leader)) 24528904Skarels printf("(truncated header, %d bytes): ", f->sin_cc); 24627727Skarels (*fn)(ip, f->sin_cc); 24728904Skarels if (rawheader && fn != impundef) { 24828904Skarels putchar('\t'); 24927727Skarels impundef(ip, f->sin_cc); 25028904Skarels } 2516478Ssam } 2526478Ssam 2536478Ssam impdata(ip, cc) 2546478Ssam register struct imp_leader *ip; 2556478Ssam { 25627727Skarels printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp); 2576478Ssam if (ip->il_link == IMPLINK_IP) 2586478Ssam printf("ip,"); 2596478Ssam else 2606478Ssam printf("%d,", ip->il_link); 2619195Ssam printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 2626478Ssam if (showcontents) { 2636478Ssam register u_char *cp = ((u_char *)ip) + sizeof(*ip); 2646478Ssam register int i; 2656478Ssam 2666478Ssam i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 2676478Ssam cc = min(i, cc); 2686478Ssam printf("data: (%d bytes)", cc); 2696478Ssam for (i = 0; i < cc; i++, cp++) { 2706478Ssam if (i % 25 == 0) 2716478Ssam printf("\n"); 2726478Ssam printf("%02x ", *cp); 2736478Ssam } 2746478Ssam putchar('\n'); 2756478Ssam } 2766478Ssam } 2776478Ssam 2786478Ssam char *badleader[] = { 2796478Ssam "error flip-flop set", 2806478Ssam "message < 80 bits", 2816478Ssam "illegal type field", 2826478Ssam "opposite leader type" 2836478Ssam }; 2846478Ssam 2856478Ssam impbadleader(ip) 2866478Ssam register struct imp_leader *ip; 2876478Ssam { 2886478Ssam printf("bad leader: "); 2896478Ssam if (ip->il_subtype > IMPLEADER_OPPOSITE) 2906478Ssam printf("%x\n", ip->il_subtype); 2916478Ssam else 2926478Ssam printf("%s\n", badleader[ip->il_subtype]); 2936478Ssam } 2946478Ssam 2956478Ssam impdown(ip) 2966478Ssam register struct imp_leader *ip; 2976478Ssam { 2986478Ssam int tdown, tbackup; 2996478Ssam 300*33455Skarels printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]); 301*33455Skarels tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) * 302*33455Skarels IMPDOWN_WHENUNIT; 303*33455Skarels if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING) 3046478Ssam printf(" in %d minutes", tdown); 305*33455Skarels tbackup = ip->il_subtype * IMPDOWN_WHENUNIT; 3066478Ssam printf(": back up "); 3076478Ssam if (tbackup) 3086478Ssam printf("%d minutes\n", tbackup); 3096478Ssam else 3106478Ssam printf("immediately\n"); 3116478Ssam } 3126478Ssam 3136478Ssam impnoop(ip) 3146478Ssam register struct imp_leader *ip; 3156478Ssam { 3169195Ssam printf("noop: host %d, imp %d\n", ip->il_host, 31727727Skarels (u_short)ip->il_imp); 3186478Ssam } 3196478Ssam 3206478Ssam imprfnm(ip) 3216478Ssam register struct imp_leader *ip; 3226478Ssam { 3236478Ssam printf("rfnm: htype=%x, source=%d/%d, link=", 3246478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3256478Ssam if (ip->il_link == IMPLINK_IP) 3266478Ssam printf("ip,"); 3276478Ssam else 32827727Skarels printf("%d,", ip->il_link); 3296478Ssam printf(" subtype=%x\n", ip->il_subtype); 3306478Ssam } 3316478Ssam 3326478Ssam char *hostdead[] = { 3339195Ssam "#0", 3346478Ssam "ready-line negated", 3356478Ssam "tardy receiving messages", 3366478Ssam "ncc doesn't know host", 3376478Ssam "imp software won't allow messages", 3386478Ssam "host down for scheduled pm", 3396478Ssam "host down for hardware work", 3406478Ssam "host down for software work", 3416478Ssam "host down for emergency restart", 3426478Ssam "host down because of power outage", 3436478Ssam "host stopped at a breakpoint", 3446478Ssam "host down due to hardware failure", 3456478Ssam "host not scheduled to be up", 3469195Ssam "#13", 3479195Ssam "#14", 3486478Ssam "host in the process of coming up" 3496478Ssam }; 3506478Ssam 3516478Ssam imphostdead(ip) 3526478Ssam register struct imp_leader *ip; 3536478Ssam { 35427727Skarels printf("host %d/%d dead: ", ip->il_host, ip->il_imp); 3556478Ssam if (ip->il_link & IMP_DMASK) 356*33455Skarels printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]); 3576478Ssam if (ip->il_subtype <= IMPHOST_COMINGUP) 3586478Ssam printf("%s\n", hostdead[ip->il_subtype]); 3596478Ssam else 3606478Ssam printf("subtype=%x\n", ip->il_subtype); 3616478Ssam } 3626478Ssam 3636478Ssam char *hostunreach[] = { 3646478Ssam "destination imp can't be reached", 3656478Ssam "destination host isn't up", 3666478Ssam "host doesn't support long leader", 3676478Ssam "communication is prohibited" 3686478Ssam }; 3696478Ssam 3706478Ssam imphostunreach(ip) 3716478Ssam register struct imp_leader *ip; 3726478Ssam { 37327727Skarels printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp); 3746478Ssam if (ip->il_subtype <= IMPREACH_PROHIBITED) 3756478Ssam printf("%s\n", hostunreach[ip->il_subtype]); 3766478Ssam else 3776478Ssam printf("subtype=%x\n", ip->il_subtype); 3786478Ssam } 3796478Ssam 3806478Ssam impbaddata(ip) 3816478Ssam register struct imp_leader *ip; 3826478Ssam { 3836478Ssam printf("error in data: htype=%x, source=%d/%d, link=", 3846478Ssam ip->il_htype, ip->il_host, ip->il_imp); 3856478Ssam if (ip->il_link == IMPLINK_IP) 3866478Ssam printf("ip, "); 3876478Ssam else 38827727Skarels printf("%d, ", ip->il_link); 3896478Ssam printf("subtype=%x\n", ip->il_subtype); 3906478Ssam } 3916478Ssam 3926478Ssam char *incomplete[] = { 3936478Ssam "host didn't take data fast enough", 3946478Ssam "message was too long", 3956478Ssam "message transmission time > 15 seconds", 3966478Ssam "imp/circuit failure", 3976478Ssam "no resources within 15 seconds", 3986478Ssam "source imp i/o failure during receipt" 3996478Ssam }; 4006478Ssam 4016478Ssam impincomplete(ip) 4026478Ssam register struct imp_leader *ip; 4036478Ssam { 4046478Ssam printf("incomplete: 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 if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 4116478Ssam printf(" %s\n", incomplete[ip->il_subtype]); 4126478Ssam else 4136478Ssam printf(" subtype=%x\n", ip->il_subtype); 4146478Ssam } 4156478Ssam 4166478Ssam impreset(ip) 4176478Ssam register struct imp_leader *ip; 4186478Ssam { 4196478Ssam printf("reset complete\n"); 4206478Ssam } 4216478Ssam 4226478Ssam char *retry[] = { 4236478Ssam "imp buffer wasn't available", 4246478Ssam "connection block unavailable" 4256478Ssam }; 4266478Ssam 4276478Ssam impretry(ip) 4286478Ssam register struct imp_leader *ip; 4296478Ssam { 4306478Ssam printf("refused, try again: "); 4316478Ssam if (ip->il_subtype <= IMPRETRY_BLOCK) 4326478Ssam printf("%s\n", retry[ip->il_subtype]); 4336478Ssam else 4346478Ssam printf("subtype=%x\n", ip->il_subtype); 4356478Ssam } 4366478Ssam 4376478Ssam char *notify[] = { 4389195Ssam "#0", 4399195Ssam "#1", 4406478Ssam "connection not available", 4416478Ssam "reassembly space not available at destination", 4426478Ssam "message number not available", 4436478Ssam "transaction block for message not available" 4446478Ssam }; 4456478Ssam 4466478Ssam impnotify(ip) 4476478Ssam register struct imp_leader *ip; 4486478Ssam { 4496478Ssam printf("refused, will notify: "); 4506478Ssam if (ip->il_subtype <= 5) 4516478Ssam printf("%s\n", notify[ip->il_subtype]); 4526478Ssam else 4536478Ssam printf("subtype=%x\n", ip->il_subtype); 4546478Ssam } 4556478Ssam 4566478Ssam imptrying(ip) 4576478Ssam register struct imp_leader *ip; 4586478Ssam { 4596478Ssam printf("refused, still trying\n"); 4606478Ssam } 4616478Ssam 4626478Ssam impready(ip) 4636478Ssam register struct imp_leader *ip; 4646478Ssam { 4656478Ssam printf("ready\n"); 4666478Ssam } 4676478Ssam 46828904Skarels impundef(ip, len) 4696478Ssam register struct imp_leader *ip; 4706478Ssam { 4716478Ssam printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 4726478Ssam ip->il_network, ip->il_flags); 47328904Skarels printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=", 47428904Skarels ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host, 47528904Skarels ip->il_imp, ip->il_imp); 4766478Ssam if (ip->il_link == IMPLINK_IP) 4776478Ssam printf("ip,"); 4786478Ssam else 47928904Skarels printf("%d (x%x),", ip->il_link, ip->il_link); 48028904Skarels printf(" subtype=%x", ip->il_subtype); 48128904Skarels if (len >= sizeof(struct imp_leader) && ip->il_length) 48228904Skarels printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3); 48328904Skarels printf(">\n"); 4846478Ssam } 485