URI:
       tip6.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
       ---
       tip6.c (5377B)
       ---
            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        vcf[4];                        /* Version and header length */
           11         uchar        length[2];                /* packet length */
           12         uchar        proto;                        /* Protocol */
           13         uchar        ttl;                        /* Time to live */
           14         uchar        src[IPaddrlen];                /* IP source */
           15         uchar        dst[IPaddrlen];                /* IP destination */
           16 };
           17 
           18 enum
           19 {
           20         IP6HDR                = 40,                /* sizeof(Iphdr) */
           21         IP_VER                = 0x60,                /* Using IP version 4 */
           22         HBH_HDR                = 0,
           23         ROUT_HDR        = 43,
           24         FRAG_HDR        = 44,
           25         FRAG_HSZ        = 8,                 /* in bytes */
           26         DEST_HDR        = 60
           27 };
           28 
           29 static Mux p_mux[] =
           30 {
           31         { "igmp", 2, },
           32         { "ggp", 3, },
           33         { "ip", 4, },
           34         { "st", 5, },
           35         { "tcp", 6, },
           36         { "ucl", 7, },
           37         { "egp", 8, },
           38         { "igp", 9, },
           39         { "bbn-rcc-mon", 10, },
           40         { "nvp-ii", 11, },
           41         { "pup", 12, },
           42         { "argus", 13, },
           43         { "emcon", 14, },
           44         { "xnet", 15, },
           45         { "chaos", 16, },
           46         { "udp", 17, },
           47         { "mux", 18, },
           48         { "dcn-meas", 19, },
           49         { "hmp", 20, },
           50         { "prm", 21, },
           51         { "xns-idp", 22, },
           52         { "trunk-1", 23, },
           53         { "trunk-2", 24, },
           54         { "leaf-1", 25, },
           55         { "leaf-2", 26, },
           56         { "rdp", 27, },
           57         { "irtp", 28, },
           58         { "iso-tp4", 29, },
           59         { "netblt", 30, },
           60         { "mfe-nsp", 31, },
           61         { "merit-inp", 32, },
           62         { "sep", 33, },
           63         { "3pc", 34, },
           64         { "idpr", 35, },
           65         { "xtp", 36, },
           66         { "ddp", 37, },
           67         { "idpr-cmtp", 38, },
           68         { "tp++", 39, },
           69         { "il", 40, },
           70         { "sip", 41, },
           71         { "sdrp", 42, },
           72         { "idrp", 45, },
           73         { "rsvp", 46, },
           74         { "gre", 47, },
           75         { "mhrp", 48, },
           76         { "bna", 49, },
           77         { "sipp-esp", 50, },
           78         { "sipp-ah", 51, },
           79         { "i-nlsp", 52, },
           80         { "swipe", 53, },
           81         { "nhrp", 54, },
           82         { "icmp6", 58, },
           83         { "any", 61, },
           84         { "cftp", 62, },
           85         { "any", 63, },
           86         { "sat-expak", 64, },
           87         { "kryptolan", 65, },
           88         { "rvd", 66, },
           89         { "ippc", 67, },
           90         { "any", 68, },
           91         { "sat-mon", 69, },
           92         { "visa", 70, },
           93         { "ipcv", 71, },
           94         { "cpnx", 72, },
           95         { "cphb", 73, },
           96         { "wsn", 74, },
           97         { "pvp", 75, },
           98         { "br-sat-mon", 76, },
           99         { "sun-nd", 77, },
          100         { "wb-mon", 78, },
          101         { "wb-expak", 79, },
          102         { "iso-ip", 80, },
          103         { "vmtp", 81, },
          104         { "secure-vmtp", 82, },
          105         { "vines", 83, },
          106         { "ttp", 84, },
          107         { "nsfnet-igp", 85, },
          108         { "dgp", 86, },
          109         { "tcf", 87, },
          110         { "igrp", 88, },
          111         { "ospf", 89, },
          112         { "sprite-rpc", 90, },
          113         { "larp", 91, },
          114         { "mtp", 92, },
          115         { "ax.25", 93, },
          116         { "ipip", 94, },
          117         { "micp", 95, },
          118         { "scc-sp", 96, },
          119         { "etherip", 97, },
          120         { "encap", 98, },
          121         { "any", 99, },
          122         { "gmtp", 100, },
          123         { "rudp", 254, },
          124         { 0 }
          125 };
          126 
          127 enum
          128 {
          129         Os,        /* source */
          130         Od,        /* destination */
          131         Osd,        /* source or destination */
          132         Ot,        /* type */
          133 };
          134 
          135 static Field p_fields[] =
          136 {
          137         {"s",        Fv6ip,        Os,        "source address",        } ,
          138         {"d",        Fv6ip,        Od,        "destination address",        } ,
          139         {"a",        Fv6ip,        Osd,        "source|destination address",} ,
          140         {"t",        Fnum,        Ot,        "sub protocol number",        } ,
          141         {0}
          142 };
          143 
          144 static void
          145 p_compile(Filter *f)
          146 {
          147         Mux *m;
          148 
          149         if(f->op == '='){
          150                 compile_cmp(ip6.name, f, p_fields);
          151                 return;
          152         }
          153         for(m = p_mux; m->name != nil; m++)
          154                 if(strcmp(f->s, m->name) == 0){
          155                         f->pr = m->pr;
          156                         f->ulv = m->val;
          157                         f->subop = Ot;
          158                         return;
          159                 }
          160         sysfatal("unknown ip6 field or protocol: %s", f->s);
          161 }
          162 
          163 static int
          164 v6hdrlen(Hdr *h)
          165 {
          166         int plen, len = IP6HDR;
          167         int pktlen = IP6HDR + NetS(h->length);
          168         uchar nexthdr = h->proto;
          169         uchar *pkt = (uchar*) h;
          170 
          171         pkt += len;
          172         plen = len;
          173 
          174         while ( (nexthdr == HBH_HDR) || (nexthdr == ROUT_HDR) ||
          175                 (nexthdr == FRAG_HDR) || (nexthdr == DEST_HDR) ) {
          176 
          177                 if (nexthdr == FRAG_HDR)
          178                         len = FRAG_HSZ;
          179                 else
          180                         len = ( ((int) *(pkt+1)) + 1) * 8;
          181 
          182                 if (plen + len > pktlen)
          183                         return -1;
          184 
          185                 pkt += len;
          186                 nexthdr = *pkt;
          187                 plen += len;
          188         }
          189         return plen;
          190 }
          191 
          192 static int
          193 p_filter(Filter *f, Msg *m)
          194 {
          195         Hdr *h;
          196         int hlen;
          197 
          198         if(m->pe - m->ps < IP6HDR)
          199                 return 0;
          200 
          201         h = (Hdr*)m->ps;
          202 
          203         if ((hlen = v6hdrlen(h)) < 0)
          204                 return 0;
          205         else
          206                 m->ps += hlen;
          207         switch(f->subop){
          208         case Os:
          209                 return !memcmp(h->src, f->a, IPaddrlen);
          210         case Od:
          211                 return !memcmp(h->dst, f->a, IPaddrlen);
          212         case Osd:
          213                 return !memcmp(h->src, f->a, IPaddrlen) || !memcmp(h->dst, f->a, IPaddrlen);
          214         case Ot:
          215                 return h->proto == f->ulv;
          216         }
          217         return 0;
          218 }
          219 
          220 static int
          221 v6hdr_seprint(Msg *m)
          222 {
          223         int len = IP6HDR;
          224         uchar *pkt = m->ps;
          225         Hdr *h = (Hdr *) pkt;
          226         int pktlen = IP6HDR + NetS(h->length);
          227         uchar nexthdr = h->proto;
          228         int plen;
          229 
          230         pkt += len;
          231         plen = len;
          232 
          233         while ( (nexthdr == HBH_HDR) || (nexthdr == ROUT_HDR) ||
          234                 (nexthdr == FRAG_HDR) || (nexthdr == DEST_HDR) ) {
          235 
          236                 switch (nexthdr) {
          237                 case FRAG_HDR:
          238                         m->p = seprint(m->p, m->e, "\n          xthdr=frag id=%d offset=%d pr=%d more=%d res1=%d res2=%d",
          239                                         NetL(pkt+4),
          240                                         NetS(pkt+2) & ~7,
          241                                         (int) (*pkt),
          242                                         (int) (*(pkt+3) & 0x1),
          243                                         (int) *(pkt+1),
          244                                         (int) (*(pkt+3) & 0x6)
          245                                 );
          246                         len = FRAG_HSZ;
          247                         break;
          248 
          249                 case HBH_HDR:
          250                 case ROUT_HDR:
          251                 case DEST_HDR:
          252                         len = ( ((int) *(pkt+1)) + 1) * 8;
          253                         break;
          254                 }
          255 
          256                 if (plen + len > pktlen) {
          257                         m->p = seprint(m->p, m->e, "bad pkt");
          258                         m->pr = &dump;
          259                         return -1;
          260                 }
          261                 plen += len;
          262                 pkt += len;
          263                 nexthdr = *pkt;
          264         }
          265 
          266         m->ps = pkt;
          267         return 1;
          268 
          269 }
          270 
          271 static int
          272 p_seprint(Msg *m)
          273 {
          274         Hdr *h;
          275         int len;
          276 
          277         if(m->pe - m->ps < IP6HDR)
          278                 return -1;
          279         h = (Hdr*)m->ps;
          280 
          281         demux(p_mux, h->proto, h->proto, m, &dump);
          282 
          283         /* truncate the message if there's extra */
          284         len = NetS(h->length) + IP6HDR;
          285         if(len < m->pe - m->ps)
          286                 m->pe = m->ps + len;
          287 
          288         m->p = seprint(m->p, m->e, "s=%I d=%I ttl=%3d pr=%d ln=%d",
          289                         h->src, h->dst,
          290                         h->ttl,
          291                         h->proto,
          292                         NetS(h->length)
          293                         );
          294 
          295         v6hdr_seprint(m);
          296 
          297         return 0;
          298 }
          299 
          300 Proto ip6 =
          301 {
          302         "ip6",
          303         p_compile,
          304         p_filter,
          305         p_seprint,
          306         p_mux,
          307         "%lud",
          308         p_fields,
          309         defaultframer
          310 };