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