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