149400Ssklower /*-
249400Ssklower * Copyright (c) 1988, 1991 The Regents of the University of California.
349400Ssklower * All rights reserved.
449400Ssklower *
549400Ssklower * %sccs.include.redist.c%
649400Ssklower */
749400Ssklower
849400Ssklower #ifndef lint
949400Ssklower char copyright[] =
1049400Ssklower "@(#) Copyright (c) 1988, 1991 The Regents of the University of California.\n\
1149400Ssklower All rights reserved.\n";
1249400Ssklower #endif /* not lint */
1349400Ssklower
1449400Ssklower #ifndef lint
15*49598Ssklower static char sccsid[] = "@(#)pk_dump.c 7.2 (Berkeley) 05/09/91";
1649400Ssklower #endif /* not lint */
1749400Ssklower
1849400Ssklower /*
1949400Ssklower * This is a kernel debugging aid.
2049400Ssklower * dumps out a cache of mbufs.
2149400Ssklower */
2249400Ssklower
2349400Ssklower #include <sys/param.h>
2449400Ssklower #include <sys/mbuf.h>
2549400Ssklower #include <sys/socket.h>
2649400Ssklower #include <sys/socketvar.h>
2749400Ssklower #include <net/if.h>
2849400Ssklower #include <netccitt/x25.h>
2949400Ssklower #include <netccitt/pk.h>
3049400Ssklower #include <netccitt/pk_var.h>
3149400Ssklower
3249400Ssklower #include <errno.h>
3349400Ssklower #include <netdb.h>
3449400Ssklower #include <nlist.h>
3549400Ssklower #include <kvm.h>
3649400Ssklower #include <paths.h>
3749400Ssklower #include <stdio.h>
3849400Ssklower /*
3949400Ssklower * This procedure decodes the X.25 level 3 packet returning a
4049400Ssklower * code to be used in switchs or arrays.
4149400Ssklower */
4249400Ssklower
pk_decode(xp)4349400Ssklower pk_decode (xp)
4449400Ssklower register struct x25_packet *xp;
4549400Ssklower {
4649400Ssklower register int type;
4749400Ssklower
4849400Ssklower if (xp -> fmt_identifier != 1)
4949400Ssklower return (INVALID_PACKET);
5049400Ssklower #ifdef ancient_history
5149400Ssklower /*
5249400Ssklower * Make sure that the logical channel group number is 0.
5349400Ssklower * This restriction may be removed at some later date.
5449400Ssklower */
5549400Ssklower if (xp -> lc_group_number != 0)
5649400Ssklower return (INVALID_PACKET);
5749400Ssklower #endif
5849400Ssklower /*
5949400Ssklower * Test for data packet first.
6049400Ssklower */
6149400Ssklower if (!(xp -> packet_type & DATA_PACKET_DESIGNATOR))
6249400Ssklower return (DATA);
6349400Ssklower
6449400Ssklower /*
6549400Ssklower * Test if flow control packet (RR or RNR).
6649400Ssklower */
6749400Ssklower if (!(xp -> packet_type & RR_OR_RNR_PACKET_DESIGNATOR))
6849400Ssklower switch (xp -> packet_type & 0x1f) {
6949400Ssklower case X25_RR:
7049400Ssklower return (RR);
7149400Ssklower case X25_RNR:
7249400Ssklower return (RNR);
7349400Ssklower case X25_REJECT:
7449400Ssklower return (REJECT);
7549400Ssklower }
7649400Ssklower
7749400Ssklower /*
7849400Ssklower * Determine the rest of the packet types.
7949400Ssklower */
8049400Ssklower switch (xp -> packet_type) {
8149400Ssklower case X25_CALL:
8249400Ssklower type = CALL;
8349400Ssklower break;
8449400Ssklower
8549400Ssklower case X25_CALL_ACCEPTED:
8649400Ssklower type = CALL_ACCEPTED;
8749400Ssklower break;
8849400Ssklower
8949400Ssklower case X25_CLEAR:
9049400Ssklower type = CLEAR;
9149400Ssklower break;
9249400Ssklower
9349400Ssklower case X25_CLEAR_CONFIRM:
9449400Ssklower type = CLEAR_CONF;
9549400Ssklower break;
9649400Ssklower
9749400Ssklower case X25_INTERRUPT:
9849400Ssklower type = INTERRUPT;
9949400Ssklower break;
10049400Ssklower
10149400Ssklower case X25_INTERRUPT_CONFIRM:
10249400Ssklower type = INTERRUPT_CONF;
10349400Ssklower break;
10449400Ssklower
10549400Ssklower case X25_RESET:
10649400Ssklower type = RESET;
10749400Ssklower break;
10849400Ssklower
10949400Ssklower case X25_RESET_CONFIRM:
11049400Ssklower type = RESET_CONF;
11149400Ssklower break;
11249400Ssklower
11349400Ssklower case X25_RESTART:
11449400Ssklower type = RESTART;
11549400Ssklower break;
11649400Ssklower
11749400Ssklower case X25_RESTART_CONFIRM:
11849400Ssklower type = RESTART_CONF;
11949400Ssklower break;
12049400Ssklower
12149400Ssklower case X25_DIAGNOSTIC:
12249400Ssklower type = DIAG_TYPE;
12349400Ssklower break;
12449400Ssklower
12549400Ssklower default:
12649400Ssklower type = INVALID_PACKET;
12749400Ssklower }
12849400Ssklower return (type);
12949400Ssklower }
13049400Ssklower
13149400Ssklower char *pk_state[] = {
13249400Ssklower "Listen", "Ready", "Received-Call",
13349400Ssklower "Sent-Call", "Data-Transfer","Received-Clear",
13449400Ssklower "Sent-Clear",
13549400Ssklower };
13649400Ssklower
13749400Ssklower char *pk_name[] = {
13849400Ssklower "Call", "Call-Conf", "Clear",
13949400Ssklower "Clear-Conf", "Data", "Intr", "Intr-Conf",
14049400Ssklower "Rr", "Rnr", "Reset", "Reset-Conf",
14149400Ssklower "Restart", "Restart-Conf", "Reject", "Diagnostic",
14249400Ssklower "Invalid"
14349400Ssklower };
14449400Ssklower
14549400Ssklower int pk_lengths[] = {0, 0, 0,
14649400Ssklower 0, 3, 5, 3,
14749400Ssklower 3, 3, 5, 5,
14849400Ssklower 5, 5, 5, 0,
14949400Ssklower 0, 0};
15049400Ssklower
pk_trace(m,dir)15149400Ssklower pk_trace (m, dir)
15249400Ssklower register struct mbuf *m;
15349400Ssklower char *dir;
15449400Ssklower {
15549400Ssklower register char *s;
15649400Ssklower struct x25_packet *xp = mtod(m, struct x25_packet *);
15749400Ssklower register int i, len = 0, cnt = 0;
15849400Ssklower
15949400Ssklower i = pk_decode (xp) / MAXSTATES;
16049400Ssklower if ((len = pk_lengths[i]) || (len = m -> m_len))
16149400Ssklower if (len > 5)
16249400Ssklower len = 5;
16349400Ssklower
16449400Ssklower printf ("%s LCN=%d: %s (", dir, LCN(xp), pk_name[i]);
16549400Ssklower
16649400Ssklower for (s = (char *) xp, i = 0; i < len; ++i, ++s)
16749400Ssklower printf ("%x ", (int) * s & 0xff);
16849400Ssklower printf (")\n");
16949400Ssklower }
17049400Ssklower
bprintf(fp,b,s)17149400Ssklower bprintf(fp, b, s)
17249400Ssklower register FILE *fp;
17349400Ssklower register int b;
17449400Ssklower register u_char *s;
17549400Ssklower {
17649400Ssklower register int i;
17749400Ssklower int gotsome = 0;
17849400Ssklower
17949400Ssklower if (b == 0)
18049400Ssklower return;
18149400Ssklower while (i = *s++) {
18249400Ssklower if (b & (1 << (i-1))) {
18349400Ssklower if (gotsome == 0)
18449400Ssklower i = '<';
18549400Ssklower else
18649400Ssklower i = ',';
18749400Ssklower (void) putc(i, fp);
18849400Ssklower gotsome = 1;
18949400Ssklower for (; (i = *s) > 32; s++)
19049400Ssklower (void) putc(i, fp);
19149400Ssklower } else
19249400Ssklower while (*s > 32)
19349400Ssklower s++;
19449400Ssklower }
19549400Ssklower if (gotsome)
19649400Ssklower (void) putc('>', fp);
19749400Ssklower }
19849400Ssklower
199*49598Ssklower int verbose = 0; /* so you can adb -w the binary */
200*49598Ssklower int tflag = 0;
201*49598Ssklower int Iflag = 0;
202*49598Ssklower int Aflag = 0;
20349400Ssklower char *vmunix = _PATH_UNIX;
20449400Ssklower char *kmemf;
20549400Ssklower struct nlist nl[] = {
206*49598Ssklower {"_pk_output_cache"},
20749400Ssklower {"_pk_input_cache"},
20849400Ssklower 0
20949400Ssklower };
21049400Ssklower
main(argc,argv)21149400Ssklower main(argc, argv)
21249400Ssklower int argc;
21349400Ssklower char **argv;
21449400Ssklower {
21549400Ssklower
21649400Ssklower if (kvm_openfiles(vmunix, kmemf, NULL) == -1) {
21749400Ssklower fprintf(stderr, "netstat: kvm_openfiles: %s\n", kvm_geterr());
21849400Ssklower exit(1);
21949400Ssklower }
22049400Ssklower if (kvm_nlist(nl) < 0 || nl[0].n_type == 0) {
22149400Ssklower fprintf(stderr, "%s: no namelist\n", vmunix);
22249400Ssklower exit(1);
22349400Ssklower }
22449400Ssklower mbuf_cache_dump(nl);
22549400Ssklower mbuf_cache_dump(nl + 1);
22649400Ssklower }
227*49598Ssklower struct mbuf_cache c;
228*49598Ssklower struct mbuf **mbvec;
22949400Ssklower #define kget(p, d) \
23049400Ssklower (kvm_read((void *)(p), &(d), sizeof (d)))
23149400Ssklower
23249400Ssklower mbuf_cache_dump(nl)
23349400Ssklower struct nlist *nl;
23449400Ssklower {
23549400Ssklower register struct mbuf *m;
23649400Ssklower unsigned cache_size;
23749400Ssklower int i;
23849400Ssklower
23949400Ssklower printf("Dumping %s:\n", nl->n_name);
24049400Ssklower kget(nl->n_value, c);
24149400Ssklower if (cache_size = c.mbc_size * sizeof(m))
24249400Ssklower mbvec = (struct mbuf **)malloc(cache_size);
243*49598Ssklower if (mbvec == 0 || c.mbc_cache == 0)
24449400Ssklower return;
24549400Ssklower kvm_read(c.mbc_cache, mbvec, cache_size);
24649400Ssklower for (i = c.mbc_num;;) {
24749400Ssklower if (i == 0)
24849400Ssklower i = c.mbc_size;
24949400Ssklower i--;
25049400Ssklower if (m = mbvec[i])
25149400Ssklower mbuf_dump(m);
25249400Ssklower if (i == c.mbc_num)
25349400Ssklower break;
25449400Ssklower }
25549400Ssklower }
25649400Ssklower
25749400Ssklower
mbuf_dump(m)25849400Ssklower mbuf_dump(m)
25949400Ssklower register struct mbuf *m;
26049400Ssklower {
26149400Ssklower int virgin = 1;
26249400Ssklower register struct x25_packet *xp;
26349400Ssklower struct mbuf n;
26449400Ssklower char extbuf[1024];
26549400Ssklower
26649400Ssklower putchar('\n');
26749400Ssklower for (; m; m = n.m_next) {
26849400Ssklower kget(m, n);
26949400Ssklower printf("m %x", m);
27049400Ssklower if (n.m_flags) {
27149400Ssklower printf(" flags ");
27249400Ssklower bprintf(stdout, n.m_flags,
27349400Ssklower "\1M_EXT\2M_PKTHDR\3M_EOR\4M_BCAST\5M_MCAST");
27449400Ssklower }
27549400Ssklower if (Aflag)
27649400Ssklower printf(" chained %x", n.m_nextpkt);
27749400Ssklower printf(" next %x len %d", n.m_next, n.m_len);
27849400Ssklower if (n.m_flags & M_PKTHDR) {
27949400Ssklower printf(" total %d", n.m_pkthdr.len);
28049400Ssklower if (Iflag)
28149400Ssklower printf(" rcvif %x", n.m_pkthdr.rcvif);
28249400Ssklower }
28349400Ssklower putchar('\n');
28449400Ssklower if (n.m_flags & M_EXT) {
28549400Ssklower kvm_read(n.m_ext.ext_buf, extbuf, sizeof(extbuf));
28649400Ssklower n.m_data = extbuf + (n.m_data - n.m_ext.ext_buf);
28749400Ssklower } else if (n.m_data < m->m_dat + MLEN)
28849400Ssklower n.m_data = n.m_dat + (n.m_data - m->m_dat);
28949400Ssklower else {
29049400Ssklower printf("mbuf screwup\n");
29149400Ssklower continue;
29249400Ssklower }
29349400Ssklower if (virgin) {
29449400Ssklower virgin = 0;
29549400Ssklower pk_trace(&n, " X.25: ");
29649400Ssklower }
29749400Ssklower dumpit("data: ",n.m_data, n.m_len);
29849400Ssklower }
29949400Ssklower }
30049400Ssklower
dumpit(what,where,n)30149400Ssklower dumpit(what, where, n)
30249400Ssklower char *what; unsigned short *where; int n;
30349400Ssklower {
30449400Ssklower unsigned short *s = where;
30549400Ssklower unsigned short *z = where + (n+1)/2;
30649400Ssklower int count = 0;
30749400Ssklower
30849400Ssklower if (verbose == 0)
30949400Ssklower return;
31049400Ssklower printf(what);
31149400Ssklower while(s < z) {
31249400Ssklower count++;
31349400Ssklower printf("%x ",*s++);
31449400Ssklower if ((count & 15) == 0)
31549400Ssklower putchar('\n');
31649400Ssklower }
31749400Ssklower if (count & 15)
31849400Ssklower putchar('\n');
31949400Ssklower fflush(stdout);
32049400Ssklower }
321