xref: /plan9/sys/src/cmd/ip/snoopy/dhcp.c (revision b751ae26be1094fda8622607119a26860f1833ab)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <ip.h>
49a747e4fSDavid du Colombier #include "dat.h"
59a747e4fSDavid du Colombier #include "protos.h"
69a747e4fSDavid du Colombier 
79a747e4fSDavid du Colombier enum
89a747e4fSDavid du Colombier {
99a747e4fSDavid du Colombier 	Maxoptlen=	312-4,
109a747e4fSDavid du Colombier 
119a747e4fSDavid du Colombier 	/* dhcp types */
129a747e4fSDavid du Colombier 	Discover=	1,
139a747e4fSDavid du Colombier 	Offer=		2,
149a747e4fSDavid du Colombier 	Request=	3,
159a747e4fSDavid du Colombier 	Decline=	4,
169a747e4fSDavid du Colombier 	Ack=		5,
179a747e4fSDavid du Colombier 	Nak=		6,
189a747e4fSDavid du Colombier 	Release=	7,
199a747e4fSDavid du Colombier 	Inform=		8,
209a747e4fSDavid du Colombier 
219a747e4fSDavid du Colombier 	/* bootp option types */
229a747e4fSDavid du Colombier 	OBend=			255,
239a747e4fSDavid du Colombier 	OBpad=			0,
249a747e4fSDavid du Colombier 	OBmask=			1,
259a747e4fSDavid du Colombier 	OBtimeoff=		2,
269a747e4fSDavid du Colombier 	OBrouter=		3,
279a747e4fSDavid du Colombier 	OBtimeserver=		4,
289a747e4fSDavid du Colombier 	OBnameserver=		5,
299a747e4fSDavid du Colombier 	OBdnserver=		6,
309a747e4fSDavid du Colombier 	OBlogserver=		7,
319a747e4fSDavid du Colombier 	OBcookieserver=		8,
329a747e4fSDavid du Colombier 	OBlprserver=		9,
339a747e4fSDavid du Colombier 	OBimpressserver=	10,
349a747e4fSDavid du Colombier 	OBrlserver=		11,
359a747e4fSDavid du Colombier 	OBhostname=		12,	/* 0xc0 */
369a747e4fSDavid du Colombier 	OBbflen=		13,
379a747e4fSDavid du Colombier 	OBdumpfile=		14,
389a747e4fSDavid du Colombier 	OBdomainname=		15,
399a747e4fSDavid du Colombier 	OBswapserver=		16,	/* 0x10 */
409a747e4fSDavid du Colombier 	OBrootpath=		17,
419a747e4fSDavid du Colombier 	OBextpath=		18,
429a747e4fSDavid du Colombier 	OBipforward=		19,
439a747e4fSDavid du Colombier 	OBnonlocal=		20,
449a747e4fSDavid du Colombier 	OBpolicyfilter=		21,
459a747e4fSDavid du Colombier 	OBmaxdatagram=		22,
469a747e4fSDavid du Colombier 	OBttl=			23,
479a747e4fSDavid du Colombier 	OBpathtimeout=		24,
489a747e4fSDavid du Colombier 	OBpathplateau=		25,
499a747e4fSDavid du Colombier 	OBmtu=			26,
509a747e4fSDavid du Colombier 	OBsubnetslocal=		27,
519a747e4fSDavid du Colombier 	OBbaddr=		28,
529a747e4fSDavid du Colombier 	OBdiscovermask=		29,
539a747e4fSDavid du Colombier 	OBsupplymask=		30,
549a747e4fSDavid du Colombier 	OBdiscoverrouter=	31,
559a747e4fSDavid du Colombier 	OBrsserver=		32,	/* 0x20 */
569a747e4fSDavid du Colombier 	OBstaticroutes=		33,
579a747e4fSDavid du Colombier 	OBtrailerencap=		34,
589a747e4fSDavid du Colombier 	OBarptimeout=		35,
599a747e4fSDavid du Colombier 	OBetherencap=		36,
609a747e4fSDavid du Colombier 	OBtcpttl=		37,
619a747e4fSDavid du Colombier 	OBtcpka=		38,
629a747e4fSDavid du Colombier 	OBtcpkag=		39,
639a747e4fSDavid du Colombier 	OBnisdomain=		40,
649a747e4fSDavid du Colombier 	OBniserver=		41,
659a747e4fSDavid du Colombier 	OBntpserver=		42,
669a747e4fSDavid du Colombier 	OBvendorinfo=		43,	/* 0x2b */
679a747e4fSDavid du Colombier 	OBnetbiosns=		44,
689a747e4fSDavid du Colombier 	OBnetbiosdds=		45,
699a747e4fSDavid du Colombier 	OBnetbiostype=		46,
709a747e4fSDavid du Colombier 	OBnetbiosscope=		47,
719a747e4fSDavid du Colombier 	OBxfontserver=		48,	/* 0x30 */
729a747e4fSDavid du Colombier 	OBxdispmanager=		49,
739a747e4fSDavid du Colombier 	OBnisplusdomain=	64,	/* 0x40 */
749a747e4fSDavid du Colombier 	OBnisplusserver=	65,
759a747e4fSDavid du Colombier 	OBhomeagent=		68,
769a747e4fSDavid du Colombier 	OBsmtpserver=		69,
779a747e4fSDavid du Colombier 	OBpop3server=		70,
789a747e4fSDavid du Colombier 	OBnntpserver=		71,
799a747e4fSDavid du Colombier 	OBwwwserver=		72,
809a747e4fSDavid du Colombier 	OBfingerserver=		73,
819a747e4fSDavid du Colombier 	OBircserver=		74,
829a747e4fSDavid du Colombier 	OBstserver=		75,
839a747e4fSDavid du Colombier 	OBstdaserver=		76,
849a747e4fSDavid du Colombier 
859a747e4fSDavid du Colombier 	/* dhcp options */
869a747e4fSDavid du Colombier 	ODipaddr=		50,	/* 0x32 */
879a747e4fSDavid du Colombier 	ODlease=		51,
889a747e4fSDavid du Colombier 	ODoverload=		52,
899a747e4fSDavid du Colombier 	ODtype=			53,	/* 0x35 */
909a747e4fSDavid du Colombier 	ODserverid=		54,	/* 0x36 */
919a747e4fSDavid du Colombier 	ODparams=		55,	/* 0x37 */
929a747e4fSDavid du Colombier 	ODmessage=		56,
939a747e4fSDavid du Colombier 	ODmaxmsg=		57,
949a747e4fSDavid du Colombier 	ODrenewaltime=		58,
959a747e4fSDavid du Colombier 	ODrebindingtime=	59,
969a747e4fSDavid du Colombier 	ODvendorclass=		60,
979a747e4fSDavid du Colombier 	ODclientid=		61,	/* 0x3d */
989a747e4fSDavid du Colombier 	ODtftpserver=		66,
999a747e4fSDavid du Colombier 	ODbootfile=		67,
1009a747e4fSDavid du Colombier 
1019a747e4fSDavid du Colombier 	/* plan9 vendor info options */
102*b751ae26SDavid du Colombier 	OP9fsv4=		128,	/* plan9 file servers */
103*b751ae26SDavid du Colombier 	OP9authv4=		129,	/* plan9 auth servers */
1049a747e4fSDavid du Colombier };
1059a747e4fSDavid du Colombier 
1069a747e4fSDavid du Colombier /*
1079a747e4fSDavid du Colombier  *  convert a byte array to hex
1089a747e4fSDavid du Colombier  */
1099a747e4fSDavid du Colombier static char
hex(int x)1109a747e4fSDavid du Colombier hex(int x)
1119a747e4fSDavid du Colombier {
1129a747e4fSDavid du Colombier 	if(x < 10)
1139a747e4fSDavid du Colombier 		return x + '0';
1149a747e4fSDavid du Colombier 	return x - 10 + 'a';
1159a747e4fSDavid du Colombier }
1169a747e4fSDavid du Colombier static char*
phex(char * p,char * e,char * tag,uchar * o,int n)1179a747e4fSDavid du Colombier phex(char *p, char *e, char *tag, uchar *o, int n)
1189a747e4fSDavid du Colombier {
1199a747e4fSDavid du Colombier 	p = seprint(p, e, "%s=", tag);
1209a747e4fSDavid du Colombier 
1219a747e4fSDavid du Colombier 	for(; p+2 < e && n > 0; n--){
1229a747e4fSDavid du Colombier 		*p++ = hex(*o >> 4);
1239a747e4fSDavid du Colombier 		*p++ = hex(*o & 0xf);
1249a747e4fSDavid du Colombier 		o++;
1259a747e4fSDavid du Colombier 	}
1269a747e4fSDavid du Colombier 	return p;
1279a747e4fSDavid du Colombier }
1289a747e4fSDavid du Colombier 
1299a747e4fSDavid du Colombier static char*
pstring(char * p,char * e,char * tag,uchar * o,int n)1309a747e4fSDavid du Colombier pstring(char *p, char *e, char *tag, uchar *o, int n)
1319a747e4fSDavid du Colombier {
1329a747e4fSDavid du Colombier 	char msg[256];
1339a747e4fSDavid du Colombier 
1349a747e4fSDavid du Colombier 	if(n > sizeof msg - 1)
1359a747e4fSDavid du Colombier 		n = sizeof msg - 1;
1369a747e4fSDavid du Colombier 	memmove(msg, o, n);
1379a747e4fSDavid du Colombier 	msg[n] = 0;
1389a747e4fSDavid du Colombier 	return seprint(p, e, "%s=%s", tag, msg);
1399a747e4fSDavid du Colombier }
1409a747e4fSDavid du Colombier 
1419a747e4fSDavid du Colombier static char*
pint(char * p,char * e,char * tag,uchar * o,int n)1429a747e4fSDavid du Colombier pint(char *p, char *e, char *tag, uchar *o, int n)
1439a747e4fSDavid du Colombier {
1449a747e4fSDavid du Colombier 	int x;
1459a747e4fSDavid du Colombier 
1469a747e4fSDavid du Colombier 	x = *(char*)o++;
1479a747e4fSDavid du Colombier 	for(; n > 1; n--)
148e6dcbf51SDavid du Colombier 		x = x<<8 | *o++;
1499a747e4fSDavid du Colombier 	return seprint(p, e, "%s=%d", tag, x);
1509a747e4fSDavid du Colombier }
1519a747e4fSDavid du Colombier 
1529a747e4fSDavid du Colombier static char*
puint(char * p,char * e,char * tag,uchar * o,int n)1539a747e4fSDavid du Colombier puint(char *p, char *e, char *tag, uchar *o, int n)
1549a747e4fSDavid du Colombier {
1559a747e4fSDavid du Colombier 	uint x;
1569a747e4fSDavid du Colombier 
1579a747e4fSDavid du Colombier 	x = *o++;
1589a747e4fSDavid du Colombier 	for(; n > 1; n--)
159e6dcbf51SDavid du Colombier 		x = x<<8 | *o++;
1609a747e4fSDavid du Colombier 	return seprint(p, e, "%s=%ud", tag, x);
1619a747e4fSDavid du Colombier }
1629a747e4fSDavid du Colombier 
1639a747e4fSDavid du Colombier static char*
pserver(char * p,char * e,char * tag,uchar * o,int n)1649a747e4fSDavid du Colombier pserver(char *p, char *e, char *tag, uchar *o, int n)
1659a747e4fSDavid du Colombier {
1669a747e4fSDavid du Colombier 	p = seprint(p, e, "%s=(", tag);
1679a747e4fSDavid du Colombier 	while(n >= 4){
1689a747e4fSDavid du Colombier 		p = seprint(p, e, " %V", o);
1699a747e4fSDavid du Colombier 		n -= 4;
1709a747e4fSDavid du Colombier 		o += 4;
1719a747e4fSDavid du Colombier 	}
1729a747e4fSDavid du Colombier 	p = seprint(p, e, ")");
1739a747e4fSDavid du Colombier 	return p;
1749a747e4fSDavid du Colombier }
1759a747e4fSDavid du Colombier 
1769a747e4fSDavid du Colombier static char *dhcptype[256] =
1779a747e4fSDavid du Colombier {
1789a747e4fSDavid du Colombier [Discover]	"Discover",
1799a747e4fSDavid du Colombier [Offer]		"Offer",
1809a747e4fSDavid du Colombier [Request]	"Request",
1819a747e4fSDavid du Colombier [Decline]	"Decline",
1829a747e4fSDavid du Colombier [Ack]		"Ack",
1839a747e4fSDavid du Colombier [Nak]		"Nak",
1849a747e4fSDavid du Colombier [Release]	"Release",
1859a747e4fSDavid du Colombier [Inform]	"Inform",
1869a747e4fSDavid du Colombier };
1879a747e4fSDavid du Colombier 
1889a747e4fSDavid du Colombier 
1899a747e4fSDavid du Colombier static char*
ptype(char * p,char * e,uchar val)1909a747e4fSDavid du Colombier ptype(char *p, char *e, uchar val)
1919a747e4fSDavid du Colombier {
1929a747e4fSDavid du Colombier 	char *x;
1939a747e4fSDavid du Colombier 
1949a747e4fSDavid du Colombier 	x = dhcptype[val];
1959a747e4fSDavid du Colombier 	if(x != nil)
1969a747e4fSDavid du Colombier 		return seprint(p, e, "t=%s", x);
1979a747e4fSDavid du Colombier 	else
1989a747e4fSDavid du Colombier 		return seprint(p, e, "t=%d", val);
1999a747e4fSDavid du Colombier }
2009a747e4fSDavid du Colombier 
2019a747e4fSDavid du Colombier static int
p_seprint(Msg * m)2029a747e4fSDavid du Colombier p_seprint(Msg *m)
2039a747e4fSDavid du Colombier {
2049a747e4fSDavid du Colombier 	int i, n, code;
2059a747e4fSDavid du Colombier 	uchar *o, *ps;
2069a747e4fSDavid du Colombier 	char *p, *e;
2079a747e4fSDavid du Colombier 	char msg[64];
2089a747e4fSDavid du Colombier 
2099a747e4fSDavid du Colombier 	/* no next proto */
2109a747e4fSDavid du Colombier 	m->pr = nil;
2119a747e4fSDavid du Colombier 
2129a747e4fSDavid du Colombier 	p = m->p;
2139a747e4fSDavid du Colombier 	e = m->e;
2149a747e4fSDavid du Colombier 	ps = m->ps;
2159a747e4fSDavid du Colombier 
2169a747e4fSDavid du Colombier 	while(ps < m->pe){
2179a747e4fSDavid du Colombier 		code = *ps++;
2189a747e4fSDavid du Colombier 		if(code == 255)
2199a747e4fSDavid du Colombier 			break;
2209a747e4fSDavid du Colombier 		if(code == 0)
2219a747e4fSDavid du Colombier 			continue;
2229a747e4fSDavid du Colombier 
2239a747e4fSDavid du Colombier 		/* ignore anything that's too long */
2249a747e4fSDavid du Colombier 		n = *ps++;
2259a747e4fSDavid du Colombier 		o = ps;
2269a747e4fSDavid du Colombier 		ps += n;
2279a747e4fSDavid du Colombier 		if(ps > m->pe)
2289a747e4fSDavid du Colombier 			break;
2299a747e4fSDavid du Colombier 
2309a747e4fSDavid du Colombier 		switch(code){
2319a747e4fSDavid du Colombier 		case ODipaddr:	/* requested ip address */
2329a747e4fSDavid du Colombier 			p = pserver(p, e, "ipaddr", o, n);
2339a747e4fSDavid du Colombier 			break;
2349a747e4fSDavid du Colombier 		case ODlease:	/* requested lease time */
2359a747e4fSDavid du Colombier 			p = pint(p, e, "lease", o, n);
2369a747e4fSDavid du Colombier 			break;
2379a747e4fSDavid du Colombier 		case ODtype:
2389a747e4fSDavid du Colombier 			p = ptype(p, e, *o);
2399a747e4fSDavid du Colombier 			break;
2409a747e4fSDavid du Colombier 		case ODserverid:
2419a747e4fSDavid du Colombier 			p = pserver(p, e, "serverid", o, n);
2429a747e4fSDavid du Colombier 			break;
2439a747e4fSDavid du Colombier 		case ODmessage:
2449a747e4fSDavid du Colombier 			p = pstring(p, e, "message", o, n);
2459a747e4fSDavid du Colombier 			break;
2469a747e4fSDavid du Colombier 		case ODmaxmsg:
2479a747e4fSDavid du Colombier 			p = puint(p, e, "maxmsg", o, n);
2489a747e4fSDavid du Colombier 			break;
2499a747e4fSDavid du Colombier 		case ODclientid:
2509a747e4fSDavid du Colombier 			p = phex(p, e, "clientid", o, n);
2519a747e4fSDavid du Colombier 			break;
2529a747e4fSDavid du Colombier 		case ODparams:
2539a747e4fSDavid du Colombier 			p = seprint(p, e, " requested=(");
2549a747e4fSDavid du Colombier 			for(i = 0; i < n; i++){
2559a747e4fSDavid du Colombier 				if(i != 0)
2569a747e4fSDavid du Colombier 					p = seprint(p, e, " ");
2579a747e4fSDavid du Colombier 				p = seprint(p, e, "%ud", o[i]);
2589a747e4fSDavid du Colombier 			}
2599a747e4fSDavid du Colombier 			p = seprint(p, e, ")");
2609a747e4fSDavid du Colombier 			break;
2619a747e4fSDavid du Colombier 		case ODvendorclass:
2629a747e4fSDavid du Colombier 			p = pstring(p, e, "vendorclass", o, n);
2639a747e4fSDavid du Colombier 			break;
2649a747e4fSDavid du Colombier 		case OBmask:
2659a747e4fSDavid du Colombier 			p = pserver(p, e, "mask", o, n);
2669a747e4fSDavid du Colombier 			break;
2679a747e4fSDavid du Colombier 		case OBtimeoff:
2689a747e4fSDavid du Colombier 			p = pint(p, e, "timeoff", o, n);
2699a747e4fSDavid du Colombier 			break;
2709a747e4fSDavid du Colombier 		case OBrouter:
2719a747e4fSDavid du Colombier 			p = pserver(p, e, "router", o, n);
2729a747e4fSDavid du Colombier 			break;
2739a747e4fSDavid du Colombier 		case OBtimeserver:
2749a747e4fSDavid du Colombier 			p = pserver(p, e, "timesrv", o, n);
2759a747e4fSDavid du Colombier 			break;
2769a747e4fSDavid du Colombier 		case OBnameserver:
2779a747e4fSDavid du Colombier 			p = pserver(p, e, "namesrv", o, n);
2789a747e4fSDavid du Colombier 			break;
2799a747e4fSDavid du Colombier 		case OBdnserver:
2809a747e4fSDavid du Colombier 			p = pserver(p, e, "dnssrv", o, n);
2819a747e4fSDavid du Colombier 			break;
2829a747e4fSDavid du Colombier 		case OBlogserver:
2839a747e4fSDavid du Colombier 			p = pserver(p, e, "logsrv", o, n);
2849a747e4fSDavid du Colombier 			break;
2859a747e4fSDavid du Colombier 		case OBcookieserver:
2869a747e4fSDavid du Colombier 			p = pserver(p, e, "cookiesrv", o, n);
2879a747e4fSDavid du Colombier 			break;
2889a747e4fSDavid du Colombier 		case OBlprserver:
2899a747e4fSDavid du Colombier 			p = pserver(p, e, "lprsrv", o, n);
2909a747e4fSDavid du Colombier 			break;
2919a747e4fSDavid du Colombier 		case OBimpressserver:
2929a747e4fSDavid du Colombier 			p = pserver(p, e, "impresssrv", o, n);
2939a747e4fSDavid du Colombier 			break;
2949a747e4fSDavid du Colombier 		case OBrlserver:
2959a747e4fSDavid du Colombier 			p = pserver(p, e, "rlsrv", o, n);
2969a747e4fSDavid du Colombier 			break;
2979a747e4fSDavid du Colombier 		case OBhostname:
2989a747e4fSDavid du Colombier 			p = pstring(p, e, "hostname", o, n);
2999a747e4fSDavid du Colombier 			break;
3009a747e4fSDavid du Colombier 		case OBbflen:
3019a747e4fSDavid du Colombier 			break;
3029a747e4fSDavid du Colombier 		case OBdumpfile:
3039a747e4fSDavid du Colombier 			p = pstring(p, e, "dumpfile", o, n);
3049a747e4fSDavid du Colombier 			break;
3059a747e4fSDavid du Colombier 		case OBdomainname:
3069a747e4fSDavid du Colombier 			p = pstring(p, e, "domname", o, n);
3079a747e4fSDavid du Colombier 			break;
3089a747e4fSDavid du Colombier 		case OBswapserver:
3099a747e4fSDavid du Colombier 			p = pserver(p, e, "swapsrv", o, n);
3109a747e4fSDavid du Colombier 			break;
3119a747e4fSDavid du Colombier 		case OBrootpath:
3129a747e4fSDavid du Colombier 			p = pstring(p, e, "rootpath", o, n);
3139a747e4fSDavid du Colombier 			break;
3149a747e4fSDavid du Colombier 		case OBextpath:
3159a747e4fSDavid du Colombier 			p = pstring(p, e, "extpath", o, n);
3169a747e4fSDavid du Colombier 			break;
3179a747e4fSDavid du Colombier 		case OBipforward:
3189a747e4fSDavid du Colombier 			p = phex(p, e, "ipforward", o, n);
3199a747e4fSDavid du Colombier 			break;
3209a747e4fSDavid du Colombier 		case OBnonlocal:
3219a747e4fSDavid du Colombier 			p = phex(p, e, "nonlocal", o, n);
3229a747e4fSDavid du Colombier 			break;
3239a747e4fSDavid du Colombier 		case OBpolicyfilter:
3249a747e4fSDavid du Colombier 			p = phex(p, e, "policyfilter", o, n);
3259a747e4fSDavid du Colombier 			break;
3269a747e4fSDavid du Colombier 		case OBmaxdatagram:
3279a747e4fSDavid du Colombier 			p = phex(p, e, "maxdatagram", o, n);
3289a747e4fSDavid du Colombier 			break;
3299a747e4fSDavid du Colombier 		case OBttl:
3309a747e4fSDavid du Colombier 			p = puint(p, e, "ttl", o, n);
3319a747e4fSDavid du Colombier 			break;
3329a747e4fSDavid du Colombier 		case OBpathtimeout:
3339a747e4fSDavid du Colombier 			p = puint(p, e, "pathtimeout", o, n);
3349a747e4fSDavid du Colombier 			break;
3359a747e4fSDavid du Colombier 		case OBpathplateau:
3369a747e4fSDavid du Colombier 			p = phex(p, e, "pathplateau", o, n);
3379a747e4fSDavid du Colombier 			break;
3389a747e4fSDavid du Colombier 		case OBmtu:
3399a747e4fSDavid du Colombier 			p = puint(p, e, "mtu", o, n);
3409a747e4fSDavid du Colombier 			break;
3419a747e4fSDavid du Colombier 		case OBsubnetslocal:
3429a747e4fSDavid du Colombier 			p = pserver(p, e, "subnet", o, n);
3439a747e4fSDavid du Colombier 			break;
3449a747e4fSDavid du Colombier 		case OBbaddr:
3459a747e4fSDavid du Colombier 			p = pserver(p, e, "baddr", o, n);
3469a747e4fSDavid du Colombier 			break;
3479a747e4fSDavid du Colombier 		case OBdiscovermask:
3489a747e4fSDavid du Colombier 			p = pserver(p, e, "discovermsak", o, n);
3499a747e4fSDavid du Colombier 			break;
3509a747e4fSDavid du Colombier 		case OBsupplymask:
3519a747e4fSDavid du Colombier 			p = pserver(p, e, "rousupplymaskter", o, n);
3529a747e4fSDavid du Colombier 			break;
3539a747e4fSDavid du Colombier 		case OBdiscoverrouter:
3549a747e4fSDavid du Colombier 			p = pserver(p, e, "discoverrouter", o, n);
3559a747e4fSDavid du Colombier 			break;
3569a747e4fSDavid du Colombier 		case OBrsserver:
3579a747e4fSDavid du Colombier 			p = pserver(p, e, "rsrouter", o, n);
3589a747e4fSDavid du Colombier 			break;
3599a747e4fSDavid du Colombier 		case OBstaticroutes:
3609a747e4fSDavid du Colombier 			p = phex(p, e, "staticroutes", o, n);
3619a747e4fSDavid du Colombier 			break;
3629a747e4fSDavid du Colombier 		case OBtrailerencap:
3639a747e4fSDavid du Colombier 			p = phex(p, e, "trailerencap", o, n);
3649a747e4fSDavid du Colombier 			break;
3659a747e4fSDavid du Colombier 		case OBarptimeout:
3669a747e4fSDavid du Colombier 			p = puint(p, e, "arptimeout", o, n);
3679a747e4fSDavid du Colombier 			break;
3689a747e4fSDavid du Colombier 		case OBetherencap:
3699a747e4fSDavid du Colombier 			p = phex(p, e, "etherencap", o, n);
3709a747e4fSDavid du Colombier 			break;
3719a747e4fSDavid du Colombier 		case OBtcpttl:
3729a747e4fSDavid du Colombier 			p = puint(p, e, "tcpttl", o, n);
3739a747e4fSDavid du Colombier 			break;
3749a747e4fSDavid du Colombier 		case OBtcpka:
3759a747e4fSDavid du Colombier 			p = puint(p, e, "tcpka", o, n);
3769a747e4fSDavid du Colombier 			break;
3779a747e4fSDavid du Colombier 		case OBtcpkag:
3789a747e4fSDavid du Colombier 			p = phex(p, e, "tcpkag", o, n);
3799a747e4fSDavid du Colombier 			break;
3809a747e4fSDavid du Colombier 		case OBnisdomain:
3819a747e4fSDavid du Colombier 			p = pstring(p, e, "nisdomain", o, n);
3829a747e4fSDavid du Colombier 			break;
3839a747e4fSDavid du Colombier 		case OBniserver:
3849a747e4fSDavid du Colombier 			p = pserver(p, e, "nisrv", o, n);
3859a747e4fSDavid du Colombier 			break;
3869a747e4fSDavid du Colombier 		case OBntpserver:
3879a747e4fSDavid du Colombier 			p = pserver(p, e, "ntpsrv", o, n);
3889a747e4fSDavid du Colombier 			break;
3899a747e4fSDavid du Colombier 		case OBvendorinfo:
3909a747e4fSDavid du Colombier 			p = phex(p, e, "vendorinfo", o, n);
3919a747e4fSDavid du Colombier 			break;
3929a747e4fSDavid du Colombier 		case OBnetbiosns:
3939a747e4fSDavid du Colombier 			p = pserver(p, e, "biosns", o, n);
3949a747e4fSDavid du Colombier 			break;
3959a747e4fSDavid du Colombier 		case OBnetbiosdds:
3969a747e4fSDavid du Colombier 			p = phex(p, e, "biosdds", o, n);
3979a747e4fSDavid du Colombier 			break;
3989a747e4fSDavid du Colombier 		case OBnetbiostype:
3999a747e4fSDavid du Colombier 			p = phex(p, e, "biostype", o, n);
4009a747e4fSDavid du Colombier 			break;
4019a747e4fSDavid du Colombier 		case OBnetbiosscope:
4029a747e4fSDavid du Colombier 			p = phex(p, e, "biosscope", o, n);
4039a747e4fSDavid du Colombier 			break;
4049a747e4fSDavid du Colombier 		case OBxfontserver:
4059a747e4fSDavid du Colombier 			p = pserver(p, e, "fontsrv", o, n);
4069a747e4fSDavid du Colombier 			break;
4079a747e4fSDavid du Colombier 		case OBxdispmanager:
4089a747e4fSDavid du Colombier 			p = pserver(p, e, "xdispmgr", o, n);
4099a747e4fSDavid du Colombier 			break;
4109a747e4fSDavid du Colombier 		case OBnisplusdomain:
4119a747e4fSDavid du Colombier 			p = pstring(p, e, "nisplusdomain", o, n);
4129a747e4fSDavid du Colombier 			break;
4139a747e4fSDavid du Colombier 		case OBnisplusserver:
4149a747e4fSDavid du Colombier 			p = pserver(p, e, "nisplussrv", o, n);
4159a747e4fSDavid du Colombier 			break;
4169a747e4fSDavid du Colombier 		case OBhomeagent:
4179a747e4fSDavid du Colombier 			p = pserver(p, e, "homeagent", o, n);
4189a747e4fSDavid du Colombier 			break;
4199a747e4fSDavid du Colombier 		case OBsmtpserver:
4209a747e4fSDavid du Colombier 			p = pserver(p, e, "smtpsrv", o, n);
4219a747e4fSDavid du Colombier 			break;
4229a747e4fSDavid du Colombier 		case OBpop3server:
4239a747e4fSDavid du Colombier 			p = pserver(p, e, "pop3srv", o, n);
4249a747e4fSDavid du Colombier 			break;
4259a747e4fSDavid du Colombier 		case OBnntpserver:
4269a747e4fSDavid du Colombier 			p = pserver(p, e, "ntpsrv", o, n);
4279a747e4fSDavid du Colombier 			break;
4289a747e4fSDavid du Colombier 		case OBwwwserver:
4299a747e4fSDavid du Colombier 			p = pserver(p, e, "wwwsrv", o, n);
4309a747e4fSDavid du Colombier 			break;
4319a747e4fSDavid du Colombier 		case OBfingerserver:
4329a747e4fSDavid du Colombier 			p = pserver(p, e, "fingersrv", o, n);
4339a747e4fSDavid du Colombier 			break;
4349a747e4fSDavid du Colombier 		case OBircserver:
4359a747e4fSDavid du Colombier 			p = pserver(p, e, "ircsrv", o, n);
4369a747e4fSDavid du Colombier 			break;
4379a747e4fSDavid du Colombier 		case OBstserver:
4389a747e4fSDavid du Colombier 			p = pserver(p, e, "stsrv", o, n);
4399a747e4fSDavid du Colombier 			break;
4409a747e4fSDavid du Colombier 		case OBstdaserver:
4419a747e4fSDavid du Colombier 			p = pserver(p, e, "stdasrv", o, n);
4429a747e4fSDavid du Colombier 			break;
4439a747e4fSDavid du Colombier 		case OBend:
4449a747e4fSDavid du Colombier 			goto out;
4459a747e4fSDavid du Colombier 		default:
4469a747e4fSDavid du Colombier 			snprint(msg, sizeof msg, " T%ud", code);
4479a747e4fSDavid du Colombier 			p = phex(p, e, msg, o, n);
4489a747e4fSDavid du Colombier 			break;
4499a747e4fSDavid du Colombier 		}
4509a747e4fSDavid du Colombier 		if(*ps != OBend)
4519a747e4fSDavid du Colombier 			p = seprint(p, e, " ");
4529a747e4fSDavid du Colombier 	}
4539a747e4fSDavid du Colombier out:
4549a747e4fSDavid du Colombier 	m->p = p;
4559a747e4fSDavid du Colombier 	m->ps = ps;
4569a747e4fSDavid du Colombier 	return 0;
4579a747e4fSDavid du Colombier }
4589a747e4fSDavid du Colombier 
4599a747e4fSDavid du Colombier Proto dhcp =
4609a747e4fSDavid du Colombier {
4619a747e4fSDavid du Colombier 	"dhcp",
4622cca75a1SDavid du Colombier 	nil,
4632cca75a1SDavid du Colombier 	nil,
4649a747e4fSDavid du Colombier 	p_seprint,
4659a747e4fSDavid du Colombier 	nil,
4669a747e4fSDavid du Colombier 	nil,
467ed397113SDavid du Colombier 	nil,
4683ff48bf5SDavid du Colombier 	defaultframer,
4699a747e4fSDavid du Colombier };
470