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