1 /* 2 * Copyright (c) 1985 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) 1985 Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)trsp.c 6.9 (Berkeley) 01/28/92"; 16 #endif /* not lint */ 17 18 #include <sys/cdefs.h> 19 #include <sys/param.h> 20 #include <sys/socket.h> 21 #include <sys/socketvar.h> 22 #define PRUREQUESTS 23 #include <sys/protosw.h> 24 25 #include <net/route.h> 26 #include <net/if.h> 27 28 #define TCPSTATES 29 #include <netinet/tcp_fsm.h> 30 #define TCPTIMERS 31 #include <netinet/tcp_timer.h> 32 33 #include <netns/ns.h> 34 #include <netns/sp.h> 35 #include <netns/idp.h> 36 #include <netns/spidp.h> 37 #include <netns/spp_timer.h> 38 #include <netns/spp_var.h> 39 #include <netns/ns_pcb.h> 40 #include <netns/idp_var.h> 41 #define SANAMES 42 #include <netns/spp_debug.h> 43 44 #include <stdio.h> 45 #include <errno.h> 46 #include <nlist.h> 47 #include <paths.h> 48 49 unsigned long ntime; 50 int sflag; 51 int tflag; 52 int jflag; 53 int aflag; 54 int zflag; 55 int numeric(); 56 struct nlist nl[] = { 57 { "_spp_debug" }, 58 { "_spp_debx" }, 59 0 60 }; 61 struct spp_debug spp_debug[SPP_NDEBUG]; 62 caddr_t spp_pcbs[SPP_NDEBUG]; 63 int spp_debx; 64 65 main(argc, argv) 66 int argc; 67 char **argv; 68 { 69 int i, mask = 0, npcbs = 0; 70 char *system, *core; 71 72 system = _PATH_UNIX; 73 core = _PATH_KMEM; 74 75 argc--, argv++; 76 again: 77 if (argc > 0 && !strcmp(*argv, "-a")) { 78 aflag++, argc--, argv++; 79 goto again; 80 } 81 if (argc > 0 && !strcmp(*argv, "-z")) { 82 zflag++, argc--, argv++; 83 goto again; 84 } 85 if (argc > 0 && !strcmp(*argv, "-s")) { 86 sflag++, argc--, argv++; 87 goto again; 88 } 89 if (argc > 0 && !strcmp(*argv, "-t")) { 90 tflag++, argc--, argv++; 91 goto again; 92 } 93 if (argc > 0 && !strcmp(*argv, "-j")) { 94 jflag++, argc--, argv++; 95 goto again; 96 } 97 if (argc > 0 && !strcmp(*argv, "-p")) { 98 argc--, argv++; 99 if (argc < 1) { 100 fprintf(stderr, "-p: missing sppcb address\n"); 101 exit(1); 102 } 103 if (npcbs >= SPP_NDEBUG) { 104 fprintf(stderr, "-p: too many pcb's specified\n"); 105 exit(1); 106 } 107 sscanf(*argv, "%x", &spp_pcbs[npcbs++]); 108 argc--, argv++; 109 goto again; 110 } 111 if (argc > 0) { 112 system = *argv; 113 argc--, argv++; 114 mask++; 115 /* 116 * Discard setgid privileges if not the running kernel so that 117 * bad guys can't print interesting stuff from kernel memory. 118 */ 119 setgid(getgid()); 120 } 121 if (argc > 0) { 122 core = *argv; 123 argc--, argv++; 124 mask++; 125 setgid(getgid()); 126 } 127 (void) nlist(system, nl); 128 if (nl[0].n_value == 0) { 129 fprintf(stderr, "trsp: %s: no namelist\n", system); 130 exit(1); 131 } 132 (void) close(0); 133 if (open(core, 0) < 0) { 134 fprintf(stderr, "trsp: "); perror(core); 135 exit(2); 136 } 137 if (mask) { 138 nl[0].n_value &= 0x7fffffff; 139 nl[1].n_value &= 0x7fffffff; 140 } 141 (void) lseek(0, nl[1].n_value, 0); 142 if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 143 fprintf(stderr, "trsp: "); perror("spp_debx"); 144 exit(3); 145 } 146 printf("spp_debx=%d\n", spp_debx); 147 (void) lseek(0, nl[0].n_value, 0); 148 if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 149 fprintf(stderr, "trsp: "); perror("spp_debug"); 150 exit(3); 151 } 152 /* 153 * Here, we just want to clear out the old trace data and start over. 154 */ 155 if (zflag) { 156 char *cp = (char *) spp_debug, 157 *cplim = cp + sizeof(spp_debug); 158 (void) close(0); 159 if (open(core, 2) < 0) { 160 fprintf(stderr, "trsp: "); perror(core); 161 exit(2); 162 } 163 while(cp < cplim) *cp++ = 0; 164 (void) lseek(0, nl[0].n_value, 0); 165 if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 166 fprintf(stderr, "trsp: "); perror("spp_debug"); 167 exit(3); 168 } 169 (void) lseek(0, nl[1].n_value, 0); 170 spp_debx = 0; 171 if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 172 fprintf(stderr, "trsp: "); perror("spp_debx"); 173 exit(3); 174 } 175 exit(0); 176 } 177 /* 178 * If no control blocks have been specified, figure 179 * out how many distinct one we have and summarize 180 * them in spp_pcbs for sorting the trace records 181 * below. 182 */ 183 if (npcbs == 0) { 184 for (i = 0; i < SPP_NDEBUG; i++) { 185 register int j; 186 register struct spp_debug *sd = &spp_debug[i]; 187 188 if (sd->sd_cb == 0) 189 continue; 190 for (j = 0; j < npcbs; j++) 191 if (spp_pcbs[j] == sd->sd_cb) 192 break; 193 if (j >= npcbs) 194 spp_pcbs[npcbs++] = sd->sd_cb; 195 } 196 } 197 qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric); 198 if (jflag) { 199 char *cp = ""; 200 201 for (i = 0; i < npcbs; i++) { 202 printf("%s%x", cp, spp_pcbs[i]); 203 cp = ", "; 204 } 205 if (*cp) 206 putchar('\n'); 207 exit(0); 208 } 209 for (i = 0; i < npcbs; i++) { 210 printf("\n%x:\n", spp_pcbs[i]); 211 dotrace(spp_pcbs[i]); 212 } 213 exit(0); 214 } 215 216 dotrace(sppcb) 217 register caddr_t sppcb; 218 { 219 register int i; 220 register struct spp_debug *sd; 221 222 for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) { 223 sd = &spp_debug[i]; 224 if (sppcb && sd->sd_cb != sppcb) 225 continue; 226 ntime = ntohl(sd->sd_time); 227 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 228 &sd->sd_si, sd->sd_req); 229 } 230 for (i = 0; i < spp_debx % SPP_NDEBUG; i++) { 231 sd = &spp_debug[i]; 232 if (sppcb && sd->sd_cb != sppcb) 233 continue; 234 ntime = ntohl(sd->sd_time); 235 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 236 &sd->sd_si, sd->sd_req); 237 } 238 } 239 240 ptime(ms) 241 int ms; 242 { 243 244 printf("%03d ", (ms/10) % 1000); 245 } 246 247 numeric(c1, c2) 248 caddr_t *c1, *c2; 249 { 250 251 return (*c1 - *c2); 252 } 253 254 spp_trace(act, ostate, asp, sp, si, req) 255 short act, ostate; 256 struct sppcb *asp, *sp; 257 struct spidp *si; 258 int req; 259 { 260 u_short seq, ack, len, alo; 261 int flags, timer; 262 char *cp; 263 264 if(ostate >= TCP_NSTATES) ostate = 0; 265 if(act > SA_DROP) act = SA_DROP; 266 printf("\n"); 267 ptime(ntime); 268 printf("%s:%s", tcpstates[ostate], sanames[act]); 269 270 if (si != 0) { 271 seq = si->si_seq; 272 ack = si->si_ack; 273 alo = si->si_alo; 274 len = si->si_len; 275 switch (act) { 276 case SA_RESPOND: 277 case SA_OUTPUT: 278 seq = ntohs(seq); 279 ack = ntohs(ack); 280 alo = ntohs(alo); 281 len = ntohs(len); 282 case SA_INPUT: 283 case SA_DROP: 284 if (aflag) { 285 printf("\n\tsna="); 286 ns_printhost(&si->si_sna); 287 printf("\tdna="); 288 ns_printhost(&si->si_dna); 289 } 290 printf("\n\t"); 291 #define p1(name, f) { \ 292 printf("%s = %x, ", name, f); \ 293 } 294 p1("seq", seq); 295 p1("ack", ack); 296 p1("alo", alo); 297 p1("len", len); 298 flags = si->si_cc; 299 printf("flags=%x", flags); 300 #define pf(name, f) { \ 301 if (flags & f) { \ 302 printf("%s%s", cp, name); \ 303 cp = ","; \ 304 } \ 305 } 306 if (flags) { 307 char *cp = "<"; 308 pf("SP_SP", SP_SP); 309 pf("SP_SA", SP_SA); 310 pf("SP_OB", SP_OB); 311 pf("SP_EM", SP_EM); 312 printf(">"); 313 } 314 printf(", "); 315 #define p2(name, f) { \ 316 printf("%s = %x, ", name, f); \ 317 } 318 p2("sid", si->si_sid); 319 p2("did", si->si_did); 320 p2("dt", si->si_dt); 321 printf("\n\tsna="); 322 ns_printhost(&si->si_sna); 323 printf("\tdna="); 324 ns_printhost(&si->si_dna); 325 } 326 } 327 if(act == SA_USER) { 328 printf("\treq=%s", prurequests[req&0xff]); 329 if ((req & 0xff) == PRU_SLOWTIMO) 330 printf("<%s>", tcptimers[req>>8]); 331 } 332 printf(" -> %s", tcpstates[sp->s_state]); 333 334 /* print out internal state of sp !?! */ 335 printf("\n"); 336 if (sp == 0) 337 return; 338 #define p3(name, f) { \ 339 printf("%s = %x, ", name, f); \ 340 } 341 if (sflag) { 342 printf("\t"); 343 p3("rack", sp->s_rack); 344 p3("ralo", sp->s_ralo); 345 p3("smax", sp->s_smax); 346 p3("snxt", sp->s_snxt); 347 p3("flags", sp->s_flags); 348 #undef pf 349 #define pf(name, f) { \ 350 if (flags & f) { \ 351 printf("%s%s", cp, name); \ 352 cp = ","; \ 353 } \ 354 } 355 flags = sp->s_flags; 356 if (flags || sp->s_oobflags) { 357 char *cp = "<"; 358 pf("ACKNOW", SF_ACKNOW); 359 pf("DELACK", SF_DELACK); 360 pf("HI", SF_HI); 361 pf("HO", SF_HO); 362 pf("PI", SF_PI); 363 pf("WIN", SF_WIN); 364 pf("RXT", SF_RXT); 365 pf("RVD", SF_RVD); 366 flags = sp->s_oobflags; 367 pf("SOOB", SF_SOOB); 368 pf("IOOB", SF_IOOB); 369 printf(">"); 370 } 371 } 372 /* print out timers? */ 373 if (tflag) { 374 char *cp = "\t"; 375 register int i; 376 377 printf("\n\tTIMERS: "); 378 p3("idle", sp->s_idle); 379 p3("force", sp->s_force); 380 p3("rtseq", sp->s_rtseq); 381 for (i = 0; i < TCPT_NTIMERS; i++) { 382 if (sp->s_timer[i] == 0) 383 continue; 384 printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]); 385 if (i == TCPT_REXMT) 386 printf(" (s_rxtshft=%d)", sp->s_rxtshift); 387 cp = ", "; 388 } 389 if (*cp != '\t') 390 putchar('\n'); 391 } 392 } 393 394 ns_printhost(p) 395 register struct ns_addr *p; 396 { 397 398 printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>", 399 p->x_net.s_net[0], 400 p->x_net.s_net[1], 401 p->x_host.s_host[0], 402 p->x_host.s_host[1], 403 p->x_host.s_host[2], 404 p->x_port); 405 406 } 407 408