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