1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 char copyright[] = 9 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10 All rights reserved.\n"; 11 #endif not lint 12 13 #ifndef lint 14 static char sccsid[] = "@(#)implog.c 5.5 (Berkeley) 05/30/86"; 15 #endif not lint 16 17 #include <stdio.h> 18 #include <signal.h> 19 #include <sgtty.h> 20 21 #include <sys/time.h> 22 #include <sys/types.h> 23 #include <sys/stat.h> 24 #include <sys/socket.h> 25 26 #include <netinet/in.h> 27 #define IMPLEADERS 28 #include <netimp/if_imp.h> 29 30 #define min(a, b) ((a) < (b) ? (a) : (b)) 31 32 u_char buf[1024]; 33 int showdata = 1; 34 int showcontents = 0; 35 int rawheader = 0; 36 int follow = 0; 37 int link = -1; 38 int host = -1; 39 int imp = -1; 40 int packettype = -1; 41 extern int errno; 42 int log; 43 char *logfile = "/usr/adm/implog"; 44 45 /* 46 * Socket address, internet style, with 47 * unused space taken by timestamp and packet 48 * size. 49 */ 50 struct sockstamp { 51 short sin_family; 52 u_short sin_port; 53 struct in_addr sin_addr; 54 time_t sin_time; 55 int sin_cc; 56 }; 57 struct sockstamp from; 58 59 main(argc, argv) 60 char *argv[]; 61 { 62 struct stat b; 63 int size; 64 char *cp; 65 int hostfrom, impfrom; 66 67 argc--, argv++; 68 while (argc > 0 && argv[0][0] == '-') { 69 if (strcmp(*argv, "-D") == 0) { 70 showdata = 0; 71 argv++, argc--; 72 continue; 73 } 74 if (strcmp(*argv, "-f") == 0) { 75 follow++; 76 argv++, argc--; 77 continue; 78 } 79 if (strcmp(*argv, "-c") == 0) { 80 showcontents++; 81 argv++, argc--; 82 continue; 83 } 84 if (strcmp(*argv, "-r") == 0) { 85 rawheader++; 86 argv++, argc--; 87 continue; 88 } 89 if (strcmp(*argv, "-l") == 0) { 90 argc--, argv++; 91 if (argc > 0) { 92 link = atoi(*argv); 93 argc--, argv++; 94 } else 95 link = IMPLINK_IP; 96 continue; 97 } 98 if (strcmp(*argv, "-h") == 0) { 99 argc--, argv++; 100 if (argc < 1) { 101 printf("-h: missing host #\n"); 102 exit(2); 103 } 104 host = atoi(*argv); 105 argv++, argc--; 106 continue; 107 } 108 if (strcmp(*argv, "-i") == 0) { 109 argc--, argv++; 110 if (argc < 1) { 111 printf("-i: missing imp #\n"); 112 exit(2); 113 } 114 imp = atoi(*argv); 115 argv++, argc--; 116 continue; 117 } 118 if (strcmp(*argv, "-t") == 0) { 119 argc--, argv++;; 120 if (argc < 1) { 121 printf("-t: missing packet type\n"); 122 exit(2); 123 } 124 packettype = atoi(*argv); 125 argv++, argc--;; 126 continue; 127 } 128 printf("usage: implog [ -D ] [ -c ] [ -f ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n"); 129 exit(2); 130 } 131 if (argc > 0) 132 logfile = argv[0]; 133 log = open(logfile, 0); 134 if (log < 0) { 135 perror(logfile); 136 exit(1); 137 } 138 fstat(log, &b); 139 size = b.st_size; 140 again: 141 while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) { 142 if (from.sin_family == 0) { 143 printf("restarted: %.24s\n", ctime(&from.sin_time)); 144 continue; 145 } 146 if (host >= 0) { 147 long addr = ntohs(from.sin_addr.s_addr); 148 149 if (IN_CLASSA(addr)) { 150 hostfrom = ((addr>>16) & 0xFF); 151 impfrom = addr & 0xFF; 152 } else if (IN_CLASSB(addr)) { 153 hostfrom = ((addr>>8) & 0xFF); 154 impfrom = addr & 0xFF; 155 } else { 156 hostfrom = ((addr>>4) & 0xF); 157 impfrom = addr & 0xF; 158 } 159 } 160 if (host >= 0 && hostfrom != host) { 161 lseek(log, from.sin_cc, 1); 162 continue; 163 } 164 if (imp >= 0 && impfrom != imp) { 165 lseek(log, from.sin_cc, 1); 166 continue; 167 } 168 process(log, &from); 169 } 170 while (follow) { 171 fflush(stdout); 172 sleep(5); 173 fstat(log, &b); 174 if (b.st_size > size) { 175 size = b.st_size; 176 goto again; 177 } 178 } 179 } 180 181 int impdata(), impbadleader(), impdown(), impnoop(); 182 int imprfnm(), impincomplete(), imphostdead(), imphostunreach(); 183 int impbaddata(), impreset(), impretry(), impnotify(), imptrying(); 184 int impready(), impundef(); 185 186 struct messages { 187 u_char m_type; /* type of message */ 188 int (*m_func)(); /* routine to process message */ 189 } mtypes[] = { 190 { IMPTYPE_DATA, impdata }, 191 { IMPTYPE_BADLEADER, impbadleader }, 192 { IMPTYPE_DOWN, impdown }, 193 { IMPTYPE_NOOP, impnoop }, 194 { IMPTYPE_RFNM, imprfnm }, 195 { IMPTYPE_INCOMPLETE, impincomplete }, 196 { IMPTYPE_HOSTDEAD, imphostdead }, 197 { IMPTYPE_HOSTUNREACH, imphostunreach }, 198 { IMPTYPE_BADDATA, impbaddata }, 199 { IMPTYPE_RESET, impreset }, 200 { IMPTYPE_RETRY, impretry }, 201 { IMPTYPE_NOTIFY, impnotify }, 202 { IMPTYPE_TRYING, imptrying }, 203 { IMPTYPE_READY, impready }, 204 { -1, impundef } 205 }; 206 207 /* 208 * Print a packet. 209 */ 210 process(l, f) 211 int l; 212 struct sockstamp *f; 213 { 214 register struct messages *mp; 215 struct imp_leader *ip; 216 int (*fn)(); 217 218 if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) { 219 perror("read"); 220 return; 221 } 222 ip = (struct imp_leader *)buf; 223 ip->il_imp = ntohs(ip->il_imp); 224 if (ip->il_format != IMP_NFF) 225 fn = impundef; 226 else { 227 for (mp = mtypes; mp->m_type != -1; mp++) 228 if (mp->m_type == ip->il_mtype) 229 break; 230 fn = mp->m_func; 231 } 232 if (ip->il_mtype == IMPTYPE_DATA) { 233 if (link >= 0 && ip->il_link != link) 234 return; 235 if (!showdata) 236 return; 237 } 238 if (packettype >= 0 && ip->il_mtype != packettype) 239 return; 240 printf("%.24s: ", ctime(&f->sin_time)); 241 if (f->sin_cc < sizeof(struct control_leader)) 242 printf("(truncated header, %d bytes): ", f->sin_cc); 243 (*fn)(ip, f->sin_cc); 244 if (rawheader && fn != impundef) { 245 putchar('\t'); 246 impundef(ip, f->sin_cc); 247 } 248 } 249 250 impdata(ip, cc) 251 register struct imp_leader *ip; 252 { 253 printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp); 254 if (ip->il_link == IMPLINK_IP) 255 printf("ip,"); 256 else 257 printf("%d,", ip->il_link); 258 printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 259 if (showcontents) { 260 register u_char *cp = ((u_char *)ip) + sizeof(*ip); 261 register int i; 262 263 i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 264 cc = min(i, cc); 265 printf("data: (%d bytes)", cc); 266 for (i = 0; i < cc; i++, cp++) { 267 if (i % 25 == 0) 268 printf("\n"); 269 printf("%02x ", *cp); 270 } 271 putchar('\n'); 272 } 273 } 274 275 char *badleader[] = { 276 "error flip-flop set", 277 "message < 80 bits", 278 "illegal type field", 279 "opposite leader type" 280 }; 281 282 impbadleader(ip) 283 register struct imp_leader *ip; 284 { 285 printf("bad leader: "); 286 if (ip->il_subtype > IMPLEADER_OPPOSITE) 287 printf("%x\n", ip->il_subtype); 288 else 289 printf("%s\n", badleader[ip->il_subtype]); 290 } 291 292 char *down[] = { 293 "in 30 secs", 294 "for hardware pm", 295 "for software reload", 296 "for emergency restart" 297 }; 298 299 impdown(ip) 300 register struct imp_leader *ip; 301 { 302 int tdown, tbackup; 303 304 printf("imp going down %s", down[ip->il_link & IMP_DMASK]); 305 tdown = ((ip->il_link >> 2) & 0xf) * 5; 306 if (ip->il_link & IMP_DMASK) 307 printf(" in %d minutes", tdown); 308 tbackup = ip->il_subtype * 5; 309 printf(": back up "); 310 if (tbackup) 311 printf("%d minutes\n", tbackup); 312 else 313 printf("immediately\n"); 314 } 315 316 impnoop(ip) 317 register struct imp_leader *ip; 318 { 319 printf("noop: host %d, imp %d\n", ip->il_host, 320 (u_short)ip->il_imp); 321 } 322 323 imprfnm(ip) 324 register struct imp_leader *ip; 325 { 326 printf("rfnm: htype=%x, source=%d/%d, link=", 327 ip->il_htype, ip->il_host, ip->il_imp); 328 if (ip->il_link == IMPLINK_IP) 329 printf("ip,"); 330 else 331 printf("%d,", ip->il_link); 332 printf(" subtype=%x\n", ip->il_subtype); 333 } 334 335 char *hostdead[] = { 336 "#0", 337 "ready-line negated", 338 "tardy receiving messages", 339 "ncc doesn't know host", 340 "imp software won't allow messages", 341 "host down for scheduled pm", 342 "host down for hardware work", 343 "host down for software work", 344 "host down for emergency restart", 345 "host down because of power outage", 346 "host stopped at a breakpoint", 347 "host down due to hardware failure", 348 "host not scheduled to be up", 349 "#13", 350 "#14", 351 "host in the process of coming up" 352 }; 353 354 imphostdead(ip) 355 register struct imp_leader *ip; 356 { 357 printf("host %d/%d dead: ", ip->il_host, ip->il_imp); 358 if (ip->il_link & IMP_DMASK) 359 printf("down %s, ", down[ip->il_link & IMP_DMASK]); 360 if (ip->il_subtype <= IMPHOST_COMINGUP) 361 printf("%s\n", hostdead[ip->il_subtype]); 362 else 363 printf("subtype=%x\n", ip->il_subtype); 364 } 365 366 char *hostunreach[] = { 367 "destination imp can't be reached", 368 "destination host isn't up", 369 "host doesn't support long leader", 370 "communication is prohibited" 371 }; 372 373 imphostunreach(ip) 374 register struct imp_leader *ip; 375 { 376 printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp); 377 if (ip->il_subtype <= IMPREACH_PROHIBITED) 378 printf("%s\n", hostunreach[ip->il_subtype]); 379 else 380 printf("subtype=%x\n", ip->il_subtype); 381 } 382 383 impbaddata(ip) 384 register struct imp_leader *ip; 385 { 386 printf("error in data: htype=%x, source=%d/%d, link=", 387 ip->il_htype, ip->il_host, ip->il_imp); 388 if (ip->il_link == IMPLINK_IP) 389 printf("ip, "); 390 else 391 printf("%d, ", ip->il_link); 392 printf("subtype=%x\n", ip->il_subtype); 393 } 394 395 char *incomplete[] = { 396 "host didn't take data fast enough", 397 "message was too long", 398 "message transmission time > 15 seconds", 399 "imp/circuit failure", 400 "no resources within 15 seconds", 401 "source imp i/o failure during receipt" 402 }; 403 404 impincomplete(ip) 405 register struct imp_leader *ip; 406 { 407 printf("incomplete: htype=%x, source=%d/%d, link=", 408 ip->il_htype, ip->il_host, ip->il_imp); 409 if (ip->il_link == IMPLINK_IP) 410 printf("ip,"); 411 else 412 printf("%d,", ip->il_link); 413 if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 414 printf(" %s\n", incomplete[ip->il_subtype]); 415 else 416 printf(" subtype=%x\n", ip->il_subtype); 417 } 418 419 impreset(ip) 420 register struct imp_leader *ip; 421 { 422 printf("reset complete\n"); 423 } 424 425 char *retry[] = { 426 "imp buffer wasn't available", 427 "connection block unavailable" 428 }; 429 430 impretry(ip) 431 register struct imp_leader *ip; 432 { 433 printf("refused, try again: "); 434 if (ip->il_subtype <= IMPRETRY_BLOCK) 435 printf("%s\n", retry[ip->il_subtype]); 436 else 437 printf("subtype=%x\n", ip->il_subtype); 438 } 439 440 char *notify[] = { 441 "#0", 442 "#1", 443 "connection not available", 444 "reassembly space not available at destination", 445 "message number not available", 446 "transaction block for message not available" 447 }; 448 449 impnotify(ip) 450 register struct imp_leader *ip; 451 { 452 printf("refused, will notify: "); 453 if (ip->il_subtype <= 5) 454 printf("%s\n", notify[ip->il_subtype]); 455 else 456 printf("subtype=%x\n", ip->il_subtype); 457 } 458 459 imptrying(ip) 460 register struct imp_leader *ip; 461 { 462 printf("refused, still trying\n"); 463 } 464 465 impready(ip) 466 register struct imp_leader *ip; 467 { 468 printf("ready\n"); 469 } 470 471 impundef(ip, len) 472 register struct imp_leader *ip; 473 { 474 printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 475 ip->il_network, ip->il_flags); 476 printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=", 477 ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host, 478 ip->il_imp, ip->il_imp); 479 if (ip->il_link == IMPLINK_IP) 480 printf("ip,"); 481 else 482 printf("%d (x%x),", ip->il_link, ip->il_link); 483 printf(" subtype=%x", ip->il_subtype); 484 if (len >= sizeof(struct imp_leader) && ip->il_length) 485 printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3); 486 printf(">\n"); 487 } 488