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