1 /* $NetBSD: iso.c,v 1.31 2009/02/22 07:43:01 dholland Exp $ */
4 * Copyright (c) 1983, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "from: @(#)iso.c 8.1 (Berkeley) 6/6/93";
37 __RCSID("$NetBSD: iso.c,v 1.31 2009/02/22 07:43:01 dholland Exp $");
41 /*******************************************************************************
42 Copyright IBM Corporation 1987
46 Permission to use, copy, modify, and distribute this software and its
47 documentation for any purpose and without fee is hereby granted,
48 provided that the above copyright notice appear in all copies and that
49 both that copyright notice and this permission notice appear in
50 supporting documentation, and that the name of IBM not be
51 used in advertising or publicity pertaining to distribution of the
52 software without specific, written prior permission.
54 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
55 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
56 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
57 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
58 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
59 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
62 *******************************************************************************/
65 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
68 #include <sys/param.h>
69 #include <sys/queue.h>
72 #include <sys/domain.h>
73 #include <sys/protosw.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
78 #include <net/route.h>
79 #include <netinet/in.h>
80 #include <netinet/in_systm.h>
81 #include <netinet/ip.h>
82 #include <netinet/in_pcb.h>
83 #include <netinet/ip_var.h>
84 #include <netiso/iso.h>
85 #include <netiso/iso_errno.h>
86 #include <netiso/clnp.h>
87 #include <netiso/esis.h>
88 #include <netiso/clnp_stat.h>
89 #include <netiso/argo_debug.h>
91 #include <netiso/tp_param.h>
92 #include <netiso/tp_states.h>
93 #include <netiso/tp_pcb.h>
94 #include <netiso/tp_stat.h>
95 #include <netiso/iso_pcb.h>
96 #include <netiso/cltp_var.h>
97 #include <netiso/cons.h>
98 #include <arpa/inet.h>
107 static void tprintstat
__P((struct tp_stat
*, int));
108 static void isonetprint
__P((struct sockaddr_iso
*, int));
109 static void hexprint
__P((int, const char *, const char *));
110 extern void inetprint
__P((struct in_addr
*, u_int16_t
, const char *, int));
116 esis_stats(off
, name
)
120 struct esis_stat esis_stat
;
123 kread(off
, (char *)&esis_stat
, sizeof (struct esis_stat
)))
125 printf("%s:\n", name
);
127 #define ps(f, m) if (esis_stat.f || sflag <= 1) \
128 printf(m, (unsigned long long)esis_stat.f)
129 #define ps2(f1, f2, m) if (esis_stat.f1 || esis_stat.f2 || sflag <= 1) \
130 printf(m, (unsigned long long)esis_stat.f1, (unsigned long long)esis_stat.f2)
132 ps2(es_eshsent
, es_eshrcvd
, "\t%llu esh sent, %llu esh received\n");
133 ps2(es_ishsent
, es_ishrcvd
, "\t%llu ish sent, %llu ish received\n");
134 ps2(es_rdsent
, es_rdrcvd
, "\t%llu rd sent, %llu rd received\n");
135 ps(es_nomem
, "\t%llu pdus not sent due to insufficient memory\n");
136 ps(es_badcsum
, "\t%llu pdus received with bad checksum\n");
137 ps(es_badvers
, "\t%llu pdus received with bad version number\n");
138 ps(es_badtype
, "\t%llu pdus received with bad type field\n");
139 ps(es_toosmall
, "\t%llu short pdus received\n");
146 * Dump clnp statistics structure.
149 clnp_stats(off
, name
)
153 struct clnp_stat clnp_stat
;
156 kread(off
, (char *)&clnp_stat
, sizeof (clnp_stat
)))
159 printf("%s:\n", name
);
161 #define ps(f, m) if (clnp_stat.f || sflag <= 1) \
162 printf(m, (unsigned long long)clnp_stat.f)
163 #define p(f, m) if (clnp_stat.f || sflag <= 1) \
164 printf(m, (unsigned long long)clnp_stat.f, plural(clnp_stat.f))
166 ps(cns_sent
, "\t%llu total packets sent\n");
167 ps(cns_fragments
, "\t%llu total fragments sent\n");
168 ps(cns_total
, "\t%llu total packets received\n");
169 ps(cns_toosmall
, "\t%llu with fixed part of header too small\n");
170 ps(cns_badhlen
, "\t%llu with header length not reasonable\n");
171 p(cns_badcsum
, "\t%llu incorrect checksum%s\n");
172 ps(cns_badaddr
, "\t%llu with unreasonable address lengths\n");
173 ps(cns_noseg
, "\t%llu with forgotten segmentation information\n");
174 ps(cns_noproto
, "\t%llu with an incorrect protocol identifier\n");
175 ps(cns_badvers
, "\t%llu with an incorrect version\n");
176 ps(cns_ttlexpired
, "\t%llu dropped because the ttl has expired\n");
177 ps(cns_cachemiss
, "\t%llu clnp cache misses\n");
178 ps(cns_congest_set
, "\t%llu clnp congestion experience bits set\n");
180 "\t%llu clnp congestion experience bits received\n");
186 * Dump CLTP statistics structure.
189 cltp_stats(off
, name
)
193 struct cltpstat cltpstat
;
196 kread(off
, (char *)&cltpstat
, sizeof (cltpstat
)))
200 printf("%s:\n", name
);
202 #define p(f, m) if (cltpstat.f || sflag <= 1) \
203 printf(m, (unsigned long long)cltpstat.f, plural(cltpstat.f))
205 p(cltps_hdrops
, "\t%llu incomplete header%s\n");
206 p(cltps_badlen
,"\t%llu bad data length field%s\n");
207 p(cltps_badsum
,"\t%llu bad checksum%s\n");
213 struct isopcb isopcb
;
216 struct sockaddr_iso siso
;
220 (kread((u_long)(o), (char *)&p, sizeof (p)))
222 static int first
= 1;
225 * Print a summary of connections related to an Internet
226 * protocol. For TP, also give state of connection.
227 * Listening processes (aflag) are suppressed unless the
228 * -a (all) flag is specified.
231 iso_protopr(off
, name
)
236 struct isopcb
*prev
, *next
;
241 if (strcmp(name
, "tp") == 0) {
242 tp_protopr(off
, name
);
245 if (kread(off
, (char *)&cb
, sizeof(cb
)))
248 prev
= (struct isopcb
*)off
;
249 if (isopcb
.isop_next
== (struct isopcb
*)off
)
251 while (isopcb
.isop_next
!= (struct isopcb
*)off
) {
252 next
= isopcb
.isop_next
;
254 if (isopcb
.isop_prev
!= prev
) {
255 printf("prev %p next %p isop_prev %p isop_next %p???\n",
256 prev
, next
, isopcb
.isop_prev
, isopcb
.isop_next
);
259 kget(isopcb
.isop_socket
, sockb
);
260 iso_protopr1((u_long
)next
, 0);
267 iso_protopr1(kern_addr
, istp
)
273 printf("Active ISO net connections");
275 printf(" (including servers)");
279 printf("%-8.8s ", "PCB");
281 printf( "%-5.5s %-6.6s %-6.6s %-*.*s %-*.*s %s\n",
282 "Proto", "Recv-Q", "Send-Q",
283 width
, width
, "Local Address",
284 width
, width
, "Foreign Address", "(state)");
289 (u_long
) (sockb
.so_pcb
? (void *)sockb
.so_pcb
:
291 printf("%-5.5s %6ld %6ld ", "tp",
292 sockb
.so_rcv
.sb_cc
, sockb
.so_snd
.sb_cc
);
293 if (istp
&& tpcb
.tp_lsuffixlen
) {
294 hexprint(tpcb
.tp_lsuffixlen
, tpcb
.tp_lsuffix
, "()");
296 } else if (isopcb
.isop_laddr
== 0)
299 if ((char *)isopcb
.isop_laddr
== ((char *)kern_addr
) +
300 offsetof(struct isopcb
, isop_sladdr
))
301 laddr
.siso
= isopcb
.isop_sladdr
;
303 kget(isopcb
.isop_laddr
, laddr
);
304 isonetprint((struct sockaddr_iso
*)&laddr
, 1);
306 if (istp
&& tpcb
.tp_fsuffixlen
) {
307 hexprint(tpcb
.tp_fsuffixlen
, tpcb
.tp_fsuffix
, "()");
309 } else if (isopcb
.isop_faddr
== 0)
312 if ((char *)isopcb
.isop_faddr
== ((char *)kern_addr
) +
313 offsetof(struct isopcb
, isop_sfaddr
))
314 faddr
.siso
= isopcb
.isop_sfaddr
;
316 kget(isopcb
.isop_faddr
, faddr
);
317 isonetprint((struct sockaddr_iso
*)&faddr
, 0);
322 tp_protopr(off
, name
)
326 extern const char * const tp_sstring
[]; /* from sys/netiso/tp_astring.c */
327 struct tp_ref
*tpr
, *tpr_base
;
328 struct tp_refinfo tpkerninfo
;
331 kget(off
, tpkerninfo
);
332 size
= tpkerninfo
.tpr_size
* sizeof (*tpr
);
333 tpr_base
= (struct tp_ref
*)malloc(size
);
336 kread((u_long
)(tpkerninfo
.tpr_base
), (char *)tpr_base
, size
);
337 for (tpr
= tpr_base
; tpr
< tpr_base
+ tpkerninfo
.tpr_size
; tpr
++) {
338 if (tpr
->tpr_pcb
== 0)
340 kget(tpr
->tpr_pcb
, tpcb
);
341 if (tpcb
.tp_state
== ST_ERROR
)
342 printf("undefined tpcb state: %p\n", tpr
->tpr_pcb
);
344 (tpcb
.tp_state
== TP_LISTENING
||
345 tpcb
.tp_state
== TP_CLOSED
||
346 tpcb
.tp_state
== TP_REFWAIT
)) {
349 kget(tpcb
.tp_sock
, sockb
);
350 if (tpcb
.tp_npcb
) switch(tpcb
.tp_netservice
) {
352 tp_inproto((u_long
)tpkerninfo
.tpr_base
);
355 kget(tpcb
.tp_npcb
, isopcb
);
356 iso_protopr1((u_long
)tpcb
.tp_npcb
, 1);
359 if (tpcb
.tp_state
>= tp_NSTATES
)
360 printf(" %d", tpcb
.tp_state
);
362 printf(" %-12.12s", tp_sstring
[tpcb
.tp_state
]);
374 kget(tpcb
.tp_npcb
, inpcb
);
375 if (!aflag
&& inet_lnaof(inpcb
.inp_faddr
) == INADDR_ANY
)
378 printf("%8lx ", pcb
);
379 printf("%-5.5s %6ld %6ld ", "tpip",
380 sockb
.so_rcv
.sb_cc
, sockb
.so_snd
.sb_cc
);
381 inetprint(&inpcb
.inp_laddr
, inpcb
.inp_lport
, "tp", 1);
382 inetprint(&inpcb
.inp_faddr
, inpcb
.inp_fport
, "tp", 1);
386 * Pretty print an iso address (net address + port).
387 * If the numeric_addr or numeric_port were specified,
388 * use numbers instead of names.
394 struct iso_addr
*iso
;
396 struct sockaddr_iso sa
;
397 struct iso_hostent
*ihe
= 0;
398 struct iso_hostent
*iso_gethostentrybyaddr();
399 struct iso_hostent
*iso_getserventrybytsel();
400 struct iso_hostent Ihe
;
401 static char line
[80];
403 memset(line
, 0, sizeof(line
));
405 sa
.siso_family
= AF_ISO
;
410 ihe
= iso_gethostentrybyaddr(&sa
, 0, 0);
414 (void)snprintf(line
, sizeof line
, "%s", ihe
->isoh_hname
);
416 (void)snprintf(line
, sizeof line
, "%s", iso_ntoa(iso
));
419 (void)snprintf(line
, sizeof line
, "*");
425 isonetprint(iso
, sufx
, sufxlen
, islocal
)
426 struct iso_addr
*iso
;
431 struct iso_hostent
*iso_getserventrybytsel(), *ihe
;
432 struct iso_hostent Ihe
;
434 int Alen
= Aflag
? 18 : 22;
436 line
= isonetname(iso
);
437 cp
= strchr(line
, '\0');
438 ihe
= (struct iso_hostent
*)0;
449 if ((cp
- line
) > 10) {
451 memset(cp
, 0, sizeof(line
)-10);
457 if (!Aflag
&& !numeric_port
&&
458 (ihe
= iso_getserventrybytsel(sufx
, sufxlen
))) {
462 if (ihe
&& (strlen(ihe
->isoh_aname
) > 0)) {
463 sprintf(cp
, "%s", ihe
->isoh_aname
); /* XXX */
465 iso_sprinttsel(cp
, sufx
, sufxlen
);
470 fprintf(stdout, Aflag?" %-18.18s":" %-22.22s", line);
473 if( strlen(line
) > Alen
) {
474 fprintf(stdout
, " %s", line
);
475 fprintf(stdout
, "\n %*.s", islocal
+Alen
," ");
477 fprintf(stdout
, " %-*.*s", Alen
, Alen
,line
);
484 x25_protopr(off
, name
)
488 static char *xpcb_states
[] = {
496 struct isopcb
*prev
, *next
;
502 kread(off
, &xpcb
, sizeof (struct x25_pcb
));
503 prev
= (struct isopcb
*)off
;
504 if (xpcb
.x_next
== (struct isopcb
*)off
)
506 while (xpcb
.x_next
!= (struct isopcb
*)off
) {
507 next
= isopcb
.isop_next
;
508 kread((u_long
)next
, &xpcb
, sizeof (struct x25_pcb
));
509 if (xpcb
.x_prev
!= prev
) {
513 kread((u_long
)xpcb
.x_socket
, &sockb
, sizeof (sockb
));
516 xpcb
.x_state
== LISTENING
||
517 xpcb
.x_state
== TP_CLOSED
) {
522 printf("Active X25 net connections");
524 printf(" (including servers)");
527 printf("%-8.8s ", "PCB");
529 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
530 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
531 "Proto", "Recv-Q", "Send-Q",
532 "Local Address", "Foreign Address", "(state)");
535 printf("%-5.5s %6d %6d ", name
, sockb
.so_rcv
.sb_cc
,
537 isonetprint(&xpcb
.x_laddr
.siso_addr
, &xpcb
.x_lport
,
538 sizeof(xpcb
.x_lport
), 1);
539 isonetprint(&xpcb
.x_faddr
.siso_addr
, &xpcb
.x_fport
,
540 sizeof(xpcb
.x_lport
), 0);
541 if (xpcb
.x_state
< 0 || xpcb
.x_state
>= x25_NSTATES
)
542 printf(" 0x0x0x0x0x0x0x0x0x%x", xpcb
.x_state
);
544 printf(" %-12.12s", xpcb_states
[xpcb
.x_state
]);
551 struct tp_stat tp_stat
;
560 printf("TP not configured\n\n");
563 printf("%s:\n", name
);
565 tprintstat(&tp_stat
, 8);
573 #define o(f) offsetof(struct tp_stat, f)
575 static struct tpstatpr tpstatpr_r
[] = {
576 { o(ts_param_ignored
), "\t%*s%ld variable parameter%s ignored\n"},
577 { o(ts_inv_pcode
), "\t%*s%ld invalid parameter code%s\n"},
578 { o(ts_inv_pval
), "\t%*s%ld invalid parameter value%s\n"},
579 { o(ts_inv_dutype
), "\t%*s%ld invalid dutype%s\n"},
580 { o(ts_negotfailed
), "\t%*s%ld negotiation failure%s\n"},
581 { o(ts_inv_dref
), "\t%*s%ld invalid destination reference%s\n"},
582 { o(ts_inv_sufx
), "\t%*s%ld invalid suffix parameter%s\n"},
583 { o(ts_inv_length
), "\t%*s%ld invalid length%s\n"},
584 { o(ts_bad_csum
), "\t%*s%ld invalid checksum%s\n"},
585 { o(ts_dt_ooo
), "\t%*s%ld DT%s out of order\n"},
586 { o(ts_dt_niw
), "\t%*s%ld DT%s not in window\n"},
587 { o(ts_dt_dup
), "\t%*s%ld duplicate DT%s\n"},
588 { o(ts_xpd_niw
), "\t%*s%ld XPD%s not in window\n"},
589 { o(ts_xpd_dup
), "\t%*s%ld XPD%s w/o credit to stash\n"},
590 { o(ts_lcdt_reduced
), "\t%*s%ld time%s local credit reneged\n"},
591 { o(ts_concat_rcvd
), "\t%*s%ld concatenated TPDU%s\n"},
595 static struct tpstatpr tpstatpr_s
[] = {
596 { o(ts_xpdmark_del
), "\t%*s%ld XPD mark%s discarded\n"},
597 { o(ts_xpd_intheway
), "\t%*sXPD stopped data flow %ld time%s\n"},
598 { o(ts_zfcdt
), "\t%*s%ld time%s foreign window closed\n"},
602 static struct tpstatpr tpstatpr_m
[] = {
603 { o(ts_mb_small
), "\t%*s%ld small mbuf%s\n"},
604 { o(ts_mb_cluster
), "\t%*s%ld cluster%s\n"},
605 { o(ts_quench
), "\t%*s%ld source quench%s\n"},
606 { o(ts_rcvdecbit
), "\t%*s%ld dec bit%s\n"},
607 { o(ts_eot_input
), "\t%*s%ld EOT%s rcvd\n"},
608 { o(ts_EOT_sent
), "\t%*s%ld EOT%s sent\n"},
609 { o(ts_eot_user
), "\t%*s%ld EOT indication%s\n"},
613 static struct tpstatpr tpstatpr_c
[] = {
614 { o(ts_xtd_fmt
), "\t%*s%ld connection%s used extended format\n"},
615 { o(ts_use_txpd
), "\t%*s%ld connection%s allowed transport expedited data\n"},
616 { o(ts_csum_off
), "\t%*s%ld connection%s turned off checksumming\n"},
617 { o(ts_conn_gaveup
), "\t%*s%ld connection%s dropped due to retrans limit\n"},
618 { o(ts_tp4_conn
), "\t%*s%ld tp 4 connection%s\n"},
619 { o(ts_tp0_conn
), "\t%*s%ld tp 0 connection%s\n"},
623 static struct tpstatpr tpstatpr_p
[] = {
624 { o(ts_zdebug
), "\t%*s%6ld CC%s sent to zero dref\n"},
625 /* SAME LINE AS ABOVE */
626 { o(ts_ydebug
), "\t%*s%6ld random DT%s dropped\n"},
627 { o(ts_vdebug
), "\t%*s%6ld illegally large XPD TPDU%s\n"},
628 { o(ts_ldebug
), "\t%*s%6ld faked reneging%s of cdt\n"},
632 static struct tpstatpr tpstatpr_A
[] = {
633 { o(ts_ackreason
[_ACK_DONT_
]), "\t%*s%6ld not acked immediately%s\n"},
634 { o(ts_ackreason
[_ACK_STRAT_EACH_
]), "\t%*s%6ld strategy==each%s\n"},
635 { o(ts_ackreason
[_ACK_STRAT_FULLWIN_
]), "\t%*s%6ld strategy==fullwindow%s\n"},
636 { o(ts_ackreason
[_ACK_DUP_
]), "\t%*s%6ld duplicate DT%s\n"},
637 { o(ts_ackreason
[_ACK_EOT_
]), "\t%*s%6ld EOTSDU%s\n"},
638 { o(ts_ackreason
[_ACK_REORDER_
]), "\t%*s%6ld reordered DT%s\n"},
639 { o(ts_ackreason
[_ACK_USRRCV_
]), "\t%*s%6ld user rcvd%s\n"},
640 { o(ts_ackreason
[_ACK_FCC_
]), "\t%*s%6ld fcc reqd%s\n"},
646 tprintstat(s
, indent
)
650 int j
, tpfirst
, tpfirst2
;
652 static const char *rttname
[]= {
660 * Loop through a struct tpstatpr; if any value is non-zero,
661 * or sflag<=1, print the header if first, and then print the value.
663 #define pgroup(group, header) \
664 for (j = 0, tpfirst=1; group[j].text; j++) \
665 if (*(u_long*)((u_long)s + group[j].off) || \
669 header,indent," "); \
672 fprintf(stdout, group[j].text, indent, " ", \
673 *(u_long*)((u_long)s + group[j].off), \
674 plural(*(u_long*)((u_long)s + group[j].off))); \
678 pgroup(tpstatpr_r
, "%*sReceived:\n");
679 pgroup(tpstatpr_s
, "%*sSending:\n");
681 pgroup(tpstatpr_m
, "%*sMiscellaneous:\n");
682 /* print the mbuf chain statistics under the Misc. header */
684 for( j
=0, tpfirst2
=1; j
<=8; j
++) {
685 if (s
->ts_mb_len_distr
[j
] || s
->ts_mb_len_distr
[j
<<1] ||
688 fprintf(stdout
, "%*sMiscellaneous:\n",
694 "\t%*sM:L ( M mbuf chains of length L)\n",
699 fprintf(stdout
, "\t%*s%ld: over 16\n",
700 indent
, " ", s
->ts_mb_len_distr
[0]);
703 "\t%*s%ld: %d\t\t%ld: %d\n", indent
, " ",
704 s
->ts_mb_len_distr
[j
],j
,
705 s
->ts_mb_len_distr
[j
<<1],j
<<1);
709 pgroup(tpstatpr_c
, "%*sConnections:\n");
712 for (j
= 0; j
<= 3; j
++) {
713 if (s
->ts_rtt
[j
] || s
->ts_rtt
[j
] || s
->ts_rtv
[j
] ||
714 s
->ts_rtv
[j
] || sflag
<=1) {
717 "\n%*sRound trip times, "
719 "\t%*s%11.11s %12.12s | "
720 "%12.12s | %s\n", indent
, " ",
723 "Smoothed avg", "Deviation",
728 "\t%*s%11.11s: %-11d | %-11d | %-11d | %-11d\n",
730 rttname
[j
], s
->ts_rtt
[j
], s
->ts_rtt
[j
],
731 s
->ts_rtv
[j
], s
->ts_rtv
[j
]);
736 if (s
->ts_tpdu_rcvd
|| s
->ts_pkt_rcvd
|| s
->ts_recv_drop
||
737 s
->ts_DT_rcvd
|| s
->ts_AK_rcvd
|| s
->ts_DR_rcvd
|| s
->ts_CR_rcvd
||
738 s
->ts_XPD_rcvd
|| s
->ts_XAK_rcvd
|| s
->ts_DC_rcvd
||
739 s
->ts_CC_rcvd
|| s
->ts_ER_rcvd
|| sflag
<=1 ) {
740 fprintf(stdout
, "\n%*sTpdus RECVD "
741 "[%ld valid, %3.6f %% of total (%ld); %ld dropped]\n",
742 indent
," ", s
->ts_tpdu_rcvd
,
743 ((s
->ts_pkt_rcvd
> 0) ?
744 ((100 * (float)s
->ts_tpdu_rcvd
)/(float)s
->ts_pkt_rcvd
)
746 s
->ts_pkt_rcvd
, s
->ts_recv_drop
);
748 "\t%*sDT %6ld AK %6ld DR %4ld CR %4ld \n",
749 indent
, " ", s
->ts_DT_rcvd
, s
->ts_AK_rcvd
, s
->ts_DR_rcvd
,
751 fprintf(stdout
, "\t%*sXPD %6ld XAK %6ld DC %4ld "
752 "CC %4ld ER %4ld\n", indent
, " ", s
->ts_XPD_rcvd
,
753 s
->ts_XAK_rcvd
, s
->ts_DC_rcvd
, s
->ts_CC_rcvd
,
757 if (s
->ts_tpdu_sent
|| s
->ts_send_drop
|| s
->ts_DT_sent
||
758 s
->ts_AK_sent
|| s
->ts_DR_sent
|| s
->ts_CR_sent
||
759 s
->ts_XPD_sent
|| s
->ts_XAK_sent
|| s
->ts_DC_sent
||
760 s
->ts_CC_sent
|| s
->ts_ER_sent
|| sflag
<=1 ) {
762 "\n%*sTpdus SENT [%ld total, %ld dropped]\n", indent
, " ",
763 s
->ts_tpdu_sent
, s
->ts_send_drop
);
765 "\t%*sDT %6ld AK %6ld DR %4ld CR %4ld \n",
766 indent
, " ", s
->ts_DT_sent
, s
->ts_AK_sent
, s
->ts_DR_sent
,
768 fprintf(stdout
, "\t%*sXPD %6ld XAK %6ld DC %4ld "
769 "CC %4ld ER %4ld\n", indent
, " ", s
->ts_XPD_sent
,
770 s
->ts_XAK_sent
, s
->ts_DC_sent
, s
->ts_CC_sent
,
774 if (s
->ts_retrans_cr
|| s
->ts_retrans_cc
|| s
->ts_retrans_dr
||
775 s
->ts_retrans_dt
|| s
->ts_retrans_xpd
|| sflag
<=1) {
777 "\n%*sRetransmissions:\n", indent
, " ");
778 #define PERCENT(X,Y) (((Y)>0)?((100 *(float)(X)) / (float) (Y)):0)
780 "\t%*sCR %6ld CC %6ld DR %6ld \n", indent
, " ",
781 s
->ts_retrans_cr
, s
->ts_retrans_cc
, s
->ts_retrans_dr
);
783 "\t%*sDT %6ld (%5.2f%%)\n", indent
, " ",
785 PERCENT(s
->ts_retrans_dt
, s
->ts_DT_sent
));
787 "\t%*sXPD %6ld (%5.2f%%)\n", indent
, " ",
789 PERCENT(s
->ts_retrans_xpd
, s
->ts_XPD_sent
));
793 if (s
->ts_Eticks
|| s
->ts_Eset
|| s
->ts_Eexpired
|| s
->ts_Ecan_act
||
796 "\n%*sE Timers: [%6ld ticks]\n", indent
, " ",
799 "%*s%6ld timer%s set \t%6ld timer%s expired "
800 "\t%6ld timer%s cancelled\n", indent
, " ",
801 s
->ts_Eset
, plural(s
->ts_Eset
),
802 s
->ts_Eexpired
, plural(s
->ts_Eexpired
),
803 s
->ts_Ecan_act
, plural(s
->ts_Ecan_act
));
806 if (s
->ts_Cset
|| s
->ts_Cexpired
|| s
->ts_Ccan_act
||
807 s
->ts_Ccan_inact
|| sflag
<=1) {
809 "\n%*sC Timers: [%6ld ticks]\n", indent
, " ",
812 "%*s%6ld timer%s set \t%6ld timer%s expired "
813 "\t%6ld timer%s cancelled\n",
815 s
->ts_Cset
, plural(s
->ts_Cset
),
816 s
->ts_Cexpired
, plural(s
->ts_Cexpired
),
817 s
->ts_Ccan_act
, plural(s
->ts_Ccan_act
));
819 "%*s%6ld inactive timer%s cancelled\n", indent
, " ",
820 s
->ts_Ccan_inact
, plural(s
->ts_Ccan_inact
));
823 pgroup(tpstatpr_p
, "\n%*sPathological debugging activity:\n");
825 pgroup(tpstatpr_A
, "\n%*sACK reasons:\n");
829 #define SSEL(s) ((s)->siso_tlen + TSEL(s))
830 #define PSEL(s) ((s)->siso_slen + SSEL(s))
834 isonetprint(siso
, islocal
)
835 struct sockaddr_iso
*siso
;
839 hexprint(siso
->siso_nlen
, siso
->siso_addr
.isoa_genaddr
, "{}");
840 if (siso
->siso_tlen
|| siso
->siso_slen
|| siso
->siso_plen
)
841 hexprint(siso
->siso_tlen
, TSEL(siso
), "()");
842 if (siso
->siso_slen
|| siso
->siso_plen
)
843 hexprint(siso
->siso_slen
, SSEL(siso
), "[]");
845 hexprint(siso
->siso_plen
, PSEL(siso
), "<>");
849 static char hexlist
[] = "0123456789abcdef", obuf
[128];
852 hexprint(n
, buf
, delim
)
857 const u_char
*in
= (const u_char
*)buf
, *top
= in
+ n
;
867 out
[1] = hexlist
[i
& 0xf];
874 *obuf
= *delim
; *out
++ = delim
[1]; *out
= 0;