URI: 
       tbootp.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
       ---
       tbootp.c (3436B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <ip.h>
            4 #include "dat.h"
            5 #include "protos.h"
            6 
            7 enum
            8 {
            9         OfferTimeout=        60,                /* when an offer times out */
           10         MaxLease=        60*60,                /* longest lease for dynamic binding */
           11         MinLease=        15*60,                /* shortest lease for dynamic binding */
           12         StaticLease=        30*60,                /* lease for static binding */
           13 
           14         IPUDPHDRSIZE=        28,                /* size of an IP plus UDP header */
           15         MINSUPPORTED=        576,                /* biggest IP message the client must support */
           16 
           17         /* lengths of some bootp fields */
           18         Maxhwlen=        16,
           19         Maxfilelen=        128,
           20         Maxoptlen=        312-4,
           21 
           22         /* bootp types */
           23         Bootrequest=        1,
           24         Bootreply=         2,
           25 
           26         /* bootp flags */
           27         Fbroadcast=        1<<15
           28 };
           29 
           30 typedef struct Hdr        Hdr;
           31 struct Hdr
           32 {
           33         uchar        op;                        /* opcode */
           34         uchar        htype;                        /* hardware type */
           35         uchar        hlen;                        /* hardware address len */
           36         uchar        hops;                        /* hops */
           37         uchar        xid[4];                        /* a random number */
           38         uchar        secs[2];                /* elapsed since client started booting */
           39         uchar        flags[2];
           40         uchar        ciaddr[IPv4addrlen];        /* client IP address (client tells server) */
           41         uchar        yiaddr[IPv4addrlen];        /* client IP address (server tells client) */
           42         uchar        siaddr[IPv4addrlen];        /* server IP address */
           43         uchar        giaddr[IPv4addrlen];        /* gateway IP address */
           44         uchar        chaddr[Maxhwlen];        /* client hardware address */
           45         char        sname[64];                /* server host name (optional) */
           46         char        file[Maxfilelen];        /* boot file name */
           47         uchar        optmagic[4];
           48         uchar        optdata[Maxoptlen];
           49 };
           50 
           51 enum
           52 {
           53         Oca,
           54         Osa,
           55         Ot
           56 };
           57 
           58 static Field p_fields[] =
           59 {
           60         {"ca",                Fv4ip,        Oca,        "client IP addr",        } ,
           61         {"sa",                Fv4ip,        Osa,        "server IP addr",        } ,
           62         {0}
           63 };
           64 
           65 #define plan9opt ((ulong)(('p'<<24) | ('9'<<16) | (' '<<8) | ' '))
           66 #define genericopt (0x63825363UL)
           67 
           68 static Mux p_mux[] =
           69 {
           70         {"dhcp",         genericopt,},
           71         {"plan9bootp",        plan9opt,},
           72         {"dump",        0,},
           73         {0}
           74 };
           75 
           76 static void
           77 p_compile(Filter *f)
           78 {
           79         Mux *m;
           80 
           81         if(f->op == '='){
           82                 compile_cmp(arp.name, f, p_fields);
           83                 return;
           84         }
           85         for(m = p_mux; m->name != nil; m++)
           86                 if(strcmp(f->s, m->name) == 0){
           87                         f->pr = m->pr;
           88                         f->ulv = m->val;
           89                         f->subop = Ot;
           90                         return;
           91                 }
           92         sysfatal("unknown bootp field: %s", f->s);
           93 }
           94 
           95 static int
           96 p_filter(Filter *f, Msg *m)
           97 {
           98         Hdr *h;
           99 
          100         h = (Hdr*)m->ps;
          101 
          102         if(m->pe < (uchar*)h->sname)
          103                 return 0;
          104         m->ps = h->optdata;
          105 
          106         switch(f->subop){
          107         case Oca:
          108                 return NetL(h->ciaddr) == f->ulv || NetL(h->yiaddr) == f->ulv;
          109         case Osa:
          110                 return NetL(h->siaddr) == f->ulv;
          111         case Ot:
          112                 return NetL(h->optmagic) == f->ulv;
          113         }
          114         return 0;
          115 }
          116 
          117 static char*
          118 op(int i)
          119 {
          120         static char x[20];
          121 
          122         switch(i){
          123         case Bootrequest:
          124                 return "Req";
          125         case Bootreply:
          126                 return "Rep";
          127         default:
          128                 sprint(x, "%d", i);
          129                 return x;
          130         }
          131 }
          132 
          133 
          134 static int
          135 p_seprint(Msg *m)
          136 {
          137         Hdr *h;
          138         ulong x;
          139 
          140         h = (Hdr*)m->ps;
          141 
          142         if(m->pe < (uchar*)h->sname)
          143                 return -1;
          144 
          145         /* point past data */
          146         m->ps = h->optdata;
          147 
          148         /* next protocol */
          149         m->pr = nil;
          150         if(m->pe >= (uchar*)h->optdata){
          151                 x = NetL(h->optmagic);
          152                 demux(p_mux, x, x, m, &dump);
          153         }
          154 
          155         m->p = seprint(m->p, m->e, "t=%s ht=%d hl=%d hp=%d xid=%ux sec=%d fl=%4.4ux ca=%V ya=%V sa=%V ga=%V cha=%E magic=%lux",
          156                 op(h->op), h->htype, h->hlen, h->hops,
          157                 NetL(h->xid), NetS(h->secs), NetS(h->flags),
          158                 h->ciaddr, h->yiaddr, h->siaddr, h->giaddr, h->chaddr,
          159                 (ulong)NetL(h->optmagic));
          160         if(m->pe > (uchar*)h->sname && *h->sname)
          161                 m->p = seprint(m->p, m->e, " snam=%s", h->sname);
          162         if(m->pe > (uchar*)h->file && *h->file)
          163                 m->p = seprint(m->p, m->e, " file=%s", h->file);
          164         return 0;
          165 }
          166 
          167 Proto bootp =
          168 {
          169         "bootp",
          170         p_compile,
          171         p_filter,
          172         p_seprint,
          173         p_mux,
          174         "%#.8lux",
          175         p_fields,
          176         defaultframer
          177 };