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