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