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