Initial import from FreeBSD RELENG_4:
[games.git] / contrib / isc-dhcp / common / options.c
1 /* options.c
2
3    DHCP options parsing and reassembly. */
4
5 /*
6  * Copyright (c) 1995-2002 Internet Software Consortium.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of The Internet Software Consortium nor the names
19  *    of its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * This software has been written for the Internet Software Consortium
37  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38  * To learn more about the Internet Software Consortium, see
39  * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
40  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
41  * ``http://www.nominum.com''.
42  */
43
44 #ifndef lint
45 static char copyright[] =
46 "$Id: options.c,v 1.85.2.9 2002/11/17 02:26:58 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium.  All rights reserved.\n";
47 #endif /* not lint */
48
49 #define DHCP_OPTION_DATA
50 #include "dhcpd.h"
51 #include <omapip/omapip_p.h>
52
53 struct option *vendor_cfg_option;
54
55 static void do_option_set PROTO ((pair *,
56                                   struct option_cache *,
57                                   enum statement_op));
58
59 /* Parse all available options out of the specified packet. */
60
61 int parse_options (packet)
62         struct packet *packet;
63 {
64         int i;
65         struct option_cache *op = (struct option_cache *)0;
66
67         /* Allocate a new option state. */
68         if (!option_state_allocate (&packet -> options, MDL)) {
69                 packet -> options_valid = 0;
70                 return 0;
71         }
72
73         /* If we don't see the magic cookie, there's nothing to parse. */
74         if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) {
75                 packet -> options_valid = 0;
76                 return 1;
77         }
78
79         /* Go through the options field, up to the end of the packet
80            or the End field. */
81         if (!parse_option_buffer (packet -> options,
82                                   &packet -> raw -> options [4],
83                                   (packet -> packet_length -
84                                    DHCP_FIXED_NON_UDP - 4),
85                                   &dhcp_universe))
86                 return 0;
87
88         /* If we parsed a DHCP Option Overload option, parse more
89            options out of the buffer(s) containing them. */
90         if (packet -> options_valid &&
91             (op = lookup_option (&dhcp_universe, packet -> options,
92                                  DHO_DHCP_OPTION_OVERLOAD))) {
93                 if (op -> data.data [0] & 1) {
94                         if (!parse_option_buffer
95                             (packet -> options,
96                              (unsigned char *)packet -> raw -> file,
97                              sizeof packet -> raw -> file,
98                              &dhcp_universe))
99                                 return 0;
100                 }
101                 if (op -> data.data [0] & 2) {
102                         if (!parse_option_buffer
103                             (packet -> options,
104                              (unsigned char *)packet -> raw -> sname,
105                              sizeof packet -> raw -> sname,
106                              &dhcp_universe))
107                                 return 0;
108                 }
109         }
110         packet -> options_valid = 1;
111         return 1;
112 }
113
114 /* Parse options out of the specified buffer, storing addresses of option
115    values in packet -> options and setting packet -> options_valid if no
116    errors are encountered. */
117
118 int parse_option_buffer (options, buffer, length, universe)
119         struct option_state *options;
120         const unsigned char *buffer;
121         unsigned length;
122         struct universe *universe;
123 {
124         unsigned char *t;
125         const unsigned char *end = buffer + length;
126         unsigned len, offset;
127         int code;
128         struct option_cache *op = (struct option_cache *)0;
129         struct buffer *bp = (struct buffer *)0;
130
131         if (!buffer_allocate (&bp, length, MDL)) {
132                 log_error ("no memory for option buffer.");
133                 return 0;
134         }
135         memcpy (bp -> data, buffer, length);
136         
137         for (offset = 0; buffer [offset] != DHO_END && offset < length; ) {
138                 code = buffer [offset];
139                 /* Pad options don't have a length - just skip them. */
140                 if (code == DHO_PAD) {
141                         ++offset;
142                         continue;
143                 }
144
145                 /* Don't look for length if the buffer isn't that big. */
146                 if (offset + 2 > length) {
147                         len = 65536;
148                         goto bogus;
149                 }
150
151                 /* All other fields (except end, see above) have a
152                    one-byte length. */
153                 len = buffer [offset + 1];
154
155                 /* If the length is outrageous, the options are bad. */
156                 if (offset + len + 2 > length) {
157                       bogus:
158                         log_error ("parse_option_buffer: option %s (%d) %s.",
159                                    dhcp_options [code].name, len,
160                                    "larger than buffer");
161                         buffer_dereference (&bp, MDL);
162                         return 0;
163                 }
164
165                 /* If the option contains an encapsulation, parse it.   If
166                    the parse fails, or the option isn't an encapsulation (by
167                    far the most common case), or the option isn't entirely
168                    an encapsulation, keep the raw data as well. */
169                 if (!((universe -> options [code] -> format [0] == 'e' ||
170                        universe -> options [code] -> format [0] == 'E') &&
171                       (parse_encapsulated_suboptions
172                        (options, universe -> options [code],
173                         buffer + offset + 2, len,
174                         universe, (const char *)0)))) {
175                     save_option_buffer (universe, options, bp,
176                                         &bp -> data [offset + 2], len,
177                                         universe -> options [code], 1);
178                 }
179                 offset += len + 2;
180         }
181         buffer_dereference (&bp, MDL);
182         return 1;
183 }
184
185 /* If an option in an option buffer turns out to be an encapsulation,
186    figure out what to do.   If we don't know how to de-encapsulate it,
187    or it's not well-formed, return zero; otherwise, return 1, indicating
188    that we succeeded in de-encapsulating it. */
189
190 struct universe *find_option_universe (struct option *eopt, const char *uname)
191 {
192         int i;
193         char *s, *t;
194         struct universe *universe = (struct universe *)0;
195
196         /* Look for the E option in the option format. */
197         s = strchr (eopt -> format, 'E');
198         if (!s) {
199                 log_error ("internal encapsulation format error 1.");
200                 return 0;
201         }
202         /* Look for the universe name in the option format. */
203         t = strchr (++s, '.');
204         /* If there was no trailing '.', or there's something after the
205            trailing '.', the option is bogus and we can't use it. */
206         if (!t || t [1]) {
207                 log_error ("internal encapsulation format error 2.");
208                 return 0;
209         }
210         if (t == s && uname) {
211                 for (i = 0; i < universe_count; i++) {
212                         if (!strcmp (universes [i] -> name, uname)) {
213                                 universe = universes [i];
214                                 break;
215                         }
216                 }
217         } else if (t != s) {
218                 for (i = 0; i < universe_count; i++) {
219                         if (strlen (universes [i] -> name) == t - s &&
220                             !memcmp (universes [i] -> name,
221                                      s, (unsigned)(t - s))) {
222                                 universe = universes [i];
223                                 break;
224                         }
225                 }
226         }
227         return universe;
228 }
229
230 /* If an option in an option buffer turns out to be an encapsulation,
231    figure out what to do.   If we don't know how to de-encapsulate it,
232    or it's not well-formed, return zero; otherwise, return 1, indicating
233    that we succeeded in de-encapsulating it. */
234
235 int parse_encapsulated_suboptions (struct option_state *options,
236                                    struct option *eopt,
237                                    const unsigned char *buffer,
238                                    unsigned len, struct universe *eu,
239                                    const char *uname)
240 {
241         int i;
242         struct universe *universe = find_option_universe (eopt, uname);
243
244         /* If we didn't find the universe, we can't do anything with it
245            right now (e.g., we can't decode vendor options until we've
246            decoded the packet and executed the scopes that it matches). */
247         if (!universe)
248                 return 0;
249                 
250         /* If we don't have a decoding function for it, we can't decode
251            it. */
252         if (!universe -> decode)
253                 return 0;
254
255         i = (*universe -> decode) (options, buffer, len, universe);
256
257         /* If there is stuff before the suboptions, we have to keep it. */
258         if (eopt -> format [0] != 'E')
259                 return 0;
260         /* Otherwise, return the status of the decode function. */
261         return i;
262 }
263
264 int fqdn_universe_decode (struct option_state *options,
265                           const unsigned char *buffer,
266                           unsigned length, struct universe *u)
267 {
268         char *name;
269         struct buffer *bp = (struct buffer *)0;
270
271         /* FQDN options have to be at least four bytes long. */
272         if (length < 3)
273                 return 0;
274
275         /* Save the contents of the option in a buffer. */
276         if (!buffer_allocate (&bp, length + 4, MDL)) {
277                 log_error ("no memory for option buffer.");
278                 return 0;
279         }
280         memcpy (&bp -> data [3], buffer + 1, length - 1);
281
282         if (buffer [0] & 4)     /* encoded */
283                 bp -> data [0] = 1;
284         else
285                 bp -> data [0] = 0;
286         if (!save_option_buffer (&fqdn_universe, options, bp,
287                                  &bp -> data [0], 1,
288                                  &fqdn_options [FQDN_ENCODED], 0)) {
289               bad:
290                 buffer_dereference (&bp, MDL);
291                 return 0;
292         }
293
294         if (buffer [0] & 1)     /* server-update */
295                 bp -> data [2] = 1;
296         else
297                 bp -> data [2] = 0;
298         if (buffer [0] & 2)     /* no-client-update */
299                 bp -> data [1] = 1;
300         else
301                 bp -> data [1] = 0;
302
303         /* XXX Ideally we should store the name in DNS format, so if the
304            XXX label isn't in DNS format, we convert it to DNS format,
305            XXX rather than converting labels specified in DNS format to
306            XXX the plain ASCII representation.   But that's hard, so
307            XXX not now. */
308
309         /* Not encoded using DNS format? */
310         if (!bp -> data [0]) {
311                 unsigned i;
312
313                 /* Some broken clients NUL-terminate this option. */
314                 if (buffer [length - 1] == 0) {
315                         --length;
316                         bp -> data [1] = 1;
317                 }
318
319                 /* Determine the length of the hostname component of the
320                    name.  If the name contains no '.' character, it
321                    represents a non-qualified label. */
322                 for (i = 3; i < length && buffer [i] != '.'; i++);
323                 i -= 3;
324
325                 /* Note: If the client sends a FQDN, the first '.' will
326                    be used as a NUL terminator for the hostname. */
327                 if (i)
328                         if (!save_option_buffer (&fqdn_universe, options, bp,
329                                                  &bp -> data[5], i,
330                                                  &fqdn_options [FQDN_HOSTNAME],
331                                                  0))
332                         goto bad;
333                 /* Note: If the client sends a single label, the
334                    FQDN_DOMAINNAME option won't be set. */
335                 if (length > 4 + i &&
336                     !save_option_buffer (&fqdn_universe, options, bp,
337                                          &bp -> data[6 + i], length - 4 - i,
338                                          &fqdn_options [FQDN_DOMAINNAME], 1))
339                         goto bad;
340                 /* Also save the whole name. */
341                 if (length > 3)
342                         if (!save_option_buffer (&fqdn_universe, options, bp,
343                                                  &bp -> data [5], length - 3,
344                                                  &fqdn_options [FQDN_FQDN], 1))
345                                 goto bad;
346         } else {
347                 unsigned len;
348                 unsigned total_len = 0;
349                 unsigned first_len = 0;
350                 int terminated = 0;
351                 unsigned char *s;
352
353                 s = &bp -> data[5];
354
355                 while (s < &bp -> data[0] + length + 2) {
356                         len = *s;
357                         if (len > 63) {
358                                 log_info ("fancy bits in fqdn option");
359                                 return 0;
360                         }       
361                         if (len == 0) {
362                                 terminated = 1;
363                                 break;
364                         }
365                         if (s + len > &bp -> data [0] + length + 3) {
366                                 log_info ("fqdn tag longer than buffer");
367                                 return 0;
368                         }
369
370                         if (first_len == 0) {
371                                 first_len = len;
372                         }
373
374                         *s = '.';
375                         s += len + 1;
376                         total_len += len + 1;
377                 }
378
379                 /* We wind up with a length that's one too many because
380                    we shouldn't increment for the last label, but there's
381                    no way to tell we're at the last label until we exit
382                    the loop.   :'*/
383                 if (total_len > 0)
384                         total_len--;
385
386                 if (!terminated) {
387                         first_len = total_len;
388                 }
389
390                 if (first_len > 0 &&
391                     !save_option_buffer (&fqdn_universe, options, bp,
392                                          &bp -> data[6], first_len,
393                                          &fqdn_options [FQDN_HOSTNAME], 0))
394                         goto bad;
395                 if (total_len > 0 && first_len != total_len) {
396                         if (!save_option_buffer
397                             (&fqdn_universe, options, bp,
398                              &bp -> data[6 + first_len], total_len - first_len,
399                              &fqdn_options [FQDN_DOMAINNAME], 1))
400                                 goto bad;
401                 }
402                 if (total_len > 0)
403                         if (!save_option_buffer (&fqdn_universe, options, bp,
404                                                  &bp -> data [6], total_len,
405                                                  &fqdn_options [FQDN_FQDN], 1))
406                                 goto bad;
407         }
408
409         if (!save_option_buffer (&fqdn_universe, options, bp,
410                                  &bp -> data [1], 1,
411                                  &fqdn_options [FQDN_NO_CLIENT_UPDATE], 0))
412             goto bad;
413         if (!save_option_buffer (&fqdn_universe, options, bp,
414                                  &bp -> data [2], 1,
415                                  &fqdn_options [FQDN_SERVER_UPDATE], 0))
416                 goto bad;
417
418         if (!save_option_buffer (&fqdn_universe, options, bp,
419                                  &bp -> data [3], 1,
420                                  &fqdn_options [FQDN_RCODE1], 0))
421                 goto bad;
422         if (!save_option_buffer (&fqdn_universe, options, bp,
423                                  &bp -> data [4], 1,
424                                  &fqdn_options [FQDN_RCODE2], 0))
425                 goto bad;
426
427         buffer_dereference (&bp, MDL);
428         return 1;
429 }
430
431 /* cons options into a big buffer, and then split them out into the
432    three seperate buffers if needed.  This allows us to cons up a set
433    of vendor options using the same routine. */
434
435 int cons_options (inpacket, outpacket, lease, client_state,
436                   mms, in_options, cfg_options,
437                   scope, overload, terminate, bootpp, prl, vuname)
438         struct packet *inpacket;
439         struct dhcp_packet *outpacket;
440         struct lease *lease;
441         struct client_state *client_state;
442         int mms;
443         struct option_state *in_options;
444         struct option_state *cfg_options;
445         struct binding_scope **scope;
446         int overload;   /* Overload flags that may be set. */
447         int terminate;
448         int bootpp;
449         struct data_string *prl;
450         const char *vuname;
451 {
452 #define PRIORITY_COUNT 300
453         unsigned priority_list [PRIORITY_COUNT];
454         int priority_len;
455         unsigned char buffer [4096];    /* Really big buffer... */
456         unsigned main_buffer_size;
457         unsigned mainbufix, bufix, agentix;
458         unsigned option_size;
459         unsigned length;
460         int i;
461         struct option_cache *op;
462         struct data_string ds;
463         pair pp, *hash;
464         int need_endopt = 0;
465         int have_sso = 0;
466
467         memset (&ds, 0, sizeof ds);
468
469         /* If there's a Maximum Message Size option in the incoming packet
470            and no alternate maximum message size has been specified, take the
471            one in the packet. */
472
473         if (!mms && inpacket &&
474             (op = lookup_option (&dhcp_universe, inpacket -> options,
475                                  DHO_DHCP_MAX_MESSAGE_SIZE))) {
476                 evaluate_option_cache (&ds, inpacket,
477                                        lease, client_state, in_options,
478                                        cfg_options, scope, op, MDL);
479                 if (ds.len >= sizeof (u_int16_t))
480                         mms = getUShort (ds.data);
481                 data_string_forget (&ds, MDL);
482         }
483
484         /* If the client has provided a maximum DHCP message size,
485            use that; otherwise, if it's BOOTP, only 64 bytes; otherwise
486            use up to the minimum IP MTU size (576 bytes). */
487         /* XXX if a BOOTP client specifies a max message size, we will
488            honor it. */
489
490         if (mms) {
491                 main_buffer_size = mms - DHCP_FIXED_LEN;
492
493                 /* Enforce a minimum packet size... */
494                 if (main_buffer_size < (576 - DHCP_FIXED_LEN))
495                         main_buffer_size = 576 - DHCP_FIXED_LEN;
496         } else if (bootpp) {
497                 if (inpacket) {
498                         main_buffer_size =
499                                 inpacket -> packet_length - DHCP_FIXED_LEN;
500                         if (main_buffer_size < 64)
501                                 main_buffer_size = 64;
502                 } else
503                         main_buffer_size = 64;
504         } else
505                 main_buffer_size = 576 - DHCP_FIXED_LEN;
506
507         /* Set a hard limit at the size of the output buffer. */
508         if (main_buffer_size > sizeof buffer)
509                 main_buffer_size = sizeof buffer;
510
511         /* Preload the option priority list with mandatory options. */
512         priority_len = 0;
513         priority_list [priority_len++] = DHO_DHCP_MESSAGE_TYPE;
514         priority_list [priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
515         priority_list [priority_len++] = DHO_DHCP_LEASE_TIME;
516         priority_list [priority_len++] = DHO_DHCP_MESSAGE;
517         priority_list [priority_len++] = DHO_DHCP_REQUESTED_ADDRESS;
518         priority_list [priority_len++] = DHO_FQDN;
519
520         if (prl && prl -> len > 0) {
521                 if ((op = lookup_option (&dhcp_universe, cfg_options,
522                                          DHO_SUBNET_SELECTION))) {
523                         if (priority_len < PRIORITY_COUNT)
524                                 priority_list [priority_len++] =
525                                         DHO_SUBNET_SELECTION;
526                 }
527                             
528                 data_string_truncate (prl, (PRIORITY_COUNT - priority_len));
529
530                 for (i = 0; i < prl -> len; i++) {
531                         /* Prevent client from changing order of delivery
532                            of relay agent information option. */
533                         if (prl -> data [i] != DHO_DHCP_AGENT_OPTIONS)
534                                 priority_list [priority_len++] =
535                                         prl -> data [i];
536                 }
537         } else {
538                 /* First, hardcode some more options that ought to be
539                    sent first... */
540                 priority_list [priority_len++] = DHO_SUBNET_MASK;
541                 priority_list [priority_len++] = DHO_ROUTERS;
542                 priority_list [priority_len++] = DHO_DOMAIN_NAME_SERVERS;
543                 priority_list [priority_len++] = DHO_HOST_NAME;
544
545                 /* Append a list of the standard DHCP options from the
546                    standard DHCP option space.  Actually, if a site
547                    option space hasn't been specified, we wind up
548                    treating the dhcp option space as the site option
549                    space, and the first for loop is skipped, because
550                    it's slightly more general to do it this way,
551                    taking the 1Q99 DHCP futures work into account. */
552                 if (cfg_options -> site_code_min) {
553                     for (i = 0; i < OPTION_HASH_SIZE; i++) {
554                         hash = cfg_options -> universes [dhcp_universe.index];
555                         if (hash) {
556                             for (pp = hash [i]; pp; pp = pp -> cdr) {
557                                 op = (struct option_cache *)(pp -> car);
558                                 if (op -> option -> code <
559                                     cfg_options -> site_code_min &&
560                                     priority_len < PRIORITY_COUNT &&
561                                     (op -> option -> code !=
562                                      DHO_DHCP_AGENT_OPTIONS))
563                                         priority_list [priority_len++] =
564                                                 op -> option -> code;
565                             }
566                         }
567                     }
568                 }
569
570                 /* Now cycle through the site option space, or if there
571                    is no site option space, we'll be cycling through the
572                    dhcp option space. */
573                 for (i = 0; i < OPTION_HASH_SIZE; i++) {
574                     hash = (cfg_options -> universes
575                             [cfg_options -> site_universe]);
576                     if (hash)
577                         for (pp = hash [i]; pp; pp = pp -> cdr) {
578                                 op = (struct option_cache *)(pp -> car);
579                                 if (op -> option -> code >=
580                                     cfg_options -> site_code_min &&
581                                     priority_len < PRIORITY_COUNT &&
582                                     (op -> option -> code !=
583                                      DHO_DHCP_AGENT_OPTIONS))
584                                         priority_list [priority_len++] =
585                                                 op -> option -> code;
586                         }
587                 }
588
589                 /* Now go through all the universes for which options
590                    were set and see if there are encapsulations for
591                    them; if there are, put the encapsulation options
592                    on the priority list as well. */
593                 for (i = 0; i < cfg_options -> universe_count; i++) {
594                     if (cfg_options -> universes [i] &&
595                         universes [i] -> enc_opt &&
596                         priority_len < PRIORITY_COUNT &&
597                         universes [i] -> enc_opt -> universe == &dhcp_universe)
598                     {
599                             if (universes [i] -> enc_opt -> code !=
600                                 DHO_DHCP_AGENT_OPTIONS)
601                                     priority_list [priority_len++] =
602                                             universes [i] -> enc_opt -> code;
603                     }
604                 }
605
606                 /* The vendor option space can't stand on its own, so always
607                    add it to the list. */
608                 if (priority_len < PRIORITY_COUNT)
609                         priority_list [priority_len++] =
610                                 DHO_VENDOR_ENCAPSULATED_OPTIONS;
611         }
612
613         /* Copy the options into the big buffer... */
614         option_size = store_options (buffer,
615                                      (main_buffer_size - 7 +
616                                       ((overload & 1) ? DHCP_FILE_LEN : 0) +
617                                       ((overload & 2) ? DHCP_SNAME_LEN : 0)),
618                                      inpacket, lease, client_state,
619                                      in_options, cfg_options, scope,
620                                      priority_list, priority_len,
621                                      main_buffer_size,
622                                      (main_buffer_size +
623                                       ((overload & 1) ? DHCP_FILE_LEN : 0)),
624                                      terminate, vuname);
625
626         /* Put the cookie up front... */
627         memcpy (outpacket -> options, DHCP_OPTIONS_COOKIE, 4);
628         mainbufix = 4;
629
630         /* If we're going to have to overload, store the overload
631            option at the beginning.  If we can, though, just store the
632            whole thing in the packet's option buffer and leave it at
633            that. */
634         if (option_size <= main_buffer_size - mainbufix) {
635                 memcpy (&outpacket -> options [mainbufix],
636                         buffer, option_size);
637                 mainbufix += option_size;
638                 agentix = mainbufix;
639                 if (mainbufix < main_buffer_size)
640                         need_endopt = 1;
641                 length = DHCP_FIXED_NON_UDP + mainbufix;
642         } else {
643                 outpacket -> options [mainbufix++] = DHO_DHCP_OPTION_OVERLOAD;
644                 outpacket -> options [mainbufix++] = 1;
645                 if (option_size > main_buffer_size - mainbufix + DHCP_FILE_LEN)
646                         outpacket -> options [mainbufix++] = 3;
647                 else
648                         outpacket -> options [mainbufix++] = 1;
649
650                 memcpy (&outpacket -> options [mainbufix],
651                         buffer, main_buffer_size - mainbufix);
652                 length = DHCP_FIXED_NON_UDP + main_buffer_size;
653                 agentix = main_buffer_size;
654
655                 bufix = main_buffer_size - mainbufix;
656                 if (overload & 1) {
657                         if (option_size - bufix <= DHCP_FILE_LEN) {
658                                 memcpy (outpacket -> file,
659                                         &buffer [bufix], option_size - bufix);
660                                 mainbufix = option_size - bufix;
661                                 if (mainbufix < DHCP_FILE_LEN)
662                                         outpacket -> file [mainbufix++]
663                                                 = DHO_END;
664                                 while (mainbufix < DHCP_FILE_LEN)
665                                         outpacket -> file [mainbufix++]
666                                                 = DHO_PAD;
667                         } else {
668                                 memcpy (outpacket -> file,
669                                         &buffer [bufix], DHCP_FILE_LEN);
670                                 bufix += DHCP_FILE_LEN;
671                         }
672                 }
673                 if ((overload & 2) && option_size < bufix) {
674                         memcpy (outpacket -> sname,
675                                 &buffer [bufix], option_size - bufix);
676
677                         mainbufix = option_size - bufix;
678                         if (mainbufix < DHCP_SNAME_LEN)
679                                 outpacket -> file [mainbufix++]
680                                         = DHO_END;
681                         while (mainbufix < DHCP_SNAME_LEN)
682                                 outpacket -> file [mainbufix++]
683                                         = DHO_PAD;
684                 }
685         }
686
687         /* Now hack in the agent options if there are any. */
688         priority_list [0] = DHO_DHCP_AGENT_OPTIONS;
689         priority_len = 1;
690         agentix +=
691                 store_options (&outpacket -> options [agentix],
692                                1500 - DHCP_FIXED_LEN - agentix,
693                                inpacket, lease, client_state,
694                                in_options, cfg_options, scope,
695                                priority_list, priority_len,
696                                1500 - DHCP_FIXED_LEN - agentix,
697                                1500 - DHCP_FIXED_LEN - agentix, 0, (char *)0);
698
699         /* Tack a DHO_END option onto the packet if we need to. */
700         if (agentix < 1500 - DHCP_FIXED_LEN && need_endopt)
701                 outpacket -> options [agentix++] = DHO_END;
702
703         /* Figure out the length. */
704         length = DHCP_FIXED_NON_UDP + agentix;
705         return length;
706 }
707
708 /* Store all the requested options into the requested buffer. */
709
710 int store_options (buffer, buflen, packet, lease, client_state,
711                    in_options, cfg_options, scope, priority_list, priority_len,
712                    first_cutoff, second_cutoff, terminate, vuname)
713         unsigned char *buffer;
714         unsigned buflen;
715         struct packet *packet;
716         struct lease *lease;
717         struct client_state *client_state;
718         struct option_state *in_options;
719         struct option_state *cfg_options;
720         struct binding_scope **scope;
721         unsigned *priority_list;
722         int priority_len;
723         unsigned first_cutoff, second_cutoff;
724         int terminate;
725         const char *vuname;
726 {
727         int bufix = 0;
728         int i;
729         int ix;
730         int tto;
731         struct data_string od;
732         struct option_cache *oc;
733         unsigned code;
734         int optstart;
735
736         memset (&od, 0, sizeof od);
737
738         /* Eliminate duplicate options in the parameter request list.
739            There's got to be some clever knuthian way to do this:
740            Eliminate all but the first occurance of a value in an array
741            of values without otherwise disturbing the order of the array. */
742         for (i = 0; i < priority_len - 1; i++) {
743                 tto = 0;
744                 for (ix = i + 1; ix < priority_len + tto; ix++) {
745                         if (tto)
746                                 priority_list [ix - tto] =
747                                         priority_list [ix];
748                         if (priority_list [i] == priority_list [ix]) {
749                                 tto++;
750                                 priority_len--;
751                         }
752                 }
753         }
754
755         /* Copy out the options in the order that they appear in the
756            priority list... */
757         for (i = 0; i < priority_len; i++) {
758             /* Number of bytes left to store (some may already
759                have been stored by a previous pass). */
760             unsigned length;
761             int optstart;
762             struct universe *u;
763             int have_encapsulation = 0;
764             struct data_string encapsulation;
765
766             memset (&encapsulation, 0, sizeof encapsulation);
767
768             /* Code for next option to try to store. */
769             code = priority_list [i];
770             
771             /* Look up the option in the site option space if the code
772                is above the cutoff, otherwise in the DHCP option space. */
773             if (code >= cfg_options -> site_code_min)
774                     u = universes [cfg_options -> site_universe];
775             else
776                     u = &dhcp_universe;
777
778             oc = lookup_option (u, cfg_options, code);
779
780             /* It's an encapsulation, try to find the universe
781                to be encapsulated first, except that if it's a straight
782                encapsulation and the user has provided a value for the
783                encapsulation option, use the user-provided value. */
784             if (u -> options [code] &&
785                 ((u -> options [code] -> format [0] == 'E' && !oc) ||
786                  u -> options [code] -> format [0] == 'e')) {
787                 int uix;
788                 static char *s, *t;
789                 struct option_cache *tmp;
790                 struct data_string name;
791
792                 s = strchr (u -> options [code] -> format, 'E');
793                 if (s)
794                     t = strchr (++s, '.');
795                 if (s && t) {
796                     memset (&name, 0, sizeof name);
797
798                     /* A zero-length universe name means the vendor
799                        option space, if one is defined. */
800                     if (t == s) {
801                         if (vendor_cfg_option) {
802                             tmp = lookup_option (vendor_cfg_option -> universe,
803                                                  cfg_options,
804                                                  vendor_cfg_option -> code);
805                             if (tmp)
806                                 evaluate_option_cache (&name, packet, lease,
807                                                        client_state,
808                                                        in_options,
809                                                        cfg_options,
810                                                        scope, tmp, MDL);
811                         } else if (vuname) {
812                             name.data = (unsigned char *)s;
813                             name.len = strlen (s);
814                         }
815                     } else {
816                         name.data = (unsigned char *)s;
817                         name.len = t - s;
818                     }
819                         
820                     /* If we found a universe, and there are options configured
821                        for that universe, try to encapsulate it. */
822                     if (name.len) {
823                         have_encapsulation =
824                                 (option_space_encapsulate
825                                  (&encapsulation, packet, lease, client_state,
826                                   in_options, cfg_options, scope, &name));
827                         data_string_forget (&name, MDL);
828                     }
829                 }
830             }
831
832             /* In order to avoid memory leaks, we have to get to here
833                with any option cache that we allocated in tmp not being
834                referenced by tmp, and whatever option cache is referenced
835                by oc being an actual reference.   lookup_option doesn't
836                generate a reference (this needs to be fixed), so the
837                preceding goop ensures that if we *didn't* generate a new
838                option cache, oc still winds up holding an actual reference. */
839
840             /* If no data is available for this option, skip it. */
841             if (!oc && !have_encapsulation) {
842                     continue;
843             }
844             
845             /* Find the value of the option... */
846             if (oc) {
847                 evaluate_option_cache (&od, packet,
848                                        lease, client_state, in_options,
849                                        cfg_options, scope, oc, MDL);
850                 if (!od.len) {
851                     data_string_forget (&encapsulation, MDL);
852                     data_string_forget (&od, MDL);
853                     have_encapsulation = 0;
854                     continue;
855                 }
856             }
857
858             /* We should now have a constant length for the option. */
859             length = od.len;
860             if (have_encapsulation) {
861                     length += encapsulation.len;
862                     if (!od.len) {
863                             data_string_copy (&od, &encapsulation, MDL);
864                             data_string_forget (&encapsulation, MDL);
865                     } else {
866                             struct buffer *bp = (struct buffer *)0;
867                             if (!buffer_allocate (&bp, length, MDL)) {
868                                     option_cache_dereference (&oc, MDL);
869                                     data_string_forget (&od, MDL);
870                                     data_string_forget (&encapsulation, MDL);
871                                     continue;
872                             }
873                             memcpy (&bp -> data [0], od.data, od.len);
874                             memcpy (&bp -> data [od.len], encapsulation.data,
875                                     encapsulation.len);
876                             data_string_forget (&od, MDL);
877                             data_string_forget (&encapsulation, MDL);
878                             od.data = &bp -> data [0];
879                             buffer_reference (&od.buffer, bp, MDL);
880                             buffer_dereference (&bp, MDL);
881                             od.len = length;
882                             od.terminated = 0;
883                     }
884             }
885
886             /* Do we add a NUL? */
887             if (terminate && dhcp_options [code].format [0] == 't') {
888                     length++;
889                     tto = 1;
890             } else {
891                     tto = 0;
892             }
893
894             /* Try to store the option. */
895             
896             /* If the option's length is more than 255, we must store it
897                in multiple hunks.   Store 255-byte hunks first.  However,
898                in any case, if the option data will cross a buffer
899                boundary, split it across that boundary. */
900
901             ix = 0;
902             optstart = bufix;
903             while (length) {
904                     unsigned char incr = length > 255 ? 255 : length;
905                     int consumed = 0;
906                     
907                     /* If this hunk of the buffer will cross a
908                        boundary, only go up to the boundary in this
909                        pass. */
910                     if (bufix < first_cutoff &&
911                         bufix + incr > first_cutoff)
912                             incr = first_cutoff - bufix;
913                     else if (bufix < second_cutoff &&
914                              bufix + incr > second_cutoff)
915                             incr = second_cutoff - bufix;
916                     
917                     /* If this option is going to overflow the buffer,
918                        skip it. */
919                     if (bufix + 2 + incr > buflen) {
920                             bufix = optstart;
921                             break;
922                     }
923                     
924                     /* Everything looks good - copy it in! */
925                     buffer [bufix] = code;
926                     buffer [bufix + 1] = incr;
927                     if (tto && incr == length) {
928                             memcpy (buffer + bufix + 2,
929                                     od.data + ix, (unsigned)(incr - 1));
930                             buffer [bufix + 2 + incr - 1] = 0;
931                     } else {
932                             memcpy (buffer + bufix + 2,
933                                     od.data + ix, (unsigned)incr);
934                     }
935                     length -= incr;
936                     ix += incr;
937                     bufix += 2 + incr;
938             }
939             data_string_forget (&od, MDL);
940         }
941
942         return bufix;
943 }
944
945 /* Format the specified option so that a human can easily read it. */
946
947 const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
948         struct option *option;
949         const unsigned char *data;
950         unsigned len;
951         int emit_commas;
952         int emit_quotes;
953 {
954         static char optbuf [32768]; /* XXX */
955         int hunksize = 0;
956         int opthunk = 0;
957         int hunkinc = 0;
958         int numhunk = -1;
959         int numelem = 0;
960         char fmtbuf [32];
961         struct enumeration *enumbuf [32];
962         int i, j, k, l;
963         char *op = optbuf;
964         const unsigned char *dp = data;
965         struct in_addr foo;
966         char comma;
967         unsigned long tval;
968
969         if (emit_commas)
970                 comma = ',';
971         else
972                 comma = ' ';
973         
974         memset (enumbuf, 0, sizeof enumbuf);
975
976         /* Figure out the size of the data. */
977         for (l = i = 0; option -> format [i]; i++, l++) {
978                 if (!numhunk) {
979                         log_error ("%s: Extra codes in format string: %s",
980                                    option -> name,
981                                    &(option -> format [i]));
982                         break;
983                 }
984                 numelem++;
985                 fmtbuf [l] = option -> format [i];
986                 switch (option -> format [i]) {
987                       case 'a':
988                         --numelem;
989                         fmtbuf [l] = 0;
990                         numhunk = 0;
991                         break;
992                       case 'A':
993                         --numelem;
994                         fmtbuf [l] = 0;
995                         numhunk = 0;
996                         break;
997                       case 'E':
998                         /* Skip the universe name. */
999                         while (option -> format [i] &&
1000                                option -> format [i] != '.')
1001                                 i++;
1002                       case 'X':
1003                         for (k = 0; k < len; k++) {
1004                                 if (!isascii (data [k]) ||
1005                                     !isprint (data [k]))
1006                                         break;
1007                         }
1008                         /* If we found no bogus characters, or the bogus
1009                            character we found is a trailing NUL, it's
1010                            okay to print this option as text. */
1011                         if (k == len || (k + 1 == len && data [k] == 0)) {
1012                                 fmtbuf [l] = 't';
1013                                 numhunk = -2;
1014                         } else {
1015                                 fmtbuf [l] = 'x';
1016                                 hunksize++;
1017                                 comma = ':';
1018                                 numhunk = 0;
1019                         }
1020                         fmtbuf [l + 1] = 0;
1021                         break;
1022                       case 'd':
1023                       case 't':
1024                         fmtbuf [l] = 't';
1025                         fmtbuf [l + 1] = 0;
1026                         numhunk = -2;
1027                         break;
1028                       case 'N':
1029                         k = i;
1030                         while (option -> format [i] &&
1031                                option -> format [i] != '.')
1032                                 i++;
1033                         enumbuf [l] =
1034                                 find_enumeration (&option -> format [k] + 1,
1035                                                   i - k - 1);
1036                         hunksize += 1;
1037                         hunkinc = 1;
1038                         break;
1039                       case 'I':
1040                       case 'l':
1041                       case 'L':
1042                       case 'T':
1043                         hunksize += 4;
1044                         hunkinc = 4;
1045                         break;
1046                       case 's':
1047                       case 'S':
1048                         hunksize += 2;
1049                         hunkinc = 2;
1050                         break;
1051                       case 'b':
1052                       case 'B':
1053                       case 'f':
1054                         hunksize++;
1055                         hunkinc = 1;
1056                         break;
1057                       case 'e':
1058                         break;
1059                       case 'o':
1060                         opthunk += hunkinc;
1061                         break;
1062                       default:
1063                         log_error ("%s: garbage in format string: %s",
1064                               option -> name,
1065                               &(option -> format [i]));
1066                         break;
1067                 } 
1068         }
1069
1070         /* Check for too few bytes... */
1071         if (hunksize - opthunk > len) {
1072                 log_error ("%s: expecting at least %d bytes; got %d",
1073                       option -> name,
1074                       hunksize, len);
1075                 return "<error>";
1076         }
1077         /* Check for too many bytes... */
1078         if (numhunk == -1 && hunksize < len)
1079                 log_error ("%s: %d extra bytes",
1080                       option -> name,
1081                       len - hunksize);
1082
1083         /* If this is an array, compute its size. */
1084         if (!numhunk)
1085                 numhunk = len / hunksize;
1086         /* See if we got an exact number of hunks. */
1087         if (numhunk > 0 && numhunk * hunksize < len)
1088                 log_error ("%s: %d extra bytes at end of array\n",
1089                       option -> name,
1090                       len - numhunk * hunksize);
1091
1092         /* A one-hunk array prints the same as a single hunk. */
1093         if (numhunk < 0)
1094                 numhunk = 1;
1095
1096         /* Cycle through the array (or hunk) printing the data. */
1097         for (i = 0; i < numhunk; i++) {
1098                 for (j = 0; j < numelem; j++) {
1099                         switch (fmtbuf [j]) {
1100                               case 't':
1101                                 if (emit_quotes)
1102                                         *op++ = '"';
1103                                 for (; dp < data + len; dp++) {
1104                                         if (!isascii (*dp) ||
1105                                             !isprint (*dp)) {
1106                                                 /* Skip trailing NUL. */
1107                                             if (dp + 1 != data + len ||
1108                                                 *dp != 0) {
1109                                                     sprintf (op, "\\%03o",
1110                                                              *dp);
1111                                                     op += 4;
1112                                             }
1113                                         } else if (*dp == '"' ||
1114                                                    *dp == '\'' ||
1115                                                    *dp == '$' ||
1116                                                    *dp == '`' ||
1117                                                    *dp == '\\') {
1118                                                 *op++ = '\\';
1119                                                 *op++ = *dp;
1120                                         } else
1121                                                 *op++ = *dp;
1122                                 }
1123                                 if (emit_quotes)
1124                                         *op++ = '"';
1125                                 *op = 0;
1126                                 break;
1127                                 /* pretty-printing an array of enums is
1128                                    going to get ugly. */
1129                               case 'N':
1130                                 if (!enumbuf [j])
1131                                         goto enum_as_num;
1132                                 for (i = 0; ;i++) {
1133                                         if (!enumbuf [j] -> values [i].name)
1134                                                 goto enum_as_num;
1135                                         if (enumbuf [j] -> values [i].value ==
1136                                             *dp)
1137                                                 break;
1138                                 }
1139                                 strcpy (op, enumbuf [j] -> values [i].name);
1140                                 op += strlen (op);
1141                                 break;
1142                               case 'I':
1143                                 foo.s_addr = htonl (getULong (dp));
1144                                 strcpy (op, inet_ntoa (foo));
1145                                 dp += 4;
1146                                 break;
1147                               case 'l':
1148                                 sprintf (op, "%ld", (long)getLong (dp));
1149                                 dp += 4;
1150                                 break;
1151                               case 'T':
1152                                 tval = getULong (dp);
1153                                 if (tval == -1)
1154                                         sprintf (op, "%s", "infinite");
1155                                 else
1156                                         sprintf (op, "%ld", tval);
1157                                 break;
1158                               case 'L':
1159                                 sprintf (op, "%ld",
1160                                          (unsigned long)getULong (dp));
1161                                 dp += 4;
1162                                 break;
1163                               case 's':
1164                                 sprintf (op, "%d", (int)getShort (dp));
1165                                 dp += 2;
1166                                 break;
1167                               case 'S':
1168                                 sprintf (op, "%d", (unsigned)getUShort (dp));
1169                                 dp += 2;
1170                                 break;
1171                               case 'b':
1172                                 sprintf (op, "%d", *(const char *)dp++);
1173                                 break;
1174                               case 'B':
1175                               enum_as_num:
1176                                 sprintf (op, "%d", *dp++);
1177                                 break;
1178                               case 'x':
1179                                 sprintf (op, "%x", *dp++);
1180                                 break;
1181                               case 'f':
1182                                 strcpy (op, *dp++ ? "true" : "false");
1183                                 break;
1184                               default:
1185                                 log_error ("Unexpected format code %c",
1186                                            fmtbuf [j]);
1187                         }
1188                         op += strlen (op);
1189                         if (dp == data + len)
1190                                 break;
1191                         if (j + 1 < numelem && comma != ':')
1192                                 *op++ = ' ';
1193                 }
1194                 if (i + 1 < numhunk) {
1195                         *op++ = comma;
1196                 }
1197                 if (dp == data + len)
1198                         break;
1199         }
1200         return optbuf;
1201 }
1202
1203 int get_option (result, universe, packet, lease, client_state,
1204                 in_options, cfg_options, options, scope, code, file, line)
1205         struct data_string *result;
1206         struct universe *universe;
1207         struct packet *packet;
1208         struct lease *lease;
1209         struct client_state *client_state;
1210         struct option_state *in_options;
1211         struct option_state *cfg_options;
1212         struct option_state *options;
1213         struct binding_scope **scope;
1214         unsigned code;
1215         const char *file;
1216         int line;
1217 {
1218         struct option_cache *oc;
1219
1220         if (!universe -> lookup_func)
1221                 return 0;
1222         oc = ((*universe -> lookup_func) (universe, options, code));
1223         if (!oc)
1224                 return 0;
1225         if (!evaluate_option_cache (result, packet, lease, client_state,
1226                                     in_options, cfg_options, scope, oc,
1227                                     file, line))
1228                 return 0;
1229         return 1;
1230 }
1231
1232 void set_option (universe, options, option, op)
1233         struct universe *universe;
1234         struct option_state *options;
1235         struct option_cache *option;
1236         enum statement_op op;
1237 {
1238         struct option_cache *oc, *noc;
1239
1240         switch (op) {
1241               case if_statement:
1242               case add_statement:
1243               case eval_statement:
1244               case break_statement:
1245               default:
1246                 log_error ("bogus statement type in do_option_set.");
1247                 break;
1248
1249               case default_option_statement:
1250                 oc = lookup_option (universe, options,
1251                                     option -> option -> code);
1252                 if (oc)
1253                         break;
1254                 save_option (universe, options, option);
1255                 break;
1256
1257               case supersede_option_statement:
1258               case send_option_statement:
1259                 /* Install the option, replacing any existing version. */
1260                 save_option (universe, options, option);
1261                 break;
1262
1263               case append_option_statement:
1264               case prepend_option_statement:
1265                 oc = lookup_option (universe, options,
1266                                     option -> option -> code);
1267                 if (!oc) {
1268                         save_option (universe, options, option);
1269                         break;
1270                 }
1271                 /* If it's not an expression, make it into one. */
1272                 if (!oc -> expression && oc -> data.len) {
1273                         if (!expression_allocate (&oc -> expression, MDL)) {
1274                                 log_error ("Can't allocate const expression.");
1275                                 break;
1276                         }
1277                         oc -> expression -> op = expr_const_data;
1278                         data_string_copy
1279                                 (&oc -> expression -> data.const_data,
1280                                  &oc -> data, MDL);
1281                         data_string_forget (&oc -> data, MDL);
1282                 }
1283                 noc = (struct option_cache *)0;
1284                 if (!option_cache_allocate (&noc, MDL))
1285                         break;
1286                 if (op == append_option_statement) {
1287                         if (!make_concat (&noc -> expression,
1288                                           oc -> expression,
1289                                           option -> expression)) {
1290                                 option_cache_dereference (&noc, MDL);
1291                                 break;
1292                         }
1293                 } else {
1294                         if (!make_concat (&noc -> expression,
1295                                           option -> expression,
1296                                           oc -> expression)) {
1297                                 option_cache_dereference (&noc, MDL);
1298                                 break;
1299                         }
1300                 }
1301                 noc -> option = oc -> option;
1302                 save_option (universe, options, noc);
1303                 option_cache_dereference (&noc, MDL);
1304                 break;
1305         }
1306 }
1307
1308 struct option_cache *lookup_option (universe, options, code)
1309         struct universe *universe;
1310         struct option_state *options;
1311         unsigned code;
1312 {
1313         if (!options)
1314                 return (struct option_cache *)0;
1315         if (universe -> lookup_func)
1316                 return (*universe -> lookup_func) (universe, options, code);
1317         else
1318                 log_error ("can't look up options in %s space.",
1319                            universe -> name);
1320         return (struct option_cache *)0;
1321 }
1322
1323 struct option_cache *lookup_hashed_option (universe, options, code)
1324         struct universe *universe;
1325         struct option_state *options;
1326         unsigned code;
1327 {
1328         int hashix;
1329         pair bptr;
1330         pair *hash;
1331
1332         /* Make sure there's a hash table. */
1333         if (universe -> index >= options -> universe_count ||
1334             !(options -> universes [universe -> index]))
1335                 return (struct option_cache *)0;
1336
1337         hash = options -> universes [universe -> index];
1338
1339         hashix = compute_option_hash (code);
1340         for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
1341                 if (((struct option_cache *)(bptr -> car)) -> option -> code ==
1342                     code)
1343                         return (struct option_cache *)(bptr -> car);
1344         }
1345         return (struct option_cache *)0;
1346 }
1347
1348 int save_option_buffer (struct universe *universe,
1349                         struct option_state *options,
1350                         struct buffer *bp,
1351                         unsigned char *buffer, unsigned length,
1352                         struct option *option, int tp)
1353 {
1354         struct buffer *lbp = (struct buffer *)0;
1355         struct option_cache *op = (struct option_cache *)0;
1356
1357         if (!option_cache_allocate (&op, MDL)) {
1358                 log_error ("No memory for option %s.%s.",
1359                            universe -> name,
1360                            option -> name);
1361                 return 0;
1362         }
1363
1364         /* If we weren't passed a buffer in which the data are saved and
1365            refcounted, allocate one now. */
1366         if (!bp) {
1367                 if (!buffer_allocate (&lbp, length, MDL)) {
1368                         log_error ("no memory for option buffer.");
1369
1370                         option_cache_dereference (&op, MDL);
1371                         return 0;
1372                 }
1373                 memcpy (lbp -> data, buffer, length + tp);
1374                 bp = lbp;
1375                 buffer = &bp -> data [0]; /* Refer to saved buffer. */
1376         }
1377
1378         /* Reference buffer copy to option cache. */
1379         op -> data.buffer = (struct buffer *)0;
1380         buffer_reference (&op -> data.buffer, bp, MDL);
1381                 
1382         /* Point option cache into buffer. */
1383         op -> data.data = buffer;
1384         op -> data.len = length;
1385                         
1386         if (tp) {
1387                 /* NUL terminate (we can get away with this because we (or
1388                    the caller!) allocated one more than the buffer size, and
1389                    because the byte following the end of an option is always
1390                    the code of the next option, which the caller is getting
1391                    out of the *original* buffer. */
1392                 buffer [length] = 0;
1393                 op -> data.terminated = 1;
1394         } else
1395                 op -> data.terminated = 0;
1396         
1397         op -> option = option;
1398
1399         /* Now store the option. */
1400         save_option (universe, options, op);
1401
1402         /* And let go of our reference. */
1403         option_cache_dereference (&op, MDL);
1404
1405         return 1;
1406 }
1407
1408 void save_option (struct universe *universe,
1409                   struct option_state *options, struct option_cache *oc)
1410 {
1411         if (universe -> save_func)
1412                 (*universe -> save_func) (universe, options, oc);
1413         else
1414                 log_error ("can't store options in %s space.",
1415                            universe -> name);
1416 }
1417
1418 void save_hashed_option (universe, options, oc)
1419         struct universe *universe;
1420         struct option_state *options;
1421         struct option_cache *oc;
1422 {
1423         int hashix;
1424         pair bptr;
1425         pair *hash = options -> universes [universe -> index];
1426
1427         if (oc -> refcnt == 0)
1428                 abort ();
1429
1430         /* Compute the hash. */
1431         hashix = compute_option_hash (oc -> option -> code);
1432
1433         /* If there's no hash table, make one. */
1434         if (!hash) {
1435                 hash = (pair *)dmalloc (OPTION_HASH_SIZE * sizeof *hash, MDL);
1436                 if (!hash) {
1437                         log_error ("no memory to store %s.%s",
1438                                    universe -> name, oc -> option -> name);
1439                         return;
1440                 }
1441                 memset (hash, 0, OPTION_HASH_SIZE * sizeof *hash);
1442                 options -> universes [universe -> index] = (VOIDPTR)hash;
1443         } else {
1444                 /* Try to find an existing option matching the new one. */
1445                 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
1446                         if (((struct option_cache *)
1447                              (bptr -> car)) -> option -> code ==
1448                             oc -> option -> code)
1449                                 break;
1450                 }
1451
1452                 /* If we find one, dereference it and put the new one
1453                    in its place. */
1454                 if (bptr) {
1455                         option_cache_dereference
1456                                 ((struct option_cache **)&bptr -> car, MDL);
1457                         option_cache_reference
1458                                 ((struct option_cache **)&bptr -> car,
1459                                  oc, MDL);
1460                         return;
1461                 }
1462         }
1463
1464         /* Otherwise, just put the new one at the head of the list. */
1465         bptr = new_pair (MDL);
1466         if (!bptr) {
1467                 log_error ("No memory for option_cache reference.");
1468                 return;
1469         }
1470         bptr -> cdr = hash [hashix];
1471         bptr -> car = 0;
1472         option_cache_reference ((struct option_cache **)&bptr -> car, oc, MDL);
1473         hash [hashix] = bptr;
1474 }
1475
1476 void delete_option (universe, options, code)
1477         struct universe *universe;
1478         struct option_state *options;
1479         int code;
1480 {
1481         if (universe -> delete_func)
1482                 (*universe -> delete_func) (universe, options, code);
1483         else
1484                 log_error ("can't delete options from %s space.",
1485                            universe -> name);
1486 }
1487
1488 void delete_hashed_option (universe, options, code)
1489         struct universe *universe;
1490         struct option_state *options;
1491         int code;
1492 {
1493         int hashix;
1494         pair bptr, prev = (pair)0;
1495         pair *hash = options -> universes [universe -> index];
1496
1497         /* There may not be any options in this space. */
1498         if (!hash)
1499                 return;
1500
1501         /* Try to find an existing option matching the new one. */
1502         hashix = compute_option_hash (code);
1503         for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
1504                 if (((struct option_cache *)(bptr -> car)) -> option -> code
1505                     == code)
1506                         break;
1507                 prev = bptr;
1508         }
1509         /* If we found one, wipe it out... */
1510         if (bptr) {
1511                 if (prev)
1512                         prev -> cdr = bptr -> cdr;
1513                 else
1514                         hash [hashix] = bptr -> cdr;
1515                 option_cache_dereference
1516                         ((struct option_cache **)(&bptr -> car), MDL);
1517                 free_pair (bptr, MDL);
1518         }
1519 }
1520
1521 extern struct option_cache *free_option_caches; /* XXX */
1522
1523 int option_cache_dereference (ptr, file, line)
1524         struct option_cache **ptr;
1525         const char *file;
1526         int line;
1527 {
1528         if (!ptr || !*ptr) {
1529                 log_error ("Null pointer in option_cache_dereference: %s(%d)",
1530                            file, line);
1531 #if defined (POINTER_DEBUG)
1532                 abort ();
1533 #else
1534                 return 0;
1535 #endif
1536         }
1537
1538         (*ptr) -> refcnt--;
1539         rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
1540         if (!(*ptr) -> refcnt) {
1541                 if ((*ptr) -> data.buffer)
1542                         data_string_forget (&(*ptr) -> data, file, line);
1543                 if ((*ptr) -> expression)
1544                         expression_dereference (&(*ptr) -> expression,
1545                                                 file, line);
1546                 if ((*ptr) -> next)
1547                         option_cache_dereference (&((*ptr) -> next),
1548                                                   file, line);
1549                 /* Put it back on the free list... */
1550                 (*ptr) -> expression = (struct expression *)free_option_caches;
1551                 free_option_caches = *ptr;
1552                 dmalloc_reuse (free_option_caches, (char *)0, 0, 0);
1553         }
1554         if ((*ptr) -> refcnt < 0) {
1555                 log_error ("%s(%d): negative refcnt!", file, line);
1556 #if defined (DEBUG_RC_HISTORY)
1557                 dump_rc_history (*ptr);
1558 #endif
1559 #if defined (POINTER_DEBUG)
1560                 abort ();
1561 #else
1562                 *ptr = (struct option_cache *)0;
1563                 return 0;
1564 #endif
1565         }
1566         *ptr = (struct option_cache *)0;
1567         return 1;
1568
1569 }
1570
1571 int hashed_option_state_dereference (universe, state, file, line)
1572         struct universe *universe;
1573         struct option_state *state;
1574         const char *file;
1575         int line;
1576 {
1577         pair *heads;
1578         pair cp, next;
1579         int i;
1580
1581         /* Get the pointer to the array of hash table bucket heads. */
1582         heads = (pair *)(state -> universes [universe -> index]);
1583         if (!heads)
1584                 return 0;
1585
1586         /* For each non-null head, loop through all the buckets dereferencing
1587            the attached option cache structures and freeing the buckets. */
1588         for (i = 0; i < OPTION_HASH_SIZE; i++) {
1589                 for (cp = heads [i]; cp; cp = next) {
1590                         next = cp -> cdr;
1591                         option_cache_dereference
1592                                 ((struct option_cache **)&cp -> car,
1593                                  file, line);
1594                         free_pair (cp, file, line);
1595                 }
1596         }
1597
1598         dfree (heads, file, line);
1599         state -> universes [universe -> index] = (void *)0;
1600         return 1;
1601 }
1602
1603 int store_option (result, universe, packet, lease, client_state,
1604                   in_options, cfg_options, scope, oc)
1605         struct data_string *result;
1606         struct universe *universe;
1607         struct packet *packet;
1608         struct lease *lease;
1609         struct client_state *client_state;
1610         struct option_state *in_options;
1611         struct option_state *cfg_options;
1612         struct binding_scope **scope;
1613         struct option_cache *oc;
1614 {
1615         struct data_string d1, d2;
1616
1617         memset (&d1, 0, sizeof d1);
1618         memset (&d2, 0, sizeof d2);
1619
1620         if (evaluate_option_cache (&d2, packet, lease, client_state,
1621                                    in_options, cfg_options, scope, oc, MDL)) {
1622                 if (!buffer_allocate (&d1.buffer,
1623                                       (result -> len +
1624                                        universe -> length_size +
1625                                        universe -> tag_size + d2.len), MDL)) {
1626                         data_string_forget (result, MDL);
1627                         data_string_forget (&d2, MDL);
1628                         return 0;
1629                 }
1630                 d1.data = &d1.buffer -> data [0];
1631                 if (result -> len)
1632                         memcpy (d1.buffer -> data,
1633                                 result -> data, result -> len);
1634                 d1.len = result -> len;
1635                 (*universe -> store_tag) (&d1.buffer -> data [d1.len],
1636                                           oc -> option -> code);
1637                 d1.len += universe -> tag_size;
1638                 (*universe -> store_length) (&d1.buffer -> data [d1.len],
1639                                              d2.len);
1640                 d1.len += universe -> length_size;
1641                 memcpy (&d1.buffer -> data [d1.len], d2.data, d2.len);
1642                 d1.len += d2.len;
1643                 data_string_forget (&d2, MDL);
1644                 data_string_forget (result, MDL);
1645                 data_string_copy (result, &d1, MDL);
1646                 data_string_forget (&d1, MDL);
1647                 return 1;
1648         }
1649         return 0;
1650 }
1651         
1652 int option_space_encapsulate (result, packet, lease, client_state,
1653                               in_options, cfg_options, scope, name)
1654         struct data_string *result;
1655         struct packet *packet;
1656         struct lease *lease;
1657         struct client_state *client_state;
1658         struct option_state *in_options;
1659         struct option_state *cfg_options;
1660         struct binding_scope **scope;
1661         struct data_string *name;
1662 {
1663         struct universe *u;
1664
1665         u = (struct universe *)0;
1666         universe_hash_lookup (&u, universe_hash,
1667                               (const char *)name -> data, name -> len, MDL);
1668         if (!u)
1669                 return 0;
1670
1671         if (u -> encapsulate)
1672                 return (*u -> encapsulate) (result, packet, lease,
1673                                             client_state,
1674                                             in_options, cfg_options, scope, u);
1675         log_error ("encapsulation requested for %s with no support.",
1676                    name -> data);
1677         return 0;
1678 }
1679
1680 int hashed_option_space_encapsulate (result, packet, lease, client_state,
1681                                      in_options, cfg_options, scope, universe)
1682         struct data_string *result;
1683         struct packet *packet;
1684         struct lease *lease;
1685         struct client_state *client_state;
1686         struct option_state *in_options;
1687         struct option_state *cfg_options;
1688         struct binding_scope **scope;
1689         struct universe *universe;
1690 {
1691         pair p, *hash;
1692         int status;
1693         int i;
1694
1695         if (universe -> index >= cfg_options -> universe_count)
1696                 return 0;
1697
1698         hash = cfg_options -> universes [universe -> index];
1699         if (!hash)
1700                 return 0;
1701
1702         status = 0;
1703         for (i = 0; i < OPTION_HASH_SIZE; i++) {
1704                 for (p = hash [i]; p; p = p -> cdr) {
1705                         if (store_option (result, universe, packet,
1706                                           lease, client_state, in_options,
1707                                           cfg_options, scope,
1708                                           (struct option_cache *)p -> car))
1709                                 status = 1;
1710                 }
1711         }
1712
1713         return status;
1714 }
1715
1716 int nwip_option_space_encapsulate (result, packet, lease, client_state,
1717                                    in_options, cfg_options, scope, universe)
1718         struct data_string *result;
1719         struct packet *packet;
1720         struct lease *lease;
1721         struct client_state *client_state;
1722         struct option_state *in_options;
1723         struct option_state *cfg_options;
1724         struct binding_scope **scope;
1725         struct universe *universe;
1726 {
1727         pair ocp;
1728         int status;
1729         int i;
1730         static struct option_cache *no_nwip;
1731         struct data_string ds;
1732         struct option_chain_head *head;
1733
1734         if (universe -> index >= cfg_options -> universe_count)
1735                 return 0;
1736         head = ((struct option_chain_head *)
1737                 cfg_options -> universes [fqdn_universe.index]);
1738         if (!head)
1739                 return 0;
1740
1741         status = 0;
1742         for (ocp = head -> first; ocp; ocp = ocp -> cdr) {
1743                 struct option_cache *oc = (struct option_cache *)(ocp -> car);
1744                 if (store_option (result, universe, packet,
1745                                   lease, client_state, in_options,
1746                                   cfg_options, scope,
1747                                   (struct option_cache *)ocp -> car))
1748                         status = 1;
1749         }
1750
1751         /* If there's no data, the nwip suboption is supposed to contain
1752            a suboption saying there's no data. */
1753         if (!status) {
1754                 if (!no_nwip) {
1755                         static unsigned char nni [] = { 1, 0 };
1756                         memset (&ds, 0, sizeof ds);
1757                         ds.data = nni;
1758                         ds.len = 2;
1759                         if (option_cache_allocate (&no_nwip, MDL))
1760                                 data_string_copy (&no_nwip -> data, &ds, MDL);
1761                         no_nwip -> option = nwip_universe.options [1];
1762                 }
1763                 if (no_nwip) {
1764                         if (store_option (result, universe, packet, lease,
1765                                           client_state, in_options,
1766                                           cfg_options, scope, no_nwip))
1767                                 status = 1;
1768                 }
1769         } else {
1770                 memset (&ds, 0, sizeof ds);
1771
1772                 /* If we have nwip options, the first one has to be the
1773                    nwip-exists-in-option-area option. */
1774                 if (!buffer_allocate (&ds.buffer, result -> len + 2, MDL)) {
1775                         data_string_forget (result, MDL);
1776                         return 0;
1777                 }
1778                 ds.data = &ds.buffer -> data [0];
1779                 ds.buffer -> data [0] = 2;
1780                 ds.buffer -> data [1] = 0;
1781                 memcpy (&ds.buffer -> data [2], result -> data, result -> len);
1782                 data_string_forget (result, MDL);
1783                 data_string_copy (result, &ds, MDL);
1784                 data_string_forget (&ds, MDL);
1785         }
1786
1787         return status;
1788 }
1789
1790 int fqdn_option_space_encapsulate (result, packet, lease, client_state,
1791                                    in_options, cfg_options, scope, universe)
1792         struct data_string *result;
1793         struct packet *packet;
1794         struct lease *lease;
1795         struct client_state *client_state;
1796         struct option_state *in_options;
1797         struct option_state *cfg_options;
1798         struct binding_scope **scope;
1799         struct universe *universe;
1800 {
1801         pair ocp;
1802         struct data_string results [FQDN_SUBOPTION_COUNT + 1];
1803         unsigned i;
1804         unsigned len;
1805         struct buffer *bp = (struct buffer *)0;
1806         struct option_chain_head *head;
1807
1808         /* If there's no FQDN universe, don't encapsulate. */
1809         if (fqdn_universe.index >= cfg_options -> universe_count)
1810                 return 0;
1811         head = ((struct option_chain_head *)
1812                 cfg_options -> universes [fqdn_universe.index]);
1813         if (!head)
1814                 return 0;
1815
1816         /* Figure out the values of all the suboptions. */
1817         memset (results, 0, sizeof results);
1818         for (ocp = head -> first; ocp; ocp = ocp -> cdr) {
1819                 struct option_cache *oc = (struct option_cache *)(ocp -> car);
1820                 if (oc -> option -> code > FQDN_SUBOPTION_COUNT)
1821                         continue;
1822                 evaluate_option_cache (&results [oc -> option -> code],
1823                                        packet, lease, client_state, in_options,
1824                                        cfg_options, scope,  oc, MDL);
1825         }
1826         len = 4 + results [FQDN_FQDN].len;
1827         /* Save the contents of the option in a buffer. */
1828         if (!buffer_allocate (&bp, len, MDL)) {
1829                 log_error ("no memory for option buffer.");
1830                 return 0;
1831         }
1832         buffer_reference (&result -> buffer, bp, MDL);
1833         result -> len = 3;
1834         result -> data = &bp -> data [0];
1835
1836         memset (&bp -> data [0], 0, len);
1837         if (results [FQDN_NO_CLIENT_UPDATE].len &&
1838             results [FQDN_NO_CLIENT_UPDATE].data [0])
1839                 bp -> data [0] |= 2;
1840         if (results [FQDN_SERVER_UPDATE].len &&
1841             results [FQDN_SERVER_UPDATE].data [0])
1842                 bp -> data [0] |= 1;
1843         if (results [FQDN_RCODE1].len)
1844                 bp -> data [1] = results [FQDN_RCODE1].data [0];
1845         if (results [FQDN_RCODE2].len)
1846                 bp -> data [2] = results [FQDN_RCODE2].data [0];
1847
1848         if (results [FQDN_ENCODED].len &&
1849             results [FQDN_ENCODED].data [0]) {
1850                 unsigned char *out;
1851                 int i;
1852                 bp -> data [0] |= 4;
1853                 out = &bp -> data [3];
1854                 if (results [FQDN_FQDN].len) {
1855                         i = 0;
1856                         while (i < results [FQDN_FQDN].len) {
1857                                 int j;
1858                                 for (j = i; ('.' !=
1859                                              results [FQDN_FQDN].data [j]) &&
1860                                              j < results [FQDN_FQDN].len; j++)
1861                                         ;
1862                                 *out++ = j - i;
1863                                 memcpy (out, &results [FQDN_FQDN].data [i],
1864                                         (unsigned)(j - i));
1865                                 out += j - i;
1866                                 i = j;
1867                                 if (results [FQDN_FQDN].data [j] == '.')
1868                                         i++;
1869                         }
1870                         if ((results [FQDN_FQDN].data
1871                              [results [FQDN_FQDN].len - 1] == '.'))
1872                                 *out++ = 0;
1873                         result -> len = out - result -> data;
1874                         result -> terminated = 0;
1875                 }
1876         } else {
1877                 if (results [FQDN_FQDN].len) {
1878                         memcpy (&bp -> data [3], results [FQDN_FQDN].data,
1879                                 results [FQDN_FQDN].len);
1880                         result -> len += results [FQDN_FQDN].len;
1881                         result -> terminated = 0;
1882                 }
1883         }
1884         for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) {
1885                 if (results [i].len)
1886                         data_string_forget (&results [i], MDL);
1887         }
1888         buffer_dereference (&bp, MDL);
1889         return 1;
1890 }
1891
1892 void option_space_foreach (struct packet *packet, struct lease *lease,
1893                            struct client_state *client_state,
1894                            struct option_state *in_options,
1895                            struct option_state *cfg_options,
1896                            struct binding_scope **scope,
1897                            struct universe *u, void *stuff,
1898                            void (*func) (struct option_cache *,
1899                                          struct packet *,
1900                                          struct lease *, struct client_state *,
1901                                          struct option_state *,
1902                                          struct option_state *,
1903                                          struct binding_scope **,
1904                                          struct universe *, void *))
1905 {
1906         if (u -> foreach)
1907                 (*u -> foreach) (packet, lease, client_state, in_options,
1908                                  cfg_options, scope, u, stuff, func);
1909 }
1910
1911 void suboption_foreach (struct packet *packet, struct lease *lease,
1912                         struct client_state *client_state,
1913                         struct option_state *in_options,
1914                         struct option_state *cfg_options,
1915                         struct binding_scope **scope,
1916                         struct universe *u, void *stuff,
1917                         void (*func) (struct option_cache *,
1918                                       struct packet *,
1919                                       struct lease *, struct client_state *,
1920                                       struct option_state *,
1921                                       struct option_state *,
1922                                       struct binding_scope **,
1923                                       struct universe *, void *),
1924                         struct option_cache *oc,
1925                         const char *vsname)
1926 {
1927         struct universe *universe = find_option_universe (oc -> option,
1928                                                           vsname);
1929         int i;
1930
1931         if (universe -> foreach)
1932                 (*universe -> foreach) (packet, lease, client_state,
1933                                         in_options, cfg_options,
1934                                         scope, universe, stuff, func);
1935 }
1936
1937 void hashed_option_space_foreach (struct packet *packet, struct lease *lease,
1938                                   struct client_state *client_state,
1939                                   struct option_state *in_options,
1940                                   struct option_state *cfg_options,
1941                                   struct binding_scope **scope,
1942                                   struct universe *u, void *stuff,
1943                                   void (*func) (struct option_cache *,
1944                                                 struct packet *,
1945                                                 struct lease *,
1946                                                 struct client_state *,
1947                                                 struct option_state *,
1948                                                 struct option_state *,
1949                                                 struct binding_scope **,
1950                                                 struct universe *, void *))
1951 {
1952         pair *hash;
1953         int i;
1954         struct option_cache *oc;
1955
1956         if (cfg_options -> universe_count <= u -> index)
1957                 return;
1958
1959         hash = cfg_options -> universes [u -> index];
1960         if (!hash)
1961                 return;
1962         for (i = 0; i < OPTION_HASH_SIZE; i++) {
1963                 pair p;
1964                 /* XXX save _all_ options! XXX */
1965                 for (p = hash [i]; p; p = p -> cdr) {
1966                         oc = (struct option_cache *)p -> car;
1967                         (*func) (oc, packet, lease, client_state,
1968                                  in_options, cfg_options, scope, u, stuff);
1969                 }
1970         }
1971 }
1972
1973 void save_linked_option (universe, options, oc)
1974         struct universe *universe;
1975         struct option_state *options;
1976         struct option_cache *oc;
1977 {
1978         pair *tail;
1979         pair np = (pair )0;
1980         struct option_chain_head *head;
1981
1982         if (universe -> index >= options -> universe_count)
1983                 return;
1984         head = ((struct option_chain_head *)
1985                 options -> universes [universe -> index]);
1986         if (!head) {
1987                 if (!option_chain_head_allocate (((struct option_chain_head **)
1988                                                   &options -> universes
1989                                                   [universe -> index]), MDL))
1990                         return;
1991                 head = ((struct option_chain_head *)
1992                         options -> universes [universe -> index]);
1993         }
1994
1995         /* Find the tail of the list. */
1996         for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {
1997                 if (oc -> option ==
1998                     ((struct option_cache *)((*tail) -> car)) -> option) {
1999                         option_cache_dereference ((struct option_cache **)
2000                                                   (&(*tail) -> car), MDL);
2001                         option_cache_reference ((struct option_cache **)
2002                                                 (&(*tail) -> car), oc, MDL);
2003                         return;
2004                 }
2005         }
2006
2007         *tail = cons (0, 0);
2008         if (*tail) {
2009                 option_cache_reference ((struct option_cache **)
2010                                         (&(*tail) -> car), oc, MDL);
2011         }
2012 }
2013
2014 int linked_option_space_encapsulate (result, packet, lease, client_state,
2015                                     in_options, cfg_options, scope, universe)
2016         struct data_string *result;
2017         struct packet *packet;
2018         struct lease *lease;
2019         struct client_state *client_state;
2020         struct option_state *in_options;
2021         struct option_state *cfg_options;
2022         struct binding_scope **scope;
2023         struct universe *universe;
2024 {
2025         int status;
2026         pair oc;
2027         struct option_chain_head *head;
2028
2029         if (universe -> index >= cfg_options -> universe_count)
2030                 return 0;
2031         head = ((struct option_chain_head *)
2032                 cfg_options -> universes [universe -> index]);
2033         if (!head)
2034                 return 0;
2035
2036         status = 0;
2037         for (oc = head -> first; oc; oc = oc -> cdr) {
2038                 if (store_option (result, universe, packet,
2039                                   lease, client_state, in_options, cfg_options,
2040                                   scope, (struct option_cache *)(oc -> car)))
2041                         status = 1;
2042         }
2043
2044         return status;
2045 }
2046
2047 void delete_linked_option (universe, options, code)
2048         struct universe *universe;
2049         struct option_state *options;
2050         int code;
2051 {
2052         pair *tail, tmp = (pair)0;
2053         struct option_chain_head *head;
2054
2055         if (universe -> index >= options -> universe_count)
2056                 return;
2057         head = ((struct option_chain_head *)
2058                 options -> universes [universe -> index]);
2059         if (!head)
2060                 return;
2061
2062         for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {
2063                 if (code ==
2064                     ((struct option_cache *)(*tail) -> car) -> option -> code)
2065                 {
2066                         tmp = (*tail) -> cdr;
2067                         option_cache_dereference ((struct option_cache **)
2068                                                   (&(*tail) -> car), MDL);
2069                         dfree (*tail, MDL);
2070                         (*tail) = tmp;
2071                         break;
2072                 }
2073         }
2074 }
2075
2076 struct option_cache *lookup_linked_option (universe, options, code)
2077         struct universe *universe;
2078         struct option_state *options;
2079         unsigned code;
2080 {
2081         pair oc;
2082         struct option_chain_head *head;
2083
2084         if (universe -> index >= options -> universe_count)
2085                 return 0;
2086         head = ((struct option_chain_head *)
2087                 options -> universes [universe -> index]);
2088         if (!head)
2089                 return 0;
2090
2091         for (oc = head -> first; oc; oc = oc -> cdr) {
2092                 if (code ==
2093                     ((struct option_cache *)(oc -> car)) -> option -> code) {
2094                         return (struct option_cache *)(oc -> car);
2095                 }
2096         }
2097
2098         return (struct option_cache *)0;
2099 }
2100
2101 int linked_option_state_dereference (universe, state, file, line)
2102         struct universe *universe;
2103         struct option_state *state;
2104         const char *file;
2105         int line;
2106 {
2107         return (option_chain_head_dereference
2108                 ((struct option_chain_head **)
2109                  (&state -> universes [universe -> index]), MDL));
2110 }
2111
2112 void linked_option_space_foreach (struct packet *packet, struct lease *lease,
2113                                   struct client_state *client_state,
2114                                   struct option_state *in_options,
2115                                   struct option_state *cfg_options,
2116                                   struct binding_scope **scope,
2117                                   struct universe *u, void *stuff,
2118                                   void (*func) (struct option_cache *,
2119                                                 struct packet *,
2120                                                 struct lease *,
2121                                                 struct client_state *,
2122                                                 struct option_state *,
2123                                                 struct option_state *,
2124                                                 struct binding_scope **,
2125                                                 struct universe *, void *))
2126 {
2127         pair car;
2128         struct option_chain_head *head;
2129
2130         if (u -> index >= cfg_options -> universe_count)
2131                 return;
2132         head = ((struct option_chain_head *)
2133                 cfg_options -> universes [u -> index]);
2134         if (!head)
2135                 return;
2136         for (car = head -> first; car; car = car -> cdr) {
2137                 (*func) ((struct option_cache *)(car -> car),
2138                          packet, lease, client_state,
2139                          in_options, cfg_options, scope, u, stuff);
2140         }
2141 }
2142
2143 void do_packet (interface, packet, len, from_port, from, hfrom)
2144         struct interface_info *interface;
2145         struct dhcp_packet *packet;
2146         unsigned len;
2147         unsigned int from_port;
2148         struct iaddr from;
2149         struct hardware *hfrom;
2150 {
2151         int i;
2152         struct option_cache *op;
2153         struct packet *decoded_packet;
2154 #if defined (DEBUG_MEMORY_LEAKAGE)
2155         unsigned long previous_outstanding = dmalloc_outstanding;
2156 #endif
2157
2158 #if defined (TRACING)
2159         trace_inpacket_stash (interface, packet, len, from_port, from, hfrom);
2160 #endif
2161
2162         decoded_packet = (struct packet *)0;
2163         if (!packet_allocate (&decoded_packet, MDL)) {
2164                 log_error ("do_packet: no memory for incoming packet!");
2165                 return;
2166         }
2167         decoded_packet -> raw = packet;
2168         decoded_packet -> packet_length = len;
2169         decoded_packet -> client_port = from_port;
2170         decoded_packet -> client_addr = from;
2171         interface_reference (&decoded_packet -> interface, interface, MDL);
2172         decoded_packet -> haddr = hfrom;
2173         
2174         if (packet -> hlen > sizeof packet -> chaddr) {
2175                 packet_dereference (&decoded_packet, MDL);
2176                 log_info ("Discarding packet with bogus hlen.");
2177                 return;
2178         }
2179
2180         /* If there's an option buffer, try to parse it. */
2181         if (decoded_packet -> packet_length >= DHCP_FIXED_NON_UDP + 4) {
2182                 if (!parse_options (decoded_packet)) {
2183                         if (decoded_packet -> options)
2184                                 option_state_dereference
2185                                         (&decoded_packet -> options, MDL);
2186                         packet_dereference (&decoded_packet, MDL);
2187                         return;
2188                 }
2189
2190                 if (decoded_packet -> options_valid &&
2191                     (op = lookup_option (&dhcp_universe,
2192                                          decoded_packet -> options, 
2193                                          DHO_DHCP_MESSAGE_TYPE))) {
2194                         struct data_string dp;
2195                         memset (&dp, 0, sizeof dp);
2196                         evaluate_option_cache (&dp, decoded_packet,
2197                                                (struct lease *)0,
2198                                                (struct client_state *)0,
2199                                                decoded_packet -> options,
2200                                                (struct option_state *)0,
2201                                                (struct binding_scope **)0,
2202                                                op, MDL);
2203                         if (dp.len > 0)
2204                                 decoded_packet -> packet_type = dp.data [0];
2205                         else
2206                                 decoded_packet -> packet_type = 0;
2207                         data_string_forget (&dp, MDL);
2208                 }
2209         }
2210                 
2211         if (decoded_packet -> packet_type)
2212                 dhcp (decoded_packet);
2213         else
2214                 bootp (decoded_packet);
2215
2216         /* If the caller kept the packet, they'll have upped the refcnt. */
2217         packet_dereference (&decoded_packet, MDL);
2218
2219 #if defined (DEBUG_MEMORY_LEAKAGE)
2220         log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
2221                   dmalloc_generation,
2222                   dmalloc_outstanding - previous_outstanding,
2223                   dmalloc_outstanding, dmalloc_longterm);
2224 #endif
2225 #if defined (DEBUG_MEMORY_LEAKAGE)
2226         dmalloc_dump_outstanding ();
2227 #endif
2228 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
2229         dump_rc_history (0);
2230 #endif
2231 }
2232