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