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
pk_decode(xp)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
pk_trace(m,dir)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
bprintf(fp,b,s)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
main(argc,argv)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
mbuf_dump(m)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
dumpit(what,where,n)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