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