xref: /csrg-svn/usr.bin/netstat/ns.c (revision 24303)
1*24303Ssklower /*
2*24303Ssklower  * Copyright (c) 1983 Regents of the University of California.
3*24303Ssklower  * All rights reserved.  The Berkeley software License Agreement
4*24303Ssklower  * specifies the terms and conditions for redistribution.
5*24303Ssklower  */
6*24303Ssklower 
7*24303Ssklower 
8*24303Ssklower #ifndef lint
9*24303Ssklower static char sccsid[] = "@(#)ns.c	5.1 (Berkeley) 08/16/85";
10*24303Ssklower #endif not lint
11*24303Ssklower 
12*24303Ssklower #include <stdio.h>
13*24303Ssklower #include <errno.h>
14*24303Ssklower #include <nlist.h>
15*24303Ssklower 
16*24303Ssklower #include <sys/types.h>
17*24303Ssklower #include <sys/socket.h>
18*24303Ssklower #include <sys/socketvar.h>
19*24303Ssklower #include <sys/mbuf.h>
20*24303Ssklower #include <sys/protosw.h>
21*24303Ssklower 
22*24303Ssklower #include <net/route.h>
23*24303Ssklower #include <net/if.h>
24*24303Ssklower 
25*24303Ssklower #include <netinet/tcp_fsm.h>
26*24303Ssklower #include <netinet/tcp_timer.h>
27*24303Ssklower 
28*24303Ssklower #include <netns/ns.h>
29*24303Ssklower #include <netns/ns_pcb.h>
30*24303Ssklower #include <netns/idp.h>
31*24303Ssklower #include <netns/idp_var.h>
32*24303Ssklower #include <netns/ns_error.h>
33*24303Ssklower #include <netns/sp.h>
34*24303Ssklower #include <netns/spidp.h>
35*24303Ssklower #include <netns/spp_var.h>
36*24303Ssklower #define SANAMES
37*24303Ssklower #include <netns/spp_debug.h>
38*24303Ssklower 
39*24303Ssklower 
40*24303Ssklower struct	nspcb nspcb;
41*24303Ssklower struct	sppcb sppcb;
42*24303Ssklower struct	socket sockb;
43*24303Ssklower struct	protosw proto;
44*24303Ssklower extern	int kmem;
45*24303Ssklower extern	int Aflag;
46*24303Ssklower extern	int aflag;
47*24303Ssklower extern	int nflag;
48*24303Ssklower char *ns_prpr();
49*24303Ssklower 
50*24303Ssklower static	int first = 1;
51*24303Ssklower 
52*24303Ssklower /*
53*24303Ssklower  * Print a summary of connections related to a Network Systems
54*24303Ssklower  * protocol.  For SPP, also give state of connection.
55*24303Ssklower  * Listening processes (aflag) are suppressed unless the
56*24303Ssklower  * -a (all) flag is specified.
57*24303Ssklower  */
58*24303Ssklower 
59*24303Ssklower nsprotopr(off, name)
60*24303Ssklower 	off_t off;
61*24303Ssklower 	char *name;
62*24303Ssklower {
63*24303Ssklower 	struct nspcb cb;
64*24303Ssklower 	register struct nspcb *prev, *next;
65*24303Ssklower 	int isspp;
66*24303Ssklower 
67*24303Ssklower 	if (off == 0) {
68*24303Ssklower 		printf("%s control block: symbol not in namelist\n", name);
69*24303Ssklower 		return;
70*24303Ssklower 	}
71*24303Ssklower 	isspp = strcmp(name, "spp") == 0;
72*24303Ssklower 	klseek(kmem, off, 0);
73*24303Ssklower 	read(kmem, &cb, sizeof (struct nspcb));
74*24303Ssklower 	nspcb = cb;
75*24303Ssklower 	prev = (struct nspcb *)off;
76*24303Ssklower 	if (first) {
77*24303Ssklower 		printf("Active connections");
78*24303Ssklower 		if (aflag)
79*24303Ssklower 			printf(" (including servers)");
80*24303Ssklower 		putchar('\n');
81*24303Ssklower 		if (Aflag)
82*24303Ssklower 			printf("%-8.8s ", "PCB");
83*24303Ssklower 		printf(Aflag ? "%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
84*24303Ssklower 			"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
85*24303Ssklower 			"Proto", "Recv-Q", "Send-Q",
86*24303Ssklower 			"Local Address", "Foreign Address", "(state)");
87*24303Ssklower 		first = 0;
88*24303Ssklower 	}
89*24303Ssklower 	for (;nspcb.nsp_next != (struct nspcb *)off; prev = next) {
90*24303Ssklower 		char *cp;
91*24303Ssklower 		off_t ppcb;
92*24303Ssklower 
93*24303Ssklower 		next = nspcb.nsp_next;
94*24303Ssklower 		klseek(kmem, (off_t)next, 0);
95*24303Ssklower 		read(kmem, &nspcb, sizeof (nspcb));
96*24303Ssklower 		if (nspcb.nsp_prev != prev) {
97*24303Ssklower 			printf("???\n");
98*24303Ssklower 			break;
99*24303Ssklower 		}
100*24303Ssklower 		if (!aflag && ns_nullhost(nspcb.nsp_faddr) ) {
101*24303Ssklower 			continue;
102*24303Ssklower 		}
103*24303Ssklower 		klseek(kmem, (off_t)nspcb.nsp_socket, 0);
104*24303Ssklower 		read(kmem, &sockb, sizeof (sockb));
105*24303Ssklower 		ppcb = (off_t) nspcb.nsp_pcb;
106*24303Ssklower 		if (ppcb) {
107*24303Ssklower 			if (isspp) {
108*24303Ssklower 				klseek(kmem, ppcb, 0);
109*24303Ssklower 				read(kmem, &sppcb, sizeof (sppcb));
110*24303Ssklower 			} else continue;
111*24303Ssklower 		} else
112*24303Ssklower 			if (isspp) continue;
113*24303Ssklower 		if (Aflag)
114*24303Ssklower 			printf("%8x ", ppcb);
115*24303Ssklower 		printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
116*24303Ssklower 			sockb.so_snd.sb_cc);
117*24303Ssklower 		printf("  %-22.22s", ns_prpr(&nspcb.nsp_laddr));
118*24303Ssklower 		printf(" %-22.22s", ns_prpr(&nspcb.nsp_faddr));
119*24303Ssklower 		if (isspp) {
120*24303Ssklower 			extern char *tcpstates[];
121*24303Ssklower 			if (sppcb.s_state < 0 || sppcb.s_state >= TCP_NSTATES)
122*24303Ssklower 				printf(" %d", sppcb.s_state);
123*24303Ssklower 			else
124*24303Ssklower 				printf(" %s", tcpstates[sppcb.s_state]);
125*24303Ssklower 		}
126*24303Ssklower 		putchar('\n');
127*24303Ssklower 		prev = next;
128*24303Ssklower 	}
129*24303Ssklower }
130*24303Ssklower #define ANY(x,y,z)  ((x) ? printf("\t%d %s%s%s\n",x,y,plural(x),z) : 0)
131*24303Ssklower 
132*24303Ssklower /*
133*24303Ssklower  * Dump SPP statistics structure.
134*24303Ssklower  */
135*24303Ssklower spp_stats(off, name)
136*24303Ssklower 	off_t off;
137*24303Ssklower 	char *name;
138*24303Ssklower {
139*24303Ssklower 	struct spp_istat spp_istat;
140*24303Ssklower 
141*24303Ssklower 	if (off == 0) {
142*24303Ssklower 		printf("%sstat: symbol not in namelist\n", name);
143*24303Ssklower 		return;
144*24303Ssklower 	}
145*24303Ssklower 	klseek(kmem, off, 0);
146*24303Ssklower 	read(kmem, (char *)&spp_istat, sizeof (spp_istat));
147*24303Ssklower 	printf("%s:\n", name);
148*24303Ssklower 	ANY(spp_istat.nonucn, "connection", " dropped due to no new sockets ");
149*24303Ssklower 	ANY(spp_istat.gonawy, "connection", " terminated due to our end dying");
150*24303Ssklower 	ANY(spp_istat.nonucn, "connection", " dropped due to inability to connect");
151*24303Ssklower 	ANY(spp_istat.noconn, "connection", " dropped due to inability to connect");
152*24303Ssklower 	ANY(spp_istat.notme, "connection", " incompleted due to mismatched id's");
153*24303Ssklower 	ANY(spp_istat.wrncon, "connection", " dropped due to mismatched id's");
154*24303Ssklower 	ANY(spp_istat.bdreas, "packet", " dropped out of sequence");
155*24303Ssklower 	ANY(spp_istat.lstdup, "packet", " duplicating the highest packet");
156*24303Ssklower 	ANY(spp_istat.notyet, "packet", " refused as exceeding allocation");
157*24303Ssklower }
158*24303Ssklower 
159*24303Ssklower /*
160*24303Ssklower  * Dump IDP statistics structure.
161*24303Ssklower  */
162*24303Ssklower idp_stats(off, name)
163*24303Ssklower 	off_t off;
164*24303Ssklower 	char *name;
165*24303Ssklower {
166*24303Ssklower 	struct idpstat idpstat;
167*24303Ssklower 
168*24303Ssklower 	if (off == 0) {
169*24303Ssklower 		printf("%sstat: symbol not in namelist\n", name);
170*24303Ssklower 		return;
171*24303Ssklower 	}
172*24303Ssklower 	klseek(kmem, off, 0);
173*24303Ssklower 	read(kmem, (char *)&idpstat, sizeof (idpstat));
174*24303Ssklower 	ANY(idpstat.idps_toosmall, "packet", " smaller than a header");
175*24303Ssklower 	ANY(idpstat.idps_tooshort, "packet", " smaller than advertised");
176*24303Ssklower 	ANY(idpstat.idps_badsum, "packet", " with bad checksums");
177*24303Ssklower }
178*24303Ssklower 
179*24303Ssklower static	char *((ns_errnames[])[2]) = {
180*24303Ssklower 	{"Unspecified Error", " at Destination"},
181*24303Ssklower 	{"Bad Checksum", " at Destination"},
182*24303Ssklower 	{"No Listener", " at Socket"},
183*24303Ssklower 	{"Packet", " Refused due to lack of space at Destination"},
184*24303Ssklower 	{"Unspecified Error", " while gatewayed"},
185*24303Ssklower 	{"Bad Checksum", " while gatewayed"},
186*24303Ssklower 	{"Packet", " forwarded too many times"},
187*24303Ssklower 	{"Packet", " too large to be forwarded"},
188*24303Ssklower };
189*24303Ssklower 
190*24303Ssklower /*
191*24303Ssklower  * Dump NS Error statistics structure.
192*24303Ssklower  */
193*24303Ssklower nserr_stats(off, name)
194*24303Ssklower 	off_t off;
195*24303Ssklower 	char *name;
196*24303Ssklower {
197*24303Ssklower 	struct ns_errstat ns_errstat;
198*24303Ssklower 	register int j;
199*24303Ssklower 	register int histoprint = 1;
200*24303Ssklower 	int z;
201*24303Ssklower 
202*24303Ssklower 	if (off == 0) {
203*24303Ssklower 		printf("%sstat: symbol not in namelist\n", name);
204*24303Ssklower 		return;
205*24303Ssklower 	}
206*24303Ssklower 	klseek(kmem, off, 0);
207*24303Ssklower 	read(kmem, (char *)&ns_errstat, sizeof (ns_errstat));
208*24303Ssklower 	printf("NS error statistics:\n");
209*24303Ssklower 	ANY(ns_errstat.ns_es_error, "call", " to ns_error");
210*24303Ssklower 	ANY(ns_errstat.ns_es_oldshort, "error",
211*24303Ssklower 		" ignored due to insufficient addressing");
212*24303Ssklower 	ANY(ns_errstat.ns_es_oldns_err, "error request",
213*24303Ssklower 		" in response to error packets");
214*24303Ssklower 	ANY(ns_errstat.ns_es_tooshort, "error packet",
215*24303Ssklower 		" received incomplete");
216*24303Ssklower 	ANY(ns_errstat.ns_es_badcode, "error packet",
217*24303Ssklower 		" received of unknown type");
218*24303Ssklower 	for(j = 0; j < NS_ERR_MAX; j ++) {
219*24303Ssklower 		z = ns_errstat.ns_es_outhist[j];
220*24303Ssklower 		if (z && histoprint) {
221*24303Ssklower 			printf("Output Error Histogram:\n");
222*24303Ssklower 			histoprint = 0;
223*24303Ssklower 		}
224*24303Ssklower 		ANY(z, ns_errnames[j][0], ns_errnames[j][1]);
225*24303Ssklower 	}
226*24303Ssklower 	histoprint = 1;
227*24303Ssklower 	for(j = 0; j < NS_ERR_MAX; j ++) {
228*24303Ssklower 		z = ns_errstat.ns_es_inhist[j];
229*24303Ssklower 		if (z && histoprint) {
230*24303Ssklower 			printf("Input Error Histogram:\n");
231*24303Ssklower 			histoprint = 0;
232*24303Ssklower 		}
233*24303Ssklower 		ANY(z, ns_errnames[j][0], ns_errnames[j][1]);
234*24303Ssklower 	}
235*24303Ssklower }
236*24303Ssklower static struct sockaddr_ns ssns = {AF_NS};
237*24303Ssklower 
238*24303Ssklower char *ns_prpr(x)
239*24303Ssklower struct ns_addr *x;
240*24303Ssklower {
241*24303Ssklower 	extern char *ns_print();
242*24303Ssklower 	struct sockaddr_ns *sns = &ssns;
243*24303Ssklower 	sns->sns_addr = *x;
244*24303Ssklower 	return(ns_print(sns));
245*24303Ssklower }
246