Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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