xref: /csrg-svn/sys/tests/netccitt/pk_dump.c (revision 49400)
1*49400Ssklower /*-
2*49400Ssklower  * Copyright (c) 1988, 1991 The Regents of the University of California.
3*49400Ssklower  * All rights reserved.
4*49400Ssklower  *
5*49400Ssklower  * %sccs.include.redist.c%
6*49400Ssklower  */
7*49400Ssklower 
8*49400Ssklower #ifndef lint
9*49400Ssklower char copyright[] =
10*49400Ssklower "@(#) Copyright (c) 1988, 1991 The Regents of the University of California.\n\
11*49400Ssklower  All rights reserved.\n";
12*49400Ssklower #endif /* not lint */
13*49400Ssklower 
14*49400Ssklower #ifndef lint
15*49400Ssklower static char sccsid[] = "@(#)pk_dump.c	7.1 (Berkeley) 05/07/91";
16*49400Ssklower #endif /* not lint */
17*49400Ssklower 
18*49400Ssklower /*
19*49400Ssklower  * This is a kernel debugging aid.
20*49400Ssklower  * dumps out a cache of mbufs.
21*49400Ssklower  */
22*49400Ssklower 
23*49400Ssklower #include <sys/param.h>
24*49400Ssklower #include <sys/mbuf.h>
25*49400Ssklower #include <sys/socket.h>
26*49400Ssklower #include <sys/socketvar.h>
27*49400Ssklower #include <net/if.h>
28*49400Ssklower #include <netccitt/x25.h>
29*49400Ssklower #include <netccitt/pk.h>
30*49400Ssklower #include <netccitt/pk_var.h>
31*49400Ssklower #include <netccitt/pk_debug.h>
32*49400Ssklower 
33*49400Ssklower #include <errno.h>
34*49400Ssklower #include <netdb.h>
35*49400Ssklower #include <nlist.h>
36*49400Ssklower #include <kvm.h>
37*49400Ssklower #include <paths.h>
38*49400Ssklower #include <stdio.h>
39*49400Ssklower /*
40*49400Ssklower  *  This procedure decodes the X.25 level 3 packet returning a
41*49400Ssklower  *  code to be used in switchs or arrays.
42*49400Ssklower  */
43*49400Ssklower 
44*49400Ssklower pk_decode (xp)
45*49400Ssklower register struct x25_packet *xp;
46*49400Ssklower {
47*49400Ssklower 	register int type;
48*49400Ssklower 
49*49400Ssklower 	if (xp -> fmt_identifier != 1)
50*49400Ssklower 		return (INVALID_PACKET);
51*49400Ssklower #ifdef ancient_history
52*49400Ssklower 	/*
53*49400Ssklower 	 *  Make sure that the logical channel group number is 0.
54*49400Ssklower 	 *  This restriction may be removed at some later date.
55*49400Ssklower 	 */
56*49400Ssklower 	if (xp -> lc_group_number != 0)
57*49400Ssklower 		return (INVALID_PACKET);
58*49400Ssklower #endif
59*49400Ssklower 	/*
60*49400Ssklower 	 *  Test for data packet first.
61*49400Ssklower 	 */
62*49400Ssklower 	if (!(xp -> packet_type & DATA_PACKET_DESIGNATOR))
63*49400Ssklower 		return (DATA);
64*49400Ssklower 
65*49400Ssklower 	/*
66*49400Ssklower 	 *  Test if flow control packet (RR or RNR).
67*49400Ssklower 	 */
68*49400Ssklower 	if (!(xp -> packet_type & RR_OR_RNR_PACKET_DESIGNATOR))
69*49400Ssklower 		switch (xp -> packet_type & 0x1f) {
70*49400Ssklower 		case X25_RR:
71*49400Ssklower 			return (RR);
72*49400Ssklower 		case X25_RNR:
73*49400Ssklower 			return (RNR);
74*49400Ssklower 		case X25_REJECT:
75*49400Ssklower 			return (REJECT);
76*49400Ssklower 		}
77*49400Ssklower 
78*49400Ssklower 	/*
79*49400Ssklower 	 *  Determine the rest of the packet types.
80*49400Ssklower 	 */
81*49400Ssklower 	switch (xp -> packet_type) {
82*49400Ssklower 	case X25_CALL:
83*49400Ssklower 		type = CALL;
84*49400Ssklower 		break;
85*49400Ssklower 
86*49400Ssklower 	case X25_CALL_ACCEPTED:
87*49400Ssklower 		type = CALL_ACCEPTED;
88*49400Ssklower 		break;
89*49400Ssklower 
90*49400Ssklower 	case X25_CLEAR:
91*49400Ssklower 		type = CLEAR;
92*49400Ssklower 		break;
93*49400Ssklower 
94*49400Ssklower 	case X25_CLEAR_CONFIRM:
95*49400Ssklower 		type = CLEAR_CONF;
96*49400Ssklower 		break;
97*49400Ssklower 
98*49400Ssklower 	case X25_INTERRUPT:
99*49400Ssklower 		type = INTERRUPT;
100*49400Ssklower 		break;
101*49400Ssklower 
102*49400Ssklower 	case X25_INTERRUPT_CONFIRM:
103*49400Ssklower 		type = INTERRUPT_CONF;
104*49400Ssklower 		break;
105*49400Ssklower 
106*49400Ssklower 	case X25_RESET:
107*49400Ssklower 		type = RESET;
108*49400Ssklower 		break;
109*49400Ssklower 
110*49400Ssklower 	case X25_RESET_CONFIRM:
111*49400Ssklower 		type = RESET_CONF;
112*49400Ssklower 		break;
113*49400Ssklower 
114*49400Ssklower 	case X25_RESTART:
115*49400Ssklower 		type = RESTART;
116*49400Ssklower 		break;
117*49400Ssklower 
118*49400Ssklower 	case X25_RESTART_CONFIRM:
119*49400Ssklower 		type = RESTART_CONF;
120*49400Ssklower 		break;
121*49400Ssklower 
122*49400Ssklower 	case X25_DIAGNOSTIC:
123*49400Ssklower 		type = DIAG_TYPE;
124*49400Ssklower 		break;
125*49400Ssklower 
126*49400Ssklower 	default:
127*49400Ssklower 		type = INVALID_PACKET;
128*49400Ssklower 	}
129*49400Ssklower 	return (type);
130*49400Ssklower }
131*49400Ssklower 
132*49400Ssklower char	*pk_state[] = {
133*49400Ssklower 	"Listen",	"Ready",	"Received-Call",
134*49400Ssklower 	"Sent-Call",	"Data-Transfer","Received-Clear",
135*49400Ssklower 	"Sent-Clear",
136*49400Ssklower };
137*49400Ssklower 
138*49400Ssklower char   *pk_name[] = {
139*49400Ssklower 	"Call",		"Call-Conf",	"Clear",
140*49400Ssklower 	"Clear-Conf",	"Data",		"Intr",		"Intr-Conf",
141*49400Ssklower 	"Rr",		"Rnr",		"Reset",	"Reset-Conf",
142*49400Ssklower 	"Restart",	"Restart-Conf",	"Reject",	"Diagnostic",
143*49400Ssklower 	"Invalid"
144*49400Ssklower };
145*49400Ssklower 
146*49400Ssklower int pk_lengths[] = {0, 0, 0,
147*49400Ssklower 0, 3, 5, 3,
148*49400Ssklower 3, 3, 5, 5,
149*49400Ssklower 5, 5, 5, 0,
150*49400Ssklower 0, 0};
151*49400Ssklower 
152*49400Ssklower pk_trace (m, dir)
153*49400Ssklower register struct mbuf *m;
154*49400Ssklower char *dir;
155*49400Ssklower {
156*49400Ssklower 	register char *s;
157*49400Ssklower 	struct x25_packet *xp = mtod(m, struct x25_packet *);
158*49400Ssklower 	register int i, len = 0, cnt = 0;
159*49400Ssklower 
160*49400Ssklower 	i = pk_decode (xp) / MAXSTATES;
161*49400Ssklower 	if ((len = pk_lengths[i]) || (len = m -> m_len))
162*49400Ssklower 		if (len > 5)
163*49400Ssklower 			len = 5;
164*49400Ssklower 
165*49400Ssklower 	printf ("%s LCN=%d: %s (", dir, LCN(xp), pk_name[i]);
166*49400Ssklower 
167*49400Ssklower 	for (s = (char *) xp, i = 0; i < len; ++i, ++s)
168*49400Ssklower 		printf ("%x ", (int) * s & 0xff);
169*49400Ssklower 	printf (")\n");
170*49400Ssklower }
171*49400Ssklower 
172*49400Ssklower bprintf(fp, b, s)
173*49400Ssklower 	register FILE *fp;
174*49400Ssklower 	register int b;
175*49400Ssklower 	register u_char *s;
176*49400Ssklower {
177*49400Ssklower 	register int i;
178*49400Ssklower 	int gotsome = 0;
179*49400Ssklower 
180*49400Ssklower 	if (b == 0)
181*49400Ssklower 		return;
182*49400Ssklower 	while (i = *s++) {
183*49400Ssklower 		if (b & (1 << (i-1))) {
184*49400Ssklower 			if (gotsome == 0)
185*49400Ssklower 				i = '<';
186*49400Ssklower 			else
187*49400Ssklower 				i = ',';
188*49400Ssklower 			(void) putc(i, fp);
189*49400Ssklower 			gotsome = 1;
190*49400Ssklower 			for (; (i = *s) > 32; s++)
191*49400Ssklower 				(void) putc(i, fp);
192*49400Ssklower 		} else
193*49400Ssklower 			while (*s > 32)
194*49400Ssklower 				s++;
195*49400Ssklower 	}
196*49400Ssklower 	if (gotsome)
197*49400Ssklower 		(void) putc('>', fp);
198*49400Ssklower }
199*49400Ssklower 
200*49400Ssklower int verbose;
201*49400Ssklower int tflag;
202*49400Ssklower int Iflag;
203*49400Ssklower int Aflag;
204*49400Ssklower char *vmunix = _PATH_UNIX;
205*49400Ssklower char *kmemf;
206*49400Ssklower struct nlist nl[] = {
207*49400Ssklower {"_pk_input_cache"},
208*49400Ssklower {"_pk_output_cache"},
209*49400Ssklower 0
210*49400Ssklower };
211*49400Ssklower 
212*49400Ssklower main(argc, argv)
213*49400Ssklower 	int argc;
214*49400Ssklower 	char **argv;
215*49400Ssklower {
216*49400Ssklower 
217*49400Ssklower 	if (kvm_openfiles(vmunix, kmemf, NULL) == -1) {
218*49400Ssklower 		fprintf(stderr, "netstat: kvm_openfiles: %s\n", kvm_geterr());
219*49400Ssklower 		exit(1);
220*49400Ssklower 	}
221*49400Ssklower 	if (kvm_nlist(nl) < 0 || nl[0].n_type == 0) {
222*49400Ssklower 		fprintf(stderr, "%s: no namelist\n", vmunix);
223*49400Ssklower 		exit(1);
224*49400Ssklower 	}
225*49400Ssklower 	mbuf_cache_dump(nl);
226*49400Ssklower 	mbuf_cache_dump(nl + 1);
227*49400Ssklower }
228*49400Ssklower #define kget(p, d) \
229*49400Ssklower 	(kvm_read((void *)(p), &(d), sizeof (d)))
230*49400Ssklower 
231*49400Ssklower mbuf_cache_dump(nl)
232*49400Ssklower struct nlist *nl;
233*49400Ssklower {
234*49400Ssklower 	struct mbuf_cache c;
235*49400Ssklower 	struct mbuf **mbvec;
236*49400Ssklower 	register struct mbuf *m;
237*49400Ssklower 	unsigned cache_size;
238*49400Ssklower 	int i;
239*49400Ssklower 
240*49400Ssklower 	printf("Dumping %s:\n", nl->n_name);
241*49400Ssklower 	kget(nl->n_value, c);
242*49400Ssklower 	if (cache_size = c.mbc_size * sizeof(m))
243*49400Ssklower 		mbvec = (struct mbuf **)malloc(cache_size);
244*49400Ssklower 	if (mbvec == 0)
245*49400Ssklower 		return;
246*49400Ssklower 	kvm_read(c.mbc_cache, mbvec, cache_size);
247*49400Ssklower 	for (i = c.mbc_num;;) {
248*49400Ssklower 		if (i == 0)
249*49400Ssklower 			i = c.mbc_size;
250*49400Ssklower 		i--;
251*49400Ssklower 		if (m = mbvec[i])
252*49400Ssklower 			mbuf_dump(m);
253*49400Ssklower 		if (i == c.mbc_num)
254*49400Ssklower 			break;
255*49400Ssklower 	}
256*49400Ssklower }
257*49400Ssklower 
258*49400Ssklower 
259*49400Ssklower mbuf_dump(m)
260*49400Ssklower register struct mbuf *m;
261*49400Ssklower {
262*49400Ssklower 	int virgin = 1;
263*49400Ssklower 	register struct x25_packet *xp;
264*49400Ssklower 	struct mbuf n;
265*49400Ssklower 	char extbuf[1024];
266*49400Ssklower 
267*49400Ssklower 	putchar('\n');
268*49400Ssklower 	for (; m; m = n.m_next) {
269*49400Ssklower 		kget(m, n);
270*49400Ssklower 		printf("m %x", m);
271*49400Ssklower 		if (n.m_flags) {
272*49400Ssklower 			printf(" flags ");
273*49400Ssklower 			bprintf(stdout, n.m_flags,
274*49400Ssklower 			    "\1M_EXT\2M_PKTHDR\3M_EOR\4M_BCAST\5M_MCAST");
275*49400Ssklower 		}
276*49400Ssklower 		if (Aflag)
277*49400Ssklower 			printf(" chained %x", n.m_nextpkt);
278*49400Ssklower 		printf(" next %x len %d", n.m_next, n.m_len);
279*49400Ssklower 		if (n.m_flags & M_PKTHDR) {
280*49400Ssklower 			printf(" total %d", n.m_pkthdr.len);
281*49400Ssklower 			if (Iflag)
282*49400Ssklower 				printf(" rcvif %x", n.m_pkthdr.rcvif);
283*49400Ssklower 		}
284*49400Ssklower 		putchar('\n');
285*49400Ssklower 		if (n.m_flags & M_EXT) {
286*49400Ssklower 			kvm_read(n.m_ext.ext_buf, extbuf, sizeof(extbuf));
287*49400Ssklower 			n.m_data = extbuf + (n.m_data - n.m_ext.ext_buf);
288*49400Ssklower 		} else if (n.m_data <  m->m_dat + MLEN)
289*49400Ssklower 			n.m_data = n.m_dat + (n.m_data - m->m_dat);
290*49400Ssklower 		else {
291*49400Ssklower 			printf("mbuf screwup\n");
292*49400Ssklower 			continue;
293*49400Ssklower 		}
294*49400Ssklower 		if (virgin) {
295*49400Ssklower 			virgin = 0;
296*49400Ssklower 			pk_trace(&n, "  X.25: ");
297*49400Ssklower 		}
298*49400Ssklower 		dumpit("data: ",n.m_data, n.m_len);
299*49400Ssklower 	}
300*49400Ssklower }
301*49400Ssklower 
302*49400Ssklower dumpit(what, where, n)
303*49400Ssklower char *what; unsigned short *where; int n;
304*49400Ssklower {
305*49400Ssklower 	unsigned short *s = where;
306*49400Ssklower 	unsigned short *z = where + (n+1)/2;
307*49400Ssklower 	int count = 0;
308*49400Ssklower 
309*49400Ssklower 	if (verbose == 0)
310*49400Ssklower 		return;
311*49400Ssklower 	printf(what);
312*49400Ssklower 	while(s < z) {
313*49400Ssklower 		count++;
314*49400Ssklower 		printf("%x ",*s++);
315*49400Ssklower 		if ((count & 15) == 0)
316*49400Ssklower 			putchar('\n');
317*49400Ssklower 	}
318*49400Ssklower 	if (count & 15)
319*49400Ssklower 		putchar('\n');
320*49400Ssklower 	fflush(stdout);
321*49400Ssklower }
322