1 /*- 2 * Copyright (c) 1989, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)iso.c 5.7 (Berkeley) 01/27/92"; 10 #endif /* not lint */ 11 12 /* 13 * $Header: iso.c,v 3.3 88/12/08 14:44:49 hagens Exp $ 14 * $Source: /usr/argo/src/ucb/netstat/RCS/iso.c,v $ 15 */ 16 /******************************************************************************* 17 Copyright IBM Corporation 1987 18 19 All Rights Reserved 20 21 Permission to use, copy, modify, and distribute this software and its 22 documentation for any purpose and without fee is hereby granted, 23 provided that the above copyright notice appear in all copies and that 24 both that copyright notice and this permission notice appear in 25 supporting documentation, and that the name of IBM not be 26 used in advertising or publicity pertaining to distribution of the 27 software without specific, written prior permission. 28 29 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 30 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 31 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 32 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 33 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 34 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 35 SOFTWARE. 36 37 *******************************************************************************/ 38 39 /* 40 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison 41 */ 42 43 #include <sys/param.h> 44 #include <sys/mbuf.h> 45 #include <sys/time.h> 46 #include <sys/domain.h> 47 #include <sys/protosw.h> 48 #include <sys/socket.h> 49 #include <sys/socketvar.h> 50 #include <errno.h> 51 #include <net/if.h> 52 #include <net/route.h> 53 #include <netinet/in.h> 54 #include <netinet/in_systm.h> 55 #include <netinet/ip.h> 56 #include <netinet/in_pcb.h> 57 #include <netinet/ip_var.h> 58 #include <netiso/iso.h> 59 #include <netiso/iso_errno.h> 60 #include <netiso/clnp.h> 61 #include <netiso/esis.h> 62 #include <netiso/clnp_stat.h> 63 #include <netiso/argo_debug.h> 64 #undef satosiso 65 #include <netiso/tp_param.h> 66 #include <netiso/tp_states.h> 67 #include <netiso/tp_astring.c> 68 #include <netiso/tp_pcb.h> 69 #include <netiso/tp_stat.h> 70 #include <netiso/iso_pcb.h> 71 #include <netiso/cltp_var.h> 72 #include <netiso/cons.h> 73 #ifdef IncStat 74 #undef IncStat 75 #endif 76 #include <netiso/cons_pcb.h> 77 #include <netdb.h> 78 79 80 /* 81 * Dump esis stats 82 */ 83 esis_stats(off, name) 84 off_t off; 85 char *name; 86 { 87 struct esis_stat esis_stat; 88 89 if (off == 0) 90 return; 91 kvm_read(off, (char *)&esis_stat, sizeof (struct esis_stat)); 92 printf("%s:\n", name); 93 printf("\t%d esh sent, %d esh received\n", esis_stat.es_eshsent, 94 esis_stat.es_eshrcvd); 95 printf("\t%d ish sent, %d ish received\n", esis_stat.es_ishsent, 96 esis_stat.es_ishrcvd); 97 printf("\t%d rd sent, %d rd received\n", esis_stat.es_rdsent, 98 esis_stat.es_rdrcvd); 99 printf("\t%d pdus not sent due to insufficient memory\n", 100 esis_stat.es_nomem); 101 printf("\t%d pdus received with bad checksum\n", esis_stat.es_badcsum); 102 printf("\t%d pdus received with bad version number\n", 103 esis_stat.es_badvers); 104 printf("\t%d pdus received with bad type field\n", esis_stat.es_badtype); 105 printf("\t%d short pdus received\n", esis_stat.es_toosmall); 106 } 107 108 /* 109 * Dump clnp statistics structure. 110 */ 111 clnp_stats(off, name) 112 off_t off; 113 char *name; 114 { 115 struct clnp_stat clnp_stat; 116 117 if (off == 0) 118 return; 119 kvm_read(off, (char *)&clnp_stat, sizeof (clnp_stat)); 120 121 printf("%s:\n\t%d total packets sent\n", name, clnp_stat.cns_sent); 122 printf("\t%d total fragments sent\n", clnp_stat.cns_fragments); 123 printf("\t%d total packets received\n", clnp_stat.cns_total); 124 printf("\t%d with fixed part of header too small\n", 125 clnp_stat.cns_toosmall); 126 printf("\t%d with header length not reasonable\n", clnp_stat.cns_badhlen); 127 printf("\t%d incorrect checksum%s\n", 128 clnp_stat.cns_badcsum, plural(clnp_stat.cns_badcsum)); 129 printf("\t%d with unreasonable address lengths\n", clnp_stat.cns_badaddr); 130 printf("\t%d with forgotten segmentation information\n", 131 clnp_stat.cns_noseg); 132 printf("\t%d with an incorrect protocol identifier\n", clnp_stat.cns_noproto); 133 printf("\t%d with an incorrect version\n", clnp_stat.cns_badvers); 134 printf("\t%d dropped because the ttl has expired\n", 135 clnp_stat.cns_ttlexpired); 136 printf("\t%d clnp cache misses\n", clnp_stat.cns_cachemiss); 137 printf("\t%d clnp congestion experience bits set\n", 138 clnp_stat.cns_congest_set); 139 printf("\t%d clnp congestion experience bits received\n", 140 clnp_stat.cns_congest_rcvd); 141 } 142 /* 143 * Dump CLTP statistics structure. 144 */ 145 cltp_stats(off, name) 146 off_t off; 147 char *name; 148 { 149 struct cltpstat cltpstat; 150 151 if (off == 0) 152 return; 153 kvm_read(off, (char *)&cltpstat, sizeof (cltpstat)); 154 printf("%s:\n\t%u incomplete header%s\n", name, 155 cltpstat.cltps_hdrops, plural(cltpstat.cltps_hdrops)); 156 printf("\t%u bad data length field%s\n", 157 cltpstat.cltps_badlen, plural(cltpstat.cltps_badlen)); 158 printf("\t%u bad checksum%s\n", 159 cltpstat.cltps_badsum, plural(cltpstat.cltps_badsum)); 160 } 161 162 struct tp_pcb tpcb; 163 struct isopcb isopcb; 164 struct socket sockb; 165 union { 166 struct sockaddr_iso siso; 167 char data[128]; 168 } laddr, faddr; 169 #define kget(o, p) \ 170 (kvm_read((off_t)(o), (char *)&p, sizeof (p))) 171 extern int Aflag; 172 extern int aflag; 173 extern int nflag; 174 175 static int first = 1; 176 177 /* 178 * Print a summary of connections related to an Internet 179 * protocol. For TP, also give state of connection. 180 * Listening processes (aflag) are suppressed unless the 181 * -a (all) flag is specified. 182 */ 183 iso_protopr(off, name) 184 off_t off; 185 char *name; 186 { 187 struct isopcb cb; 188 register struct isopcb *prev, *next; 189 190 if (off == 0) { 191 printf("%s control block: symbol not in namelist\n", name); 192 return; 193 } 194 if (strcmp(name, "tp") == 0) 195 return tp_protopr(off, name); 196 kget(off, cb); 197 isopcb = cb; 198 prev = (struct isopcb *)off; 199 if (isopcb.isop_next == (struct isopcb *)off) 200 return; 201 while (isopcb.isop_next != (struct isopcb *)off) { 202 next = isopcb.isop_next; 203 kget(next, isopcb); 204 if (isopcb.isop_prev != prev) { 205 printf("prev 0x%x next 0x%x isop_prev 0x%x isop_next 0x%x???\n", 206 prev, next, isopcb.isop_prev, isopcb.isop_next); 207 break; 208 } 209 kget(isopcb.isop_socket, sockb); 210 iso_protopr1((off_t)next, 0); 211 putchar('\n'); 212 prev = next; 213 } 214 } 215 216 iso_protopr1(kern_addr, istp) 217 off_t kern_addr; 218 { 219 if (first) { 220 printf("Active ISO net connections"); 221 if (aflag) 222 printf(" (including servers)"); 223 putchar('\n'); 224 if (Aflag) 225 printf("%-8.8s ", "PCB"); 226 printf(Aflag ? 227 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 228 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 229 "Proto", "Recv-Q", "Send-Q", 230 "Local Address", "Foreign Address", "(state)"); 231 first = 0; 232 } 233 if (Aflag) 234 printf("%8x ", 235 (sockb.so_pcb ? (off_t)sockb.so_pcb : (off_t)kern_addr)); 236 printf("%-5.5s %6d %6d ", "tp", sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); 237 if (istp && tpcb.tp_lsuffixlen) { 238 hexprint(tpcb.tp_lsuffixlen, tpcb.tp_lsuffix, "()"); 239 printf("\t"); 240 } else if (isopcb.isop_laddr == 0) 241 printf("*.*\t"); 242 else { 243 if ((char *)isopcb.isop_laddr == ((char *)kern_addr) + 244 _offsetof(struct isopcb, isop_sladdr)) 245 laddr.siso = isopcb.isop_sladdr; 246 else 247 kget(isopcb.isop_laddr, laddr); 248 isonetprint(&laddr, 1); 249 } 250 if (istp && tpcb.tp_fsuffixlen) { 251 hexprint(tpcb.tp_fsuffixlen, tpcb.tp_fsuffix, "()"); 252 printf("\t"); 253 } else if (isopcb.isop_faddr == 0) 254 printf("*.*\t"); 255 else { 256 if ((char *)isopcb.isop_faddr == ((char *)kern_addr) + 257 _offsetof(struct isopcb, isop_sfaddr)) 258 faddr.siso = isopcb.isop_sfaddr; 259 else 260 kget(isopcb.isop_faddr, faddr); 261 isonetprint(&faddr, 0); 262 } 263 } 264 265 tp_protopr(off, name) 266 off_t off; 267 char *name; 268 { 269 struct tp_ref *tpr, *tpr_base; 270 struct tp_refinfo tpkerninfo; 271 int size; 272 273 kget(off, tpkerninfo); 274 size = tpkerninfo.tpr_size * sizeof (*tpr); 275 tpr_base = (struct tp_ref *)malloc(size); 276 if (tpr_base == 0) 277 return; 278 kvm_read((off_t)(tpkerninfo.tpr_base), (char *)tpr_base, size); 279 for (tpr = tpr_base; tpr < tpr_base + tpkerninfo.tpr_size; tpr++) { 280 if (tpr->tpr_pcb == 0) 281 continue; 282 kget(tpr->tpr_pcb, tpcb); 283 if (tpcb.tp_state == ST_ERROR) 284 printf("undefined tpcb state: 0x%x\n", tpr->tpr_pcb); 285 if (!aflag && 286 (tpcb.tp_state == TP_LISTENING || 287 tpcb.tp_state == TP_CLOSED || 288 tpcb.tp_state == TP_REFWAIT)) { 289 continue; 290 } 291 kget(tpcb.tp_sock, sockb); 292 if (tpcb.tp_npcb) switch(tpcb.tp_netservice) { 293 case IN_CLNS: 294 tp_inproto(tpkerninfo.tpr_base); 295 break; 296 default: 297 kget(tpcb.tp_npcb, isopcb); 298 iso_protopr1(tpcb.tp_npcb, 1); 299 break; 300 } 301 if (tpcb.tp_state >= tp_NSTATES) 302 printf(" %d", tpcb.tp_state); 303 else 304 printf(" %-12.12s", tp_sstring[tpcb.tp_state]); 305 putchar('\n'); 306 } 307 } 308 tp_inproto(pcb) 309 off_t pcb; 310 { 311 struct inpcb inpcb; 312 kget(tpcb.tp_npcb, inpcb); 313 if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) 314 return; 315 if (Aflag) 316 printf("%8x ", pcb); 317 printf("%-5.5s %6d %6d ", "tpip", sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); 318 inetprint(&inpcb.inp_laddr, inpcb.inp_lport, "tp"); 319 inetprint(&inpcb.inp_faddr, inpcb.inp_fport, "tp"); 320 } 321 /* 322 * Pretty print an iso address (net address + port). 323 * If the nflag was specified, use numbers instead of names. 324 */ 325 326 #ifdef notdef 327 char * 328 isonetname(iso) 329 register struct iso_addr *iso; 330 { 331 struct sockaddr_iso sa; 332 struct iso_hostent *ihe = 0; 333 struct iso_hostent *iso_gethostentrybyaddr(); 334 struct iso_hostent *iso_getserventrybytsel(); 335 struct iso_hostent Ihe; 336 static char line[80]; 337 char *index(); 338 339 bzero(line, sizeof(line)); 340 if( iso->isoa_afi ) { 341 sa.siso_family = AF_ISO; 342 sa.siso_addr = *iso; 343 sa.siso_tsuffix = 0; 344 345 if (!nflag ) 346 ihe = iso_gethostentrybyaddr( &sa, 0, 0 ); 347 if( ihe ) { 348 Ihe = *ihe; 349 ihe = &Ihe; 350 sprintf(line, "%s", ihe->isoh_hname); 351 } else { 352 sprintf(line, "%s", iso_ntoa(iso)); 353 } 354 } else { 355 sprintf(line, "*"); 356 } 357 return line; 358 } 359 360 isonetprint(iso, sufx, sufxlen, islocal) 361 register struct iso_addr *iso; 362 char *sufx; 363 u_short sufxlen; 364 int islocal; 365 { 366 struct iso_hostent *iso_getserventrybytsel(), *ihe; 367 struct iso_hostent Ihe; 368 char *line, *cp, *index(); 369 int Alen = Aflag?18:22; 370 371 line = isonetname(iso); 372 cp = index(line, '\0'); 373 ihe = (struct iso_hostent *)0; 374 375 if( islocal ) 376 islocal = 20; 377 else 378 islocal = 22 + Alen; 379 380 if(Aflag) 381 islocal += 10 ; 382 383 if(!nflag) { 384 if( (cp -line)>10 ) { 385 cp = line+10; 386 bzero(cp, sizeof(line)-10); 387 } 388 } 389 390 *cp++ = '.'; 391 if(sufxlen) { 392 if( !Aflag && !nflag && (ihe=iso_getserventrybytsel(sufx, sufxlen))) { 393 Ihe = *ihe; 394 ihe = &Ihe; 395 } 396 if( ihe && (strlen(ihe->isoh_aname)>0) ) { 397 sprintf(cp, "%s", ihe->isoh_aname); 398 } else { 399 iso_sprinttsel(cp, sufx, sufxlen); 400 } 401 } else 402 sprintf(cp, "*"); 403 /* 404 fprintf(stdout, Aflag?" %-18.18s":" %-22.22s", line); 405 */ 406 407 if( strlen(line) > Alen ) { 408 fprintf(stdout, " %s", line); 409 fprintf(stdout, "\n %*.s", islocal+Alen," "); 410 } else { 411 fprintf(stdout, " %-*.*s", Alen, Alen,line); 412 } 413 } 414 #endif 415 416 #ifdef notdef 417 x25_protopr(off, name) 418 off_t off; 419 char *name; 420 { 421 static char *xpcb_states[] = { 422 "CLOSED", 423 "LISTENING", 424 "CLOSING", 425 "CONNECTING", 426 "ACKWAIT", 427 "OPEN", 428 }; 429 register struct isopcb *prev, *next; 430 struct x25_pcb xpcb; 431 432 if (off == 0) { 433 printf("%s control block: symbol not in namelist\n", name); 434 return; 435 } 436 kvm_read(off, &xpcb, sizeof (struct x25_pcb)); 437 prev = (struct isopcb *)off; 438 if (xpcb.x_next == (struct isopcb *)off) 439 return; 440 while (xpcb.x_next != (struct isopcb *)off) { 441 next = isopcb.isop_next; 442 kvm_read((off_t)next, &xpcb, sizeof (struct x25_pcb)); 443 if (xpcb.x_prev != prev) { 444 printf("???\n"); 445 break; 446 } 447 kvm_read((off_t)xpcb.x_socket, &sockb, sizeof (sockb)); 448 449 if (!aflag && 450 xpcb.x_state == LISTENING || 451 xpcb.x_state == TP_CLOSED ) { 452 prev = next; 453 continue; 454 } 455 if (first) { 456 printf("Active X25 net connections"); 457 if (aflag) 458 printf(" (including servers)"); 459 putchar('\n'); 460 if (Aflag) 461 printf("%-8.8s ", "PCB"); 462 printf(Aflag ? 463 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 464 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 465 "Proto", "Recv-Q", "Send-Q", 466 "Local Address", "Foreign Address", "(state)"); 467 first = 0; 468 } 469 printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, 470 sockb.so_snd.sb_cc); 471 isonetprint(&xpcb.x_laddr.siso_addr, &xpcb.x_lport, 472 sizeof(xpcb.x_lport), 1); 473 isonetprint(&xpcb.x_faddr.siso_addr, &xpcb.x_fport, 474 sizeof(xpcb.x_lport), 0); 475 if (xpcb.x_state < 0 || xpcb.x_state >= x25_NSTATES) 476 printf(" 0x0x0x0x0x0x0x0x0x%x", xpcb.x_state); 477 else 478 printf(" %-12.12s", xpcb_states[xpcb.x_state]); 479 putchar('\n'); 480 prev = next; 481 } 482 } 483 #endif 484 485 struct tp_stat tp_stat; 486 487 tp_stats(off, name) 488 caddr_t off, name; 489 { 490 if (off == 0) { 491 printf("TP not configured\n\n"); 492 return; 493 } 494 printf("%s:\n", name); 495 kget(off, tp_stat); 496 tprintstat(&tp_stat, 8); 497 } 498 499 #define OUT stdout 500 501 #define plural(x) (x>1?"s":"") 502 503 tprintstat(s, indent) 504 register struct tp_stat *s; 505 int indent; 506 { 507 fprintf(OUT, 508 "%*sReceiving:\n",indent," "); 509 fprintf(OUT, 510 "\t%*s%d variable parameter%s ignored\n", indent," ", 511 s->ts_param_ignored ,plural(s->ts_param_ignored)); 512 fprintf(OUT, 513 "\t%*s%d invalid parameter code%s\n", indent, " ", 514 s->ts_inv_pcode ,plural(s->ts_inv_pcode)); 515 fprintf(OUT, 516 "\t%*s%d invalid parameter value%s\n", indent, " ", 517 s->ts_inv_pval ,plural(s->ts_inv_pval)); 518 fprintf(OUT, 519 "\t%*s%d invalid dutype%s\n", indent, " ", 520 s->ts_inv_dutype ,plural(s->ts_inv_dutype)); 521 fprintf(OUT, 522 "\t%*s%d negotiation failure%s\n", indent, " ", 523 s->ts_negotfailed ,plural(s->ts_negotfailed)); 524 fprintf(OUT, 525 "\t%*s%d invalid destination reference%s\n", indent, " ", 526 s->ts_inv_dref ,plural(s->ts_inv_dref)); 527 fprintf(OUT, 528 "\t%*s%d invalid suffix parameter%s\n", indent, " ", 529 s->ts_inv_sufx ,plural(s->ts_inv_sufx)); 530 fprintf(OUT, 531 "\t%*s%d invalid length\n",indent, " ", s->ts_inv_length); 532 fprintf(OUT, 533 "\t%*s%d invalid checksum%s\n", indent, " ", 534 s->ts_bad_csum ,plural(s->ts_bad_csum)); 535 fprintf(OUT, 536 "\t%*s%d DT%s out of order\n", indent, " ", 537 s->ts_dt_ooo ,plural(s->ts_dt_ooo)); 538 fprintf(OUT, 539 "\t%*s%d DT%s not in window\n", indent, " ", 540 s->ts_dt_niw ,plural(s->ts_dt_niw)); 541 fprintf(OUT, 542 "\t%*s%d duplicate DT%s\n", indent, " ", 543 s->ts_dt_dup ,plural(s->ts_dt_dup)); 544 fprintf(OUT, 545 "\t%*s%d XPD%s not in window\n", indent, " ", 546 s->ts_xpd_niw ,plural(s->ts_xpd_niw)); 547 fprintf(OUT, 548 "\t%*s%d XPD%s w/o credit to stash\n", indent, " ", 549 s->ts_xpd_dup ,plural(s->ts_xpd_dup)); 550 fprintf(OUT, 551 "\t%*s%d time%s local credit reneged\n", indent, " ", 552 s->ts_lcdt_reduced ,plural(s->ts_lcdt_reduced)); 553 fprintf(OUT, 554 "\t%*s%d concatenated TPDU%s\n", indent, " ", 555 s->ts_concat_rcvd ,plural(s->ts_concat_rcvd)); 556 fprintf(OUT, 557 "%*sSending:\n", indent, " "); 558 fprintf(OUT, 559 "\t%*s%d XPD mark%s discarded\n", indent, " ", 560 s->ts_xpdmark_del ,plural(s->ts_xpdmark_del)); 561 fprintf(OUT, 562 "\t%*sXPD stopped data flow %d time%s\n", indent, " ", 563 s->ts_xpd_intheway ,plural(s->ts_xpd_intheway)); 564 fprintf(OUT, 565 "\t%*s%d time%s foreign window closed\n", indent, " ", 566 s->ts_zfcdt ,plural(s->ts_zfcdt)); 567 fprintf(OUT, 568 "%*sMiscellaneous:\n", indent, " "); 569 fprintf(OUT, 570 "\t%*s%d small mbuf%s\n", indent, " ", 571 s->ts_mb_small ,plural(s->ts_mb_small)); 572 fprintf(OUT, 573 "\t%*s%d cluster%s\n", indent, " ", 574 s->ts_mb_cluster, plural(s->ts_mb_cluster)); 575 fprintf(OUT, 576 "\t%*s%d source quench \n",indent, " ", 577 s->ts_quench); 578 fprintf(OUT, 579 "\t%*s%d dec bit%s\n", indent, " ", 580 s->ts_rcvdecbit, plural(s->ts_rcvdecbit)); 581 fprintf(OUT, 582 "\t%*sM:L ( M mbuf chains of length L)\n", indent, " "); 583 { 584 register int j; 585 586 fprintf(OUT, "\t%*s%d: over 16\n", indent, " ", 587 s->ts_mb_len_distr[0]); 588 for( j=1; j<=8; j++) { 589 fprintf(OUT, 590 "\t%*s%d: %d\t\t%d: %d\n", indent, " ", 591 s->ts_mb_len_distr[j],j, 592 s->ts_mb_len_distr[j<<1],j<<1 593 ); 594 } 595 } 596 fprintf(OUT, 597 "\t%*s%d EOT rcvd\n", indent, " ", s->ts_eot_input); 598 fprintf(OUT, 599 "\t%*s%d EOT sent\n", indent, " ", s->ts_EOT_sent); 600 fprintf(OUT, 601 "\t%*s%d EOT indication%s\n", indent, " ", 602 s->ts_eot_user ,plural(s->ts_eot_user)); 603 604 fprintf(OUT, 605 "%*sConnections:\n", indent, " "); 606 fprintf(OUT, 607 "\t%*s%d connection%s used extended format\n", indent, " ", 608 s->ts_xtd_fmt ,plural(s->ts_xtd_fmt)); 609 fprintf(OUT, 610 "\t%*s%d connection%s allowed transport expedited data\n", indent, " ", 611 s->ts_use_txpd ,plural(s->ts_use_txpd)); 612 fprintf(OUT, 613 "\t%*s%d connection%s turned off checksumming\n", indent, " ", 614 s->ts_csum_off ,plural(s->ts_csum_off)); 615 fprintf(OUT, 616 "\t%*s%d connection%s dropped due to retrans limit\n", indent, " ", 617 s->ts_conn_gaveup ,plural(s->ts_conn_gaveup)); 618 fprintf(OUT, 619 "\t%*s%d tp 4 connection%s\n", indent, " ", 620 s->ts_tp4_conn ,plural(s->ts_tp4_conn)); 621 fprintf(OUT, 622 "\t%*s%d tp 0 connection%s\n", indent, " ", 623 s->ts_tp0_conn ,plural(s->ts_tp0_conn)); 624 fprintf(OUT, 625 "\n%*sTpdus RECVD [%d valid, %3.6f %% of total (%d); %d dropped]\n",indent," ", 626 s->ts_tpdu_rcvd , 627 ((s->ts_pkt_rcvd > 0) ? 628 ((100 * (float)s->ts_tpdu_rcvd)/(float)s->ts_pkt_rcvd) 629 : 0), 630 s->ts_pkt_rcvd, 631 s->ts_recv_drop ); 632 633 fprintf(OUT, 634 "\t%*sDT %6d AK %6d DR %4d CR %4d \n", indent, " ", 635 s->ts_DT_rcvd, s->ts_AK_rcvd, s->ts_DR_rcvd, s->ts_CR_rcvd); 636 fprintf(OUT, 637 "\t%*sXPD %6d XAK %6d DC %4d CC %4d ER %4d\n", indent, " ", 638 s->ts_XPD_rcvd, s->ts_XAK_rcvd, s->ts_DC_rcvd, s->ts_CC_rcvd, 639 s->ts_ER_rcvd); 640 fprintf(OUT, 641 "\n%*sTpdus SENT [%d total, %d dropped]\n", indent, " ", 642 s->ts_tpdu_sent, s->ts_send_drop); 643 644 fprintf(OUT, 645 "\t%*sDT %6d AK %6d DR %4d CR %4d \n", indent, " ", 646 s->ts_DT_sent, s->ts_AK_sent, s->ts_DR_sent, s->ts_CR_sent); 647 fprintf(OUT, 648 "\t%*sXPD %6d XAK %6d DC %4d CC %4d ER %4d\n", indent, " ", 649 s->ts_XPD_sent, s->ts_XAK_sent, s->ts_DC_sent, s->ts_CC_sent, 650 s->ts_ER_sent); 651 652 fprintf(OUT, 653 "\n%*sRetransmissions:\n", indent, " "); 654 #define PERCENT(X,Y) (((Y)>0)?((100 *(float)(X)) / (float) (Y)):0) 655 656 fprintf(OUT, 657 "\t%*sCR %6d CC %6d DR %6d \n", indent, " ", 658 s->ts_retrans_cr, s->ts_retrans_cc, s->ts_retrans_dr); 659 fprintf(OUT, 660 "\t%*sDT %6d (%5.2f%%)\n", indent, " ", 661 s->ts_retrans_dt, 662 PERCENT(s->ts_retrans_dt, s->ts_DT_sent)); 663 fprintf(OUT, 664 "\t%*sXPD %6d (%5.2f%%)\n", indent, " ", 665 s->ts_retrans_xpd, 666 PERCENT(s->ts_retrans_xpd, s->ts_XPD_sent)); 667 668 669 fprintf(OUT, 670 "\n%*sE Timers: [%6d ticks]\n", indent, " ", s->ts_Eticks); 671 fprintf(OUT, 672 "%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n",indent, " ", 673 s->ts_Eset ,plural(s->ts_Eset), 674 s->ts_Eexpired ,plural(s->ts_Eexpired), 675 s->ts_Ecan_act ,plural(s->ts_Ecan_act)); 676 677 fprintf(OUT, 678 "\n%*sC Timers: [%6d ticks]\n", indent, " ",s->ts_Cticks); 679 fprintf(OUT, 680 "%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n", 681 indent, " ", 682 s->ts_Cset ,plural(s->ts_Cset), 683 s->ts_Cexpired ,plural(s->ts_Cexpired), 684 s->ts_Ccan_act ,plural(s->ts_Ccan_act)); 685 fprintf(OUT, 686 "%*s%6d inactive timer%s cancelled\n", indent, " ", 687 s->ts_Ccan_inact ,plural(s->ts_Ccan_inact)); 688 689 fprintf(OUT, 690 "\n%*sPathological debugging activity:\n", indent, " "); 691 fprintf(OUT, 692 "\t%*s%6d CC%s sent to zero dref\n", indent, " ", 693 s->ts_zdebug ,plural(s->ts_zdebug)); 694 /* SAME LINE AS ABOVE */ 695 fprintf(OUT, 696 "\t%*s%6d random DT%s dropped\n", indent, " ", 697 s->ts_ydebug ,plural(s->ts_ydebug)); 698 fprintf(OUT, 699 "\t%*s%6d illegally large XPD TPDU%s\n", indent, " ", 700 s->ts_vdebug ,plural(s->ts_vdebug)); 701 fprintf(OUT, 702 "\t%*s%6d faked reneging of cdt\n", indent, " ", 703 s->ts_ldebug ); 704 705 fprintf(OUT, 706 "\n%*sACK reasons:\n", indent, " "); 707 fprintf(OUT, "\t%*s%6d not acked immediately\n", indent, " ", 708 s->ts_ackreason[_ACK_DONT_] ); 709 fprintf(OUT, "\t%*s%6d strategy==each\n", indent, " ", 710 s->ts_ackreason[_ACK_STRAT_EACH_] ); 711 fprintf(OUT, "\t%*s%6d strategy==fullwindow\n", indent, " ", 712 s->ts_ackreason[_ACK_STRAT_FULLWIN_] ); 713 fprintf(OUT, "\t%*s%6d duplicate DT\n", indent, " ", 714 s->ts_ackreason[_ACK_DUP_] ); 715 fprintf(OUT, "\t%*s%6d EOTSDU\n", indent, " ", 716 s->ts_ackreason[_ACK_EOT_] ); 717 fprintf(OUT, "\t%*s%6d reordered DT\n", indent, " ", 718 s->ts_ackreason[_ACK_REORDER_] ); 719 fprintf(OUT, "\t%*s%6d user rcvd\n", indent, " ", 720 s->ts_ackreason[_ACK_USRRCV_] ); 721 fprintf(OUT, "\t%*s%6d fcc reqd\n", indent, " ", 722 s->ts_ackreason[_ACK_FCC_] ); 723 } 724 #ifndef SSEL 725 #define SSEL(s) ((s)->siso_tlen + TSEL(s)) 726 #define PSEL(s) ((s)->siso_slen + SSEL(s)) 727 #endif 728 729 isonetprint(siso, islocal) 730 register struct sockaddr_iso *siso; 731 int islocal; 732 { 733 hexprint(siso->siso_nlen, siso->siso_addr.isoa_genaddr, "{}"); 734 if (siso->siso_tlen || siso->siso_slen || siso->siso_plen) 735 hexprint(siso->siso_tlen, TSEL(siso), "()"); 736 if (siso->siso_slen || siso->siso_plen) 737 hexprint(siso->siso_slen, SSEL(siso), "[]"); 738 if (siso->siso_plen) 739 hexprint(siso->siso_plen, PSEL(siso), "<>"); 740 putchar(' '); 741 } 742 static char hexlist[] = "0123456789abcdef", obuf[128]; 743 744 hexprint(n, buf, delim) 745 char *buf, *delim; 746 { 747 register u_char *in = (u_char *)buf, *top = in + n; 748 register char *out = obuf; 749 register int i; 750 751 if (n == 0) 752 return; 753 while (in < top) { 754 i = *in++; 755 *out++ = '.'; 756 if (i > 0xf) { 757 out[1] = hexlist[i & 0xf]; 758 i >>= 4; 759 out[0] = hexlist[i]; 760 out += 2; 761 } else 762 *out++ = hexlist[i]; 763 } 764 *obuf = *delim; *out++ = delim[1]; *out = 0; 765 printf("%s", obuf); 766 } 767