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