1 87a52e04 2005-12-26 devnull #include <u.h>
2 87a52e04 2005-12-26 devnull #include <libc.h>
3 87a52e04 2005-12-26 devnull #include <ip.h>
4 87a52e04 2005-12-26 devnull #include "dat.h"
5 87a52e04 2005-12-26 devnull #include "protos.h"
7 87a52e04 2005-12-26 devnull typedef struct Hdr Hdr;
8 87a52e04 2005-12-26 devnull struct Hdr
10 87a52e04 2005-12-26 devnull uchar sport[2];
11 87a52e04 2005-12-26 devnull uchar dport[2];
12 87a52e04 2005-12-26 devnull uchar seq[4];
13 87a52e04 2005-12-26 devnull uchar ack[4];
14 87a52e04 2005-12-26 devnull uchar flag[2];
15 87a52e04 2005-12-26 devnull uchar win[2];
16 87a52e04 2005-12-26 devnull uchar cksum[2];
17 87a52e04 2005-12-26 devnull uchar urg[2];
18 87a52e04 2005-12-26 devnull uchar opt[1];
21 87a52e04 2005-12-26 devnull typedef struct PseudoHdr{
22 87a52e04 2005-12-26 devnull uchar src[4];
23 87a52e04 2005-12-26 devnull uchar dst[4];
24 87a52e04 2005-12-26 devnull uchar zero;
25 87a52e04 2005-12-26 devnull uchar proto;
26 87a52e04 2005-12-26 devnull uchar length[2];
27 87a52e04 2005-12-26 devnull uchar hdrdata[1580];
28 87a52e04 2005-12-26 devnull } PseudoHdr;
32 87a52e04 2005-12-26 devnull TCPLEN= 20,
42 87a52e04 2005-12-26 devnull static Field p_fields[] =
44 87a52e04 2005-12-26 devnull {"s", Fnum, Os, "source port", } ,
45 87a52e04 2005-12-26 devnull {"d", Fnum, Od, "dest port", } ,
46 87a52e04 2005-12-26 devnull {"a", Fnum, Osd, "source/dest port", } ,
47 87a52e04 2005-12-26 devnull {"sd", Fnum, Osd, "source/dest port", } ,
51 87a52e04 2005-12-26 devnull static Mux p_mux[] =
53 87a52e04 2005-12-26 devnull {"ninep", 17007, }, /* exportfs */
54 87a52e04 2005-12-26 devnull {"ninep", 564, }, /* 9fs */
55 87a52e04 2005-12-26 devnull {"ninep", 17005, }, /* ocpu */
56 87a52e04 2005-12-26 devnull {"ninep", 17010, }, /* ncpu */
57 87a52e04 2005-12-26 devnull {"ninep", 17013, }, /* cpu */
63 87a52e04 2005-12-26 devnull EOLOPT = 0,
64 87a52e04 2005-12-26 devnull NOOPOPT = 1,
65 87a52e04 2005-12-26 devnull MSSOPT = 2,
66 87a52e04 2005-12-26 devnull MSS_LENGTH = 4, /* Mean segment size */
67 87a52e04 2005-12-26 devnull WSOPT = 3,
68 87a52e04 2005-12-26 devnull WS_LENGTH = 3, /* Bits to scale window size by */
71 87a52e04 2005-12-26 devnull static void
72 87a52e04 2005-12-26 devnull p_compile(Filter *f)
76 87a52e04 2005-12-26 devnull if(f->op == '='){
77 87a52e04 2005-12-26 devnull compile_cmp(udp.name, f, p_fields);
80 87a52e04 2005-12-26 devnull for(m = p_mux; m->name != nil; m++)
81 87a52e04 2005-12-26 devnull if(strcmp(f->s, m->name) == 0){
82 87a52e04 2005-12-26 devnull f->pr = m->pr;
83 87a52e04 2005-12-26 devnull f->ulv = m->val;
84 87a52e04 2005-12-26 devnull f->subop = Osd;
87 87a52e04 2005-12-26 devnull sysfatal("unknown tcp field or protocol: %s", f->s);
90 87a52e04 2005-12-26 devnull static int
91 87a52e04 2005-12-26 devnull p_filter(Filter *f, Msg *m)
95 87a52e04 2005-12-26 devnull if(m->pe - m->ps < TCPLEN)
96 87a52e04 2005-12-26 devnull return 0;
98 87a52e04 2005-12-26 devnull h = (Hdr*)m->ps;
99 87a52e04 2005-12-26 devnull m->ps += ((NetS(h->flag)>>10)&0x3f);
101 87a52e04 2005-12-26 devnull switch(f->subop){
102 87a52e04 2005-12-26 devnull case Os:
103 87a52e04 2005-12-26 devnull return NetS(h->sport) == f->ulv;
104 87a52e04 2005-12-26 devnull case Od:
105 87a52e04 2005-12-26 devnull return NetS(h->dport) == f->ulv;
106 87a52e04 2005-12-26 devnull case Osd:
107 87a52e04 2005-12-26 devnull return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv;
109 87a52e04 2005-12-26 devnull return 0;
114 87a52e04 2005-12-26 devnull URG = 0x20, /* Data marked urgent */
115 87a52e04 2005-12-26 devnull ACK = 0x10, /* Aknowledge is valid */
116 87a52e04 2005-12-26 devnull PSH = 0x08, /* Whole data pipe is pushed */
117 87a52e04 2005-12-26 devnull RST = 0x04, /* Reset connection */
118 87a52e04 2005-12-26 devnull SYN = 0x02, /* Pkt. is synchronise */
119 87a52e04 2005-12-26 devnull FIN = 0x01, /* Start close down */
122 87a52e04 2005-12-26 devnull static char*
123 87a52e04 2005-12-26 devnull flags(int f)
125 87a52e04 2005-12-26 devnull static char fl[20];
126 87a52e04 2005-12-26 devnull char *p;
129 87a52e04 2005-12-26 devnull if(f & URG)
130 87a52e04 2005-12-26 devnull *p++ = 'U';
131 87a52e04 2005-12-26 devnull if(f & ACK)
132 87a52e04 2005-12-26 devnull *p++ = 'A';
133 87a52e04 2005-12-26 devnull if(f & PSH)
134 87a52e04 2005-12-26 devnull *p++ = 'P';
135 87a52e04 2005-12-26 devnull if(f & RST)
136 87a52e04 2005-12-26 devnull *p++ = 'R';
137 87a52e04 2005-12-26 devnull if(f & SYN)
138 87a52e04 2005-12-26 devnull *p++ = 'S';
139 87a52e04 2005-12-26 devnull if(f & FIN)
140 87a52e04 2005-12-26 devnull *p++ = 'F';
142 87a52e04 2005-12-26 devnull return fl;
146 87a52e04 2005-12-26 devnull static int
147 87a52e04 2005-12-26 devnull p_seprint(Msg *m)
150 87a52e04 2005-12-26 devnull int dport, sport;
151 87a52e04 2005-12-26 devnull int len, flag, optlen;
152 87a52e04 2005-12-26 devnull uchar *optr;
154 87a52e04 2005-12-26 devnull if(m->pe - m->ps < TCPLEN)
155 87a52e04 2005-12-26 devnull return -1;
156 87a52e04 2005-12-26 devnull h = (Hdr*)m->ps;
158 87a52e04 2005-12-26 devnull /* get tcp header length */
159 87a52e04 2005-12-26 devnull flag = NetS(h->flag);
160 87a52e04 2005-12-26 devnull len = (flag>>10)&~3;
161 87a52e04 2005-12-26 devnull flag &= 0x3ff;
162 87a52e04 2005-12-26 devnull m->ps += len;
164 87a52e04 2005-12-26 devnull /* next protocol */
165 87a52e04 2005-12-26 devnull dport = NetS(h->dport);
166 87a52e04 2005-12-26 devnull sport = NetS(h->sport);
167 87a52e04 2005-12-26 devnull demux(p_mux, sport, dport, m, &dump);
169 87a52e04 2005-12-26 devnull m->p = seprint(m->p, m->e, "s=%d d=%d seq=%lud ack=%lud fl=%s win=%d ck=%4.4ux",
170 87a52e04 2005-12-26 devnull NetS(h->sport), dport,
171 87a52e04 2005-12-26 devnull (ulong)NetL(h->seq), (ulong)NetL(h->ack),
172 87a52e04 2005-12-26 devnull flags(flag), NetS(h->win),
173 87a52e04 2005-12-26 devnull NetS(h->cksum));
175 87a52e04 2005-12-26 devnull /* tcp options */
176 87a52e04 2005-12-26 devnull len -= TCPLEN;
177 87a52e04 2005-12-26 devnull optr = h->opt;
178 87a52e04 2005-12-26 devnull while(len > 0) {
179 87a52e04 2005-12-26 devnull if(*optr == EOLOPT){
180 87a52e04 2005-12-26 devnull m->p = seprint(m->p, m->e, " opt=EOL");
183 87a52e04 2005-12-26 devnull if(*optr == NOOPOPT) {
184 87a52e04 2005-12-26 devnull m->p = seprint(m->p, m->e, " opt=NOOP");
187 87a52e04 2005-12-26 devnull continue;
189 87a52e04 2005-12-26 devnull optlen = optr[1];
190 87a52e04 2005-12-26 devnull if(optlen < 2 || optlen > len)
192 87a52e04 2005-12-26 devnull switch(*optr) {
193 87a52e04 2005-12-26 devnull case MSSOPT:
194 87a52e04 2005-12-26 devnull m->p = seprint(m->p, m->e, " opt%d=(mss %ud)", optlen, nhgets(optr+2));
196 87a52e04 2005-12-26 devnull case WSOPT:
197 87a52e04 2005-12-26 devnull m->p = seprint(m->p, m->e, " opt%d=(wscale %ud)", optlen, *(optr+2));
199 87a52e04 2005-12-26 devnull default:
200 87a52e04 2005-12-26 devnull m->p = seprint(m->p, m->e, " opt%d=(%ud %.*H)", optlen, *optr, optlen-2,optr+2);
202 87a52e04 2005-12-26 devnull len -= optlen;
203 87a52e04 2005-12-26 devnull optr += optlen;
206 87a52e04 2005-12-26 devnull if(Cflag){
207 87a52e04 2005-12-26 devnull // editing in progress by ehg
209 87a52e04 2005-12-26 devnull return 0;
212 87a52e04 2005-12-26 devnull Proto tcp =
215 87a52e04 2005-12-26 devnull p_compile,
216 87a52e04 2005-12-26 devnull p_filter,
217 87a52e04 2005-12-26 devnull p_seprint,
220 87a52e04 2005-12-26 devnull p_fields,
221 87a52e04 2005-12-26 devnull defaultframer,