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