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