tcp.c (3600B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include "dat.h" 5 #include "protos.h" 6 7 typedef struct Hdr Hdr; 8 struct Hdr 9 { 10 uchar sport[2]; 11 uchar dport[2]; 12 uchar seq[4]; 13 uchar ack[4]; 14 uchar flag[2]; 15 uchar win[2]; 16 uchar cksum[2]; 17 uchar urg[2]; 18 uchar opt[1]; 19 }; 20 21 typedef struct PseudoHdr{ 22 uchar src[4]; 23 uchar dst[4]; 24 uchar zero; 25 uchar proto; 26 uchar length[2]; 27 uchar hdrdata[1580]; 28 } PseudoHdr; 29 30 enum 31 { 32 TCPLEN= 20 33 }; 34 35 enum 36 { 37 Os, 38 Od, 39 Osd 40 }; 41 42 static Field p_fields[] = 43 { 44 {"s", Fnum, Os, "source port", } , 45 {"d", Fnum, Od, "dest port", } , 46 {"a", Fnum, Osd, "source/dest port", } , 47 {"sd", Fnum, Osd, "source/dest port", } , 48 {0} 49 }; 50 51 static Mux p_mux[] = 52 { 53 {"ninep", 17007, }, /* exportfs */ 54 {"ninep", 564, }, /* 9fs */ 55 {"ninep", 17005, }, /* ocpu */ 56 {"ninep", 17010, }, /* ncpu */ 57 {"ninep", 17013, }, /* cpu */ 58 {0} 59 }; 60 61 enum 62 { 63 EOLOPT = 0, 64 NOOPOPT = 1, 65 MSSOPT = 2, 66 MSS_LENGTH = 4, /* Mean segment size */ 67 WSOPT = 3, 68 WS_LENGTH = 3, /* Bits to scale window size by */ 69 }; 70 71 static void 72 p_compile(Filter *f) 73 { 74 Mux *m; 75 76 if(f->op == '='){ 77 compile_cmp(udp.name, f, p_fields); 78 return; 79 } 80 for(m = p_mux; m->name != nil; m++) 81 if(strcmp(f->s, m->name) == 0){ 82 f->pr = m->pr; 83 f->ulv = m->val; 84 f->subop = Osd; 85 return; 86 } 87 sysfatal("unknown tcp field or protocol: %s", f->s); 88 } 89 90 static int 91 p_filter(Filter *f, Msg *m) 92 { 93 Hdr *h; 94 95 if(m->pe - m->ps < TCPLEN) 96 return 0; 97 98 h = (Hdr*)m->ps; 99 m->ps += ((NetS(h->flag)>>10)&0x3f); 100 101 switch(f->subop){ 102 case Os: 103 return NetS(h->sport) == f->ulv; 104 case Od: 105 return NetS(h->dport) == f->ulv; 106 case Osd: 107 return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv; 108 } 109 return 0; 110 } 111 112 enum 113 { 114 URG = 0x20, /* Data marked urgent */ 115 ACK = 0x10, /* Aknowledge is valid */ 116 PSH = 0x08, /* Whole data pipe is pushed */ 117 RST = 0x04, /* Reset connection */ 118 SYN = 0x02, /* Pkt. is synchronise */ 119 FIN = 0x01, /* Start close down */ 120 }; 121 122 static char* 123 flags(int f) 124 { 125 static char fl[20]; 126 char *p; 127 128 p = fl; 129 if(f & URG) 130 *p++ = 'U'; 131 if(f & ACK) 132 *p++ = 'A'; 133 if(f & PSH) 134 *p++ = 'P'; 135 if(f & RST) 136 *p++ = 'R'; 137 if(f & SYN) 138 *p++ = 'S'; 139 if(f & FIN) 140 *p++ = 'F'; 141 *p = 0; 142 return fl; 143 } 144 145 146 static int 147 p_seprint(Msg *m) 148 { 149 Hdr *h; 150 int dport, sport; 151 int len, flag, optlen; 152 uchar *optr; 153 154 if(m->pe - m->ps < TCPLEN) 155 return -1; 156 h = (Hdr*)m->ps; 157 158 /* get tcp header length */ 159 flag = NetS(h->flag); 160 len = (flag>>10)&~3; 161 flag &= 0x3ff; 162 m->ps += len; 163 164 /* next protocol */ 165 dport = NetS(h->dport); 166 sport = NetS(h->sport); 167 demux(p_mux, sport, dport, m, &dump); 168 169 m->p = seprint(m->p, m->e, "s=%d d=%d seq=%lud ack=%lud fl=%s win=%d ck=%4.4ux", 170 NetS(h->sport), dport, 171 (ulong)NetL(h->seq), (ulong)NetL(h->ack), 172 flags(flag), NetS(h->win), 173 NetS(h->cksum)); 174 175 /* tcp options */ 176 len -= TCPLEN; 177 optr = h->opt; 178 while(len > 0) { 179 if(*optr == EOLOPT){ 180 m->p = seprint(m->p, m->e, " opt=EOL"); 181 break; 182 } 183 if(*optr == NOOPOPT) { 184 m->p = seprint(m->p, m->e, " opt=NOOP"); 185 len--; 186 optr++; 187 continue; 188 } 189 optlen = optr[1]; 190 if(optlen < 2 || optlen > len) 191 break; 192 switch(*optr) { 193 case MSSOPT: 194 m->p = seprint(m->p, m->e, " opt%d=(mss %ud)", optlen, nhgets(optr+2)); 195 break; 196 case WSOPT: 197 m->p = seprint(m->p, m->e, " opt%d=(wscale %ud)", optlen, *(optr+2)); 198 break; 199 default: 200 m->p = seprint(m->p, m->e, " opt%d=(%ud %.*H)", optlen, *optr, optlen-2,optr+2); 201 } 202 len -= optlen; 203 optr += optlen; 204 } 205 206 if(Cflag){ 207 /* editing in progress by ehg */ 208 } 209 return 0; 210 } 211 212 Proto tcp = 213 { 214 "tcp", 215 p_compile, 216 p_filter, 217 p_seprint, 218 p_mux, 219 "%lud", 220 p_fields, 221 defaultframer 222 };