diff options
author | rsc <devnull@localhost> | 2005-12-26 04:48:52 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-12-26 04:48:52 +0000 |
commit | 87a52e0485d3281ebea6bf4b725aa8023690e96f (patch) | |
tree | 0abc2d2ddb875196177231639d3cb4519e814b9d /src/cmd/ip/snoopy/tcp.c | |
parent | 35d26aa32167e84326cdb745c0e906393b8de71d (diff) | |
download | plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.gz plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.bz2 plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.zip |
new goodies
Diffstat (limited to 'src/cmd/ip/snoopy/tcp.c')
-rwxr-xr-x | src/cmd/ip/snoopy/tcp.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/cmd/ip/snoopy/tcp.c b/src/cmd/ip/snoopy/tcp.c new file mode 100755 index 00000000..31ad5663 --- /dev/null +++ b/src/cmd/ip/snoopy/tcp.c @@ -0,0 +1,221 @@ +#include <u.h> +#include <libc.h> +#include <ip.h> +#include "dat.h" +#include "protos.h" + +typedef struct Hdr Hdr; +struct Hdr +{ + uchar sport[2]; + uchar dport[2]; + uchar seq[4]; + uchar ack[4]; + uchar flag[2]; + uchar win[2]; + uchar cksum[2]; + uchar urg[2]; + uchar opt[1]; +}; + +typedef struct PseudoHdr{ + uchar src[4]; + uchar dst[4]; + uchar zero; + uchar proto; + uchar length[2]; + uchar hdrdata[1580]; +} PseudoHdr; + +enum +{ + TCPLEN= 20, +}; + +enum +{ + Os, + Od, + Osd, +}; + +static Field p_fields[] = +{ + {"s", Fnum, Os, "source port", } , + {"d", Fnum, Od, "dest port", } , + {"a", Fnum, Osd, "source/dest port", } , + {"sd", Fnum, Osd, "source/dest port", } , + {0} +}; + +static Mux p_mux[] = +{ + {"ninep", 17007, }, /* exportfs */ + {"ninep", 564, }, /* 9fs */ + {"ninep", 17005, }, /* ocpu */ + {"ninep", 17010, }, /* ncpu */ + {"ninep", 17013, }, /* cpu */ + {0}, +}; + +enum +{ + EOLOPT = 0, + NOOPOPT = 1, + MSSOPT = 2, + MSS_LENGTH = 4, /* Mean segment size */ + WSOPT = 3, + WS_LENGTH = 3, /* Bits to scale window size by */ +}; + +static void +p_compile(Filter *f) +{ + Mux *m; + + if(f->op == '='){ + compile_cmp(udp.name, f, p_fields); + return; + } + for(m = p_mux; m->name != nil; m++) + if(strcmp(f->s, m->name) == 0){ + f->pr = m->pr; + f->ulv = m->val; + f->subop = Osd; + return; + } + sysfatal("unknown tcp field or protocol: %s", f->s); +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe - m->ps < TCPLEN) + return 0; + + h = (Hdr*)m->ps; + m->ps += ((NetS(h->flag)>>10)&0x3f); + + switch(f->subop){ + case Os: + return NetS(h->sport) == f->ulv; + case Od: + return NetS(h->dport) == f->ulv; + case Osd: + return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv; + } + return 0; +} + +enum +{ + URG = 0x20, /* Data marked urgent */ + ACK = 0x10, /* Aknowledge is valid */ + PSH = 0x08, /* Whole data pipe is pushed */ + RST = 0x04, /* Reset connection */ + SYN = 0x02, /* Pkt. is synchronise */ + FIN = 0x01, /* Start close down */ +}; + +static char* +flags(int f) +{ + static char fl[20]; + char *p; + + p = fl; + if(f & URG) + *p++ = 'U'; + if(f & ACK) + *p++ = 'A'; + if(f & PSH) + *p++ = 'P'; + if(f & RST) + *p++ = 'R'; + if(f & SYN) + *p++ = 'S'; + if(f & FIN) + *p++ = 'F'; + *p = 0; + return fl; +} + + +static int +p_seprint(Msg *m) +{ + Hdr *h; + int dport, sport; + int len, flag, optlen; + uchar *optr; + + if(m->pe - m->ps < TCPLEN) + return -1; + h = (Hdr*)m->ps; + + /* get tcp header length */ + flag = NetS(h->flag); + len = (flag>>10)&~3; + flag &= 0x3ff; + m->ps += len; + + /* next protocol */ + dport = NetS(h->dport); + sport = NetS(h->sport); + demux(p_mux, sport, dport, m, &dump); + + m->p = seprint(m->p, m->e, "s=%d d=%d seq=%lud ack=%lud fl=%s win=%d ck=%4.4ux", + NetS(h->sport), dport, + (ulong)NetL(h->seq), (ulong)NetL(h->ack), + flags(flag), NetS(h->win), + NetS(h->cksum)); + + /* tcp options */ + len -= TCPLEN; + optr = h->opt; + while(len > 0) { + if(*optr == EOLOPT){ + m->p = seprint(m->p, m->e, " opt=EOL"); + break; + } + if(*optr == NOOPOPT) { + m->p = seprint(m->p, m->e, " opt=NOOP"); + len--; + optr++; + continue; + } + optlen = optr[1]; + if(optlen < 2 || optlen > len) + break; + switch(*optr) { + case MSSOPT: + m->p = seprint(m->p, m->e, " opt%d=(mss %ud)", optlen, nhgets(optr+2)); + break; + case WSOPT: + m->p = seprint(m->p, m->e, " opt%d=(wscale %ud)", optlen, *(optr+2)); + break; + default: + m->p = seprint(m->p, m->e, " opt%d=(%ud %.*H)", optlen, *optr, optlen-2,optr+2); + } + len -= optlen; + optr += optlen; + } + + if(Cflag){ + // editing in progress by ehg + } + return 0; +} + +Proto tcp = +{ + "tcp", + p_compile, + p_filter, + p_seprint, + p_mux, + p_fields, + defaultframer, +}; |