URI:
       tether.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
       ---
       tether.c (2024B)
       ---
            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 d[6];
           10         uchar s[6];
           11         uchar type[2];
           12         char data[1500];
           13 };
           14 #define        ETHERMINTU        60        /* minimum transmit size */
           15 #define        ETHERMAXTU        1514        /* maximum transmit size */
           16 #define ETHERHDRSIZE        14        /* size of an ethernet header */
           17 
           18 static Mux p_mux[] =
           19 {
           20         {"ip",                0x0800,        } ,
           21         {"arp",                0x0806,        } ,
           22         {"rarp",        0x0806,        } ,
           23         {"ip6",         0x86dd, } ,
           24         {"pppoe_disc",        0x8863, },
           25         {"pppoe_sess",        0x8864, },
           26         {"eapol",        0x888e, },
           27         {0}
           28 };
           29 
           30 enum
           31 {
           32         Os,        /* source */
           33         Od,        /* destination */
           34         Oa,        /* source or destination */
           35         Ot,        /* type */
           36 };
           37 
           38 static Field p_fields[] =
           39 {
           40         {"s",        Fether,        Os,        "source address",        } ,
           41         {"d",        Fether,        Od,        "destination address",        } ,
           42         {"a",        Fether,        Oa,        "source|destination address" } ,
           43         {"sd",        Fether,        Oa,        "source|destination address" } ,
           44         {"t",        Fnum,        Ot,        "type" } ,
           45         {0}
           46 };
           47 
           48 static void
           49 p_compile(Filter *f)
           50 {
           51         Mux *m;
           52 
           53         if(f->op == '='){
           54                 compile_cmp(ether.name, f, p_fields);
           55                 return;
           56         }
           57         for(m = p_mux; m->name != nil; m++)
           58                 if(strcmp(f->s, m->name) == 0){
           59                         f->pr = m->pr;
           60                         f->ulv = m->val;
           61                         f->subop = Ot;
           62                         return;
           63                 }
           64         sysfatal("unknown ethernet field or protocol: %s", f->s);
           65 }
           66 
           67 static int
           68 p_filter(Filter *f, Msg *m)
           69 {
           70         Hdr *h;
           71 
           72         if(m->pe - m->ps < ETHERHDRSIZE)
           73                 return 0;
           74 
           75         h = (Hdr*)m->ps;
           76         m->ps += ETHERHDRSIZE;
           77 
           78         switch(f->subop){
           79         case Os:
           80                 return !memcmp(h->s, f->a, 6);
           81         case Od:
           82                 return !memcmp(h->d, f->a, 6);
           83         case Oa:
           84                 return memcmp(h->s, f->a, 6) == 0 || memcmp(h->d, f->a, 6) == 0;
           85         case Ot:
           86                 return NetS(h->type) == f->ulv;
           87         }
           88         return 0;
           89 }
           90 
           91 static int
           92 p_seprint(Msg *m)
           93 {
           94         Hdr *h;
           95         uint t;
           96         int len;
           97 
           98         len = m->pe - m->ps;
           99         if(len < ETHERHDRSIZE)
          100                 return -1;
          101 
          102         h = (Hdr*)m->ps;
          103         m->ps += ETHERHDRSIZE;
          104 
          105         t = NetS(h->type);
          106         demux(p_mux, t, t, m, &dump);
          107 
          108         m->p = seprint(m->p, m->e, "s=%E d=%E pr=%4.4ux ln=%d", h->s, h->d,
          109                 t, len);
          110         return 0;
          111 }
          112 
          113 Proto ether =
          114 {
          115         "ether",
          116         p_compile,
          117         p_filter,
          118         p_seprint,
          119         p_mux,
          120         "%#.4lux",
          121         p_fields,
          122         defaultframer
          123 };