x = *o++;
for(; n > 1; n--)
x = x<<8 | *o++;
return seprint(p, e, "%s=%ud", tag, x);
}
static char*
pserver(char *p, char *e, char *tag, uchar *o, int n)
{
int i;
p = seprint(p, e, "%s=(", tag);
i = 0;
while(n >= 4){
if(i++ > 0)
p = seprint(p, e, " ");
p = seprint(p, e, "%V", o);
n -= 4;
o += 4;
}
p = seprint(p, e, ")");
return p;
}
static char*
pcfroutes(char *p, char *e, char *tag, uchar *o, int n)
{
int i;
p = seprint(p, e, "%s=(", tag);
i = 0;
while(n >= 8){
if(i++ > 0)
p = seprint(p, e, " ");
p = seprint(p, e, "%V→%V", o, o+4);
o += 8;
n -= 8;
}
p = seprint(p, e, ")");
return p;
}
static char*
pclroutes(char *p, char *e, char *tag, uchar *o, int n)
{
uchar addr[4];
int i, nbits, nocts;
p = seprint(p, e, "%s=(", tag);
i = 0;
while(n >= 5){
nbits = *o++;
n--;
nocts = nbits <= 32 ? (nbits+7)/8 : 4;
if(n < nocts+4)
break;
memset(addr, 0, 4);
memmove(addr, o, nocts);
o += nocts;
n -= nocts;
if(i++ > 0)
p = seprint(p, e, " ");
p = seprint(p, e, "%V/%d→%V", addr, nbits, o);
o += 4;
n -= 4;
}
p = seprint(p, e, ")");
return p;
}
/* ignore anything that's too long */
n = *ps++;
o = ps;
ps += n;
if(ps > m->pe)
break;
switch(code){
case ODipaddr: /* requested ip address */
p = pserver(p, e, "ipaddr", o, n);
break;
case ODlease: /* requested lease time */
p = pint(p, e, "lease", o, n);
break;
case ODtype:
p = ptype(p, e, *o);
break;
case ODserverid:
p = pserver(p, e, "serverid", o, n);
break;
case ODmessage:
p = pstring(p, e, "message", o, n);
break;
case ODmaxmsg:
p = puint(p, e, "maxmsg", o, n);
break;
case ODclientid:
p = phex(p, e, "clientid", o, n);
break;
case ODparams:
p = seprint(p, e, " requested=(");
for(i = 0; i < n; i++){
if(i != 0)
p = seprint(p, e, " ");
p = seprint(p, e, "%ud", o[i]);
}
p = seprint(p, e, ")");
break;
case ODvendorclass:
p = pstring(p, e, "vendorclass", o, n);
break;
case OBmask:
p = pserver(p, e, "mask", o, n);
break;
case OBtimeoff:
p = pint(p, e, "timeoff", o, n);
break;
case OBrouter:
p = pserver(p, e, "router", o, n);
break;
case OBtimeserver:
p = pserver(p, e, "timesrv", o, n);
break;
case OBnameserver:
p = pserver(p, e, "namesrv", o, n);
break;
case OBdnserver:
p = pserver(p, e, "dnssrv", o, n);
break;
case OBlogserver:
p = pserver(p, e, "logsrv", o, n);
break;
case OBcookieserver:
p = pserver(p, e, "cookiesrv", o, n);
break;
case OBlprserver:
p = pserver(p, e, "lprsrv", o, n);
break;
case OBimpressserver:
p = pserver(p, e, "impresssrv", o, n);
break;
case OBrlserver:
p = pserver(p, e, "rlsrv", o, n);
break;
case OBhostname:
p = pstring(p, e, "hostname", o, n);
break;
case OBbflen:
break;
case OBdumpfile:
p = pstring(p, e, "dumpfile", o, n);
break;
case OBdomainname:
p = pstring(p, e, "domname", o, n);
break;
case OBrootserver:
p = pserver(p, e, "rootsrv", o, n);
break;
case OBrootpath:
p = pstring(p, e, "rootpath", o, n);
break;
case OBextpath:
p = pstring(p, e, "extpath", o, n);
break;
case OBipforward:
p = phex(p, e, "ipforward", o, n);
break;
case OBnonlocal:
p = phex(p, e, "nonlocal", o, n);
break;
case OBpolicyfilter:
p = phex(p, e, "policyfilter", o, n);
break;
case OBmaxdatagram:
p = phex(p, e, "maxdatagram", o, n);
break;
case OBttl:
p = puint(p, e, "ttl", o, n);
break;
case OBpathtimeout:
p = puint(p, e, "pathtimeout", o, n);
break;
case OBpathplateau:
p = phex(p, e, "pathplateau", o, n);
break;
case OBmtu:
p = puint(p, e, "mtu", o, n);
break;
case OBsubnetslocal:
p = pserver(p, e, "subnet", o, n);
break;
case OBbaddr:
p = pserver(p, e, "baddr", o, n);
break;
case OBdiscovermask:
p = pserver(p, e, "discovermsak", o, n);
break;
case OBsupplymask:
p = pserver(p, e, "rousupplymaskter", o, n);
break;
case OBdiscoverrouter:
p = pserver(p, e, "discoverrouter", o, n);
break;
case OBrsserver:
p = pserver(p, e, "rsrouter", o, n);
break;
case OBstaticroutes:
p = pcfroutes(p, e, "cf-routes", o, n);
break;
case ODclasslessroutes:
p = pclroutes(p, e, "cl-routes", o, n);
break;
case OBtrailerencap:
p = phex(p, e, "trailerencap", o, n);
break;
case OBarptimeout:
p = puint(p, e, "arptimeout", o, n);
break;
case OBetherencap:
p = phex(p, e, "etherencap", o, n);
break;
case OBtcpttl:
p = puint(p, e, "tcpttl", o, n);
break;
case OBtcpka:
p = puint(p, e, "tcpka", o, n);
break;
case OBtcpkag:
p = phex(p, e, "tcpkag", o, n);
break;
case OBnisdomain:
p = pstring(p, e, "nisdomain", o, n);
break;
case OBniserver:
p = pserver(p, e, "nisrv", o, n);
break;
case OBntpserver:
p = pserver(p, e, "ntpsrv", o, n);
break;
case OBvendorinfo:
p = phex(p, e, "vendorinfo", o, n);
break;
case OBnetbiosns:
p = pserver(p, e, "biosns", o, n);
break;
case OBnetbiosdds:
p = phex(p, e, "biosdds", o, n);
break;
case OBnetbiostype:
p = phex(p, e, "biostype", o, n);
break;
case OBnetbiosscope:
p = phex(p, e, "biosscope", o, n);
break;
case OBxfontserver:
p = pserver(p, e, "fontsrv", o, n);
break;
case OBxdispmanager:
p = pserver(p, e, "xdispmgr", o, n);
break;
case OBnisplusdomain:
p = pstring(p, e, "nisplusdomain", o, n);
break;
case OBnisplusserver:
p = pserver(p, e, "nisplussrv", o, n);
break;
case OBhomeagent:
p = pserver(p, e, "homeagent", o, n);
break;
case OBsmtpserver:
p = pserver(p, e, "smtpsrv", o, n);
break;
case OBpop3server:
p = pserver(p, e, "pop3srv", o, n);
break;
case OBnntpserver:
p = pserver(p, e, "ntpsrv", o, n);
break;
case OBwwwserver:
p = pserver(p, e, "wwwsrv", o, n);
break;
case OBfingerserver:
p = pserver(p, e, "fingersrv", o, n);
break;
case OBircserver:
p = pserver(p, e, "ircsrv", o, n);
break;
case OBstserver:
p = pserver(p, e, "stsrv", o, n);
break;
case OBstdaserver:
p = pserver(p, e, "stdasrv", o, n);
break;
case OBend:
goto out;
default:
snprint(msg, sizeof msg, "T%ud", code);
p = phex(p, e, msg, o, n);
break;
}
if(*ps != OBend)
p = seprint(p, e, " ");
}
out:
m->p = p;
m->ps = ps;
return 0;
}