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