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.4 (Berkeley) 05/05/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((u_short)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 (*fn)(ip, f->sin_cc); 242 if (rawheader && fn != impundef) 243 impundef(ip, f->sin_cc); 244 } 245 246 impdata(ip, cc) 247 register struct imp_leader *ip; 248 { 249 printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp); 250 if (ip->il_link == IMPLINK_IP) 251 printf("ip,"); 252 else 253 printf("%d,", ip->il_link); 254 printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3); 255 if (showcontents) { 256 register u_char *cp = ((u_char *)ip) + sizeof(*ip); 257 register int i; 258 259 i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader); 260 cc = min(i, cc); 261 printf("data: (%d bytes)", cc); 262 for (i = 0; i < cc; i++, cp++) { 263 if (i % 25 == 0) 264 printf("\n"); 265 printf("%02x ", *cp); 266 } 267 putchar('\n'); 268 } 269 } 270 271 char *badleader[] = { 272 "error flip-flop set", 273 "message < 80 bits", 274 "illegal type field", 275 "opposite leader type" 276 }; 277 278 impbadleader(ip) 279 register struct imp_leader *ip; 280 { 281 printf("bad leader: "); 282 if (ip->il_subtype > IMPLEADER_OPPOSITE) 283 printf("%x\n", ip->il_subtype); 284 else 285 printf("%s\n", badleader[ip->il_subtype]); 286 } 287 288 char *down[] = { 289 "in 30 secs", 290 "for hardware pm", 291 "for software reload", 292 "for emergency restart" 293 }; 294 295 impdown(ip) 296 register struct imp_leader *ip; 297 { 298 int tdown, tbackup; 299 300 printf("imp going down %s", down[ip->il_link & IMP_DMASK]); 301 tdown = ((ip->il_link >> 2) & 0xf) * 5; 302 if (ip->il_link & IMP_DMASK) 303 printf(" in %d minutes", tdown); 304 tbackup = ip->il_subtype * 5; 305 printf(": back up "); 306 if (tbackup) 307 printf("%d minutes\n", tbackup); 308 else 309 printf("immediately\n"); 310 } 311 312 impnoop(ip) 313 register struct imp_leader *ip; 314 { 315 printf("noop: host %d, imp %d\n", ip->il_host, 316 (u_short)ip->il_imp); 317 } 318 319 imprfnm(ip) 320 register struct imp_leader *ip; 321 { 322 printf("rfnm: htype=%x, source=%d/%d, link=", 323 ip->il_htype, ip->il_host, ip->il_imp); 324 if (ip->il_link == IMPLINK_IP) 325 printf("ip,"); 326 else 327 printf("%d,", ip->il_link); 328 printf(" subtype=%x\n", ip->il_subtype); 329 } 330 331 char *hostdead[] = { 332 "#0", 333 "ready-line negated", 334 "tardy receiving messages", 335 "ncc doesn't know host", 336 "imp software won't allow messages", 337 "host down for scheduled pm", 338 "host down for hardware work", 339 "host down for software work", 340 "host down for emergency restart", 341 "host down because of power outage", 342 "host stopped at a breakpoint", 343 "host down due to hardware failure", 344 "host not scheduled to be up", 345 "#13", 346 "#14", 347 "host in the process of coming up" 348 }; 349 350 imphostdead(ip) 351 register struct imp_leader *ip; 352 { 353 printf("host %d/%d dead: ", ip->il_host, ip->il_imp); 354 if (ip->il_link & IMP_DMASK) 355 printf("down %s, ", down[ip->il_link & IMP_DMASK]); 356 if (ip->il_subtype <= IMPHOST_COMINGUP) 357 printf("%s\n", hostdead[ip->il_subtype]); 358 else 359 printf("subtype=%x\n", ip->il_subtype); 360 } 361 362 char *hostunreach[] = { 363 "destination imp can't be reached", 364 "destination host isn't up", 365 "host doesn't support long leader", 366 "communication is prohibited" 367 }; 368 369 imphostunreach(ip) 370 register struct imp_leader *ip; 371 { 372 printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp); 373 if (ip->il_subtype <= IMPREACH_PROHIBITED) 374 printf("%s\n", hostunreach[ip->il_subtype]); 375 else 376 printf("subtype=%x\n", ip->il_subtype); 377 } 378 379 impbaddata(ip) 380 register struct imp_leader *ip; 381 { 382 printf("error in data: htype=%x, source=%d/%d, link=", 383 ip->il_htype, ip->il_host, ip->il_imp); 384 if (ip->il_link == IMPLINK_IP) 385 printf("ip, "); 386 else 387 printf("%d, ", ip->il_link); 388 printf("subtype=%x\n", ip->il_subtype); 389 } 390 391 char *incomplete[] = { 392 "host didn't take data fast enough", 393 "message was too long", 394 "message transmission time > 15 seconds", 395 "imp/circuit failure", 396 "no resources within 15 seconds", 397 "source imp i/o failure during receipt" 398 }; 399 400 impincomplete(ip) 401 register struct imp_leader *ip; 402 { 403 printf("incomplete: htype=%x, source=%d/%d, link=", 404 ip->il_htype, ip->il_host, ip->il_imp); 405 if (ip->il_link == IMPLINK_IP) 406 printf("ip,"); 407 else 408 printf("%d,", ip->il_link); 409 if (ip->il_subtype <= IMPCOMPLETE_IMPIO) 410 printf(" %s\n", incomplete[ip->il_subtype]); 411 else 412 printf(" subtype=%x\n", ip->il_subtype); 413 } 414 415 impreset(ip) 416 register struct imp_leader *ip; 417 { 418 printf("reset complete\n"); 419 } 420 421 char *retry[] = { 422 "imp buffer wasn't available", 423 "connection block unavailable" 424 }; 425 426 impretry(ip) 427 register struct imp_leader *ip; 428 { 429 printf("refused, try again: "); 430 if (ip->il_subtype <= IMPRETRY_BLOCK) 431 printf("%s\n", retry[ip->il_subtype]); 432 else 433 printf("subtype=%x\n", ip->il_subtype); 434 } 435 436 char *notify[] = { 437 "#0", 438 "#1", 439 "connection not available", 440 "reassembly space not available at destination", 441 "message number not available", 442 "transaction block for message not available" 443 }; 444 445 impnotify(ip) 446 register struct imp_leader *ip; 447 { 448 printf("refused, will notify: "); 449 if (ip->il_subtype <= 5) 450 printf("%s\n", notify[ip->il_subtype]); 451 else 452 printf("subtype=%x\n", ip->il_subtype); 453 } 454 455 imptrying(ip) 456 register struct imp_leader *ip; 457 { 458 printf("refused, still trying\n"); 459 } 460 461 impready(ip) 462 register struct imp_leader *ip; 463 { 464 printf("ready\n"); 465 } 466 467 impundef(ip) 468 register struct imp_leader *ip; 469 { 470 printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format, 471 ip->il_network, ip->il_flags); 472 printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype, 473 ip->il_htype, ip->il_host, ip->il_imp); 474 if (ip->il_link == IMPLINK_IP) 475 printf("ip,"); 476 else 477 printf("%d,", ip->il_link); 478 printf(" subtype=%x>\n", ip->il_subtype); 479 } 480