Blob
1 #include <u.h>2 #include <libc.h>3 #include <ip.h>4 #include "dat.h"5 #include "protos.h"7 enum8 {9 Maxoptlen= 312-4,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,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,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,101 /* plan9 vendor info options */102 OP9fs= 128, /* plan9 file servers */103 OP9auth= 129, /* plan9 auth servers */104 };106 static void107 p_compile(Filter *f)108 {109 sysfatal("unknown dhcp field: %s", f->s);110 }112 /*113 * convert a byte array to hex114 */115 static char116 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);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 }135 static char*136 pstring(char *p, char *e, char *tag, uchar *o, int n)137 {138 char msg[256];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 }147 static char*148 pint(char *p, char *e, char *tag, uchar *o, int n)149 {150 int x;152 x = *(char*)o++;153 for(; n > 1; n--)154 x = (x<<8)|*o++;155 return seprint(p, e, "%s=%d", tag, x);156 }158 static char*159 puint(char *p, char *e, char *tag, uchar *o, int n)160 {161 uint x;163 x = *o++;164 for(; n > 1; n--)165 x = (x<<8)|*o++;166 return seprint(p, e, "%s=%ud", tag, x);167 }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 }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 };195 static char*196 ptype(char *p, char *e, uchar val)197 {198 char *x;200 x = dhcptype[val];201 if(x != nil)202 return seprint(p, e, "t=%s", x);203 else204 return seprint(p, e, "t=%d", val);205 }207 static int208 p_seprint(Msg *m)209 {210 int i, n, code;211 uchar *o, *ps;212 char *p, *e;213 char msg[64];215 /* no next proto */216 m->pr = nil;218 p = m->p;219 e = m->e;220 ps = m->ps;222 while(ps < m->pe){223 code = *ps++;224 if(code == 255)225 break;226 if(code == 0)227 continue;229 /* ignore anything that's too long */230 n = *ps++;231 o = ps;232 ps += n;233 if(ps > m->pe)234 break;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 }465 Proto dhcp =466 {467 "dhcp",468 p_compile,469 nil,470 p_seprint,471 nil,472 nil,473 nil,474 defaultframer475 };