URI:
       tip.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
       ---
       tip.c (4310B)
       ---
            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        vihl;                /* Version and header length */
           11         uchar        tos;                /* Type of service */
           12         uchar        length[2];        /* packet length */
           13         uchar        id[2];                /* ip->identification */
           14         uchar        frag[2];        /* Fragment information */
           15         uchar        ttl;                /* Time to live */
           16         uchar        proto;                /* Protocol */
           17         uchar        cksum[2];        /* Header checksum */
           18         uchar        src[4];                /* IP source */
           19         uchar        dst[4];                /* IP destination */
           20 };
           21 
           22 enum
           23 {
           24         IPHDR                = 20,                /* sizeof(Iphdr) */
           25         IP_VER                = 0x40,                /* Using IP version 4 */
           26         IP_DF                = 0x4000,        /* Don't fragment */
           27         IP_MF                = 0x2000,        /* More fragments */
           28 };
           29 
           30 static Mux p_mux[] =
           31 {
           32         { "icmp", 1, },
           33         { "igmp", 2, },
           34         { "ggp", 3, },
           35         { "ip", 4, },
           36         { "st", 5, },
           37         { "tcp", 6, },
           38         { "ucl", 7, },
           39         { "egp", 8, },
           40         { "igp", 9, },
           41         { "bbn-rcc-mon", 10, },
           42         { "nvp-ii", 11, },
           43         { "pup", 12, },
           44         { "argus", 13, },
           45         { "emcon", 14, },
           46         { "xnet", 15, },
           47         { "chaos", 16, },
           48         { "udp", 17, },
           49         { "mux", 18, },
           50         { "dcn-meas", 19, },
           51         { "hmp", 20, },
           52         { "prm", 21, },
           53         { "xns-idp", 22, },
           54         { "trunk-1", 23, },
           55         { "trunk-2", 24, },
           56         { "leaf-1", 25, },
           57         { "leaf-2", 26, },
           58         { "rdp", 27, },
           59         { "irtp", 28, },
           60         { "iso-tp4", 29, },
           61         { "netblt", 30, },
           62         { "mfe-nsp", 31, },
           63         { "merit-inp", 32, },
           64         { "sep", 33, },
           65         { "3pc", 34, },
           66         { "idpr", 35, },
           67         { "xtp", 36, },
           68         { "ddp", 37, },
           69         { "idpr-cmtp", 38, },
           70         { "tp++", 39, },
           71         { "il", 40, },
           72         { "sip", 41, },
           73         { "sdrp", 42, },
           74         { "sip-sr", 43, },
           75         { "sip-frag", 44, },
           76         { "idrp", 45, },
           77         { "rsvp", 46, },
           78         { "gre", 47, },
           79         { "mhrp", 48, },
           80         { "bna", 49, },
           81         { "sipp-esp", 50, },
           82         { "sipp-ah", 51, },
           83         { "i-nlsp", 52, },
           84         { "swipe", 53, },
           85         { "nhrp", 54, },
           86         { "any", 61, },
           87         { "cftp", 62, },
           88         { "any", 63, },
           89         { "sat-expak", 64, },
           90         { "kryptolan", 65, },
           91         { "rvd", 66, },
           92         { "ippc", 67, },
           93         { "any", 68, },
           94         { "sat-mon", 69, },
           95         { "visa", 70, },
           96         { "ipcv", 71, },
           97         { "cpnx", 72, },
           98         { "cphb", 73, },
           99         { "wsn", 74, },
          100         { "pvp", 75, },
          101         { "br-sat-mon", 76, },
          102         { "sun-nd", 77, },
          103         { "wb-mon", 78, },
          104         { "wb-expak", 79, },
          105         { "iso-ip", 80, },
          106         { "vmtp", 81, },
          107         { "secure-vmtp", 82, },
          108         { "vines", 83, },
          109         { "ttp", 84, },
          110         { "nsfnet-igp", 85, },
          111         { "dgp", 86, },
          112         { "tcf", 87, },
          113         { "igrp", 88, },
          114         { "ospf", 89, },
          115         { "sprite-rpc", 90, },
          116         { "larp", 91, },
          117         { "mtp", 92, },
          118         { "ax.25", 93, },
          119         { "ipip", 94, },
          120         { "micp", 95, },
          121         { "scc-sp", 96, },
          122         { "etherip", 97, },
          123         { "encap", 98, },
          124         { "any", 99, },
          125         { "gmtp", 100, },
          126         { "rudp", 254, },
          127         { 0 }
          128 };
          129 
          130 enum
          131 {
          132         Os,        /* source */
          133         Od,        /* destination */
          134         Osd,        /* source or destination */
          135         Ot,        /* type */
          136 };
          137 
          138 static Field p_fields[] =
          139 {
          140         {"s",        Fv4ip,        Os,        "source address",        } ,
          141         {"d",        Fv4ip,        Od,        "destination address",        } ,
          142         {"a",        Fv4ip,        Osd,        "source|destination address",} ,
          143         {"sd",        Fv4ip,        Osd,        "source|destination address",} ,
          144         {"t",        Fnum,        Ot,        "sub protocol number",        } ,
          145         {0}
          146 };
          147 
          148 static void
          149 p_compile(Filter *f)
          150 {
          151         Mux *m;
          152 
          153         if(f->op == '='){
          154                 compile_cmp(ip.name, f, p_fields);
          155                 return;
          156         }
          157         for(m = p_mux; m->name != nil; m++)
          158                 if(strcmp(f->s, m->name) == 0){
          159                         f->pr = m->pr;
          160                         f->ulv = m->val;
          161                         f->subop = Ot;
          162                         return;
          163                 }
          164         sysfatal("unknown ip field or protocol: %s", f->s);
          165 }
          166 
          167 static int
          168 p_filter(Filter *f, Msg *m)
          169 {
          170         Hdr *h;
          171 
          172         if(m->pe - m->ps < IPHDR)
          173                 return 0;
          174 
          175         h = (Hdr*)m->ps;
          176         m->ps += ((h->vihl&0xf)<<2);
          177 
          178         switch(f->subop){
          179         case Os:
          180                 return NetL(h->src) == f->ulv;
          181         case Od:
          182                 return NetL(h->dst) == f->ulv;
          183         case Osd:
          184                 return NetL(h->src) == f->ulv || NetL(h->dst) == f->ulv;
          185         case Ot:
          186                 return h->proto == f->ulv;
          187         }
          188         return 0;
          189 }
          190 
          191 static int
          192 p_seprint(Msg *m)
          193 {
          194         Hdr *h;
          195         int f;
          196         int len;
          197 
          198         if(m->pe - m->ps < IPHDR)
          199                 return -1;
          200         h = (Hdr*)m->ps;
          201 
          202         /* next protocol, just dump unless this is the first fragment */
          203         m->pr = &dump;
          204         f = NetS(h->frag);
          205         if((f & ~(IP_DF|IP_MF)) == 0)
          206                 demux(p_mux, h->proto, h->proto, m, &dump);
          207 
          208         /* truncate the message if there's extra */
          209         len = NetS(h->length);
          210         if(len < m->pe - m->ps)
          211                 m->pe = m->ps + len;
          212 
          213         /* next header */
          214         m->ps += ((h->vihl&0xf)<<2);
          215 
          216         m->p = seprint(m->p, m->e, "s=%V d=%V id=%4.4ux frag=%4.4ux ttl=%3d pr=%d ln=%d",
          217                         h->src, h->dst,
          218                         NetS(h->id),
          219                         NetS(h->frag),
          220                         h->ttl,
          221                         h->proto,
          222                         NetS(h->length)
          223                         );
          224         return 0;
          225 }
          226 
          227 Proto ip =
          228 {
          229         "ip",
          230         p_compile,
          231         p_filter,
          232         p_seprint,
          233         p_mux,
          234         "%lud",
          235         p_fields,
          236         defaultframer
          237 };