Commit | Line | Data |
---|---|---|
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 | |
35 | static char sccsid[] = "@(#)iso.c 5.6 (Berkeley) 4/27/91"; | |
36 | #endif /* not lint */ | |
37 | ||
38 | /* | |
39 | * $Header: iso.c,v 3.3 88/12/08 14:44:49 hagens Exp $ | |
40 | * $Source: /usr/argo/src/ucb/netstat/RCS/iso.c,v $ | |
41 | */ | |
42 | /******************************************************************************* | |
43 | Copyright IBM Corporation 1987 | |
44 | ||
45 | All Rights Reserved | |
46 | ||
47 | Permission to use, copy, modify, and distribute this software and its | |
48 | documentation for any purpose and without fee is hereby granted, | |
49 | provided that the above copyright notice appear in all copies and that | |
50 | both that copyright notice and this permission notice appear in | |
51 | supporting documentation, and that the name of IBM not be | |
52 | used in advertising or publicity pertaining to distribution of the | |
53 | software without specific, written prior permission. | |
54 | ||
55 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
56 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL | |
57 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
58 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
59 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
60 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
61 | SOFTWARE. | |
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 | */ | |
104 | esis_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 | */ | |
132 | clnp_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 | */ | |
166 | cltp_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 | ||
183 | struct tp_pcb tpcb; | |
184 | struct isopcb isopcb; | |
185 | struct socket sockb; | |
186 | union { | |
187 | struct sockaddr_iso siso; | |
188 | char data[128]; | |
189 | } laddr, faddr; | |
190 | #define kget(o, p) \ | |
191 | (kvm_read((off_t)(o), (char *)&p, sizeof (p))) | |
192 | extern int Aflag; | |
193 | extern int aflag; | |
194 | extern int nflag; | |
195 | ||
196 | static 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 | */ | |
204 | iso_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) { | |
213 | printf("%s control block: symbol not in namelist\n", name); | |
214 | return; | |
215 | } | |
216 | kget(off, cb); | |
217 | isopcb = cb; | |
218 | prev = (struct isopcb *)off; | |
219 | if (isopcb.isop_next == (struct isopcb *)off) | |
220 | return; | |
221 | while (isopcb.isop_next != (struct isopcb *)off) { | |
222 | next = isopcb.isop_next; | |
223 | kget(next, isopcb); | |
224 | if (isopcb.isop_prev != prev) { | |
225 | printf("prev 0x%x next 0x%x isop_prev 0x%x isop_next 0x%x???\n", | |
226 | prev, next, isopcb.isop_prev, isopcb.isop_next); | |
227 | break; | |
228 | } | |
229 | kget(isopcb.isop_socket, sockb); | |
230 | if (istp) { | |
231 | kget(sockb.so_tpcb, tpcb); | |
232 | if (tpcb.tp_state == ST_ERROR) | |
233 | fprintf(stderr,"addr: 0x%x, prev 0x%x\n", next, prev); | |
234 | if (!aflag && | |
235 | tpcb.tp_state == TP_LISTENING || | |
236 | tpcb.tp_state == TP_CLOSED || | |
237 | tpcb.tp_state == TP_REFWAIT) { | |
238 | prev = next; | |
239 | continue; | |
240 | } | |
241 | } | |
242 | if (first) { | |
243 | printf("Active ISO net connections"); | |
244 | if (aflag) | |
245 | printf(" (including servers)"); | |
246 | putchar('\n'); | |
247 | if (Aflag) | |
248 | printf("%-8.8s ", "PCB"); | |
249 | printf(Aflag ? | |
250 | "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : | |
251 | "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", | |
252 | "Proto", "Recv-Q", "Send-Q", | |
253 | "Local Address", "Foreign Address", "(state)"); | |
254 | first = 0; | |
255 | } | |
256 | if (Aflag) | |
257 | printf("%8x ", | |
258 | (istp ? (off_t)sockb.so_tpcb : (off_t)next)); | |
259 | printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, | |
260 | sockb.so_snd.sb_cc); | |
261 | if (isopcb.isop_laddr == 0) | |
262 | printf("*.*\t"); | |
263 | else { | |
264 | if ((char *)isopcb.isop_laddr == ((char *)next) + | |
265 | _offsetof(struct isopcb, isop_sladdr)) | |
266 | laddr.siso = isopcb.isop_sladdr; | |
267 | else | |
268 | kget(isopcb.isop_laddr, laddr); | |
269 | isonetprint(&laddr, 1); | |
270 | } | |
271 | if (isopcb.isop_faddr == 0) | |
272 | printf("*.*\t"); | |
273 | else { | |
274 | if ((char *)isopcb.isop_faddr == ((char *)next) + | |
275 | _offsetof(struct isopcb, isop_sfaddr)) | |
276 | faddr.siso = isopcb.isop_sfaddr; | |
277 | else | |
278 | kget(isopcb.isop_faddr, faddr); | |
279 | isonetprint(&faddr, 0); | |
280 | } | |
281 | if (istp) { | |
282 | if (tpcb.tp_state >= tp_NSTATES) | |
283 | printf(" %d", tpcb.tp_state); | |
284 | else | |
285 | printf(" %-12.12s", tp_sstring[tpcb.tp_state]); | |
286 | } | |
287 | putchar('\n'); | |
288 | prev = next; | |
289 | } | |
290 | } | |
291 | ||
292 | /* | |
293 | * Pretty print an iso address (net address + port). | |
294 | * If the nflag was specified, use numbers instead of names. | |
295 | */ | |
296 | ||
297 | #ifdef notdef | |
298 | char * | |
299 | isonetname(iso) | |
300 | register struct iso_addr *iso; | |
301 | { | |
302 | struct sockaddr_iso sa; | |
303 | struct iso_hostent *ihe = 0; | |
304 | struct iso_hostent *iso_gethostentrybyaddr(); | |
305 | struct iso_hostent *iso_getserventrybytsel(); | |
306 | struct iso_hostent Ihe; | |
307 | static char line[80]; | |
308 | char *index(); | |
309 | ||
310 | bzero(line, sizeof(line)); | |
311 | if( iso->isoa_afi ) { | |
312 | sa.siso_family = AF_ISO; | |
313 | sa.siso_addr = *iso; | |
314 | sa.siso_tsuffix = 0; | |
315 | ||
316 | if (!nflag ) | |
317 | ihe = iso_gethostentrybyaddr( &sa, 0, 0 ); | |
318 | if( ihe ) { | |
319 | Ihe = *ihe; | |
320 | ihe = &Ihe; | |
321 | sprintf(line, "%s", ihe->isoh_hname); | |
322 | } else { | |
323 | sprintf(line, "%s", iso_ntoa(iso)); | |
324 | } | |
325 | } else { | |
326 | sprintf(line, "*"); | |
327 | } | |
328 | return line; | |
329 | } | |
330 | ||
331 | isonetprint(iso, sufx, sufxlen, islocal) | |
332 | register struct iso_addr *iso; | |
333 | char *sufx; | |
334 | u_short sufxlen; | |
335 | int islocal; | |
336 | { | |
337 | struct iso_hostent *iso_getserventrybytsel(), *ihe; | |
338 | struct iso_hostent Ihe; | |
339 | char *line, *cp, *index(); | |
340 | int Alen = Aflag?18:22; | |
341 | ||
342 | line = isonetname(iso); | |
343 | cp = index(line, '\0'); | |
344 | ihe = (struct iso_hostent *)0; | |
345 | ||
346 | if( islocal ) | |
347 | islocal = 20; | |
348 | else | |
349 | islocal = 22 + Alen; | |
350 | ||
351 | if(Aflag) | |
352 | islocal += 10 ; | |
353 | ||
354 | if(!nflag) { | |
355 | if( (cp -line)>10 ) { | |
356 | cp = line+10; | |
357 | bzero(cp, sizeof(line)-10); | |
358 | } | |
359 | } | |
360 | ||
361 | *cp++ = '.'; | |
362 | if(sufxlen) { | |
363 | if( !Aflag && !nflag && (ihe=iso_getserventrybytsel(sufx, sufxlen))) { | |
364 | Ihe = *ihe; | |
365 | ihe = &Ihe; | |
366 | } | |
367 | if( ihe && (strlen(ihe->isoh_aname)>0) ) { | |
368 | sprintf(cp, "%s", ihe->isoh_aname); | |
369 | } else { | |
370 | iso_sprinttsel(cp, sufx, sufxlen); | |
371 | } | |
372 | } else | |
373 | sprintf(cp, "*"); | |
374 | /* | |
375 | fprintf(stdout, Aflag?" %-18.18s":" %-22.22s", line); | |
376 | */ | |
377 | ||
378 | if( strlen(line) > Alen ) { | |
379 | fprintf(stdout, " %s", line); | |
380 | fprintf(stdout, "\n %*.s", islocal+Alen," "); | |
381 | } else { | |
382 | fprintf(stdout, " %-*.*s", Alen, Alen,line); | |
383 | } | |
384 | } | |
385 | #endif | |
386 | ||
387 | #ifdef notdef | |
388 | x25_protopr(off, name) | |
389 | off_t off; | |
390 | char *name; | |
391 | { | |
392 | static char *xpcb_states[] = { | |
393 | "CLOSED", | |
394 | "LISTENING", | |
395 | "CLOSING", | |
396 | "CONNECTING", | |
397 | "ACKWAIT", | |
398 | "OPEN", | |
399 | }; | |
400 | register struct isopcb *prev, *next; | |
401 | struct x25_pcb xpcb; | |
402 | ||
403 | if (off == 0) { | |
404 | printf("%s control block: symbol not in namelist\n", name); | |
405 | return; | |
406 | } | |
407 | kvm_read(off, &xpcb, sizeof (struct x25_pcb)); | |
408 | prev = (struct isopcb *)off; | |
409 | if (xpcb.x_next == (struct isopcb *)off) | |
410 | return; | |
411 | while (xpcb.x_next != (struct isopcb *)off) { | |
412 | next = isopcb.isop_next; | |
413 | kvm_read((off_t)next, &xpcb, sizeof (struct x25_pcb)); | |
414 | if (xpcb.x_prev != prev) { | |
415 | printf("???\n"); | |
416 | break; | |
417 | } | |
418 | kvm_read((off_t)xpcb.x_socket, &sockb, sizeof (sockb)); | |
419 | ||
420 | if (!aflag && | |
421 | xpcb.x_state == LISTENING || | |
422 | xpcb.x_state == TP_CLOSED ) { | |
423 | prev = next; | |
424 | continue; | |
425 | } | |
426 | if (first) { | |
427 | printf("Active X25 net connections"); | |
428 | if (aflag) | |
429 | printf(" (including servers)"); | |
430 | putchar('\n'); | |
431 | if (Aflag) | |
432 | printf("%-8.8s ", "PCB"); | |
433 | printf(Aflag ? | |
434 | "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : | |
435 | "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", | |
436 | "Proto", "Recv-Q", "Send-Q", | |
437 | "Local Address", "Foreign Address", "(state)"); | |
438 | first = 0; | |
439 | } | |
440 | printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, | |
441 | sockb.so_snd.sb_cc); | |
442 | isonetprint(&xpcb.x_laddr.siso_addr, &xpcb.x_lport, | |
443 | sizeof(xpcb.x_lport), 1); | |
444 | isonetprint(&xpcb.x_faddr.siso_addr, &xpcb.x_fport, | |
445 | sizeof(xpcb.x_lport), 0); | |
446 | if (xpcb.x_state < 0 || xpcb.x_state >= x25_NSTATES) | |
447 | printf(" 0x0x0x0x0x0x0x0x0x%x", xpcb.x_state); | |
448 | else | |
449 | printf(" %-12.12s", xpcb_states[xpcb.x_state]); | |
450 | putchar('\n'); | |
451 | prev = next; | |
452 | } | |
453 | } | |
454 | #endif | |
455 | ||
456 | struct tp_stat tp_stat; | |
457 | ||
458 | tp_stats(off, name) | |
459 | caddr_t off, name; | |
460 | { | |
461 | if (off == 0) { | |
462 | printf("TP not configured\n\n"); | |
463 | return; | |
464 | } | |
465 | printf("%s:\n", name); | |
466 | kget(off, tp_stat); | |
467 | tprintstat(&tp_stat, 8); | |
468 | } | |
469 | ||
470 | #define OUT stdout | |
471 | ||
472 | #define plural(x) (x>1?"s":"") | |
473 | ||
474 | tprintstat(s, indent) | |
475 | register struct tp_stat *s; | |
476 | int indent; | |
477 | { | |
478 | fprintf(OUT, | |
479 | "%*sReceiving:\n",indent," "); | |
480 | fprintf(OUT, | |
481 | "\t%*s%d variable parameter%s ignored\n", indent," ", | |
482 | s->ts_param_ignored ,plural(s->ts_param_ignored)); | |
483 | fprintf(OUT, | |
484 | "\t%*s%d invalid parameter code%s\n", indent, " ", | |
485 | s->ts_inv_pcode ,plural(s->ts_inv_pcode)); | |
486 | fprintf(OUT, | |
487 | "\t%*s%d invalid parameter value%s\n", indent, " ", | |
488 | s->ts_inv_pval ,plural(s->ts_inv_pval)); | |
489 | fprintf(OUT, | |
490 | "\t%*s%d invalid dutype%s\n", indent, " ", | |
491 | s->ts_inv_dutype ,plural(s->ts_inv_dutype)); | |
492 | fprintf(OUT, | |
493 | "\t%*s%d negotiation failure%s\n", indent, " ", | |
494 | s->ts_negotfailed ,plural(s->ts_negotfailed)); | |
495 | fprintf(OUT, | |
496 | "\t%*s%d invalid destination reference%s\n", indent, " ", | |
497 | s->ts_inv_dref ,plural(s->ts_inv_dref)); | |
498 | fprintf(OUT, | |
499 | "\t%*s%d invalid suffix parameter%s\n", indent, " ", | |
500 | s->ts_inv_sufx ,plural(s->ts_inv_sufx)); | |
501 | fprintf(OUT, | |
502 | "\t%*s%d invalid length\n",indent, " ", s->ts_inv_length); | |
503 | fprintf(OUT, | |
504 | "\t%*s%d invalid checksum%s\n", indent, " ", | |
505 | s->ts_bad_csum ,plural(s->ts_bad_csum)); | |
506 | fprintf(OUT, | |
507 | "\t%*s%d DT%s out of order\n", indent, " ", | |
508 | s->ts_dt_ooo ,plural(s->ts_dt_ooo)); | |
509 | fprintf(OUT, | |
510 | "\t%*s%d DT%s not in window\n", indent, " ", | |
511 | s->ts_dt_niw ,plural(s->ts_dt_niw)); | |
512 | fprintf(OUT, | |
513 | "\t%*s%d duplicate DT%s\n", indent, " ", | |
514 | s->ts_dt_dup ,plural(s->ts_dt_dup)); | |
515 | fprintf(OUT, | |
516 | "\t%*s%d XPD%s not in window\n", indent, " ", | |
517 | s->ts_xpd_niw ,plural(s->ts_xpd_niw)); | |
518 | fprintf(OUT, | |
519 | "\t%*s%d XPD%s w/o credit to stash\n", indent, " ", | |
520 | s->ts_xpd_dup ,plural(s->ts_xpd_dup)); | |
521 | fprintf(OUT, | |
522 | "\t%*s%d time%s local credit reneged\n", indent, " ", | |
523 | s->ts_lcdt_reduced ,plural(s->ts_lcdt_reduced)); | |
524 | fprintf(OUT, | |
525 | "\t%*s%d concatenated TPDU%s\n", indent, " ", | |
526 | s->ts_concat_rcvd ,plural(s->ts_concat_rcvd)); | |
527 | fprintf(OUT, | |
528 | "%*sSending:\n", indent, " "); | |
529 | fprintf(OUT, | |
530 | "\t%*s%d XPD mark%s discarded\n", indent, " ", | |
531 | s->ts_xpdmark_del ,plural(s->ts_xpdmark_del)); | |
532 | fprintf(OUT, | |
533 | "\t%*sXPD stopped data flow %d time%s\n", indent, " ", | |
534 | s->ts_xpd_intheway ,plural(s->ts_xpd_intheway)); | |
535 | fprintf(OUT, | |
536 | "\t%*s%d time%s foreign window closed\n", indent, " ", | |
537 | s->ts_zfcdt ,plural(s->ts_zfcdt)); | |
538 | fprintf(OUT, | |
539 | "%*sMiscellaneous:\n", indent, " "); | |
540 | fprintf(OUT, | |
541 | "\t%*s%d small mbuf%s\n", indent, " ", | |
542 | s->ts_mb_small ,plural(s->ts_mb_small)); | |
543 | fprintf(OUT, | |
544 | "\t%*s%d cluster%s\n", indent, " ", | |
545 | s->ts_mb_cluster, plural(s->ts_mb_cluster)); | |
546 | fprintf(OUT, | |
547 | "\t%*s%d source quench \n",indent, " ", | |
548 | s->ts_quench); | |
549 | fprintf(OUT, | |
550 | "\t%*s%d dec bit%s\n", indent, " ", | |
551 | s->ts_rcvdecbit, plural(s->ts_rcvdecbit)); | |
552 | fprintf(OUT, | |
553 | "\t%*sM:L ( M mbuf chains of length L)\n", indent, " "); | |
554 | { | |
555 | register int j; | |
556 | ||
557 | fprintf(OUT, "\t%*s%d: over 16\n", indent, " ", | |
558 | s->ts_mb_len_distr[0]); | |
559 | for( j=1; j<=8; j++) { | |
560 | fprintf(OUT, | |
561 | "\t%*s%d: %d\t\t%d: %d\n", indent, " ", | |
562 | s->ts_mb_len_distr[j],j, | |
563 | s->ts_mb_len_distr[j<<1],j<<1 | |
564 | ); | |
565 | } | |
566 | } | |
567 | fprintf(OUT, | |
568 | "\t%*s%d EOT rcvd\n", indent, " ", s->ts_eot_input); | |
569 | fprintf(OUT, | |
570 | "\t%*s%d EOT sent\n", indent, " ", s->ts_EOT_sent); | |
571 | fprintf(OUT, | |
572 | "\t%*s%d EOT indication%s\n", indent, " ", | |
573 | s->ts_eot_user ,plural(s->ts_eot_user)); | |
574 | ||
575 | fprintf(OUT, | |
576 | "%*sConnections:\n", indent, " "); | |
577 | fprintf(OUT, | |
578 | "\t%*s%d connection%s used extended format\n", indent, " ", | |
579 | s->ts_xtd_fmt ,plural(s->ts_xtd_fmt)); | |
580 | fprintf(OUT, | |
581 | "\t%*s%d connection%s allowed transport expedited data\n", indent, " ", | |
582 | s->ts_use_txpd ,plural(s->ts_use_txpd)); | |
583 | fprintf(OUT, | |
584 | "\t%*s%d connection%s turned off checksumming\n", indent, " ", | |
585 | s->ts_csum_off ,plural(s->ts_csum_off)); | |
586 | fprintf(OUT, | |
587 | "\t%*s%d connection%s dropped due to retrans limit\n", indent, " ", | |
588 | s->ts_conn_gaveup ,plural(s->ts_conn_gaveup)); | |
589 | fprintf(OUT, | |
590 | "\t%*s%d tp 4 connection%s\n", indent, " ", | |
591 | s->ts_tp4_conn ,plural(s->ts_tp4_conn)); | |
592 | fprintf(OUT, | |
593 | "\t%*s%d tp 0 connection%s\n", indent, " ", | |
594 | s->ts_tp0_conn ,plural(s->ts_tp0_conn)); | |
595 | { | |
596 | register int j, div; | |
597 | register float f; | |
598 | static char *name[]= { | |
599 | "~LOCAL, PDN", | |
600 | "~LOCAL,~PDN", | |
601 | " LOCAL,~PDN", | |
602 | " LOCAL, PDN" | |
603 | }; | |
604 | #define factor(i) \ | |
605 | div = (s->ts_rtt[(i)].tv_sec * 1000000) + \ | |
606 | s->ts_rtt[(i)].tv_usec ;\ | |
607 | if(div) {\ | |
608 | f = ((s->ts_rtv[(i)].tv_sec * 1000000) + \ | |
609 | s->ts_rtv[(i)].tv_usec)/div; \ | |
610 | div = (int) (f + 0.5);\ | |
611 | } | |
612 | ||
613 | fprintf(OUT, | |
614 | "\n%*sRound trip times, listed in (sec: usec):\n", indent, " "); | |
615 | fprintf(OUT, | |
616 | "\t%*s%11.11s %12.12s | %12.12s | %s\n", indent, " ", | |
617 | "Category", | |
618 | "Smoothed avg", "Deviation", "Deviation/Avg"); | |
619 | for( j=0; j<=3; j++) { | |
620 | factor(j); | |
621 | fprintf(OUT, | |
622 | "\t%*s%11.11s: %5d:%-6d | %5d:%-6d | %-6d\n", indent, " ", | |
623 | name[j], | |
624 | s->ts_rtt[j].tv_sec, | |
625 | s->ts_rtt[j].tv_usec, | |
626 | s->ts_rtv[j].tv_sec, | |
627 | s->ts_rtv[j].tv_usec, | |
628 | div); | |
629 | } | |
630 | } | |
631 | fprintf(OUT, | |
632 | "\n%*sTpdus RECVD [%d valid, %3.6f %% of total (%d); %d dropped]\n",indent," ", | |
633 | s->ts_tpdu_rcvd , | |
634 | ((s->ts_pkt_rcvd > 0) ? | |
635 | ((100 * (float)s->ts_tpdu_rcvd)/(float)s->ts_pkt_rcvd) | |
636 | : 0), | |
637 | s->ts_pkt_rcvd, | |
638 | s->ts_recv_drop ); | |
639 | ||
640 | fprintf(OUT, | |
641 | "\t%*sDT %6d AK %6d DR %4d CR %4d \n", indent, " ", | |
642 | s->ts_DT_rcvd, s->ts_AK_rcvd, s->ts_DR_rcvd, s->ts_CR_rcvd); | |
643 | fprintf(OUT, | |
644 | "\t%*sXPD %6d XAK %6d DC %4d CC %4d ER %4d\n", indent, " ", | |
645 | s->ts_XPD_rcvd, s->ts_XAK_rcvd, s->ts_DC_rcvd, s->ts_CC_rcvd, | |
646 | s->ts_ER_rcvd); | |
647 | fprintf(OUT, | |
648 | "\n%*sTpdus SENT [%d total, %d dropped]\n", indent, " ", | |
649 | s->ts_tpdu_sent, s->ts_send_drop); | |
650 | ||
651 | fprintf(OUT, | |
652 | "\t%*sDT %6d AK %6d DR %4d CR %4d \n", indent, " ", | |
653 | s->ts_DT_sent, s->ts_AK_sent, s->ts_DR_sent, s->ts_CR_sent); | |
654 | fprintf(OUT, | |
655 | "\t%*sXPD %6d XAK %6d DC %4d CC %4d ER %4d\n", indent, " ", | |
656 | s->ts_XPD_sent, s->ts_XAK_sent, s->ts_DC_sent, s->ts_CC_sent, | |
657 | s->ts_ER_sent); | |
658 | ||
659 | fprintf(OUT, | |
660 | "\n%*sRetransmissions:\n", indent, " "); | |
661 | #define PERCENT(X,Y) (((Y)>0)?((100 *(float)(X)) / (float) (Y)):0) | |
662 | ||
663 | fprintf(OUT, | |
664 | "\t%*sCR %6d CC %6d DR %6d \n", indent, " ", | |
665 | s->ts_retrans_cr, s->ts_retrans_cc, s->ts_retrans_dr); | |
666 | fprintf(OUT, | |
667 | "\t%*sDT %6d (%5.2f%%)\n", indent, " ", | |
668 | s->ts_retrans_dt, | |
669 | PERCENT(s->ts_retrans_dt, s->ts_DT_sent)); | |
670 | fprintf(OUT, | |
671 | "\t%*sXPD %6d (%5.2f%%)\n", indent, " ", | |
672 | s->ts_retrans_xpd, | |
673 | PERCENT(s->ts_retrans_xpd, s->ts_XPD_sent)); | |
674 | ||
675 | ||
676 | fprintf(OUT, | |
677 | "\n%*sE Timers: [%6d ticks]\n", indent, " ", s->ts_Eticks); | |
678 | fprintf(OUT, | |
679 | "%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n",indent, " ", | |
680 | s->ts_Eset ,plural(s->ts_Eset), | |
681 | s->ts_Eexpired ,plural(s->ts_Eexpired), | |
682 | s->ts_Ecan_act ,plural(s->ts_Ecan_act)); | |
683 | ||
684 | fprintf(OUT, | |
685 | "\n%*sC Timers: [%6d ticks]\n", indent, " ",s->ts_Cticks); | |
686 | fprintf(OUT, | |
687 | "%*s%6d timer%s set \t%6d timer%s expired \t%6d timer%s cancelled\n", | |
688 | indent, " ", | |
689 | s->ts_Cset ,plural(s->ts_Cset), | |
690 | s->ts_Cexpired ,plural(s->ts_Cexpired), | |
691 | s->ts_Ccan_act ,plural(s->ts_Ccan_act)); | |
692 | fprintf(OUT, | |
693 | "%*s%6d inactive timer%s cancelled\n", indent, " ", | |
694 | s->ts_Ccan_inact ,plural(s->ts_Ccan_inact)); | |
695 | ||
696 | fprintf(OUT, | |
697 | "\n%*sPathological debugging activity:\n", indent, " "); | |
698 | fprintf(OUT, | |
699 | "\t%*s%6d CC%s sent to zero dref\n", indent, " ", | |
700 | s->ts_zdebug ,plural(s->ts_zdebug)); | |
701 | /* SAME LINE AS ABOVE */ | |
702 | fprintf(OUT, | |
703 | "\t%*s%6d random DT%s dropped\n", indent, " ", | |
704 | s->ts_ydebug ,plural(s->ts_ydebug)); | |
705 | fprintf(OUT, | |
706 | "\t%*s%6d illegally large XPD TPDU%s\n", indent, " ", | |
707 | s->ts_vdebug ,plural(s->ts_vdebug)); | |
708 | fprintf(OUT, | |
709 | "\t%*s%6d faked reneging of cdt\n", indent, " ", | |
710 | s->ts_ldebug ); | |
711 | ||
712 | fprintf(OUT, | |
713 | "\n%*sACK reasons:\n", indent, " "); | |
714 | fprintf(OUT, "\t%*s%6d not acked immediately\n", indent, " ", | |
715 | s->ts_ackreason[_ACK_DONT_] ); | |
716 | fprintf(OUT, "\t%*s%6d strategy==each\n", indent, " ", | |
717 | s->ts_ackreason[_ACK_STRAT_EACH_] ); | |
718 | fprintf(OUT, "\t%*s%6d strategy==fullwindow\n", indent, " ", | |
719 | s->ts_ackreason[_ACK_STRAT_FULLWIN_] ); | |
720 | fprintf(OUT, "\t%*s%6d duplicate DT\n", indent, " ", | |
721 | s->ts_ackreason[_ACK_DUP_] ); | |
722 | fprintf(OUT, "\t%*s%6d EOTSDU\n", indent, " ", | |
723 | s->ts_ackreason[_ACK_EOT_] ); | |
724 | fprintf(OUT, "\t%*s%6d reordered DT\n", indent, " ", | |
725 | s->ts_ackreason[_ACK_REORDER_] ); | |
726 | fprintf(OUT, "\t%*s%6d user rcvd\n", indent, " ", | |
727 | s->ts_ackreason[_ACK_USRRCV_] ); | |
728 | fprintf(OUT, "\t%*s%6d fcc reqd\n", indent, " ", | |
729 | s->ts_ackreason[_ACK_FCC_] ); | |
730 | } | |
731 | #ifndef SSEL | |
732 | #define SSEL(s) ((s)->siso_tlen + TSEL(s)) | |
733 | #define PSEL(s) ((s)->siso_slen + SSEL(s)) | |
734 | #endif | |
735 | ||
736 | isonetprint(siso, islocal) | |
737 | register struct sockaddr_iso *siso; | |
738 | int islocal; | |
739 | { | |
740 | hexprint(siso->siso_nlen, siso->siso_addr.isoa_genaddr, "{}"); | |
741 | if (siso->siso_tlen || siso->siso_slen || siso->siso_plen) | |
742 | hexprint(siso->siso_tlen, TSEL(siso), "()"); | |
743 | if (siso->siso_slen || siso->siso_plen) | |
744 | hexprint(siso->siso_slen, SSEL(siso), "[]"); | |
745 | if (siso->siso_plen) | |
746 | hexprint(siso->siso_plen, PSEL(siso), "<>"); | |
747 | putchar(' '); | |
748 | } | |
749 | static char hexlist[] = "0123456789abcdef", obuf[128]; | |
750 | ||
751 | hexprint(n, buf, delim) | |
752 | char *buf, *delim; | |
753 | { | |
754 | register u_char *in = (u_char *)buf, *top = in + n; | |
755 | register char *out = obuf; | |
756 | register int i; | |
757 | ||
758 | if (n == 0) | |
759 | return; | |
760 | while (in < top) { | |
761 | i = *in++; | |
762 | *out++ = '.'; | |
763 | if (i > 0xf) { | |
764 | out[1] = hexlist[i & 0xf]; | |
765 | i >>= 4; | |
766 | out[0] = hexlist[i]; | |
767 | out += 2; | |
768 | } else | |
769 | *out++ = hexlist[i]; | |
770 | } | |
771 | *obuf = *delim; *out++ = delim[1]; *out = 0; | |
772 | printf("%s", obuf); | |
773 | } |