Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / pkg / netinet / dhcp.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: dhcp.fth
4\
5\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6\
7\ - Do no alter or remove copyright notices
8\
9\ - Redistribution and use of this software in source and binary forms, with
10\ or without modification, are permitted provided that the following
11\ conditions are met:
12\
13\ - Redistribution of source code must retain the above copyright notice,
14\ this list of conditions and the following disclaimer.
15\
16\ - Redistribution in binary form must reproduce the above copyright notice,
17\ this list of conditions and the following disclaimer in the
18\ documentation and/or other materials provided with the distribution.
19\
20\ Neither the name of Sun Microsystems, Inc. or the names of contributors
21\ may be used to endorse or promote products derived from this software
22\ without specific prior written permission.
23\
24\ This software is provided "AS IS," without a warranty of any kind.
25\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
26\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
27\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
28\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
29\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
30\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
31\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
32\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
33\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
34\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
35\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
36\
37\ You acknowledge that this software is not designed, licensed or
38\ intended for use in the design, construction, operation or maintenance of
39\ any nuclear facility.
40\
41\ ========== Copyright Header End ============================================
42id: @(#)dhcp.fth 1.1 04/09/07
43purpose: DHCP support
44copyright: Copyright 2004 Sun Microsystems, Inc. All Rights Reserved
45copyright: Use is subject to license terms.
46
47\ RFC 2131: Dynamic Host Configuration Protocol
48\ RFC 2132: DHCP Options and BOOTP Vendor Extensions
49\ RFC 1534: Interoperation Between DHCP and BOOTP
50
51fload ${BP}/pkg/netinet/dhcp-h.fth
52
53headerless
54
550 instance value dhcp-sockid
56/insock instance buffer: dhcp-srv-addr
57/insock instance buffer: dhcp-cli-addr
58
59d# 32 instance buffer: dhcp-classid
60
61/ip-addr instance buffer: dhcp-offered-ip
62/ip-addr instance buffer: dhcp-server-id
63
640 instance value dhcp-sndbuf
65 instance variable dhcp-sndbuflen
660 instance value dhcp-rcvbuf
67
680 instance value chosen-bootreply \ Best offer
690 instance value /chosen-bootreply
700 instance value best-offer-points
71false instance value bootp-config? \ Is best offer a BOOTREPLY?
72
73/timer instance buffer: dhcp-timer
74
75 instance variable dhcp-state \ DHCP FSM state
76 instance variable dhcp-xid \ Transaction identifier
77
78\ Read a byte and advance the pointer.
79: c@++ ( adr -- adr+1 c ) dup ca1+ swap c@ ;
80
81\ Find an option in the specified area of a packet.
82: (find-dhcp-option) ( adr len option# -- optadr optlen true | false )
83 >r over ca+ swap ( end start ) ( r: option# )
84 begin 2dup > while
85 c@++ case
86 CD_PAD of endof
87 CD_END of r> 3drop false exit endof
88 r@ of r> drop nip c@++ true exit endof
89 ( default )
90 drop c@++ ca+ 0
91 endcase
92 repeat
93 r> 3drop false
94;
95
96\ Find the specified DHCP option. Options in a DHCP message may extend
97\ to the 'sname' and 'file' fields if an 'option overload' option is
98\ present in the variable length options field.
99: find-dhcp-option ( pkt len option# -- optadr optlen true | false )
100 2 pick >dhcp-cookie ntohl@ BOOTMAGIC <> if
101 3drop false exit
102 then
103 >r ( pkt,len ) ( r: opt# )
104 over >dhcp-options over /dhcp-header - ( pkt,len opts,len )
105 2dup r@ (find-dhcp-option) if ( pkt,len opts,len optadr,len )
106 2swap 2drop 2swap 2drop true ( optadr,len true )
107 else ( pkt,len opts,len )
108 CD_OPTION_OVERLOAD (find-dhcp-option) if ( pkt,len ovloption,len )
109 drop nip c@ dup 1 3 between if ( pkt ovlopt-value )
110 case
111 1 of >dhcp-file d# 128 endof
112 2 of >dhcp-sname d# 64 endof
113 3 of >dhcp-sname d# 192 endof
114 endcase ( adr,len )
115 r@ (find-dhcp-option) ( optadr,len true | false )
116 else ( pkt n )
117 2drop false ( false )
118 then ( optadr,len true | false )
119 else ( pkt,len )
120 2drop false ( false )
121 then ( optadr,len true | false )
122 then ( optadr,len true | false )
123 r> drop ( optadr,len true | false )
124;
125
126\ Determine if the packet contains a specific option.
127: dhcp-option-found? ( pkt len option# -- found? )
128 find-dhcp-option if 2drop true else false then
129;
130
131\ Find a vendor specific option.
132: find-vendor-option ( pkt len vendor-option# -- optadr optlen true | false )
133 >r ( pkt len ) ( r: opt# )
134 CD_VENDOR_SPEC find-dhcp-option if ( encap-options,len )
135 r@ (find-dhcp-option) ( optadr opten true | false )
136 else ( )
137 false ( false )
138 then ( optadr optlen true | false )
139 r> drop ( optadr optlen true | false )
140;
141
142\ Add an option with a 8-bit value to the packet
143: add-dhcpopt-byte ( adr code byte -- adr' )
144 rot >r ( code byte ) ( r: adr )
145 swap r@ >dhcpopt-code c! ( byte )
146 /c r@ >dhcpopt-len c! ( byte )
147 r@ >dhcpopt-data c! ( )
148 r> 3 ca+ ( adr' ) ( r: )
149;
150
151\ Add an option with a 16-bit value to the packet
152: add-dhcpopt-word ( adr code value -- adr' )
153 rot >r ( code value ) ( r: adr )
154 swap r@ >dhcpopt-code c! ( value )
155 /w r@ >dhcpopt-len c! ( value )
156 r@ >dhcpopt-data htonw! ( )
157 r> 4 ca+ ( adr' ) ( r: )
158;
159
160\ Add an option encoding a stream of bytes to the packet.
161: add-dhcpopt-bytes ( adr code data len -- adr' )
162 ?dup if ( adr code data len )
163 3 roll >r ( code data len ) ( r: adr )
164 rot r@ >dhcpopt-code c! ( data len )
165 dup r@ >dhcpopt-len c! ( data len )
166 tuck r@ >dhcpopt-data swap move ( len )
167 r> swap 2+ ca+ ( adr' ) ( r: )
168 else ( adr code data )
169 2drop ( adr' )
170 then ( adr' )
171;
172
173\ Maximum length of the DHCP message we are willing to accept.
174: /dhcp-maxmsg ( -- n ) if-mtu@ /udpip-header - ;
175
176\ The vendor class identifier is constructed from the root node's
177\ "name" property, with commas (,) replaced with periods (.).
178: init-dhcp-vendor-classid ( -- )
179 " /" " name" get-property decode-string 2swap 2drop ( $ )
180 dhcp-classid pack count bounds ?do ( )
181 i c@ ascii , = if ascii . i c! then ( )
182 loop ( )
183;
184
185\ DHCP initialization. Create a socket, initialize the client and
186\ server socket address structures, and bind local address to the
187\ socket. Allocate buffers to send/receive/store DHCP packets and
188\ determine the vendor class identifier to use.
189
190: dhcp-init ( -- )
191 AF_INET SOCK_DGRAM IPPROTO_UDP socreate to dhcp-sockid ( )
192
193 dhcp-cli-addr my-ip-addr IPPORT_BOOTPC insock-init ( )
194 dhcp-srv-addr inaddr-broadcast IPPORT_BOOTPS insock-init ( )
195
196 /dhcp-maxmsg dup alloc-mem to dhcp-sndbuf ( n )
197 dup alloc-mem to dhcp-rcvbuf ( n )
198 alloc-mem to chosen-bootreply ( )
199
200 dhcp-sockid dhcp-cli-addr /insock sobind ( )
201
202 init-dhcp-vendor-classid ( )
203;
204
205\ DHCP state cleanup. Free the DHCP packet buffers and close the
206\ connection.
207
208: dhcp-close ( -- )
209 dhcp-sndbuf /dhcp-maxmsg tuck free-mem ( n )
210 dhcp-rcvbuf over free-mem ( n )
211 chosen-bootreply swap free-mem ( )
212 dhcp-sockid soclose ( )
213;
214
215\ Filling in DHCP message options. All DHCP messages include the DHCP
216\ message type and the client identifier (if one is in use). DHCP_REQUEST
217\ and DHCP_DECLINE messages must fill the DHCP server identifier and the
218\ offered IP address. Messages other than DHCP_DECLINE must fill in the
219\ DHCP vendor class identifier, the maximum DHCP message size we are
220\ willing to accept, and the list of requested parameters. We explicitly
221\ request values for subnet mask (Option 1), Router (Option 3), Hostname
222\ (Option 12), and Vendor specific information (Option 43).
223
224: add-dhcp-options ( pkt type -- pktlen )
225 >r dup >dhcp-options ( pkt adr ) ( r: type )
226
227 CD_DHCP_TYPE r@ add-dhcpopt-byte
228 CD_CLIENTID client-id count add-dhcpopt-bytes
229
230 r@ DHCP_DECLINE <> if
231 CD_CLASSID dhcp-classid count add-dhcpopt-bytes
232 CD_REQUEST_LIST " "(01 03 0c 2b)" add-dhcpopt-bytes
233 CD_MAXMSG_SIZE /dhcp-maxmsg add-dhcpopt-word
234 CD_HOSTNAME hostname count add-dhcpopt-bytes
235 then
236
237 r> dup DHCP_REQUEST = swap DHCP_DECLINE = or if
238 CD_SERVER_ID dhcp-server-id /ip-addr add-dhcpopt-bytes
239 CD_REQ_IPADDR dhcp-offered-ip /ip-addr add-dhcpopt-bytes
240 then
241
242 CD_END over c! ca1+ swap - ( pktlen )
243;
244
245\ Common code to construct DHCP message to be sent.
246: init-dhcp-packet ( type -- )
247 dhcp-sndbuf dup >r /dhcp-maxmsg erase ( type ) ( r: pkt )
248
249 BOOTREQUEST r@ >dhcp-op c!
250 if-htype@ r@ >dhcp-htype c!
251 if-addrlen@ r@ >dhcp-hlen c!
252 if-hwaddr r@ >dhcp-chaddr copy-hw-addr
253 dhcp-xid @ r@ >dhcp-xid htonl!
254 my-ip-addr r@ >dhcp-ciaddr copy-ip-addr
255 BOOTMAGIC r@ >dhcp-cookie htonl!
256
257 r> swap add-dhcp-options dhcp-sndbuflen ! ( ) ( r: )
258;
259
260\ Transmit formatted DHCP message.
261: send-dhcp-packet ( -- )
262 dhcp-sockid dhcp-sndbuf dhcp-sndbuflen @ ( sockid pkt len )
263 DHCP_MIN_PKTLEN max ( sockid pkt len' )
264 0 dhcp-srv-addr /insock sosendto drop ( )
265;
266
267\ Managing DHCP retransmissions. Use a randomized exponential backoff
268\ to determine delay between retransmissions. On retries, the delay is
269\ doubled (for a maximum of 64 seconds), and randomized by a random
270\ number in the range +/-1.023 seconds.
271
272: dhcp-backoff ( -- )
273 dhcp-timer clear-timer 2* d# 64000 min ( timeout )
274 random dup d# 22 rshift swap 0< if negate then + ( timeout' )
275 dhcp-timer swap set-timer ( )
276;
277
278: retransmit-dhcp-packet ( -- )
279 send-dhcp-packet dhcp-backoff
280;
281
282\ Determine DHCP packet type. BOOTP packets are tagged as type 0.
283: dhcp-packet-type ( pkt len -- type )
284 over >dhcp-cookie ntohl@ BOOTMAGIC = if ( pkt,len )
285 CD_DHCP_TYPE find-dhcp-option if drop c@ else 0 then ( type )
286 else ( pkt,len )
287 2drop 0 ( 0 )
288 then ( type )
289;
290
291\ Receive data arriving on the socket.
292: (receive-dhcp-packet) ( -- pkt len )
293 dhcp-sockid dhcp-rcvbuf tuck /dhcp-maxmsg 0 0 0 sorecvfrom
294;
295
296\ Incoming responses must be BOOTREPLY packets, and the xid should match.
297: receive-dhcp-packet ( -- pkt len true | false )
298 (receive-dhcp-packet) dup 0= if 2drop false exit then
299 over >dhcp-op c@ BOOTREPLY <> if 2drop false exit then
300 over >dhcp-xid ntohl@ dhcp-xid @ <> if 2drop false exit then
301 true
302;
303
304\ Receive OFFER messages from the server. BOOTP responses must be
305\ accepted as well.
306: receive-dhcp-offer ( -- pkt len true | false )
307 receive-dhcp-packet 0= if false exit then ( pkt len )
308 2dup dhcp-packet-type ( pkt len type )
309 dup 0= if drop true exit then ( pkt len type )
310 DHCP_OFFER <> if 2drop false exit then ( pkt len )
311 2dup CD_SERVER_ID find-dhcp-option if ( pkt len optadr,len )
312 2drop true ( pkt len true )
313 else ( pkt len )
314 ." Ignoring OFFER with missing DHCP server identifier" cr
315 2drop false ( false )
316 then ( pkt len true | false )
317;
318
319\ Receive an ACK/NAK response from the server.
320: receive-dhcp-ack/nak ( -- pkt len true | false )
321 receive-dhcp-packet 0= if false exit then ( pkt len )
322 2dup dhcp-packet-type ( pkt len type )
323 dup DHCP_ACK <> swap DHCP_NAK <> and if ( pkt len )
324 2drop false ( false )
325 else ( pkt len )
326 true ( pkt len true )
327 then ( pkt len true | false )
328;
329
330\ Receive an ACK in response to the INFORM message we sent. Responses
331\ from a BOOTP server must be accepted as well.
332: receive-dhcpinform-response ( -- pkt len true | false )
333 receive-dhcp-packet 0= if false exit then ( pkt len )
334 2dup dhcp-packet-type ( pkt len type )
335 dup DHCP_ACK <> swap 0<> and if ( pkt len )
336 2drop false ( false )
337 else ( pkt len )
338 true ( pkt len true )
339 then ( pkt len true | false )
340;
341
342\ Stash away a response received from the server.
343: store-dhcp-response ( adr len -- )
344 dup >r chosen-bootreply swap move r> to /chosen-bootreply
345;
346
347\ Wait for the expected response.
348: (dhcp-response-wait) ( xt -- pkt len true | false )
349 begin ( xt )
350 dhcp-timer timer-expired? ( xt timed-out? )
351 0= while ( xt )
352 dup execute if ( xt pkt len )
353 rot drop true exit ( pkt len true )
354 then ( xt )
355 repeat ( xt )
356 drop false ( false )
357;
358
359\ Wait for expected response, retransmitting the sent packet if necessary.
360: dhcp-response-wait ( xt ntries -- pkt len true | false )
361 begin ( xt ntries )
362 over (dhcp-response-wait) if ( xt ntries pkt len )
363 2swap 2drop true exit ( pkt len true )
364 then ( xt ntries )
365 ." Timed out waiting for BOOTP/DHCP reply" cr ( xt ntries )
366 1- ( xt ntries' )
367 dup 0 u> while ( xt ntries' )
368 retransmit-dhcp-packet ( xt ntries' )
369 repeat ( xt ntries' )
370 2drop false ( false )
371;
372
373\ Wait for a minimum of 10 seconds if restarting the configuration
374\ process after a failure.
375: dhcp-restart ( -- )
376 d# 10.000 ms DHCPS_INIT dhcp-state !
377;
378
379\ INIT state processing. Select a random transaction identifier to use
380\ in DHCP packets. Move to INFORM state if using an externally configured
381\ IP address; else move to SELECTING state.
382
383: dhcps-init ( -- )
384 random dhcp-xid l!
385 my-ip-addr inaddr-any? if DHCPS_SELECTING else DHCPS_INFORM then
386 dhcp-state !
387;
388
389\ INFORM state processing. Send a DHCPINFORM and wait for a DHCPACK.
390\ If a DHCPACK is not received even after 4 retries, enter CONFIGURED
391\ state and hope for the best.
392
393: dhcps-inform ( -- )
394 DHCP_INFORM init-dhcp-packet send-dhcp-packet ( )
395 dhcp-timer d# 4000 set-timer ( )
396 ['] receive-dhcpinform-response 4 dhcp-response-wait if ( pkt len )
397 store-dhcp-response ( )
398 DHCPS_BOUND dhcp-state ! ( )
399 else
400 DHCPS_CONFIGURED dhcp-state ! ( )
401 then ( )
402;
403
404\ Selecting the best DHCPOFFER. We select the best OFFER from the possibly
405\ many incoming OFFER messages. OFFERs are evaluated using a points-based
406\ system we share with inetboot/wanboot. We prefer DHCP configurations
407\ which provide the most configuration information.
408
409: compute-offer-points ( pkt len -- #points )
410 over >dhcp-cookie ntohl@ BOOTMAGIC <> if
411 2drop 0 exit
412 then
413
414 d# 5
415 CD_DHCP_TYPE 2over rot dhcp-option-found? if d# 30 + then
416 CD_VENDOR_SPEC 2over rot dhcp-option-found? if d# 80 + then
417 CD_SUBNETMASK 2over rot dhcp-option-found? if 1+ then
418 CD_ROUTER 2over rot dhcp-option-found? if 1+ then
419 CD_HOSTNAME 2over rot dhcp-option-found? if d# 5 + then
420
421 CD_OPTION_OVERLOAD 2over rot dhcp-option-found? 0= if
422 2 pick >dhcp-sname c@ 0<> if d# 10 + then
423 2 pick >dhcp-file c@ 0<> if d# 5 + then
424 then
425
426 2 pick >dhcp-siaddr inaddr-any? 0= if d# 10 + then
427 nip nip
428;
429
430\ Process incoming offer and keep track of the best offer received.
431: process-offer ( pkt len -- )
432 2dup compute-offer-points dup best-offer-points <= if ( pkt len pts )
433 3drop exit ( )
434 then ( pkt len pts )
435 to best-offer-points ( pkt len )
436 store-dhcp-response ( )
437;
438
439\ Record information from the OFFER we selected.
440: process-best-offer ( -- )
441 chosen-bootreply /chosen-bootreply ( pkt len )
442 2dup dhcp-packet-type 0= to bootp-config? ( pkt len )
443 over >dhcp-yiaddr dhcp-offered-ip copy-ip-addr ( pkt len )
444 CD_SERVER_ID find-dhcp-option if ( opt-adr,len )
445 drop dhcp-server-id copy-ip-addr ( )
446 then ( )
447;
448
449\ SELECTING state processing. Broadcast a DISCOVER and sift through
450\ the OFFERs to select the best one. We "collect" OFFERs for a period
451\ of 4 seconds after the first OFFER is received. If the best offer
452\ is a BOOTP configuration, move to the BOUND state, else move to the
453\ REQUESTING state.
454
455: dhcps-selecting ( -- )
456 DHCP_DISCOVER init-dhcp-packet send-dhcp-packet ( )
457 dhcp-timer d# 8000 set-timer ( )
458 ['] receive-dhcp-offer dhcp-max-retries ( xt ntries )
459 dhcp-response-wait 0= if ( )
460 ." No DHCP response after" dhcp-max-retries .d ." tries" cr
461 -1 throw
462 then ( pkt len )
463 process-offer ( )
464 dhcp-timer d# 4000 set-timer ( )
465 begin ( )
466 ['] receive-dhcp-offer (dhcp-response-wait)
467 while ( pkt len )
468 process-offer ( )
469 repeat ( )
470 process-best-offer ( )
471 bootp-config? if DHCPS_BOUND else DHCPS_REQUESTING then dhcp-state !
472;
473
474\ REQUESTING state processing. Broadcast a DHCPREQUEST requesting offered
475\ parameters from one server (and implicitly declining OFFERS from other
476\ servers) and wait for a DHCPACK. On arrival of a DHCPACK, move to the
477\ VERIFYING state to perform a check on the offered IP address.
478\
479\ If a DHCPNAK is received, or there is no response to the DHCPREQUEST
480\ even after 4 retries, restart the initialization process.
481
482: dhcps-requesting ( -- )
483 DHCP_REQUEST init-dhcp-packet send-dhcp-packet ( )
484 dhcp-timer d# 4000 set-timer ( )
485 ['] receive-dhcp-ack/nak 4 dhcp-response-wait if ( pkt len )
486 2dup dhcp-packet-type DHCP_ACK = if ( pkt len )
487 store-dhcp-response ( )
488 DHCPS_VERIFYING dhcp-state ! ( )
489 else ( pkt len )
490 2drop dhcp-restart ( )
491 then ( )
492 else ( )
493 dhcp-restart ( )
494 then ( )
495;
496
497\ VERIFYING state processing. Issue an ARP request for the offered
498\ IP address. If the IP address appears to be in use, send a DHCPDECLINE
499\ message to the server and restart the initialization process; else,
500\ move to the BOUND state.
501
502: dhcps-verifying ( -- )
503 dhcp-offered-ip 1 arp-check if
504 ." IP Address " dhcp-offered-ip .ipaddr ." already in use" cr
505 DHCP_DECLINE init-dhcp-packet send-dhcp-packet
506 dhcp-restart
507 else
508 dhcp-offered-ip my-ip-addr copy-ip-addr
509 DHCPS_BOUND dhcp-state !
510 then
511;
512
513\ BOUND state processing. Extract n/w and boot configuration information
514\ we care about from the DHCP/BOOTP response. We dont deal with IP
515\ address lease times, pushing that responsibility to DHCP modules
516\ in the OS.
517
518: dhcp-set-bootsrv,file ( pkt len -- )
519
520 \ Check if boot server and filename are known.
521 bootfile count is-uri? if 2drop exit then ( pkt len )
522 bootfile count nip if ( pkt len )
523 tftp-server-ip inaddr-any? 0= if 2drop exit then
524 then ( pkt len )
525
526 \ If the package arguments did not specify use of TFTP, and
527 \ the DHCP response provides a (TFTP or HTTP) URI, set the
528 \ bootfile and exit.
529 \
530 \ If the package arguments specifies use of TFTP, and the
531 \ DHCP response provides a TFTP URI, then either the TFTP
532 \ server or the filename is being overridden. Decode the
533 \ URI and set those fields appropriately.
534 \
535 \ Else, if TFTP must be used, but a HTTP URL was provided
536 \ in the DHCP response, ignore the URL specification.
537
538 2dup VS_BOOT_URI find-vendor-option if ( pkt len $ )
539 2dup check-uri$-form ( pkt len $ )
540 tftp-server-ip inaddr-any? bootfile count nip 0= and if ( pkt len $ )
541 bootfile pack drop 2drop exit ( )
542 then ( pkt len $ )
543 2dup is-tftp-uri? if ( pkt len $ )
544 tftp-server-ip inaddr-any? if ( pkt len $ )
545 2dup tftpuri>srv tftp-server-ip inet-aton drop ( pkt len $ )
546 then ( pkt len $ )
547 bootfile count nip 0= if ( pkt len $ )
548 2dup tftpuri>file bootfile pack drop ( pkt len $ )
549 then ( pkt len $ )
550 2drop 2drop exit ( )
551 then 2drop ( pkt len )
552 then ( pkt len )
553
554 \ Extract TFTP boot information from the standard bootfile
555 \ and TFTP server fields.
556
557 bootfile count nip 0= if ( pkt len )
558 2dup CD_BOOTFILE_NAME find-dhcp-option 0= if ( pkt len )
559 over >dhcp-file dup cstrlen ( pkt len $ )
560 then bootfile pack drop ( pkt len )
561 then ( pkt len )
562 tftp-server-ip inaddr-any? if ( pkt len )
563 over >dhcp-siaddr tftp-server-ip copy-ip-addr ( pkt len )
564 then ( pkt len )
565 2drop ( )
566;
567
568: dhcps-bound ( -- )
569 chosen-bootreply /chosen-bootreply ( pkt,len )
570 my-netmask inaddr-any? if ( pkt,len )
571 2dup CD_SUBNETMASK find-dhcp-option if ( pkt,len adr,len )
572 drop my-netmask copy-ip-addr ( pkt,len )
573 then ( pkt,len )
574 then ( pkt,len )
575 router-ip inaddr-any? if ( pkt,len )
576 2dup CD_ROUTER find-dhcp-option if ( pkt,len adr,len )
577 drop router-ip copy-ip-addr ( pkt,len )
578 then ( pkt,len )
579 then ( pkt,len )
580 2dup dhcp-set-bootsrv,file ( pkt,len )
581 http-proxy count nip 0= if ( pkt,len )
582 2dup VS_HTTP_PROXY find-vendor-option if ( pkt,len proxy$ )
583 2dup check-htproxy$-form http-proxy pack drop ( pkt,len )
584 then ( pkt,len )
585 then ( pkt,len )
586 2drop ( )
587 DHCPS_CONFIGURED dhcp-state ! ( )
588;
589
590: "bootp-response" ( -- $ ) " bootp-response" ; \ Space savings
591
592\ CONFIGURED state processing. Publish contents of DHCPACK, if one was
593\ received, in /chosen:bootp-response.
594: dhcps-configured ( -- )
595 chosen-bootreply /chosen-bootreply dup if
596 encode-bytes "bootp-response" set-chosen-property
597 else
598 2drop
599 then
600;
601
602: (do-dhcp) ( -- )
603 DHCPS_INIT dhcp-state !
604 begin
605 dhcp-state @ case
606 DHCPS_INIT of dhcps-init endof
607 DHCPS_INFORM of dhcps-inform endof
608 DHCPS_SELECTING of dhcps-selecting endof
609 DHCPS_REQUESTING of dhcps-requesting endof
610 DHCPS_VERIFYING of dhcps-verifying endof
611 DHCPS_BOUND of dhcps-bound endof
612 DHCPS_CONFIGURED of dhcps-configured exit endof
613 endcase
614 again
615;
616
617: do-dhcp ( -- )
618 dhcp-init ( )
619 ['] (do-dhcp) catch ( throw? )
620 dhcp-close ( throw? )
621 throw ( )
622;
623
624headers