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