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