URI:
       tdhcp.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
       ---
       tdhcp.c (9045B)
       ---
            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         Maxoptlen=        312-4,
           10 
           11         /* dhcp types */
           12         Discover=        1,
           13         Offer=                2,
           14         Request=        3,
           15         Decline=        4,
           16         Ack=                5,
           17         Nak=                6,
           18         Release=        7,
           19         Inform=                8,
           20 
           21         /* bootp option types */
           22         OBend=                        255,
           23         OBpad=                        0,
           24         OBmask=                        1,
           25         OBtimeoff=                2,
           26         OBrouter=                3,
           27         OBtimeserver=                4,
           28         OBnameserver=                5,
           29         OBdnserver=                6,
           30         OBlogserver=                7,
           31         OBcookieserver=                8,
           32         OBlprserver=                9,
           33         OBimpressserver=        10,
           34         OBrlserver=                11,
           35         OBhostname=                12,        /* 0xc0 */
           36         OBbflen=                13,
           37         OBdumpfile=                14,
           38         OBdomainname=                15,
           39         OBswapserver=                16,        /* 0x10 */
           40         OBrootpath=                17,
           41         OBextpath=                18,
           42         OBipforward=                19,
           43         OBnonlocal=                20,
           44         OBpolicyfilter=                21,
           45         OBmaxdatagram=                22,
           46         OBttl=                        23,
           47         OBpathtimeout=                24,
           48         OBpathplateau=                25,
           49         OBmtu=                        26,
           50         OBsubnetslocal=                27,
           51         OBbaddr=                28,
           52         OBdiscovermask=                29,
           53         OBsupplymask=                30,
           54         OBdiscoverrouter=        31,
           55         OBrsserver=                32,        /* 0x20 */
           56         OBstaticroutes=                33,
           57         OBtrailerencap=                34,
           58         OBarptimeout=                35,
           59         OBetherencap=                36,
           60         OBtcpttl=                37,
           61         OBtcpka=                38,
           62         OBtcpkag=                39,
           63         OBnisdomain=                40,
           64         OBniserver=                41,
           65         OBntpserver=                42,
           66         OBvendorinfo=                43,        /* 0x2b */
           67         OBnetbiosns=                44,
           68         OBnetbiosdds=                45,
           69         OBnetbiostype=                46,
           70         OBnetbiosscope=                47,
           71         OBxfontserver=                48,        /* 0x30 */
           72         OBxdispmanager=                49,
           73         OBnisplusdomain=        64,        /* 0x40 */
           74         OBnisplusserver=        65,
           75         OBhomeagent=                68,
           76         OBsmtpserver=                69,
           77         OBpop3server=                70,
           78         OBnntpserver=                71,
           79         OBwwwserver=                72,
           80         OBfingerserver=                73,
           81         OBircserver=                74,
           82         OBstserver=                75,
           83         OBstdaserver=                76,
           84 
           85         /* dhcp options */
           86         ODipaddr=                50,        /* 0x32 */
           87         ODlease=                51,
           88         ODoverload=                52,
           89         ODtype=                        53,        /* 0x35 */
           90         ODserverid=                54,        /* 0x36 */
           91         ODparams=                55,        /* 0x37 */
           92         ODmessage=                56,
           93         ODmaxmsg=                57,
           94         ODrenewaltime=                58,
           95         ODrebindingtime=        59,
           96         ODvendorclass=                60,
           97         ODclientid=                61,        /* 0x3d */
           98         ODtftpserver=                66,
           99         ODbootfile=                67,
          100 
          101         /* plan9 vendor info options */
          102         OP9fs=                        128,        /* plan9 file servers */
          103         OP9auth=                129,        /* plan9 auth servers */
          104 };
          105 
          106 static void
          107 p_compile(Filter *f)
          108 {
          109         sysfatal("unknown dhcp field: %s", f->s);
          110 }
          111 
          112 /*
          113  *  convert a byte array to hex
          114  */
          115 static char
          116 hex(int x)
          117 {
          118         if(x < 10)
          119                 return x + '0';
          120         return x - 10 + 'a';
          121 }
          122 static char*
          123 phex(char *p, char *e, char *tag, uchar *o, int n)
          124 {
          125         p = seprint(p, e, "%s=", tag);
          126 
          127         for(; p+2 < e && n > 0; n--){
          128                 *p++ = hex(*o>>4);
          129                 *p++ = hex(*o & 0xf);
          130                 o++;
          131         }
          132         return p;
          133 }
          134 
          135 static char*
          136 pstring(char *p, char *e, char *tag, uchar *o, int n)
          137 {
          138         char msg[256];
          139 
          140         if(n > sizeof msg - 1)
          141                 n = sizeof msg - 1;
          142         memmove(msg, o, n);
          143         msg[n] = 0;
          144         return seprint(p, e, "%s=%s", tag, msg);
          145 }
          146 
          147 static char*
          148 pint(char *p, char *e, char *tag, uchar *o, int n)
          149 {
          150         int x;
          151 
          152         x = *(char*)o++;
          153         for(; n > 1; n--)
          154                 x = (x<<8)|*o++;
          155         return seprint(p, e, "%s=%d", tag, x);
          156 }
          157 
          158 static char*
          159 puint(char *p, char *e, char *tag, uchar *o, int n)
          160 {
          161         uint x;
          162 
          163         x = *o++;
          164         for(; n > 1; n--)
          165                 x = (x<<8)|*o++;
          166         return seprint(p, e, "%s=%ud", tag, x);
          167 }
          168 
          169 static char*
          170 pserver(char *p, char *e, char *tag, uchar *o, int n)
          171 {
          172         p = seprint(p, e, "%s=(", tag);
          173         while(n >= 4){
          174                 p = seprint(p, e, " %V", o);
          175                 n -= 4;
          176                 o += 4;
          177         }
          178         p = seprint(p, e, ")");
          179         return p;
          180 }
          181 
          182 static char *dhcptype[256] =
          183 {
          184 [Discover]        "Discover",
          185 [Offer]                "Offer",
          186 [Request]        "Request",
          187 [Decline]        "Decline",
          188 [Ack]                "Ack",
          189 [Nak]                "Nak",
          190 [Release]        "Release",
          191 [Inform]        "Inform"
          192 };
          193 
          194 
          195 static char*
          196 ptype(char *p, char *e, uchar val)
          197 {
          198         char *x;
          199 
          200         x = dhcptype[val];
          201         if(x != nil)
          202                 return seprint(p, e, "t=%s", x);
          203         else
          204                 return seprint(p, e, "t=%d", val);
          205 }
          206 
          207 static int
          208 p_seprint(Msg *m)
          209 {
          210         int i, n, code;
          211         uchar *o, *ps;
          212         char *p, *e;
          213         char msg[64];
          214 
          215         /* no next proto */
          216         m->pr = nil;
          217 
          218         p = m->p;
          219         e = m->e;
          220         ps = m->ps;
          221 
          222         while(ps < m->pe){
          223                 code = *ps++;
          224                 if(code == 255)
          225                         break;
          226                 if(code == 0)
          227                         continue;
          228 
          229                 /* ignore anything that's too long */
          230                 n = *ps++;
          231                 o = ps;
          232                 ps += n;
          233                 if(ps > m->pe)
          234                         break;
          235 
          236                 switch(code){
          237                 case ODipaddr:        /* requested ip address */
          238                         p = pserver(p, e, "ipaddr", o, n);
          239                         break;
          240                 case ODlease:        /* requested lease time */
          241                         p = pint(p, e, "lease", o, n);
          242                         break;
          243                 case ODtype:
          244                         p = ptype(p, e, *o);
          245                         break;
          246                 case ODserverid:
          247                         p = pserver(p, e, "serverid", o, n);
          248                         break;
          249                 case ODmessage:
          250                         p = pstring(p, e, "message", o, n);
          251                         break;
          252                 case ODmaxmsg:
          253                         p = puint(p, e, "maxmsg", o, n);
          254                         break;
          255                 case ODclientid:
          256                         p = phex(p, e, "clientid", o, n);
          257                         break;
          258                 case ODparams:
          259                         p = seprint(p, e, " requested=(");
          260                         for(i = 0; i < n; i++){
          261                                 if(i != 0)
          262                                         p = seprint(p, e, " ");
          263                                 p = seprint(p, e, "%ud", o[i]);
          264                         }
          265                         p = seprint(p, e, ")");
          266                         break;
          267                 case ODvendorclass:
          268                         p = pstring(p, e, "vendorclass", o, n);
          269                         break;
          270                 case OBmask:
          271                         p = pserver(p, e, "mask", o, n);
          272                         break;
          273                 case OBtimeoff:
          274                         p = pint(p, e, "timeoff", o, n);
          275                         break;
          276                 case OBrouter:
          277                         p = pserver(p, e, "router", o, n);
          278                         break;
          279                 case OBtimeserver:
          280                         p = pserver(p, e, "timesrv", o, n);
          281                         break;
          282                 case OBnameserver:
          283                         p = pserver(p, e, "namesrv", o, n);
          284                         break;
          285                 case OBdnserver:
          286                         p = pserver(p, e, "dnssrv", o, n);
          287                         break;
          288                 case OBlogserver:
          289                         p = pserver(p, e, "logsrv", o, n);
          290                         break;
          291                 case OBcookieserver:
          292                         p = pserver(p, e, "cookiesrv", o, n);
          293                         break;
          294                 case OBlprserver:
          295                         p = pserver(p, e, "lprsrv", o, n);
          296                         break;
          297                 case OBimpressserver:
          298                         p = pserver(p, e, "impresssrv", o, n);
          299                         break;
          300                 case OBrlserver:
          301                         p = pserver(p, e, "rlsrv", o, n);
          302                         break;
          303                 case OBhostname:
          304                         p = pstring(p, e, "hostname", o, n);
          305                         break;
          306                 case OBbflen:
          307                         break;
          308                 case OBdumpfile:
          309                         p = pstring(p, e, "dumpfile", o, n);
          310                         break;
          311                 case OBdomainname:
          312                         p = pstring(p, e, "domname", o, n);
          313                         break;
          314                 case OBswapserver:
          315                         p = pserver(p, e, "swapsrv", o, n);
          316                         break;
          317                 case OBrootpath:
          318                         p = pstring(p, e, "rootpath", o, n);
          319                         break;
          320                 case OBextpath:
          321                         p = pstring(p, e, "extpath", o, n);
          322                         break;
          323                 case OBipforward:
          324                         p = phex(p, e, "ipforward", o, n);
          325                         break;
          326                 case OBnonlocal:
          327                         p = phex(p, e, "nonlocal", o, n);
          328                         break;
          329                 case OBpolicyfilter:
          330                         p = phex(p, e, "policyfilter", o, n);
          331                         break;
          332                 case OBmaxdatagram:
          333                         p = phex(p, e, "maxdatagram", o, n);
          334                         break;
          335                 case OBttl:
          336                         p = puint(p, e, "ttl", o, n);
          337                         break;
          338                 case OBpathtimeout:
          339                         p = puint(p, e, "pathtimeout", o, n);
          340                         break;
          341                 case OBpathplateau:
          342                         p = phex(p, e, "pathplateau", o, n);
          343                         break;
          344                 case OBmtu:
          345                         p = puint(p, e, "mtu", o, n);
          346                         break;
          347                 case OBsubnetslocal:
          348                         p = pserver(p, e, "subnet", o, n);
          349                         break;
          350                 case OBbaddr:
          351                         p = pserver(p, e, "baddr", o, n);
          352                         break;
          353                 case OBdiscovermask:
          354                         p = pserver(p, e, "discovermsak", o, n);
          355                         break;
          356                 case OBsupplymask:
          357                         p = pserver(p, e, "rousupplymaskter", o, n);
          358                         break;
          359                 case OBdiscoverrouter:
          360                         p = pserver(p, e, "discoverrouter", o, n);
          361                         break;
          362                 case OBrsserver:
          363                         p = pserver(p, e, "rsrouter", o, n);
          364                         break;
          365                 case OBstaticroutes:
          366                         p = phex(p, e, "staticroutes", o, n);
          367                         break;
          368                 case OBtrailerencap:
          369                         p = phex(p, e, "trailerencap", o, n);
          370                         break;
          371                 case OBarptimeout:
          372                         p = puint(p, e, "arptimeout", o, n);
          373                         break;
          374                 case OBetherencap:
          375                         p = phex(p, e, "etherencap", o, n);
          376                         break;
          377                 case OBtcpttl:
          378                         p = puint(p, e, "tcpttl", o, n);
          379                         break;
          380                 case OBtcpka:
          381                         p = puint(p, e, "tcpka", o, n);
          382                         break;
          383                 case OBtcpkag:
          384                         p = phex(p, e, "tcpkag", o, n);
          385                         break;
          386                 case OBnisdomain:
          387                         p = pstring(p, e, "nisdomain", o, n);
          388                         break;
          389                 case OBniserver:
          390                         p = pserver(p, e, "nisrv", o, n);
          391                         break;
          392                 case OBntpserver:
          393                         p = pserver(p, e, "ntpsrv", o, n);
          394                         break;
          395                 case OBvendorinfo:
          396                         p = phex(p, e, "vendorinfo", o, n);
          397                         break;
          398                 case OBnetbiosns:
          399                         p = pserver(p, e, "biosns", o, n);
          400                         break;
          401                 case OBnetbiosdds:
          402                         p = phex(p, e, "biosdds", o, n);
          403                         break;
          404                 case OBnetbiostype:
          405                         p = phex(p, e, "biostype", o, n);
          406                         break;
          407                 case OBnetbiosscope:
          408                         p = phex(p, e, "biosscope", o, n);
          409                         break;
          410                 case OBxfontserver:
          411                         p = pserver(p, e, "fontsrv", o, n);
          412                         break;
          413                 case OBxdispmanager:
          414                         p = pserver(p, e, "xdispmgr", o, n);
          415                         break;
          416                 case OBnisplusdomain:
          417                         p = pstring(p, e, "nisplusdomain", o, n);
          418                         break;
          419                 case OBnisplusserver:
          420                         p = pserver(p, e, "nisplussrv", o, n);
          421                         break;
          422                 case OBhomeagent:
          423                         p = pserver(p, e, "homeagent", o, n);
          424                         break;
          425                 case OBsmtpserver:
          426                         p = pserver(p, e, "smtpsrv", o, n);
          427                         break;
          428                 case OBpop3server:
          429                         p = pserver(p, e, "pop3srv", o, n);
          430                         break;
          431                 case OBnntpserver:
          432                         p = pserver(p, e, "ntpsrv", o, n);
          433                         break;
          434                 case OBwwwserver:
          435                         p = pserver(p, e, "wwwsrv", o, n);
          436                         break;
          437                 case OBfingerserver:
          438                         p = pserver(p, e, "fingersrv", o, n);
          439                         break;
          440                 case OBircserver:
          441                         p = pserver(p, e, "ircsrv", o, n);
          442                         break;
          443                 case OBstserver:
          444                         p = pserver(p, e, "stsrv", o, n);
          445                         break;
          446                 case OBstdaserver:
          447                         p = pserver(p, e, "stdasrv", o, n);
          448                         break;
          449                 case OBend:
          450                         goto out;
          451                 default:
          452                         snprint(msg, sizeof msg, " T%ud", code);
          453                         p = phex(p, e, msg, o, n);
          454                         break;
          455                 }
          456                 if(*ps != OBend)
          457                         p = seprint(p, e, " ");
          458         }
          459 out:
          460         m->p = p;
          461         m->ps = ps;
          462         return 0;
          463 }
          464 
          465 Proto dhcp =
          466 {
          467         "dhcp",
          468         p_compile,
          469         nil,
          470         p_seprint,
          471         nil,
          472         nil,
          473         nil,
          474         defaultframer
          475 };