URI: 
       ticmp.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
       ---
       ticmp.c (2963B)
       ---
            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 {        uchar        type;
           10         uchar        code;
           11         uchar        cksum[2];        /* Checksum */
           12         uchar        data[1];
           13 };
           14 
           15 enum
           16 {
           17         ICMPLEN=        4
           18 };
           19 
           20 enum
           21 {
           22         Ot,        /* type */
           23         Op,        /* next protocol */
           24 };
           25 
           26 static Field p_fields[] =
           27 {
           28         {"t",                Fnum,        Ot,        "type",        } ,
           29         {0}
           30 };
           31 
           32 enum
           33 {
           34         EchoRep=        0,
           35         Unreachable=        3,
           36         SrcQuench=        4,
           37         Redirect=        5,
           38         EchoReq=        8,
           39         TimeExceed=        11,
           40         ParamProb=        12,
           41         TSreq=                13,
           42         TSrep=                14,
           43         InfoReq=        15,
           44         InfoRep=        16
           45 };
           46 
           47 static Mux p_mux[] =
           48 {
           49         {"ip",        Unreachable, },
           50         {"ip",        SrcQuench, },
           51         {"ip",        Redirect, },
           52         {"ip",        TimeExceed, },
           53         {"ip",        ParamProb, },
           54         {0}
           55 };
           56 
           57 char *icmpmsg[256] =
           58 {
           59 [EchoRep]        "EchoRep",
           60 [Unreachable]        "Unreachable",
           61 [SrcQuench]        "SrcQuench",
           62 [Redirect]        "Redirect",
           63 [EchoReq]        "EchoReq",
           64 [TimeExceed]        "TimeExceed",
           65 [ParamProb]        "ParamProb",
           66 [TSreq]                "TSreq",
           67 [TSrep]                "TSrep",
           68 [InfoReq]        "InfoReq",
           69 [InfoRep]        "InfoRep"
           70 };
           71 
           72 static void
           73 p_compile(Filter *f)
           74 {
           75         if(f->op == '='){
           76                 compile_cmp(udp.name, f, p_fields);
           77                 return;
           78         }
           79         if(strcmp(f->s, "ip") == 0){
           80                 f->pr = p_mux->pr;
           81                 f->subop = Op;
           82                 return;
           83         }
           84         sysfatal("unknown icmp field or protocol: %s", f->s);
           85 }
           86 
           87 static int
           88 p_filter(Filter *f, Msg *m)
           89 {
           90         Hdr *h;
           91 
           92         if(m->pe - m->ps < ICMPLEN)
           93                 return 0;
           94 
           95         h = (Hdr*)m->ps;
           96         m->ps += ICMPLEN;
           97 
           98         switch(f->subop){
           99         case Ot:
          100                 if(h->type == f->ulv)
          101                         return 1;
          102                 break;
          103         case Op:
          104                 switch(h->type){
          105                 case Unreachable:
          106                 case TimeExceed:
          107                 case SrcQuench:
          108                 case Redirect:
          109                 case ParamProb:
          110                         m->ps += 4;
          111                         return 1;
          112                 }
          113         }
          114         return 0;
          115 }
          116 
          117 static int
          118 p_seprint(Msg *m)
          119 {
          120         Hdr *h;
          121         char *tn;
          122         char *p = m->p;
          123         char *e = m->e;
          124         ushort cksum2, cksum;
          125 
          126         h = (Hdr*)m->ps;
          127         m->ps += ICMPLEN;
          128         m->pr = &dump;
          129 
          130         if(m->pe - m->ps < ICMPLEN)
          131                 return -1;
          132 
          133         tn = icmpmsg[h->type];
          134         if(tn == nil)
          135                 p = seprint(p, e, "t=%ud c=%d ck=%4.4ux", h->type,
          136                         h->code, (ushort)NetS(h->cksum));
          137         else
          138                 p = seprint(p, e, "t=%s c=%d ck=%4.4ux", tn,
          139                         h->code, (ushort)NetS(h->cksum));
          140         if(Cflag){
          141                 cksum = NetS(h->cksum);
          142                 h->cksum[0] = 0;
          143                 h->cksum[1] = 0;
          144                 cksum2 = ~ptclbsum((uchar*)h, m->pe - m->ps + ICMPLEN) & 0xffff;
          145                 if(cksum != cksum2)
          146                         p = seprint(p,e, " !ck=%4.4ux", cksum2);
          147         }
          148         switch(h->type){
          149         case EchoRep:
          150         case EchoReq:
          151                 m->ps += 4;
          152                 p = seprint(p, e, " id=%ux seq=%ux",
          153                         NetS(h->data), NetS(h->data+2));
          154                 break;
          155         case TSreq:
          156         case TSrep:
          157                 m->ps += 12;
          158                 p = seprint(p, e, " orig=%ud rcv=%ux xmt=%ux",
          159                         NetL(h->data), NetL(h->data+4),
          160                         NetL(h->data+8));
          161                 m->pr = nil;
          162                 break;
          163         case InfoReq:
          164         case InfoRep:
          165                 break;
          166         case Unreachable:
          167         case TimeExceed:
          168         case SrcQuench:
          169                 m->ps += 4;
          170                 m->pr = &ip;
          171                 break;
          172         case Redirect:
          173                 m->ps += 4;
          174                 m->pr = &ip;
          175                 p = seprint(p, e, "gw=%V", h->data);
          176                 break;
          177         case ParamProb:
          178                 m->ps += 4;
          179                 m->pr = &ip;
          180                 p = seprint(p, e, "ptr=%2.2ux", h->data[0]);
          181                 break;
          182         }
          183         m->p = p;
          184         return 0;
          185 }
          186 
          187 Proto icmp =
          188 {
          189         "icmp",
          190         p_compile,
          191         p_filter,
          192         p_seprint,
          193         p_mux,
          194         "%lud",
          195         p_fields,
          196         defaultframer
          197 };