URI: 
       ttcp.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       ttcp.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 };