Really fix indent.
[dragonfly.git] / usr.bin / netstat / iso.c
blob0c7a614e0efa1667a3615067d5a5dccbf2abce1d
1 /*
2 * Copyright (c) 1983, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
33 * @(#)iso.c 8.1 (Berkeley) 6/6/93
37 * $FreeBSD: src/usr.bin/netstat/iso.c,v 1.4.2.2 2001/09/17 14:53:17 ru Exp $
38 * $DragonFly: src/usr.bin/netstat/iso.c,v 1.5 2007/04/22 01:25:04 dillon Exp $
40 /*******************************************************************************
41 Copyright IBM Corporation 1987
43 All Rights Reserved
45 Permission to use, copy, modify, and distribute this software and its
46 documentation for any purpose and without fee is hereby granted,
47 provided that the above copyright notice appear in all copies and that
48 both that copyright notice and this permission notice appear in
49 supporting documentation, and that the name of IBM not be
50 used in advertising or publicity pertaining to distribution of the
51 software without specific, written prior permission.
53 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
54 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
55 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
56 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
57 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
58 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
59 SOFTWARE.
61 *******************************************************************************/
64 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
67 #include <sys/param.h>
68 #include <sys/mbuf.h>
69 #include <sys/time.h>
70 #include <sys/domain.h>
71 #include <sys/protosw.h>
72 #include <sys/socket.h>
73 #include <sys/socketvar.h>
74 #include <sys/queue.h>
75 #include <errno.h>
76 #include <net/if.h>
77 #include <net/route.h>
78 #include <netinet/in.h>
79 #include <netinet/in_systm.h>
80 #include <netinet/ip.h>
81 #include <netinet/in_pcb.h>
82 #include <netinet/ip_var.h>
83 #include <netiso/iso.h>
84 #include <netiso/iso_errno.h>
85 #include <netiso/clnp.h>
86 #include <netiso/esis.h>
87 #include <netiso/clnp_stat.h>
88 #include <netiso/argo_debug.h>
89 #undef satosiso
90 #include <netiso/tp_param.h>
91 #include <netiso/tp_states.h>
92 #include <netiso/tp_pcb.h>
93 #include <netiso/tp_stat.h>
94 #include <netiso/iso_pcb.h>
95 #include <netiso/cltp_var.h>
96 #include <netiso/cons.h>
97 #ifdef IncStat
98 #undef IncStat
99 #endif
100 #include <netiso/cons_pcb.h>
101 #include <arpa/inet.h>
102 #include <netdb.h>
103 #include <string.h>
104 #include <stdio.h>
105 #include <stdlib.h>
106 #include "netstat.h"
108 static void tprintstat (struct tp_stat *, int);
109 static void isonetprint (struct sockaddr_iso *, int);
110 static void hexprint (int, char *, char *);
111 extern void inetprint (struct in_addr *, int, char *);
114 * Dump esis stats
116 void
117 esis_stats(u_long off, char *name, int af __unused)
119 struct esis_stat esis_stat;
121 if (off == 0 ||
122 kread(off, (char *)&esis_stat, sizeof (struct esis_stat)))
123 return;
124 printf("%s:\n", name);
125 printf("\t%d esh sent, %d esh received\n", esis_stat.es_eshsent,
126 esis_stat.es_eshrcvd);
127 printf("\t%d ish sent, %d ish received\n", esis_stat.es_ishsent,
128 esis_stat.es_ishrcvd);
129 printf("\t%d rd sent, %d rd received\n", esis_stat.es_rdsent,
130 esis_stat.es_rdrcvd);
131 printf("\t%d pdus not sent due to insufficient memory\n",
132 esis_stat.es_nomem);
133 printf("\t%d pdus received with bad checksum\n", esis_stat.es_badcsum);
134 printf("\t%d pdus received with bad version number\n",
135 esis_stat.es_badvers);
136 printf("\t%d pdus received with bad type field\n", esis_stat.es_badtype);
137 printf("\t%d short pdus received\n", esis_stat.es_toosmall);
141 * Dump clnp statistics structure.
143 void
144 clnp_stats(u_long off, char *name, int af __unused)
146 struct clnp_stat clnp_stat;
148 if (off == 0 ||
149 kread(off, (char *)&clnp_stat, sizeof (clnp_stat)))
150 return;
152 printf("%s:\n\t%d total packets sent\n", name, clnp_stat.cns_sent);
153 printf("\t%d total fragments sent\n", clnp_stat.cns_fragments);
154 printf("\t%d total packets received\n", clnp_stat.cns_total);
155 printf("\t%d with fixed part of header too small\n",
156 clnp_stat.cns_toosmall);
157 printf("\t%d with header length not reasonable\n", clnp_stat.cns_badhlen);
158 printf("\t%d incorrect checksum%s\n",
159 clnp_stat.cns_badcsum, plural(clnp_stat.cns_badcsum));
160 printf("\t%d with unreasonable address lengths\n", clnp_stat.cns_badaddr);
161 printf("\t%d with forgotten segmentation information\n",
162 clnp_stat.cns_noseg);
163 printf("\t%d with an incorrect protocol identifier\n", clnp_stat.cns_noproto);
164 printf("\t%d with an incorrect version\n", clnp_stat.cns_badvers);
165 printf("\t%d dropped because the ttl has expired\n",
166 clnp_stat.cns_ttlexpired);
167 printf("\t%d clnp cache misses\n", clnp_stat.cns_cachemiss);
168 printf("\t%d clnp congestion experience bits set\n",
169 clnp_stat.cns_congest_set);
170 printf("\t%d clnp congestion experience bits received\n",
171 clnp_stat.cns_congest_rcvd);
174 * Dump CLTP statistics structure.
176 void
177 cltp_stats(u_long off, char *name, int af __unused)
179 struct cltpstat cltpstat;
181 if (off == 0 ||
182 kread(off, (char *)&cltpstat, sizeof (cltpstat)))
183 return;
184 printf("%s:\n\t%u incomplete header%s\n", name,
185 cltpstat.cltps_hdrops, plural(cltpstat.cltps_hdrops));
186 printf("\t%u bad data length field%s\n",
187 cltpstat.cltps_badlen, plural(cltpstat.cltps_badlen));
188 printf("\t%u bad checksum%s\n",
189 cltpstat.cltps_badsum, plural(cltpstat.cltps_badsum));
192 struct tp_pcb tpcb;
193 struct isopcb isopcb;
194 struct socket sockb;
195 union {
196 struct sockaddr_iso siso;
197 char data[128];
198 } laddr, faddr;
199 #define kget(o, p) \
200 (kread((u_long)(o), (char *)&p, sizeof (p)))
202 static int first = 1;
205 * Print a summary of connections related to an Internet
206 * protocol. For TP, also give state of connection.
207 * Listening processes (aflag) are suppressed unless the
208 * -a (all) flag is specified.
210 void
211 iso_protopr(u_long off, char *name, int af __unused)
213 struct isopcb cb;
214 struct isopcb *prev, *next;
216 if (off == 0) {
217 printf("%s control block: symbol not in namelist\n", name);
218 return;
220 if (strcmp(name, "tp") == 0) {
221 tp_protopr(off, name);
222 return;
224 if (kread(off, (char *)&cb, sizeof(cb)))
225 return;
226 isopcb = cb;
227 prev = (struct isopcb *)off;
228 if (isopcb.isop_next == (struct isopcb *)off)
229 return;
230 while (isopcb.isop_next != (struct isopcb *)off) {
231 next = isopcb.isop_next;
232 kget(next, isopcb);
233 if (isopcb.isop_prev != prev) {
234 printf("prev 0x%x next 0x%x isop_prev 0x%x isop_next 0x%x???\n",
235 prev, next, isopcb.isop_prev, isopcb.isop_next);
236 break;
238 kget(isopcb.isop_socket, sockb);
239 iso_protopr1((u_long)next, 0);
240 putchar('\n');
241 prev = next;
245 void
246 iso_protopr1(u_long kern_addr, int istp)
248 if (first) {
249 printf("Active ISO net connections");
250 if (aflag)
251 printf(" (including servers)");
252 putchar('\n');
253 if (Aflag)
254 printf("%-8.8s ", "PCB");
255 printf(Aflag ?
256 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
257 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
258 "Proto", "Recv-Q", "Send-Q",
259 "Local Address", "Foreign Address", "(state)");
260 first = 0;
262 if (Aflag)
263 printf("%8x ",
264 (sockb.so_pcb ? (void *)sockb.so_pcb : (void *)kern_addr));
265 printf("%-5.5s %6d %6d ", "tp", sockb.so_rcv.ssb_cc, sockb.so_snd.ssb_cc);
266 if (istp && tpcb.tp_lsuffixlen) {
267 hexprint(tpcb.tp_lsuffixlen, tpcb.tp_lsuffix, "()");
268 printf("\t");
269 } else if (isopcb.isop_laddr == 0)
270 printf("*.*\t");
271 else {
272 if ((char *)isopcb.isop_laddr == ((char *)kern_addr) +
273 _offsetof(struct isopcb, isop_sladdr))
274 laddr.siso = isopcb.isop_sladdr;
275 else
276 kget(isopcb.isop_laddr, laddr);
277 isonetprint((struct sockaddr_iso *)&laddr, 1);
279 if (istp && tpcb.tp_fsuffixlen) {
280 hexprint(tpcb.tp_fsuffixlen, tpcb.tp_fsuffix, "()");
281 printf("\t");
282 } else if (isopcb.isop_faddr == 0)
283 printf("*.*\t");
284 else {
285 if ((char *)isopcb.isop_faddr == ((char *)kern_addr) +
286 _offsetof(struct isopcb, isop_sfaddr))
287 faddr.siso = isopcb.isop_sfaddr;
288 else
289 kget(isopcb.isop_faddr, faddr);
290 isonetprint((struct sockaddr_iso *)&faddr, 0);
294 void
295 tp_protopr(u_long off, char *name, int af __unused)
297 extern char *tp_sstring[];
298 struct tp_ref *tpr, *tpr_base;
299 struct tp_refinfo tpkerninfo;
300 int size;
302 kget(off, tpkerninfo);
303 size = tpkerninfo.tpr_size * sizeof (*tpr);
304 tpr_base = (struct tp_ref *)malloc(size);
305 if (tpr_base == 0)
306 return;
307 kread((u_long)(tpkerninfo.tpr_base), (char *)tpr_base, size);
308 for (tpr = tpr_base; tpr < tpr_base + tpkerninfo.tpr_size; tpr++) {
309 if (tpr->tpr_pcb == 0)
310 continue;
311 kget(tpr->tpr_pcb, tpcb);
312 if (tpcb.tp_state == ST_ERROR)
313 printf("undefined tpcb state: 0x%x\n", tpr->tpr_pcb);
314 if (!aflag &&
315 (tpcb.tp_state == TP_LISTENING ||
316 tpcb.tp_state == TP_CLOSED ||
317 tpcb.tp_state == TP_REFWAIT)) {
318 continue;
320 kget(tpcb.tp_sock, sockb);
321 if (tpcb.tp_npcb) switch(tpcb.tp_netservice) {
322 case IN_CLNS:
323 tp_inproto((u_long)tpkerninfo.tpr_base);
324 break;
325 default:
326 kget(tpcb.tp_npcb, isopcb);
327 iso_protopr1((u_long)tpcb.tp_npcb, 1);
328 break;
330 if (tpcb.tp_state >= tp_NSTATES)
331 printf(" %d", tpcb.tp_state);
332 else
333 printf(" %-12.12s", tp_sstring[tpcb.tp_state]);
334 putchar('\n');
338 void
339 tp_inproto(u_long pcb)
341 struct inpcb inpcb;
342 kget(tpcb.tp_npcb, inpcb);
343 if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
344 return;
345 if (Aflag)
346 printf("%8x ", pcb);
347 printf("%-5.5s %6d %6d ", "tpip",
348 sockb.so_rcv.ssb_cc, sockb.so_snd.ssb_cc);
349 inetprint(&inpcb.inp_laddr, inpcb.inp_lport, "tp");
350 inetprint(&inpcb.inp_faddr, inpcb.inp_fport, "tp");
354 * Pretty print an iso address (net address + port).
355 * If the numeric_addr or numeric_port were specified,
356 * use numbers instead of names.
359 #ifdef notdef
360 char *
361 isonetname(struct iso_addr *iso)
363 struct sockaddr_iso sa;
364 struct iso_hostent *ihe = 0;
365 struct iso_hostent *iso_gethostentrybyaddr();
366 struct iso_hostent *iso_getserventrybytsel();
367 struct iso_hostent Ihe;
368 static char line[80];
370 bzero(line, sizeof(line));
371 if( iso->isoa_afi ) {
372 sa.siso_family = AF_ISO;
373 sa.siso_addr = *iso;
374 sa.siso_tsuffix = 0;
376 if ( !numeric_addr )
377 ihe = iso_gethostentrybyaddr( &sa, 0, 0 );
378 if( ihe ) {
379 Ihe = *ihe;
380 ihe = &Ihe;
381 sprintf(line, "%s", ihe->isoh_hname);
382 } else {
383 sprintf(line, "%s", iso_ntoa(iso));
385 } else {
386 sprintf(line, "*");
388 return line;
391 static void
392 isonetprint(struct iso_addr *iso, char *sufx, u_short sufxlen, int islocal)
394 struct iso_hostent *iso_getserventrybytsel(), *ihe;
395 struct iso_hostent Ihe;
396 char *line, *cp;
397 int Alen = Aflag?18:22;
399 line = isonetname(iso);
400 cp = strchr(line, '\0');
401 ihe = (struct iso_hostent *)0;
403 if( islocal )
404 islocal = 20;
405 else
406 islocal = 22 + Alen;
408 if(Aflag)
409 islocal += 10 ;
411 if(!numeric_addr) {
412 if( (cp -line)>10 ) {
413 cp = line+10;
414 bzero(cp, sizeof(line)-10);
418 *cp++ = '.';
419 if(sufxlen) {
420 if( !Aflag && !numeric_port && (ihe=iso_getserventrybytsel(sufx, sufxlen))) {
421 Ihe = *ihe;
422 ihe = &Ihe;
424 if( ihe && (strlen(ihe->isoh_aname)>0) ) {
425 sprintf(cp, "%s", ihe->isoh_aname);
426 } else {
427 iso_sprinttsel(cp, sufx, sufxlen);
429 } else
430 sprintf(cp, "*");
432 fprintf(stdout, Aflag?" %-18.18s":" %-22.22s", line);
435 if( strlen(line) > Alen ) {
436 fprintf(stdout, " %s", line);
437 fprintf(stdout, "\n %*.s", islocal+Alen," ");
438 } else {
439 fprintf(stdout, " %-*.*s", Alen, Alen,line);
442 #endif
444 #ifdef notdef
445 static void
446 x25_protopr(u_long off, char *name, int af __unused)
448 static char *xpcb_states[] = {
449 "CLOSED",
450 "LISTENING",
451 "CLOSING",
452 "CONNECTING",
453 "ACKWAIT",
454 "OPEN",
456 struct isopcb *prev, *next;
457 struct x25_pcb xpcb;
459 if (off == 0) {
460 printf("%s control block: symbol not in namelist\n", name);
461 return;
463 kread(off, &xpcb, sizeof (struct x25_pcb));
464 prev = (struct isopcb *)off;
465 if (xpcb.x_next == (struct isopcb *)off)
466 return;
467 while (xpcb.x_next != (struct isopcb *)off) {
468 next = isopcb.isop_next;
469 kread((u_long)next, &xpcb, sizeof (struct x25_pcb));
470 if (xpcb.x_prev != prev) {
471 printf("???\n");
472 break;
474 kread((u_long)xpcb.x_socket, &sockb, sizeof (sockb));
476 if (!aflag &&
477 xpcb.x_state == LISTENING ||
478 xpcb.x_state == TP_CLOSED ) {
479 prev = next;
480 continue;
482 if (first) {
483 printf("Active X25 net connections");
484 if (aflag)
485 printf(" (including servers)");
486 putchar('\n');
487 if (Aflag)
488 printf("%-8.8s ", "PCB");
489 printf(Aflag ?
490 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
491 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
492 "Proto", "Recv-Q", "Send-Q",
493 "Local Address", "Foreign Address", "(state)");
494 first = 0;
496 printf("%-5.5s %6d %6d ", name, sockb.so_rcv.ssb_cc,
497 sockb.so_snd.ssb_cc);
498 isonetprint(&xpcb.x_laddr.siso_addr, &xpcb.x_lport,
499 sizeof(xpcb.x_lport), 1);
500 isonetprint(&xpcb.x_faddr.siso_addr, &xpcb.x_fport,
501 sizeof(xpcb.x_lport), 0);
502 if (xpcb.x_state < 0 || xpcb.x_state >= x25_NSTATES)
503 printf(" 0x0x0x0x0x0x0x0x0x%x", xpcb.x_state);
504 else
505 printf(" %-12.12s", xpcb_states[xpcb.x_state]);
506 putchar('\n');
507 prev = next;
510 #endif
512 struct tp_stat tp_stat;
514 void
515 tp_stats(caddr_t off, caddr_t name)
517 if (off == 0) {
518 printf("TP not configured\n\n");
519 return;
521 printf("%s:\n", name);
522 kget(off, tp_stat);
523 tprintstat(&tp_stat, 8);
526 #define OUT stdout
528 static void
529 tprintstat(struct tp_stat *s, int indent)
531 fprintf(OUT,
532 "%*sReceiving:\n",indent," ");
533 fprintf(OUT,
534 "\t%*s%d variable parameter%s ignored\n", indent," ",
535 s->ts_param_ignored ,plural(s->ts_param_ignored));
536 fprintf(OUT,
537 "\t%*s%d invalid parameter code%s\n", indent, " ",
538 s->ts_inv_pcode ,plural(s->ts_inv_pcode));
539 fprintf(OUT,
540 "\t%*s%d invalid parameter value%s\n", indent, " ",
541 s->ts_inv_pval ,plural(s->ts_inv_pval));
542 fprintf(OUT,
543 "\t%*s%d invalid dutype%s\n", indent, " ",
544 s->ts_inv_dutype ,plural(s->ts_inv_dutype));
545 fprintf(OUT,
546 "\t%*s%d negotiation failure%s\n", indent, " ",
547 s->ts_negotfailed ,plural(s->ts_negotfailed));
548 fprintf(OUT,
549 "\t%*s%d invalid destination reference%s\n", indent, " ",
550 s->ts_inv_dref ,plural(s->ts_inv_dref));
551 fprintf(OUT,
552 "\t%*s%d invalid suffix parameter%s\n", indent, " ",
553 s->ts_inv_sufx ,plural(s->ts_inv_sufx));
554 fprintf(OUT,
555 "\t%*s%d invalid length\n",indent, " ", s->ts_inv_length);
556 fprintf(OUT,
557 "\t%*s%d invalid checksum%s\n", indent, " ",
558 s->ts_bad_csum ,plural(s->ts_bad_csum));
559 fprintf(OUT,
560 "\t%*s%d DT%s out of order\n", indent, " ",
561 s->ts_dt_ooo ,plural(s->ts_dt_ooo));
562 fprintf(OUT,
563 "\t%*s%d DT%s not in window\n", indent, " ",
564 s->ts_dt_niw ,plural(s->ts_dt_niw));
565 fprintf(OUT,
566 "\t%*s%d duplicate DT%s\n", indent, " ",
567 s->ts_dt_dup ,plural(s->ts_dt_dup));
568 fprintf(OUT,
569 "\t%*s%d XPD%s not in window\n", indent, " ",
570 s->ts_xpd_niw ,plural(s->ts_xpd_niw));
571 fprintf(OUT,
572 "\t%*s%d XPD%s w/o credit to stash\n", indent, " ",
573 s->ts_xpd_dup ,plural(s->ts_xpd_dup));
574 fprintf(OUT,
575 "\t%*s%d time%s local credit reneged\n", indent, " ",
576 s->ts_lcdt_reduced ,plural(s->ts_lcdt_reduced));
577 fprintf(OUT,
578 "\t%*s%d concatenated TPDU%s\n", indent, " ",
579 s->ts_concat_rcvd ,plural(s->ts_concat_rcvd));
580 fprintf(OUT,
581 "%*sSending:\n", indent, " ");
582 fprintf(OUT,
583 "\t%*s%d XPD mark%s discarded\n", indent, " ",
584 s->ts_xpdmark_del ,plural(s->ts_xpdmark_del));
585 fprintf(OUT,
586 "\t%*sXPD stopped data flow %d time%s\n", indent, " ",
587 s->ts_xpd_intheway ,plural(s->ts_xpd_intheway));
588 fprintf(OUT,
589 "\t%*s%d time%s foreign window closed\n", indent, " ",
590 s->ts_zfcdt ,plural(s->ts_zfcdt));
591 fprintf(OUT,
592 "%*sMiscellaneous:\n", indent, " ");
593 fprintf(OUT,
594 "\t%*s%d small mbuf%s\n", indent, " ",
595 s->ts_mb_small ,plural(s->ts_mb_small));
596 fprintf(OUT,
597 "\t%*s%d cluster%s\n", indent, " ",
598 s->ts_mb_cluster, plural(s->ts_mb_cluster));
599 fprintf(OUT,
600 "\t%*s%d source quench \n",indent, " ",
601 s->ts_quench);
602 fprintf(OUT,
603 "\t%*s%d dec bit%s\n", indent, " ",
604 s->ts_rcvdecbit, plural(s->ts_rcvdecbit));
605 fprintf(OUT,
606 "\t%*sM:L ( M mbuf chains of length L)\n", indent, " ");
608 int j;
610 fprintf(OUT, "\t%*s%d: over 16\n", indent, " ",
611 s->ts_mb_len_distr[0]);
612 for( j=1; j<=8; j++) {
613 fprintf(OUT,
614 "\t%*s%d: %d\t\t%d: %d\n", indent, " ",
615 s->ts_mb_len_distr[j],j,
616 s->ts_mb_len_distr[j<<1],j<<1
620 fprintf(OUT,
621 "\t%*s%d EOT rcvd\n", indent, " ", s->ts_eot_input);
622 fprintf(OUT,
623 "\t%*s%d EOT sent\n", indent, " ", s->ts_EOT_sent);
624 fprintf(OUT,
625 "\t%*s%d EOT indication%s\n", indent, " ",
626 s->ts_eot_user ,plural(s->ts_eot_user));
628 fprintf(OUT,
629 "%*sConnections:\n", indent, " ");
630 fprintf(OUT,
631 "\t%*s%d connection%s used extended format\n", indent, " ",
632 s->ts_xtd_fmt ,plural(s->ts_xtd_fmt));
633 fprintf(OUT,
634 "\t%*s%d connection%s allowed transport expedited data\n", indent, " ",
635 s->ts_use_txpd ,plural(s->ts_use_txpd));
636 fprintf(OUT,
637 "\t%*s%d connection%s turned off checksumming\n", indent, " ",
638 s->ts_csum_off ,plural(s->ts_csum_off));
639 fprintf(OUT,
640 "\t%*s%d connection%s dropped due to retrans limit\n", indent, " ",
641 s->ts_conn_gaveup ,plural(s->ts_conn_gaveup));
642 fprintf(OUT,
643 "\t%*s%d tp 4 connection%s\n", indent, " ",
644 s->ts_tp4_conn ,plural(s->ts_tp4_conn));
645 fprintf(OUT,
646 "\t%*s%d tp 0 connection%s\n", indent, " ",
647 s->ts_tp0_conn ,plural(s->ts_tp0_conn));
649 int j;
650 static char *name[]= {
651 "~LOCAL, PDN",
652 "~LOCAL,~PDN",
653 " LOCAL,~PDN",
654 " LOCAL, PDN"
657 fprintf(OUT,
658 "\n%*sRound trip times, listed in ticks:\n", indent, " ");
659 fprintf(OUT,
660 "\t%*s%11.11s %12.12s | %12.12s | %s\n", indent, " ",
661 "Category",
662 "Smoothed avg", "Deviation", "Deviation/Avg");
663 for (j = 0; j <= 3; j++) {
664 fprintf(OUT,
665 "\t%*s%11.11s: %-11d | %-11d | %-11d | %-11d\n", indent, " ",
666 name[j],
667 s->ts_rtt[j],
668 s->ts_rtt[j],
669 s->ts_rtv[j],
670 s->ts_rtv[j]);
673 fprintf(OUT,
674 "\n%*sTpdus RECVD [%d valid, %3.6f %% of total (%d); %d dropped]\n",indent," ",
675 s->ts_tpdu_rcvd ,
676 ((s->ts_pkt_rcvd > 0) ?
677 ((100 * (float)s->ts_tpdu_rcvd)/(float)s->ts_pkt_rcvd)
678 : 0),
679 s->ts_pkt_rcvd,
680 s->ts_recv_drop );
682 fprintf(OUT,
683 "\t%*sDT %6d AK %6d DR %4d CR %4d \n", indent, " ",
684 s->ts_DT_rcvd, s->ts_AK_rcvd, s->ts_DR_rcvd, s->ts_CR_rcvd);
685 fprintf(OUT,
686 "\t%*sXPD %6d XAK %6d DC %4d CC %4d ER %4d\n", indent, " ",
687 s->ts_XPD_rcvd, s->ts_XAK_rcvd, s->ts_DC_rcvd, s->ts_CC_rcvd,
688 s->ts_ER_rcvd);
689 fprintf(OUT,
690 "\n%*sTpdus SENT [%d total, %d dropped]\n", indent, " ",
691 s->ts_tpdu_sent, s->ts_send_drop);
693 fprintf(OUT,
694 "\t%*sDT %6d AK %6d DR %4d CR %4d \n", indent, " ",
695 s->ts_DT_sent, s->ts_AK_sent, s->ts_DR_sent, s->ts_CR_sent);
696 fprintf(OUT,
697 "\t%*sXPD %6d XAK %6d DC %4d CC %4d ER %4d\n", indent, " ",
698 s->ts_XPD_sent, s->ts_XAK_sent, s->ts_DC_sent, s->ts_CC_sent,
699 s->ts_ER_sent);
701 fprintf(OUT,
702 "\n%*sRetransmissions:\n", indent, " ");
703 #define PERCENT(X,Y) (((Y)>0)?((100 *(float)(X)) / (float) (Y)):0)
705 fprintf(OUT,
706 "\t%*sCR %6d CC %6d DR %6d \n", indent, " ",
707 s->ts_retrans_cr, s->ts_retrans_cc, s->ts_retrans_dr);
708 fprintf(OUT,
709 "\t%*sDT %6d (%5.2f%%)\n", indent, " ",
710 s->ts_retrans_dt,
711 PERCENT(s->ts_retrans_dt, s->ts_DT_sent));
712 fprintf(OUT,
713 "\t%*sXPD %6d (%5.2f%%)\n", indent, " ",
714 s->ts_retrans_xpd,
715 PERCENT(s->ts_retrans_xpd, s->ts_XPD_sent));
718 fprintf(OUT,
719 "\n%*sE Timers: [%6d ticks]\n", indent, " ", s->ts_Eticks);
720 fprintf(OUT,
721 "%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n",indent, " ",
722 s->ts_Eset ,plural(s->ts_Eset),
723 s->ts_Eexpired ,plural(s->ts_Eexpired),
724 s->ts_Ecan_act ,plural(s->ts_Ecan_act));
726 fprintf(OUT,
727 "\n%*sC Timers: [%6d ticks]\n", indent, " ",s->ts_Cticks);
728 fprintf(OUT,
729 "%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n",
730 indent, " ",
731 s->ts_Cset ,plural(s->ts_Cset),
732 s->ts_Cexpired ,plural(s->ts_Cexpired),
733 s->ts_Ccan_act ,plural(s->ts_Ccan_act));
734 fprintf(OUT,
735 "%*s%6d inactive timer%s cancelled\n", indent, " ",
736 s->ts_Ccan_inact ,plural(s->ts_Ccan_inact));
738 fprintf(OUT,
739 "\n%*sPathological debugging activity:\n", indent, " ");
740 fprintf(OUT,
741 "\t%*s%6d CC%s sent to zero dref\n", indent, " ",
742 s->ts_zdebug ,plural(s->ts_zdebug));
743 /* SAME LINE AS ABOVE */
744 fprintf(OUT,
745 "\t%*s%6d random DT%s dropped\n", indent, " ",
746 s->ts_ydebug ,plural(s->ts_ydebug));
747 fprintf(OUT,
748 "\t%*s%6d illegally large XPD TPDU%s\n", indent, " ",
749 s->ts_vdebug ,plural(s->ts_vdebug));
750 fprintf(OUT,
751 "\t%*s%6d faked reneging of cdt\n", indent, " ",
752 s->ts_ldebug );
754 fprintf(OUT,
755 "\n%*sACK reasons:\n", indent, " ");
756 fprintf(OUT, "\t%*s%6d not acked immediately\n", indent, " ",
757 s->ts_ackreason[_ACK_DONT_] );
758 fprintf(OUT, "\t%*s%6d strategy==each\n", indent, " ",
759 s->ts_ackreason[_ACK_STRAT_EACH_] );
760 fprintf(OUT, "\t%*s%6d strategy==fullwindow\n", indent, " ",
761 s->ts_ackreason[_ACK_STRAT_FULLWIN_] );
762 fprintf(OUT, "\t%*s%6d duplicate DT\n", indent, " ",
763 s->ts_ackreason[_ACK_DUP_] );
764 fprintf(OUT, "\t%*s%6d EOTSDU\n", indent, " ",
765 s->ts_ackreason[_ACK_EOT_] );
766 fprintf(OUT, "\t%*s%6d reordered DT\n", indent, " ",
767 s->ts_ackreason[_ACK_REORDER_] );
768 fprintf(OUT, "\t%*s%6d user rcvd\n", indent, " ",
769 s->ts_ackreason[_ACK_USRRCV_] );
770 fprintf(OUT, "\t%*s%6d fcc reqd\n", indent, " ",
771 s->ts_ackreason[_ACK_FCC_] );
773 #ifndef SSEL
774 #define SSEL(s) ((s)->siso_tlen + TSEL(s))
775 #define PSEL(s) ((s)->siso_slen + SSEL(s))
776 #endif
778 static void
779 isonetprint(struct sockaddr_iso *siso, int islocal)
781 hexprint(siso->siso_nlen, siso->siso_addr.isoa_genaddr, "{}");
782 if (siso->siso_tlen || siso->siso_slen || siso->siso_plen)
783 hexprint(siso->siso_tlen, TSEL(siso), "()");
784 if (siso->siso_slen || siso->siso_plen)
785 hexprint(siso->siso_slen, SSEL(siso), "[]");
786 if (siso->siso_plen)
787 hexprint(siso->siso_plen, PSEL(siso), "<>");
788 putchar(' ');
791 static char hexlist[] = "0123456789abcdef", obuf[128];
793 static void
794 hexprint(int n, char *buf, char *delim)
796 u_char *in = (u_char *)buf, *top = in + n;
797 char *out = obuf;
798 int i;
800 if (n == 0)
801 return;
802 while (in < top) {
803 i = *in++;
804 *out++ = '.';
805 if (i > 0xf) {
806 out[1] = hexlist[i & 0xf];
807 i >>= 4;
808 out[0] = hexlist[i];
809 out += 2;
810 } else
811 *out++ = hexlist[i];
813 *obuf = *delim; *out++ = delim[1]; *out = 0;
814 printf("%s", obuf);