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