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