tdhcp.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
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 }; |