125117Ssklower /*
2*61895Sbostic * Copyright (c) 1985, 1993
3*61895Sbostic * The Regents of the University of California. All rights reserved.
434940Sbostic *
542829Sbostic * %sccs.include.redist.c%
625117Ssklower */
725117Ssklower
825117Ssklower #ifndef lint
9*61895Sbostic static char copyright[] =
10*61895Sbostic "@(#) Copyright (c) 1985, 1993\n\
11*61895Sbostic The Regents of the University of California. All rights reserved.\n";
1234940Sbostic #endif /* not lint */
1325117Ssklower
1425117Ssklower #ifndef lint
15*61895Sbostic static char sccsid[] = "@(#)trsp.c 8.1 (Berkeley) 06/06/93";
1634940Sbostic #endif /* not lint */
1725117Ssklower
1846933Sbostic #include <sys/cdefs.h>
1925117Ssklower #include <sys/param.h>
2025117Ssklower #include <sys/socket.h>
2125117Ssklower #include <sys/socketvar.h>
2225117Ssklower #define PRUREQUESTS
2325117Ssklower #include <sys/protosw.h>
2425117Ssklower
2525117Ssklower #include <net/route.h>
2625117Ssklower #include <net/if.h>
2725117Ssklower
2825117Ssklower #define TCPSTATES
2925117Ssklower #include <netinet/tcp_fsm.h>
3025117Ssklower #define TCPTIMERS
3125117Ssklower #include <netinet/tcp_timer.h>
3225117Ssklower
3325117Ssklower #include <netns/ns.h>
3446933Sbostic #include <netns/sp.h>
3525117Ssklower #include <netns/idp.h>
3625117Ssklower #include <netns/spidp.h>
3735616Sbostic #include <netns/spp_timer.h>
3825117Ssklower #include <netns/spp_var.h>
3946933Sbostic #include <netns/ns_pcb.h>
4046933Sbostic #include <netns/idp_var.h>
4125117Ssklower #define SANAMES
4225117Ssklower #include <netns/spp_debug.h>
4325117Ssklower
4425117Ssklower #include <stdio.h>
4525117Ssklower #include <errno.h>
4625117Ssklower #include <nlist.h>
4737985Sbostic #include <paths.h>
4825117Ssklower
4925117Ssklower unsigned long ntime;
5025117Ssklower int sflag;
5125117Ssklower int tflag;
5225117Ssklower int jflag;
5325117Ssklower int aflag;
5425117Ssklower int zflag;
5525117Ssklower int numeric();
5625117Ssklower struct nlist nl[] = {
5725117Ssklower { "_spp_debug" },
5825117Ssklower { "_spp_debx" },
5925117Ssklower 0
6025117Ssklower };
6125117Ssklower struct spp_debug spp_debug[SPP_NDEBUG];
6225117Ssklower caddr_t spp_pcbs[SPP_NDEBUG];
6325117Ssklower int spp_debx;
6425117Ssklower
main(argc,argv)6525117Ssklower main(argc, argv)
6625117Ssklower int argc;
6725117Ssklower char **argv;
6825117Ssklower {
6925117Ssklower int i, mask = 0, npcbs = 0;
7037309Sbostic char *system, *core;
7125117Ssklower
7237309Sbostic system = _PATH_UNIX;
7337309Sbostic core = _PATH_KMEM;
7437309Sbostic
7525117Ssklower argc--, argv++;
7625117Ssklower again:
7725117Ssklower if (argc > 0 && !strcmp(*argv, "-a")) {
7825117Ssklower aflag++, argc--, argv++;
7925117Ssklower goto again;
8025117Ssklower }
8125117Ssklower if (argc > 0 && !strcmp(*argv, "-z")) {
8225117Ssklower zflag++, argc--, argv++;
8325117Ssklower goto again;
8425117Ssklower }
8525117Ssklower if (argc > 0 && !strcmp(*argv, "-s")) {
8625117Ssklower sflag++, argc--, argv++;
8725117Ssklower goto again;
8825117Ssklower }
8925117Ssklower if (argc > 0 && !strcmp(*argv, "-t")) {
9025117Ssklower tflag++, argc--, argv++;
9125117Ssklower goto again;
9225117Ssklower }
9325117Ssklower if (argc > 0 && !strcmp(*argv, "-j")) {
9425117Ssklower jflag++, argc--, argv++;
9525117Ssklower goto again;
9625117Ssklower }
9725117Ssklower if (argc > 0 && !strcmp(*argv, "-p")) {
9825117Ssklower argc--, argv++;
9925117Ssklower if (argc < 1) {
10025117Ssklower fprintf(stderr, "-p: missing sppcb address\n");
10125117Ssklower exit(1);
10225117Ssklower }
10325117Ssklower if (npcbs >= SPP_NDEBUG) {
10425117Ssklower fprintf(stderr, "-p: too many pcb's specified\n");
10525117Ssklower exit(1);
10625117Ssklower }
10725117Ssklower sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
10825117Ssklower argc--, argv++;
10925117Ssklower goto again;
11025117Ssklower }
11125117Ssklower if (argc > 0) {
11225117Ssklower system = *argv;
11325117Ssklower argc--, argv++;
11425117Ssklower mask++;
11552256Sbostic /*
11652256Sbostic * Discard setgid privileges if not the running kernel so that
11752256Sbostic * bad guys can't print interesting stuff from kernel memory.
11852256Sbostic */
11952256Sbostic setgid(getgid());
12025117Ssklower }
12125117Ssklower if (argc > 0) {
12225117Ssklower core = *argv;
12325117Ssklower argc--, argv++;
12425117Ssklower mask++;
12552256Sbostic setgid(getgid());
12625117Ssklower }
12725117Ssklower (void) nlist(system, nl);
12825117Ssklower if (nl[0].n_value == 0) {
12925117Ssklower fprintf(stderr, "trsp: %s: no namelist\n", system);
13025117Ssklower exit(1);
13125117Ssklower }
13225117Ssklower (void) close(0);
13325117Ssklower if (open(core, 0) < 0) {
13425117Ssklower fprintf(stderr, "trsp: "); perror(core);
13525117Ssklower exit(2);
13625117Ssklower }
13725117Ssklower if (mask) {
13825117Ssklower nl[0].n_value &= 0x7fffffff;
13925117Ssklower nl[1].n_value &= 0x7fffffff;
14025117Ssklower }
14125117Ssklower (void) lseek(0, nl[1].n_value, 0);
14225117Ssklower if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
14325117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx");
14425117Ssklower exit(3);
14525117Ssklower }
14625117Ssklower printf("spp_debx=%d\n", spp_debx);
14725117Ssklower (void) lseek(0, nl[0].n_value, 0);
14825117Ssklower if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
14925117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug");
15025117Ssklower exit(3);
15125117Ssklower }
15225117Ssklower /*
15325117Ssklower * Here, we just want to clear out the old trace data and start over.
15425117Ssklower */
15525117Ssklower if (zflag) {
15625117Ssklower char *cp = (char *) spp_debug,
15725117Ssklower *cplim = cp + sizeof(spp_debug);
15825117Ssklower (void) close(0);
15925117Ssklower if (open(core, 2) < 0) {
16025117Ssklower fprintf(stderr, "trsp: "); perror(core);
16125117Ssklower exit(2);
16225117Ssklower }
16325117Ssklower while(cp < cplim) *cp++ = 0;
16425117Ssklower (void) lseek(0, nl[0].n_value, 0);
16525117Ssklower if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
16625117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug");
16725117Ssklower exit(3);
16825117Ssklower }
16925117Ssklower (void) lseek(0, nl[1].n_value, 0);
17025117Ssklower spp_debx = 0;
17125117Ssklower if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
17225117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx");
17325117Ssklower exit(3);
17425117Ssklower }
17525117Ssklower exit(0);
17625117Ssklower }
17725117Ssklower /*
17825117Ssklower * If no control blocks have been specified, figure
17925117Ssklower * out how many distinct one we have and summarize
18025117Ssklower * them in spp_pcbs for sorting the trace records
18125117Ssklower * below.
18225117Ssklower */
18325117Ssklower if (npcbs == 0) {
18425117Ssklower for (i = 0; i < SPP_NDEBUG; i++) {
18525117Ssklower register int j;
18625117Ssklower register struct spp_debug *sd = &spp_debug[i];
18725117Ssklower
18825117Ssklower if (sd->sd_cb == 0)
18925117Ssklower continue;
19025117Ssklower for (j = 0; j < npcbs; j++)
19125117Ssklower if (spp_pcbs[j] == sd->sd_cb)
19225117Ssklower break;
19325117Ssklower if (j >= npcbs)
19425117Ssklower spp_pcbs[npcbs++] = sd->sd_cb;
19525117Ssklower }
19625117Ssklower }
19725117Ssklower qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
19825117Ssklower if (jflag) {
19925117Ssklower char *cp = "";
20025117Ssklower
20125117Ssklower for (i = 0; i < npcbs; i++) {
20225117Ssklower printf("%s%x", cp, spp_pcbs[i]);
20325117Ssklower cp = ", ";
20425117Ssklower }
20525117Ssklower if (*cp)
20625117Ssklower putchar('\n');
20725117Ssklower exit(0);
20825117Ssklower }
20925117Ssklower for (i = 0; i < npcbs; i++) {
21025117Ssklower printf("\n%x:\n", spp_pcbs[i]);
21125117Ssklower dotrace(spp_pcbs[i]);
21225117Ssklower }
21325117Ssklower exit(0);
21425117Ssklower }
21525117Ssklower
dotrace(sppcb)21625117Ssklower dotrace(sppcb)
21725117Ssklower register caddr_t sppcb;
21825117Ssklower {
21925117Ssklower register int i;
22025117Ssklower register struct spp_debug *sd;
22125117Ssklower
22225117Ssklower for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
22325117Ssklower sd = &spp_debug[i];
22425117Ssklower if (sppcb && sd->sd_cb != sppcb)
22525117Ssklower continue;
22625117Ssklower ntime = ntohl(sd->sd_time);
22725117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
22825117Ssklower &sd->sd_si, sd->sd_req);
22925117Ssklower }
23025117Ssklower for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
23125117Ssklower sd = &spp_debug[i];
23225117Ssklower if (sppcb && sd->sd_cb != sppcb)
23325117Ssklower continue;
23425117Ssklower ntime = ntohl(sd->sd_time);
23525117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
23625117Ssklower &sd->sd_si, sd->sd_req);
23725117Ssklower }
23825117Ssklower }
23925117Ssklower
ptime(ms)24025117Ssklower ptime(ms)
24125117Ssklower int ms;
24225117Ssklower {
24325117Ssklower
24425117Ssklower printf("%03d ", (ms/10) % 1000);
24525117Ssklower }
24625117Ssklower
numeric(c1,c2)24725117Ssklower numeric(c1, c2)
24825117Ssklower caddr_t *c1, *c2;
24925117Ssklower {
25025117Ssklower
25125117Ssklower return (*c1 - *c2);
25225117Ssklower }
25325117Ssklower
spp_trace(act,ostate,asp,sp,si,req)25425117Ssklower spp_trace(act, ostate, asp, sp, si, req)
25525117Ssklower short act, ostate;
25625117Ssklower struct sppcb *asp, *sp;
25725117Ssklower struct spidp *si;
25825117Ssklower int req;
25925117Ssklower {
26025117Ssklower u_short seq, ack, len, alo;
26125117Ssklower int flags, timer;
26225117Ssklower char *cp;
26325117Ssklower
26425117Ssklower if(ostate >= TCP_NSTATES) ostate = 0;
26525117Ssklower if(act > SA_DROP) act = SA_DROP;
26625117Ssklower printf("\n");
26725117Ssklower ptime(ntime);
26825117Ssklower printf("%s:%s", tcpstates[ostate], sanames[act]);
26925117Ssklower
27025117Ssklower if (si != 0) {
27125117Ssklower seq = si->si_seq;
27225117Ssklower ack = si->si_ack;
27325117Ssklower alo = si->si_alo;
27425117Ssklower len = si->si_len;
27525117Ssklower switch (act) {
27625117Ssklower case SA_RESPOND:
27725117Ssklower case SA_OUTPUT:
27825117Ssklower seq = ntohs(seq);
27925117Ssklower ack = ntohs(ack);
28025117Ssklower alo = ntohs(alo);
28125117Ssklower len = ntohs(len);
28225117Ssklower case SA_INPUT:
28325117Ssklower case SA_DROP:
28425117Ssklower if (aflag) {
28525117Ssklower printf("\n\tsna=");
28625117Ssklower ns_printhost(&si->si_sna);
28725117Ssklower printf("\tdna=");
28825117Ssklower ns_printhost(&si->si_dna);
28925117Ssklower }
29025117Ssklower printf("\n\t");
29146933Sbostic #define p1(name, f) { \
29246933Sbostic printf("%s = %x, ", name, f); \
29346933Sbostic }
29446933Sbostic p1("seq", seq);
29546933Sbostic p1("ack", ack);
29646933Sbostic p1("alo", alo);
29746933Sbostic p1("len", len);
29825117Ssklower flags = si->si_cc;
29925117Ssklower printf("flags=%x", flags);
30046933Sbostic #define pf(name, f) { \
30146933Sbostic if (flags & f) { \
30246933Sbostic printf("%s%s", cp, name); \
30346933Sbostic cp = ","; \
30446933Sbostic } \
30546933Sbostic }
30625117Ssklower if (flags) {
30725117Ssklower char *cp = "<";
30846933Sbostic pf("SP_SP", SP_SP);
30946933Sbostic pf("SP_SA", SP_SA);
31046933Sbostic pf("SP_OB", SP_OB);
31146933Sbostic pf("SP_EM", SP_EM);
31225117Ssklower printf(">");
31325117Ssklower }
31425117Ssklower printf(", ");
31546933Sbostic #define p2(name, f) { \
31646933Sbostic printf("%s = %x, ", name, f); \
31746933Sbostic }
31846933Sbostic p2("sid", si->si_sid);
31946933Sbostic p2("did", si->si_did);
32046933Sbostic p2("dt", si->si_dt);
32125117Ssklower printf("\n\tsna=");
32225117Ssklower ns_printhost(&si->si_sna);
32325117Ssklower printf("\tdna=");
32425117Ssklower ns_printhost(&si->si_dna);
32525117Ssklower }
32625117Ssklower }
32725117Ssklower if(act == SA_USER) {
32825117Ssklower printf("\treq=%s", prurequests[req&0xff]);
32925117Ssklower if ((req & 0xff) == PRU_SLOWTIMO)
33025117Ssklower printf("<%s>", tcptimers[req>>8]);
33125117Ssklower }
33225117Ssklower printf(" -> %s", tcpstates[sp->s_state]);
33325117Ssklower
33425117Ssklower /* print out internal state of sp !?! */
33525117Ssklower printf("\n");
33625117Ssklower if (sp == 0)
33725117Ssklower return;
33846933Sbostic #define p3(name, f) { \
33946933Sbostic printf("%s = %x, ", name, f); \
34046933Sbostic }
34146933Sbostic if (sflag) {
34246933Sbostic printf("\t");
34346933Sbostic p3("rack", sp->s_rack);
34446933Sbostic p3("ralo", sp->s_ralo);
34546933Sbostic p3("smax", sp->s_smax);
34646933Sbostic p3("snxt", sp->s_snxt);
34746933Sbostic p3("flags", sp->s_flags);
34825117Ssklower #undef pf
34946933Sbostic #define pf(name, f) { \
35046933Sbostic if (flags & f) { \
35146933Sbostic printf("%s%s", cp, name); \
35246933Sbostic cp = ","; \
35346933Sbostic } \
35446933Sbostic }
35525117Ssklower flags = sp->s_flags;
35625117Ssklower if (flags || sp->s_oobflags) {
35725117Ssklower char *cp = "<";
35846933Sbostic pf("ACKNOW", SF_ACKNOW);
35946933Sbostic pf("DELACK", SF_DELACK);
36046933Sbostic pf("HI", SF_HI);
36146933Sbostic pf("HO", SF_HO);
36246933Sbostic pf("PI", SF_PI);
36346933Sbostic pf("WIN", SF_WIN);
36446933Sbostic pf("RXT", SF_RXT);
36546933Sbostic pf("RVD", SF_RVD);
36625117Ssklower flags = sp->s_oobflags;
36746933Sbostic pf("SOOB", SF_SOOB);
36846933Sbostic pf("IOOB", SF_IOOB);
36925117Ssklower printf(">");
37025117Ssklower }
37125117Ssklower }
37225117Ssklower /* print out timers? */
37325117Ssklower if (tflag) {
37425117Ssklower char *cp = "\t";
37525117Ssklower register int i;
37625117Ssklower
37725117Ssklower printf("\n\tTIMERS: ");
37846933Sbostic p3("idle", sp->s_idle);
37946933Sbostic p3("force", sp->s_force);
38046933Sbostic p3("rtseq", sp->s_rtseq);
38125117Ssklower for (i = 0; i < TCPT_NTIMERS; i++) {
38225117Ssklower if (sp->s_timer[i] == 0)
38325117Ssklower continue;
38425117Ssklower printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
38525117Ssklower if (i == TCPT_REXMT)
38625117Ssklower printf(" (s_rxtshft=%d)", sp->s_rxtshift);
38725117Ssklower cp = ", ";
38825117Ssklower }
38925117Ssklower if (*cp != '\t')
39025117Ssklower putchar('\n');
39125117Ssklower }
39225117Ssklower }
39325117Ssklower
ns_printhost(p)39425117Ssklower ns_printhost(p)
39525117Ssklower register struct ns_addr *p;
39625117Ssklower {
39725117Ssklower
39825117Ssklower printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
39925117Ssklower p->x_net.s_net[0],
40025117Ssklower p->x_net.s_net[1],
40125117Ssklower p->x_host.s_host[0],
40225117Ssklower p->x_host.s_host[1],
40325117Ssklower p->x_host.s_host[2],
40425117Ssklower p->x_port);
40525117Ssklower
40625117Ssklower }
40725117Ssklower
408