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.8 (Berkeley) 03/02/91"; 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 if (argc > 0) { 117 core = *argv; 118 argc--, argv++; 119 mask++; 120 } 121 (void) nlist(system, nl); 122 if (nl[0].n_value == 0) { 123 fprintf(stderr, "trsp: %s: no namelist\n", system); 124 exit(1); 125 } 126 (void) close(0); 127 if (open(core, 0) < 0) { 128 fprintf(stderr, "trsp: "); perror(core); 129 exit(2); 130 } 131 if (mask) { 132 nl[0].n_value &= 0x7fffffff; 133 nl[1].n_value &= 0x7fffffff; 134 } 135 (void) lseek(0, nl[1].n_value, 0); 136 if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 137 fprintf(stderr, "trsp: "); perror("spp_debx"); 138 exit(3); 139 } 140 printf("spp_debx=%d\n", spp_debx); 141 (void) lseek(0, nl[0].n_value, 0); 142 if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 143 fprintf(stderr, "trsp: "); perror("spp_debug"); 144 exit(3); 145 } 146 /* 147 * Here, we just want to clear out the old trace data and start over. 148 */ 149 if (zflag) { 150 char *cp = (char *) spp_debug, 151 *cplim = cp + sizeof(spp_debug); 152 (void) close(0); 153 if (open(core, 2) < 0) { 154 fprintf(stderr, "trsp: "); perror(core); 155 exit(2); 156 } 157 while(cp < cplim) *cp++ = 0; 158 (void) lseek(0, nl[0].n_value, 0); 159 if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 160 fprintf(stderr, "trsp: "); perror("spp_debug"); 161 exit(3); 162 } 163 (void) lseek(0, nl[1].n_value, 0); 164 spp_debx = 0; 165 if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 166 fprintf(stderr, "trsp: "); perror("spp_debx"); 167 exit(3); 168 } 169 exit(0); 170 } 171 /* 172 * If no control blocks have been specified, figure 173 * out how many distinct one we have and summarize 174 * them in spp_pcbs for sorting the trace records 175 * below. 176 */ 177 if (npcbs == 0) { 178 for (i = 0; i < SPP_NDEBUG; i++) { 179 register int j; 180 register struct spp_debug *sd = &spp_debug[i]; 181 182 if (sd->sd_cb == 0) 183 continue; 184 for (j = 0; j < npcbs; j++) 185 if (spp_pcbs[j] == sd->sd_cb) 186 break; 187 if (j >= npcbs) 188 spp_pcbs[npcbs++] = sd->sd_cb; 189 } 190 } 191 qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric); 192 if (jflag) { 193 char *cp = ""; 194 195 for (i = 0; i < npcbs; i++) { 196 printf("%s%x", cp, spp_pcbs[i]); 197 cp = ", "; 198 } 199 if (*cp) 200 putchar('\n'); 201 exit(0); 202 } 203 for (i = 0; i < npcbs; i++) { 204 printf("\n%x:\n", spp_pcbs[i]); 205 dotrace(spp_pcbs[i]); 206 } 207 exit(0); 208 } 209 210 dotrace(sppcb) 211 register caddr_t sppcb; 212 { 213 register int i; 214 register struct spp_debug *sd; 215 216 for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) { 217 sd = &spp_debug[i]; 218 if (sppcb && sd->sd_cb != sppcb) 219 continue; 220 ntime = ntohl(sd->sd_time); 221 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 222 &sd->sd_si, sd->sd_req); 223 } 224 for (i = 0; i < spp_debx % SPP_NDEBUG; i++) { 225 sd = &spp_debug[i]; 226 if (sppcb && sd->sd_cb != sppcb) 227 continue; 228 ntime = ntohl(sd->sd_time); 229 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 230 &sd->sd_si, sd->sd_req); 231 } 232 } 233 234 ptime(ms) 235 int ms; 236 { 237 238 printf("%03d ", (ms/10) % 1000); 239 } 240 241 numeric(c1, c2) 242 caddr_t *c1, *c2; 243 { 244 245 return (*c1 - *c2); 246 } 247 248 spp_trace(act, ostate, asp, sp, si, req) 249 short act, ostate; 250 struct sppcb *asp, *sp; 251 struct spidp *si; 252 int req; 253 { 254 u_short seq, ack, len, alo; 255 int flags, timer; 256 char *cp; 257 258 if(ostate >= TCP_NSTATES) ostate = 0; 259 if(act > SA_DROP) act = SA_DROP; 260 printf("\n"); 261 ptime(ntime); 262 printf("%s:%s", tcpstates[ostate], sanames[act]); 263 264 if (si != 0) { 265 seq = si->si_seq; 266 ack = si->si_ack; 267 alo = si->si_alo; 268 len = si->si_len; 269 switch (act) { 270 case SA_RESPOND: 271 case SA_OUTPUT: 272 seq = ntohs(seq); 273 ack = ntohs(ack); 274 alo = ntohs(alo); 275 len = ntohs(len); 276 case SA_INPUT: 277 case SA_DROP: 278 if (aflag) { 279 printf("\n\tsna="); 280 ns_printhost(&si->si_sna); 281 printf("\tdna="); 282 ns_printhost(&si->si_dna); 283 } 284 printf("\n\t"); 285 #define p1(name, f) { \ 286 printf("%s = %x, ", name, f); \ 287 } 288 p1("seq", seq); 289 p1("ack", ack); 290 p1("alo", alo); 291 p1("len", len); 292 flags = si->si_cc; 293 printf("flags=%x", flags); 294 #define pf(name, f) { \ 295 if (flags & f) { \ 296 printf("%s%s", cp, name); \ 297 cp = ","; \ 298 } \ 299 } 300 if (flags) { 301 char *cp = "<"; 302 pf("SP_SP", SP_SP); 303 pf("SP_SA", SP_SA); 304 pf("SP_OB", SP_OB); 305 pf("SP_EM", SP_EM); 306 printf(">"); 307 } 308 printf(", "); 309 #define p2(name, f) { \ 310 printf("%s = %x, ", name, f); \ 311 } 312 p2("sid", si->si_sid); 313 p2("did", si->si_did); 314 p2("dt", si->si_dt); 315 printf("\n\tsna="); 316 ns_printhost(&si->si_sna); 317 printf("\tdna="); 318 ns_printhost(&si->si_dna); 319 } 320 } 321 if(act == SA_USER) { 322 printf("\treq=%s", prurequests[req&0xff]); 323 if ((req & 0xff) == PRU_SLOWTIMO) 324 printf("<%s>", tcptimers[req>>8]); 325 } 326 printf(" -> %s", tcpstates[sp->s_state]); 327 328 /* print out internal state of sp !?! */ 329 printf("\n"); 330 if (sp == 0) 331 return; 332 #define p3(name, f) { \ 333 printf("%s = %x, ", name, f); \ 334 } 335 if (sflag) { 336 printf("\t"); 337 p3("rack", sp->s_rack); 338 p3("ralo", sp->s_ralo); 339 p3("smax", sp->s_smax); 340 p3("snxt", sp->s_snxt); 341 p3("flags", sp->s_flags); 342 #undef pf 343 #define pf(name, f) { \ 344 if (flags & f) { \ 345 printf("%s%s", cp, name); \ 346 cp = ","; \ 347 } \ 348 } 349 flags = sp->s_flags; 350 if (flags || sp->s_oobflags) { 351 char *cp = "<"; 352 pf("ACKNOW", SF_ACKNOW); 353 pf("DELACK", SF_DELACK); 354 pf("HI", SF_HI); 355 pf("HO", SF_HO); 356 pf("PI", SF_PI); 357 pf("WIN", SF_WIN); 358 pf("RXT", SF_RXT); 359 pf("RVD", SF_RVD); 360 flags = sp->s_oobflags; 361 pf("SOOB", SF_SOOB); 362 pf("IOOB", SF_IOOB); 363 printf(">"); 364 } 365 } 366 /* print out timers? */ 367 if (tflag) { 368 char *cp = "\t"; 369 register int i; 370 371 printf("\n\tTIMERS: "); 372 p3("idle", sp->s_idle); 373 p3("force", sp->s_force); 374 p3("rtseq", sp->s_rtseq); 375 for (i = 0; i < TCPT_NTIMERS; i++) { 376 if (sp->s_timer[i] == 0) 377 continue; 378 printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]); 379 if (i == TCPT_REXMT) 380 printf(" (s_rxtshft=%d)", sp->s_rxtshift); 381 cp = ", "; 382 } 383 if (*cp != '\t') 384 putchar('\n'); 385 } 386 } 387 388 ns_printhost(p) 389 register struct ns_addr *p; 390 { 391 392 printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>", 393 p->x_net.s_net[0], 394 p->x_net.s_net[1], 395 p->x_host.s_host[0], 396 p->x_host.s_host[1], 397 p->x_host.s_host[2], 398 p->x_port); 399 400 } 401 402