1 /* $NetBSD: options.c,v 1.5 2021/01/13 17:01:31 christos Exp $ */ 2 3 /* options.c 4 5 DHCP options parsing and reassembly. */ 6 7 /* 8 * Copyright (c) 2004-2019 by Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1995-2003 by Internet Software Consortium 10 * 11 * This Source Code Form is subject to the terms of the Mozilla Public 12 * License, v. 2.0. If a copy of the MPL was not distributed with this 13 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Internet Systems Consortium, Inc. 24 * 950 Charter Street 25 * Redwood City, CA 94063 26 * <info@isc.org> 27 * https://www.isc.org/ 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: options.c,v 1.5 2021/01/13 17:01:31 christos Exp $"); 33 34 #define DHCP_OPTION_DATA 35 #include "dhcpd.h" 36 #include <omapip/omapip_p.h> 37 #include <limits.h> 38 39 struct option *vendor_cfg_option; 40 41 static int pretty_text(char **, char *, const unsigned char **, 42 const unsigned char *, int); 43 static int pretty_dname(char **, char *, const unsigned char *, 44 const unsigned char *); 45 static int pretty_domain(char **, char *, const unsigned char **, 46 const unsigned char *); 47 static int prepare_option_buffer(struct universe *universe, struct buffer *bp, 48 unsigned char *buffer, unsigned length, 49 unsigned code, int terminatep, 50 struct option_cache **opp); 51 52 /* Parse all available options out of the specified packet. */ 53 /* Note, the caller is responsible for allocating packet->options. */ 54 int parse_options (packet) 55 struct packet *packet; 56 { 57 struct option_cache *op = NULL; 58 59 /* If we don't see the magic cookie, there's nothing to parse. */ 60 if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) { 61 packet -> options_valid = 0; 62 return 1; 63 } 64 65 /* Go through the options field, up to the end of the packet 66 or the End field. */ 67 if (!parse_option_buffer (packet -> options, 68 &packet -> raw -> options [4], 69 (packet -> packet_length - 70 DHCP_FIXED_NON_UDP - 4), 71 &dhcp_universe)) { 72 73 /* STSN servers have a bug where they send a mangled 74 domain-name option, and whatever is beyond that in 75 the packet is junk. Microsoft clients accept this, 76 which is probably why whoever implemented the STSN 77 server isn't aware of the problem yet. To work around 78 this, we will accept corrupt packets from the server if 79 they contain a valid DHCP_MESSAGE_TYPE option, but 80 will not accept any corrupt client packets (the ISC DHCP 81 server is sufficiently widely used that it is probably 82 beneficial for it to be picky) and will not accept 83 packets whose type can't be determined. */ 84 85 if ((op = lookup_option (&dhcp_universe, packet -> options, 86 DHO_DHCP_MESSAGE_TYPE))) { 87 if (!op -> data.data || 88 (op -> data.data [0] != DHCPOFFER && 89 op -> data.data [0] != DHCPACK && 90 op -> data.data [0] != DHCPNAK)) 91 return 0; 92 } else 93 return 0; 94 } 95 96 /* If we parsed a DHCP Option Overload option, parse more 97 options out of the buffer(s) containing them. */ 98 if ((op = lookup_option (&dhcp_universe, packet -> options, 99 DHO_DHCP_OPTION_OVERLOAD))) { 100 if (op -> data.data [0] & 1) { 101 if (!parse_option_buffer 102 (packet -> options, 103 (unsigned char *)packet -> raw -> file, 104 sizeof packet -> raw -> file, 105 &dhcp_universe)) 106 return 0; 107 } 108 if (op -> data.data [0] & 2) { 109 if (!parse_option_buffer 110 (packet -> options, 111 (unsigned char *)packet -> raw -> sname, 112 sizeof packet -> raw -> sname, 113 &dhcp_universe)) 114 return 0; 115 } 116 } 117 packet -> options_valid = 1; 118 return 1; 119 } 120 121 /* Parse options out of the specified buffer, storing addresses of option 122 * values in packet->options. 123 */ 124 int parse_option_buffer (options, buffer, length, universe) 125 struct option_state *options; 126 const unsigned char *buffer; 127 unsigned length; 128 struct universe *universe; 129 { 130 unsigned len, offset; 131 unsigned code; 132 struct option_cache *op = NULL, *nop = NULL; 133 struct buffer *bp = NULL; 134 struct option *option; 135 char *reason = "general failure"; 136 137 if (!buffer_allocate (&bp, length, MDL)) { 138 log_error ("no memory for option buffer."); 139 return 0; 140 } 141 memcpy (bp -> data, buffer, length); 142 143 for (offset = 0; 144 (offset + universe->tag_size) <= length && 145 (code = universe->get_tag(buffer + offset)) != universe->end; ) { 146 option = NULL; 147 offset += universe->tag_size; 148 149 /* Pad options don't have a length - just skip them. */ 150 if (code == DHO_PAD) 151 continue; 152 153 /* Don't look for length if the buffer isn't that big. */ 154 if ((offset + universe->length_size) > length) { 155 reason = "code tag at end of buffer - missing " 156 "length field"; 157 goto bogus; 158 } 159 160 /* All other fields (except PAD and END handled above) 161 * have a length field, unless it's a DHCPv6 zero-length 162 * options space (eg any of the enterprise-id'd options). 163 * 164 * Zero-length-size option spaces basically consume the 165 * entire options buffer, so have at it. 166 */ 167 if (universe->get_length != NULL) 168 len = universe->get_length(buffer + offset); 169 else if (universe->length_size == 0) 170 len = length - universe->tag_size; 171 else { 172 log_fatal("Improperly configured option space(%s): " 173 "may not have a nonzero length size " 174 "AND a NULL get_length function.", 175 universe->name); 176 177 /* Silence compiler warnings. */ 178 return 0; 179 } 180 181 offset += universe->length_size; 182 183 if (!option_code_hash_lookup(&option, universe->code_hash, 184 &code, 0, MDL)) { 185 log_error("Can't find option with code %u", code); 186 } 187 188 /* If the length is outrageous, the options are bad. */ 189 if (offset + len > length) { 190 /* Avoid reference count overflow */ 191 if (option) 192 option_dereference(&option, MDL); 193 reason = "option length exceeds option buffer length"; 194 bogus: 195 log_error("parse_option_buffer: malformed option " 196 "%s.%s (code %u): %s.", universe->name, 197 option ? option->name : "<unknown>", 198 code, reason); 199 buffer_dereference (&bp, MDL); 200 return 0; 201 } 202 203 /* If the option contains an encapsulation, parse it. In 204 any case keep the raw data as well. (Previous to 4.4.0 205 we only kept the raw data if the parse failed, the option 206 wasn't an encapsulation (by far the most common case), or 207 the option wasn't entirely an encapsulation 208 */ 209 210 if (option && 211 (option->format[0] == 'e' || option->format[0] == 'E')) { 212 (void) parse_encapsulated_suboptions(options, option, 213 bp->data + offset, 214 len, 215 universe, NULL); 216 } 217 218 if (universe == &dhcp_universe && code == DHO_HOST_NAME && 219 len == 0) { 220 /* non-compliant clients can send it 221 * we'll just drop it and go on */ 222 log_debug ("Ignoring empty DHO_HOST_NAME option"); 223 if (option) 224 option_dereference(&option, MDL); 225 offset += len; 226 continue; 227 } 228 229 op = lookup_option(universe, options, code); 230 if (op == NULL) { 231 /* If we don't have an option create one */ 232 if (save_option_buffer(universe, options, bp, 233 bp->data + offset, len, 234 code, 1) == 0) { 235 log_error("parse_option_buffer: " 236 "save_option_buffer failed"); 237 buffer_dereference(&bp, MDL); 238 option_dereference(&option, MDL); 239 return (0); 240 } 241 } else if (universe->concat_duplicates) { 242 /* If we do have an option either concat with 243 what is there ...*/ 244 struct data_string new; 245 memset(&new, 0, sizeof new); 246 if (!buffer_allocate(&new.buffer, op->data.len + len, 247 MDL)) { 248 log_error("parse_option_buffer: No memory."); 249 buffer_dereference(&bp, MDL); 250 option_dereference(&option, MDL); 251 return (0); 252 } 253 /* Copy old option to new data object. */ 254 memcpy(new.buffer->data, op->data.data, 255 op->data.len); 256 /* Concat new option behind old. */ 257 memcpy(new.buffer->data + op->data.len, 258 bp->data + offset, len); 259 new.len = op->data.len + len; 260 new.data = new.buffer->data; 261 /* Save new concat'd object. */ 262 data_string_forget(&op->data, MDL); 263 data_string_copy(&op->data, &new, MDL); 264 data_string_forget(&new, MDL); 265 } else { 266 /* ... or we must append this statement onto the 267 * end of the list. 268 */ 269 while (op->next != NULL) 270 op = op->next; 271 272 if (!option_cache_allocate(&nop, MDL)) { 273 log_error("parse_option_buffer: No memory."); 274 buffer_dereference(&bp, MDL); 275 option_dereference(&option, MDL); 276 return (0); 277 } 278 279 option_reference(&nop->option, op->option, MDL); 280 281 nop->data.buffer = NULL; 282 buffer_reference(&nop->data.buffer, bp, MDL); 283 nop->data.data = bp->data + offset; 284 nop->data.len = len; 285 286 option_cache_reference(&op->next, nop, MDL); 287 option_cache_dereference(&nop, MDL); 288 } 289 290 if (option) 291 option_dereference(&option, MDL); 292 offset += len; 293 } 294 buffer_dereference (&bp, MDL); 295 return (1); 296 } 297 298 /* If an option in an option buffer turns out to be an encapsulation, 299 figure out what to do. If we don't know how to de-encapsulate it, 300 or it's not well-formed, return zero; otherwise, return 1, indicating 301 that we succeeded in de-encapsulating it. */ 302 303 struct universe *find_option_universe (struct option *eopt, const char *uname) 304 { 305 int i; 306 char *s, *t; 307 struct universe *universe = (struct universe *)0; 308 309 /* Look for the E option in the option format. */ 310 s = strchr (eopt -> format, 'E'); 311 if (!s) { 312 log_error ("internal encapsulation format error 1."); 313 return 0; 314 } 315 /* Look for the universe name in the option format. */ 316 t = strchr (++s, '.'); 317 /* If there was no trailing '.', or there's something after the 318 trailing '.', the option is bogus and we can't use it. */ 319 if (!t || t [1]) { 320 log_error ("internal encapsulation format error 2."); 321 return 0; 322 } 323 if (t == s && uname) { 324 for (i = 0; i < universe_count; i++) { 325 if (!strcmp (universes [i] -> name, uname)) { 326 universe = universes [i]; 327 break; 328 } 329 } 330 } else if (t != s) { 331 for (i = 0; i < universe_count; i++) { 332 if (strlen (universes [i] -> name) == t - s && 333 !memcmp (universes [i] -> name, 334 s, (unsigned)(t - s))) { 335 universe = universes [i]; 336 break; 337 } 338 } 339 } 340 return universe; 341 } 342 343 /* If an option in an option buffer turns out to be an encapsulation, 344 figure out what to do. If we don't know how to de-encapsulate it, 345 or it's not well-formed, return zero; otherwise, return 1, indicating 346 that we succeeded in de-encapsulating it. */ 347 348 int parse_encapsulated_suboptions (struct option_state *options, 349 struct option *eopt, 350 const unsigned char *buffer, 351 unsigned len, struct universe *eu, 352 const char *uname) 353 { 354 int i; 355 struct universe *universe = find_option_universe (eopt, uname); 356 357 /* If we didn't find the universe, we can't do anything with it 358 right now (e.g., we can't decode vendor options until we've 359 decoded the packet and executed the scopes that it matches). */ 360 if (!universe) 361 return 0; 362 363 /* If we don't have a decoding function for it, we can't decode 364 it. */ 365 if (!universe -> decode) 366 return 0; 367 368 i = (*universe -> decode) (options, buffer, len, universe); 369 370 /* If there is stuff before the suboptions, we have to keep it. */ 371 if (eopt -> format [0] != 'E') 372 return 0; 373 /* Otherwise, return the status of the decode function. */ 374 return i; 375 } 376 377 int fqdn_universe_decode (struct option_state *options, 378 const unsigned char *buffer, 379 unsigned length, struct universe *u) 380 { 381 struct buffer *bp = (struct buffer *)0; 382 383 /* FQDN options have to be at least four bytes long. */ 384 if (length < 3) 385 return 0; 386 387 /* Save the contents of the option in a buffer. */ 388 if (!buffer_allocate (&bp, length + 4, MDL)) { 389 log_error ("no memory for option buffer."); 390 return 0; 391 } 392 memcpy (&bp -> data [3], buffer + 1, length - 1); 393 394 if (buffer [0] & 4) /* encoded */ 395 bp -> data [0] = 1; 396 else 397 bp -> data [0] = 0; 398 if (!save_option_buffer(&fqdn_universe, options, bp, 399 bp->data, 1, FQDN_ENCODED, 0)) { 400 bad: 401 buffer_dereference (&bp, MDL); 402 return 0; 403 } 404 405 if (buffer [0] & 1) /* server-update */ 406 bp -> data [2] = 1; 407 else 408 bp -> data [2] = 0; 409 if (buffer [0] & 2) /* no-client-update */ 410 bp -> data [1] = 1; 411 else 412 bp -> data [1] = 0; 413 414 /* XXX Ideally we should store the name in DNS format, so if the 415 XXX label isn't in DNS format, we convert it to DNS format, 416 XXX rather than converting labels specified in DNS format to 417 XXX the plain ASCII representation. But that's hard, so 418 XXX not now. */ 419 420 /* Not encoded using DNS format? */ 421 if (!bp -> data [0]) { 422 unsigned i; 423 424 /* Some broken clients NUL-terminate this option. */ 425 if (buffer [length - 1] == 0) { 426 --length; 427 bp -> data [1] = 1; 428 } 429 430 /* Determine the length of the hostname component of the 431 name. If the name contains no '.' character, it 432 represents a non-qualified label. */ 433 for (i = 3; i < length && buffer [i] != '.'; i++); 434 i -= 3; 435 436 /* Note: If the client sends a FQDN, the first '.' will 437 be used as a NUL terminator for the hostname. */ 438 if (i && (!save_option_buffer(&fqdn_universe, options, bp, 439 &bp->data[5], i, 440 FQDN_HOSTNAME, 0))) 441 goto bad; 442 /* Note: If the client sends a single label, the 443 FQDN_DOMAINNAME option won't be set. */ 444 if (length > 4 + i && 445 (!save_option_buffer(&fqdn_universe, options, bp, 446 &bp -> data[6 + i], length - 4 - i, 447 FQDN_DOMAINNAME, 1))) 448 goto bad; 449 /* Also save the whole name. */ 450 if (length > 3) { 451 if (!save_option_buffer(&fqdn_universe, options, bp, 452 &bp -> data [5], length - 3, 453 FQDN_FQDN, 1)) 454 goto bad; 455 } 456 } else { 457 unsigned len; 458 unsigned total_len = 0; 459 unsigned first_len = 0; 460 int terminated = 0; 461 unsigned char *s; 462 463 s = &bp -> data[5]; 464 465 while (s < &bp -> data[0] + length + 2) { 466 len = *s; 467 if (len > 63) { 468 log_info ("fancy bits in fqdn option"); 469 return 0; 470 } 471 if (len == 0) { 472 terminated = 1; 473 break; 474 } 475 if (s + len > &bp -> data [0] + length + 3) { 476 log_info ("fqdn tag longer than buffer"); 477 return 0; 478 } 479 480 if (first_len == 0) { 481 first_len = len; 482 } 483 484 *s = '.'; 485 s += len + 1; 486 total_len += len + 1; 487 } 488 489 /* We wind up with a length that's one too many because 490 we shouldn't increment for the last label, but there's 491 no way to tell we're at the last label until we exit 492 the loop. :'*/ 493 if (total_len > 0) 494 total_len--; 495 496 if (!terminated) { 497 first_len = total_len; 498 } 499 500 if (first_len > 0 && 501 !save_option_buffer(&fqdn_universe, options, bp, 502 &bp -> data[6], first_len, 503 FQDN_HOSTNAME, 0)) 504 goto bad; 505 if (total_len > 0 && first_len != total_len) { 506 if (!save_option_buffer(&fqdn_universe, options, bp, 507 &bp->data[6 + first_len], 508 total_len - first_len, 509 FQDN_DOMAINNAME, 1)) 510 goto bad; 511 } 512 if (total_len > 0) 513 if (!save_option_buffer (&fqdn_universe, options, bp, 514 &bp -> data [6], total_len, 515 FQDN_FQDN, 1)) 516 goto bad; 517 } 518 519 if (!save_option_buffer (&fqdn_universe, options, bp, 520 &bp -> data [1], 1, 521 FQDN_NO_CLIENT_UPDATE, 0)) 522 goto bad; 523 if (!save_option_buffer (&fqdn_universe, options, bp, 524 &bp -> data [2], 1, 525 FQDN_SERVER_UPDATE, 0)) 526 goto bad; 527 528 if (!save_option_buffer (&fqdn_universe, options, bp, 529 &bp -> data [3], 1, 530 FQDN_RCODE1, 0)) 531 goto bad; 532 if (!save_option_buffer (&fqdn_universe, options, bp, 533 &bp -> data [4], 1, 534 FQDN_RCODE2, 0)) 535 goto bad; 536 537 buffer_dereference (&bp, MDL); 538 return 1; 539 } 540 541 /* 542 * Load all options into a buffer, and then split them out into the three 543 * separate fields in the dhcp packet (options, file, and sname) where 544 * options can be stored. 545 * 546 * returns 0 on error, length of packet on success 547 */ 548 int 549 cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, 550 struct lease *lease, struct client_state *client_state, 551 int mms, struct option_state *in_options, 552 struct option_state *cfg_options, 553 struct binding_scope **scope, 554 int overload_avail, int terminate, int bootpp, 555 struct data_string *prl, const char *vuname) 556 { 557 #define PRIORITY_COUNT 300 558 unsigned priority_list[PRIORITY_COUNT]; 559 int priority_len; 560 unsigned char buffer[4096], agentopts[1024]; 561 unsigned index = 0; 562 unsigned mb_size = 0, mb_max = 0; 563 unsigned option_size = 0, agent_size = 0; 564 unsigned length; 565 int i; 566 struct option_cache *op; 567 struct data_string ds; 568 pair pp, *hash; 569 int overload_used = 0; 570 int of1 = 0, of2 = 0; 571 572 memset(&ds, 0, sizeof ds); 573 574 /* 575 * If there's a Maximum Message Size option in the incoming packet 576 * and no alternate maximum message size has been specified, or 577 * if the one specified in the packet is shorter than the 578 * alternative, take the one in the packet. 579 */ 580 581 if (inpacket && 582 (op = lookup_option(&dhcp_universe, inpacket->options, 583 DHO_DHCP_MAX_MESSAGE_SIZE)) && 584 (evaluate_option_cache(&ds, inpacket, lease, 585 client_state, in_options, 586 cfg_options, scope, op, MDL) != 0)) { 587 if (ds.len >= sizeof (u_int16_t)) { 588 i = getUShort(ds.data); 589 if(!mms || (i < mms)) 590 mms = i; 591 } 592 data_string_forget(&ds, MDL); 593 } 594 595 /* 596 * If the client has provided a maximum DHCP message size, 597 * use that, up to the MTU limit. Otherwise, if it's BOOTP, 598 * only 64 bytes; otherwise use up to the minimum IP MTU size 599 * (576 bytes). 600 * 601 * XXX if a BOOTP client specifies a max message size, we will 602 * honor it. 603 */ 604 if (mms) { 605 if (mms < DHCP_MTU_MIN) 606 /* Enforce minimum packet size, per RFC 2132 */ 607 mb_size = DHCP_MIN_OPTION_LEN; 608 else if (mms > DHCP_MTU_MAX) 609 /* 610 * TODO: Packets longer than 1500 bytes really 611 * should be allowed, but it requires upstream 612 * changes to the way the packet is allocated. For 613 * now, we forbid them. They won't be needed very 614 * often anyway. 615 */ 616 mb_size = DHCP_MAX_OPTION_LEN; 617 else 618 mb_size = mms - DHCP_FIXED_LEN; 619 } else if (bootpp) { 620 mb_size = 64; 621 if (inpacket != NULL && 622 (inpacket->packet_length >= 64 + DHCP_FIXED_NON_UDP)) 623 mb_size = inpacket->packet_length - DHCP_FIXED_NON_UDP; 624 } else 625 mb_size = DHCP_MIN_OPTION_LEN; 626 627 /* 628 * If answering a client message, see whether any relay agent 629 * options were included with the message. If so, save them 630 * to copy back in later, and make space in the main buffer 631 * to accommodate them 632 */ 633 if (client_state == NULL) { 634 priority_list[0] = DHO_DHCP_AGENT_OPTIONS; 635 priority_len = 1; 636 agent_size = store_options(NULL, agentopts, 0, 637 sizeof(agentopts), 638 inpacket, lease, client_state, 639 in_options, cfg_options, scope, 640 priority_list, priority_len, 641 0, 0, 0, NULL); 642 643 mb_size += agent_size; 644 if (mb_size > DHCP_MAX_OPTION_LEN) 645 mb_size = DHCP_MAX_OPTION_LEN; 646 } 647 648 /* 649 * Set offsets for buffer data to be copied into filename 650 * and servername fields 651 */ 652 if (mb_size > agent_size) 653 mb_max = mb_size - agent_size; 654 else 655 mb_max = mb_size; 656 657 if (overload_avail & 1) { 658 of1 = mb_max; 659 mb_max += DHCP_FILE_LEN; 660 } 661 662 if (overload_avail & 2) { 663 of2 = mb_max; 664 mb_max += DHCP_SNAME_LEN; 665 } 666 667 /* 668 * Preload the option priority list with protocol-mandatory options. 669 * This effectively gives these options the highest priority. 670 * This provides the order for any available options, the option 671 * must be in the option cache in order to actually be included. 672 */ 673 priority_len = 0; 674 priority_list[priority_len++] = DHO_DHCP_MESSAGE_TYPE; 675 priority_list[priority_len++] = DHO_DHCP_SERVER_IDENTIFIER; 676 priority_list[priority_len++] = DHO_DHCP_LEASE_TIME; 677 priority_list[priority_len++] = DHO_DHCP_RENEWAL_TIME; 678 priority_list[priority_len++] = DHO_DHCP_REBINDING_TIME; 679 priority_list[priority_len++] = DHO_DHCP_MESSAGE; 680 priority_list[priority_len++] = DHO_DHCP_REQUESTED_ADDRESS; 681 priority_list[priority_len++] = DHO_ASSOCIATED_IP; 682 683 if (prl != NULL && prl->len > 0) { 684 if ((op = lookup_option(&dhcp_universe, cfg_options, 685 DHO_SUBNET_SELECTION))) { 686 if (priority_len < PRIORITY_COUNT) 687 priority_list[priority_len++] = 688 DHO_SUBNET_SELECTION; 689 } 690 691 /* If echo-client-id is on, then we add client identifier to 692 * the priority_list. This way we'll send it whether or not it 693 * is in the PRL. */ 694 if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) && 695 (inpacket->sv_echo_client_id == ISC_TRUE)) { 696 priority_list[priority_len++] = 697 DHO_DHCP_CLIENT_IDENTIFIER; 698 } 699 700 data_string_truncate(prl, (PRIORITY_COUNT - priority_len)); 701 702 /* 703 * Copy the client's PRL onto the priority_list after our high 704 * priority header. 705 */ 706 for (i = 0; i < prl->len; i++) { 707 /* 708 * Prevent client from changing order of delivery 709 * of relay agent information option. 710 */ 711 if (prl->data[i] != DHO_DHCP_AGENT_OPTIONS) 712 priority_list[priority_len++] = prl->data[i]; 713 } 714 715 /* 716 * If the client doesn't request the FQDN option explicitly, 717 * to indicate priority, consider it lowest priority. Fit 718 * in the packet if there is space. Note that the option 719 * may only be included if the client supplied one. 720 */ 721 if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) && 722 (lookup_option(&fqdn_universe, inpacket->options, 723 FQDN_ENCODED) != NULL)) 724 priority_list[priority_len++] = DHO_FQDN; 725 726 /* 727 * Some DHCP Servers will give the subnet-mask option if 728 * it is not on the parameter request list - so some client 729 * implementations have come to rely on this - so we will 730 * also make sure we supply this, at lowest priority. 731 * 732 * This is only done in response to DHCPDISCOVER or 733 * DHCPREQUEST messages, to avoid providing the option on 734 * DHCPINFORM or DHCPLEASEQUERY responses (if the client 735 * didn't request it). 736 */ 737 if ((inpacket != NULL) && (priority_len < PRIORITY_COUNT) && 738 ((inpacket->packet_type == DHCPDISCOVER) || 739 (inpacket->packet_type == DHCPREQUEST))) 740 priority_list[priority_len++] = DHO_SUBNET_MASK; 741 } else { 742 /* 743 * First, hardcode some more options that ought to be 744 * sent first...these are high priority to have in the 745 * packet. 746 */ 747 priority_list[priority_len++] = DHO_SUBNET_MASK; 748 priority_list[priority_len++] = DHO_ROUTERS; 749 priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS; 750 priority_list[priority_len++] = DHO_HOST_NAME; 751 priority_list[priority_len++] = DHO_FQDN; 752 753 /* 754 * Append a list of the standard DHCP options from the 755 * standard DHCP option space. Actually, if a site 756 * option space hasn't been specified, we wind up 757 * treating the dhcp option space as the site option 758 * space, and the first for loop is skipped, because 759 * it's slightly more general to do it this way, 760 * taking the 1Q99 DHCP futures work into account. 761 */ 762 if (cfg_options->site_code_min) { 763 for (i = 0; i < OPTION_HASH_SIZE; i++) { 764 hash = cfg_options->universes[dhcp_universe.index]; 765 if (hash) { 766 for (pp = hash[i]; pp; pp = pp->cdr) { 767 op = (struct option_cache *)(pp->car); 768 if (op->option->code < 769 cfg_options->site_code_min && 770 priority_len < PRIORITY_COUNT && 771 op->option->code != DHO_DHCP_AGENT_OPTIONS) 772 priority_list[priority_len++] = 773 op->option->code; 774 } 775 } 776 } 777 } 778 779 /* 780 * Now cycle through the site option space, or if there 781 * is no site option space, we'll be cycling through the 782 * dhcp option space. 783 */ 784 for (i = 0; i < OPTION_HASH_SIZE; i++) { 785 hash = cfg_options->universes[cfg_options->site_universe]; 786 if (hash != NULL) 787 for (pp = hash[i]; pp; pp = pp->cdr) { 788 op = (struct option_cache *)(pp->car); 789 if (op->option->code >= 790 cfg_options->site_code_min && 791 priority_len < PRIORITY_COUNT && 792 op->option->code != DHO_DHCP_AGENT_OPTIONS) 793 priority_list[priority_len++] = 794 op->option->code; 795 } 796 } 797 798 /* 799 * Put any spaces that are encapsulated on the list, 800 * sort out whether they contain values later. 801 */ 802 for (i = 0; i < cfg_options->universe_count; i++) { 803 if (universes[i]->enc_opt && 804 priority_len < PRIORITY_COUNT && 805 universes[i]->enc_opt->universe == &dhcp_universe) { 806 if (universes[i]->enc_opt->code != 807 DHO_DHCP_AGENT_OPTIONS) 808 priority_list[priority_len++] = 809 universes[i]->enc_opt->code; 810 } 811 } 812 813 /* 814 * The vendor option space can't stand on its own, so always 815 * add it to the list. 816 */ 817 if (priority_len < PRIORITY_COUNT) 818 priority_list[priority_len++] = 819 DHO_VENDOR_ENCAPSULATED_OPTIONS; 820 } 821 822 /* Put the cookie up front... */ 823 memcpy(buffer, DHCP_OPTIONS_COOKIE, 4); 824 index += 4; 825 826 /* Copy the options into the big buffer... */ 827 option_size = store_options(&overload_used, buffer, index, mb_max, 828 inpacket, lease, client_state, 829 in_options, cfg_options, scope, 830 priority_list, priority_len, 831 of1, of2, terminate, vuname); 832 833 /* If store_options() failed */ 834 if (option_size == 0) 835 return 0; 836 837 /* How much was stored in the main buffer? */ 838 index += option_size; 839 840 /* 841 * If we're going to have to overload, store the overload 842 * option first. 843 */ 844 if (overload_used) { 845 if (mb_size - agent_size - index < 3) 846 return 0; 847 848 buffer[index++] = DHO_DHCP_OPTION_OVERLOAD; 849 buffer[index++] = 1; 850 buffer[index++] = overload_used; 851 852 if (overload_used & 1) 853 memcpy(outpacket->file, &buffer[of1], DHCP_FILE_LEN); 854 855 if (overload_used & 2) 856 memcpy(outpacket->sname, &buffer[of2], DHCP_SNAME_LEN); 857 } 858 859 /* Now copy in preserved agent options, if any */ 860 if (agent_size) { 861 if (mb_size - index >= agent_size) { 862 memcpy(&buffer[index], agentopts, agent_size); 863 index += agent_size; 864 } else 865 log_error("Unable to store relay agent information " 866 "in reply packet."); 867 } 868 869 /* Tack a DHO_END option onto the packet if we need to. */ 870 if (index < mb_size) 871 buffer[index++] = DHO_END; 872 873 /* Copy main buffer into the options buffer of the packet */ 874 memcpy(outpacket->options, buffer, index); 875 876 /* Figure out the length. */ 877 length = DHCP_FIXED_NON_UDP + index; 878 return length; 879 } 880 881 /* 882 * XXX: We currently special case collecting VSIO options. 883 * We should be able to handle this in a more generic fashion, by 884 * including any encapsulated options that are present and desired. 885 * This will look something like the VSIO handling VSIO code. 886 * We may also consider handling the ORO-like options within 887 * encapsulated spaces. 888 */ 889 890 struct vsio_state { 891 char *buf; 892 int buflen; 893 int bufpos; 894 }; 895 896 static void 897 vsio_options(struct option_cache *oc, 898 struct packet *packet, 899 struct lease *dummy_lease, 900 struct client_state *dummy_client_state, 901 struct option_state *dummy_opt_state, 902 struct option_state *opt_state, 903 struct binding_scope **dummy_binding_scope, 904 struct universe *universe, 905 void *void_vsio_state) { 906 struct vsio_state *vs = (struct vsio_state *)void_vsio_state; 907 struct data_string ds; 908 int total_len; 909 910 memset(&ds, 0, sizeof(ds)); 911 if (evaluate_option_cache(&ds, packet, NULL, 912 NULL, opt_state, NULL, 913 &global_scope, oc, MDL)) { 914 total_len = ds.len + universe->tag_size + universe->length_size; 915 if (total_len <= (vs->buflen - vs->bufpos)) { 916 if (universe->tag_size == 1) { 917 vs->buf[vs->bufpos++] = oc->option->code; 918 } else if (universe->tag_size == 2) { 919 putUShort((unsigned char *)vs->buf+vs->bufpos, 920 oc->option->code); 921 vs->bufpos += 2; 922 } else if (universe->tag_size == 4) { 923 putULong((unsigned char *)vs->buf+vs->bufpos, 924 oc->option->code); 925 vs->bufpos += 4; 926 } 927 if (universe->length_size == 1) { 928 vs->buf[vs->bufpos++] = ds.len; 929 } else if (universe->length_size == 2) { 930 putUShort((unsigned char *)vs->buf+vs->bufpos, 931 ds.len); 932 vs->bufpos += 2; 933 } else if (universe->length_size == 4) { 934 putULong((unsigned char *)vs->buf+vs->bufpos, 935 ds.len); 936 vs->bufpos += 4; 937 } 938 memcpy(vs->buf + vs->bufpos, ds.data, ds.len); 939 vs->bufpos += ds.len; 940 } else { 941 log_debug("No space for option %d in VSIO space %s.", 942 oc->option->code, universe->name); 943 } 944 data_string_forget(&ds, MDL); 945 } else { 946 log_error("Error evaluating option %d in VSIO space %s.", 947 oc->option->code, universe->name); 948 } 949 } 950 951 /*! 952 * 953 * \brief Add a v6 option to the buffer 954 * 955 * Put the requested v6 option including tag, length and value 956 * into the specified buffer. If there isn't enough space for 957 * the entire option it is skipped. 958 * 959 * \param buf buffer to put the option 960 * \param buflen total length of buffer 961 * \param bufpos on input where to start putting the option 962 * on output the starting point for the next option 963 * \param code the option code number 964 * \param ds the string to put into the option 965 * 966 * \return void 967 */ 968 static void 969 add_option6_data(char *buf, int buflen, int* bufpos, uint16_t code, 970 struct data_string* ds) { 971 if ((ds->len + 4) > (buflen - *bufpos)) { 972 log_debug("No space for option %d", code); 973 } else { 974 unsigned char* tmp = (unsigned char *)buf + *bufpos; 975 /* option tag */ 976 putUShort(tmp, code); 977 /* option length */ 978 putUShort(tmp+2, ds->len); 979 /* option data */ 980 memcpy(tmp+4, ds->data, ds->len); 981 /* update position */ 982 *bufpos += 4 + ds->len; 983 } 984 } 985 986 /*! 987 * 988 * \brief Add a v6 encapsulated option to a buffer 989 * 990 * Find the universe for the requested option and if it exists 991 * call it's encapsualtion routine to produce a data string which 992 * can then be added to the current buffer. 993 * 994 * Note 1: currently we only do simple encapsulations, where the 995 * entire value of the option is in the option universe. This is 996 * the 'E' format, we don't handle the 'e' format as we haven't 997 * defined any such universes yet. This means that if there is 998 * a simple value for the option store_options6 should handle it 999 * directly and not call this routine. 1000 * 1001 * \param buf buffer to put the option 1002 * \param buflen total length of buffer 1003 * \param bufpos on input where to start putting the option 1004 * on output the starting point for the next option 1005 * \param opt_state information about option values to use 1006 * \param packet structure containing what we know about the packet 1007 * \param encap_opt information about the structure of the option 1008 * \param code the option code number 1009 * 1010 * \return void 1011 */ 1012 static void 1013 store_encap6 (char *buf, int buflen, int* bufpos, 1014 struct option_state *opt_state, struct packet *packet, 1015 struct option* encap_opt, uint16_t code) { 1016 /* We need to extract the name of the universe 1017 * to use for this option. We expect a format string 1018 * of the form "Ename.". If we don't find a name we bail. */ 1019 struct data_string ds; 1020 struct data_string name; 1021 char* s = (char*)encap_opt->format; 1022 char* t; 1023 if ((s == NULL) || (*s != 'E') || (strlen(s) <= 2)) { 1024 return; 1025 } 1026 1027 t = strchr(++s, '.'); 1028 if ((t == NULL) || (t == s)) { 1029 return; 1030 } 1031 1032 memset(&ds, 0, sizeof(ds)); 1033 memset(&name, 0, sizeof(name)); 1034 name.data = (unsigned char *)s; 1035 name.len = t - s; 1036 1037 /* Now we call the routine to find and encapsulate the requested 1038 * option/universe. A return of 0 means no option information was 1039 * available and nothing is added to the buffer */ 1040 if (option_space_encapsulate(&ds, packet, NULL, NULL, NULL, opt_state, 1041 &global_scope, &name) != 0) { 1042 add_option6_data(buf, buflen, bufpos, code, &ds); 1043 data_string_forget(&ds, MDL); 1044 } 1045 } 1046 1047 /* 1048 * Stores the options from the DHCPv6 universe into the buffer given. 1049 * 1050 * Required options are given as a 0-terminated list of option codes. 1051 * Once those are added, the ORO is consulted. 1052 */ 1053 1054 int 1055 store_options6(char *buf, int buflen, 1056 struct option_state *opt_state, 1057 struct packet *packet, 1058 const int *required_opts, 1059 struct data_string *oro) { 1060 int i, j; 1061 struct option_cache *oc; 1062 struct option *o; 1063 struct data_string ds; 1064 int bufpos; 1065 int oro_size; 1066 u_int16_t code; 1067 int in_required_opts; 1068 int vsio_option_code; 1069 int vsio_wanted; 1070 struct vsio_state vs; 1071 unsigned char *tmp; 1072 1073 bufpos = 0; 1074 vsio_wanted = 0; 1075 1076 /* 1077 * Find the option code for the VSIO universe. 1078 */ 1079 vsio_option_code = 0; 1080 o = vsio_universe.enc_opt; 1081 while (o != NULL) { 1082 if (o->universe == &dhcpv6_universe) { 1083 vsio_option_code = o->code; 1084 break; 1085 } 1086 o = o->universe->enc_opt; 1087 } 1088 if (vsio_option_code == 0) { 1089 log_fatal("No VSIO option code found."); 1090 } 1091 1092 if (required_opts != NULL) { 1093 for (i=0; required_opts[i] != 0; i++) { 1094 if (required_opts[i] == vsio_option_code) { 1095 vsio_wanted = 1; 1096 } 1097 1098 oc = lookup_option(&dhcpv6_universe, 1099 opt_state, required_opts[i]); 1100 if (oc == NULL) { 1101 continue; 1102 } 1103 memset(&ds, 0, sizeof(ds)); 1104 for (; oc != NULL ; oc = oc->next) { 1105 if (evaluate_option_cache(&ds, packet, NULL, 1106 NULL, opt_state, 1107 NULL, &global_scope, 1108 oc, MDL)) { 1109 add_option6_data(buf, buflen, &bufpos, 1110 (uint16_t)required_opts[i], &ds); 1111 data_string_forget(&ds, MDL); 1112 } else { 1113 log_error("Error evaluating option %d", 1114 required_opts[i]); 1115 } 1116 } 1117 } 1118 } 1119 1120 if (oro == NULL) { 1121 oro_size = 0; 1122 } else { 1123 oro_size = oro->len / 2; 1124 } 1125 for (i=0; i<oro_size; i++) { 1126 memcpy(&code, oro->data+(i*2), 2); 1127 code = ntohs(code); 1128 1129 /* 1130 * See if we've already included this option because 1131 * it is required. 1132 */ 1133 in_required_opts = 0; 1134 if (required_opts != NULL) { 1135 for (j=0; required_opts[j] != 0; j++) { 1136 if (required_opts[j] == code) { 1137 in_required_opts = 1; 1138 break; 1139 } 1140 } 1141 } 1142 if (in_required_opts) { 1143 continue; 1144 } 1145 1146 /* 1147 * If this is the VSIO option flag it so we'll know to 1148 * check the vsio space later on. However we still need 1149 * to check for the existence of any defined via 1150 * dhcp6.vendor-opts. Those are stored as simple values. 1151 */ 1152 if (code == vsio_option_code) { 1153 vsio_wanted = 1; 1154 } 1155 1156 /* 1157 * Not already added, find this option. 1158 */ 1159 oc = lookup_option(&dhcpv6_universe, opt_state, code); 1160 memset(&ds, 0, sizeof(ds)); 1161 if (oc != NULL) { 1162 /* We have a simple value for the option */ 1163 for (; oc != NULL ; oc = oc->next) { 1164 if (evaluate_option_cache(&ds, packet, NULL, 1165 NULL, opt_state, NULL, 1166 &global_scope, oc, 1167 MDL)) { 1168 add_option6_data(buf, buflen, &bufpos, 1169 code, &ds); 1170 data_string_forget(&ds, MDL); 1171 } else { 1172 log_error("Error evaluating option %d", 1173 code); 1174 } 1175 } 1176 } else { 1177 /* 1178 * We don't have a simple value, check to see if we 1179 * have an universe to encapsulate into an option. 1180 */ 1181 struct option *encap_opt = NULL; 1182 unsigned int code_int = code; 1183 1184 option_code_hash_lookup(&encap_opt, 1185 dhcpv6_universe.code_hash, 1186 &code_int, 0, MDL); 1187 if (encap_opt != NULL) { 1188 store_encap6(buf, buflen, &bufpos, opt_state, 1189 packet, encap_opt, code); 1190 option_dereference(&encap_opt, MDL); 1191 } 1192 } 1193 } 1194 1195 if (vsio_wanted) { 1196 for (i=0; i < opt_state->universe_count; i++) { 1197 if (opt_state->universes[i] != NULL) { 1198 o = universes[i]->enc_opt; 1199 if ((o != NULL) && 1200 (o->universe == &vsio_universe)) { 1201 /* 1202 * Add the data from this VSIO option. 1203 */ 1204 vs.buf = buf; 1205 vs.buflen = buflen; 1206 vs.bufpos = bufpos+8; 1207 option_space_foreach(packet, NULL, 1208 NULL, 1209 NULL, opt_state, 1210 NULL, 1211 universes[i], 1212 (void *)&vs, 1213 vsio_options); 1214 1215 /* 1216 * If there was actually data here, 1217 * add the "header". 1218 */ 1219 if (vs.bufpos > bufpos+8) { 1220 tmp = (unsigned char *)buf + 1221 bufpos; 1222 putUShort(tmp, 1223 vsio_option_code); 1224 putUShort(tmp+2, 1225 vs.bufpos-bufpos-4); 1226 putULong(tmp+4, o->code); 1227 1228 bufpos = vs.bufpos; 1229 } 1230 } 1231 } 1232 } 1233 } 1234 1235 return bufpos; 1236 } 1237 1238 /* 1239 * Store all the requested options into the requested buffer. 1240 * XXX: ought to be static 1241 */ 1242 int 1243 store_options(int *ocount, 1244 unsigned char *buffer, unsigned index, unsigned buflen, 1245 struct packet *packet, struct lease *lease, 1246 struct client_state *client_state, 1247 struct option_state *in_options, 1248 struct option_state *cfg_options, 1249 struct binding_scope **scope, 1250 unsigned *priority_list, int priority_len, 1251 unsigned first_cutoff, int second_cutoff, int terminate, 1252 const char *vuname) 1253 { 1254 int bufix = 0, six = 0, tix = 0; 1255 int i; 1256 int ix; 1257 int tto; 1258 int bufend, sbufend; 1259 struct data_string od; 1260 struct option_cache *oc; 1261 struct option *option = NULL; 1262 unsigned code; 1263 1264 /* 1265 * These arguments are relative to the start of the buffer, so 1266 * reduce them by the current buffer index, and advance the 1267 * buffer pointer to where we're going to start writing. 1268 */ 1269 buffer = &buffer[index]; 1270 buflen -= index; 1271 if (first_cutoff) 1272 first_cutoff -= index; 1273 if (second_cutoff) 1274 second_cutoff -= index; 1275 1276 /* Calculate the start and end of each section of the buffer */ 1277 bufend = sbufend = buflen; 1278 if (first_cutoff) { 1279 if (first_cutoff >= buflen) 1280 log_fatal("%s:%d:store_options: Invalid first cutoff.", MDL); 1281 bufend = first_cutoff; 1282 1283 if (second_cutoff) { 1284 if (second_cutoff >= buflen) 1285 log_fatal("%s:%d:store_options: Invalid second cutoff.", 1286 MDL); 1287 sbufend = second_cutoff; 1288 } 1289 } else if (second_cutoff) { 1290 if (second_cutoff >= buflen) 1291 log_fatal("%s:%d:store_options: Invalid second cutoff.", MDL); 1292 bufend = second_cutoff; 1293 } 1294 1295 memset (&od, 0, sizeof od); 1296 1297 /* Eliminate duplicate options from the parameter request list. 1298 * Enforce RFC-mandated ordering of options that are present. 1299 */ 1300 for (i = 0; i < priority_len; i++) { 1301 /* Eliminate duplicates. */ 1302 tto = 0; 1303 for (ix = i + 1; ix < priority_len + tto; ix++) { 1304 if (tto) 1305 priority_list [ix - tto] = 1306 priority_list [ix]; 1307 if (priority_list [i] == priority_list [ix]) { 1308 tto++; 1309 priority_len--; 1310 } 1311 } 1312 1313 /* Enforce ordering of SUBNET_MASK options, according to 1314 * RFC2132 Section 3.3: 1315 * 1316 * If both the subnet mask and the router option are 1317 * specified in a DHCP reply, the subnet mask option MUST 1318 * be first. 1319 * 1320 * This guidance does not specify what to do if the client 1321 * PRL explicitly requests the options out of order, it is 1322 * a general statement. 1323 */ 1324 if (priority_list[i] == DHO_SUBNET_MASK) { 1325 for (ix = i - 1 ; ix >= 0 ; ix--) { 1326 if (priority_list[ix] == DHO_ROUTERS) { 1327 /* swap */ 1328 priority_list[ix] = DHO_SUBNET_MASK; 1329 priority_list[i] = DHO_ROUTERS; 1330 break; 1331 } 1332 } 1333 } 1334 } 1335 1336 /* Copy out the options in the order that they appear in the 1337 priority list... */ 1338 for (i = 0; i < priority_len; i++) { 1339 /* Number of bytes left to store (some may already 1340 have been stored by a previous pass). */ 1341 unsigned length; 1342 int optstart, soptstart, toptstart; 1343 struct universe *u; 1344 int have_encapsulation = 0; 1345 struct data_string encapsulation; 1346 int splitup; 1347 1348 memset (&encapsulation, 0, sizeof encapsulation); 1349 have_encapsulation = 0; 1350 1351 if (option != NULL) 1352 option_dereference(&option, MDL); 1353 1354 /* Code for next option to try to store. */ 1355 code = priority_list [i]; 1356 1357 /* Look up the option in the site option space if the code 1358 is above the cutoff, otherwise in the DHCP option space. */ 1359 if (code >= cfg_options -> site_code_min) 1360 u = universes [cfg_options -> site_universe]; 1361 else 1362 u = &dhcp_universe; 1363 1364 oc = lookup_option (u, cfg_options, code); 1365 1366 if (oc && oc->option) 1367 option_reference(&option, oc->option, MDL); 1368 else 1369 option_code_hash_lookup(&option, u->code_hash, &code, 0, MDL); 1370 1371 /* If it's a straight encapsulation, and the user supplied a 1372 * value for the entire option, use that. Otherwise, search 1373 * the encapsulated space. 1374 * 1375 * If it's a limited encapsulation with preceding data, and the 1376 * user supplied values for the preceding bytes, search the 1377 * encapsulated space. 1378 */ 1379 if ((option != NULL) && 1380 (((oc == NULL) && (option->format[0] == 'E')) || 1381 ((oc != NULL) && (option->format[0] == 'e')))) { 1382 static char *s, *t; 1383 struct option_cache *tmp; 1384 struct data_string name; 1385 1386 s = strchr (option->format, 'E'); 1387 if (s) 1388 t = strchr (++s, '.'); 1389 if (s && t) { 1390 memset (&name, 0, sizeof name); 1391 1392 /* A zero-length universe name means the vendor 1393 option space, if one is defined. */ 1394 if (t == s) { 1395 if (vendor_cfg_option) { 1396 tmp = lookup_option (vendor_cfg_option -> universe, 1397 cfg_options, 1398 vendor_cfg_option -> code); 1399 if (tmp) 1400 /* No need to check the return as we check name.len below */ 1401 (void) evaluate_option_cache (&name, packet, lease, 1402 client_state, 1403 in_options, 1404 cfg_options, 1405 scope, tmp, MDL); 1406 } else if (vuname) { 1407 name.data = (unsigned char *)s; 1408 name.len = strlen (s); 1409 } 1410 } else { 1411 name.data = (unsigned char *)s; 1412 name.len = t - s; 1413 } 1414 1415 /* If we found a universe, and there are options configured 1416 for that universe, try to encapsulate it. */ 1417 if (name.len) { 1418 have_encapsulation = 1419 (option_space_encapsulate 1420 (&encapsulation, packet, lease, client_state, 1421 in_options, cfg_options, scope, &name)); 1422 } 1423 1424 data_string_forget (&name, MDL); 1425 } 1426 } 1427 1428 /* In order to avoid memory leaks, we have to get to here 1429 with any option cache that we allocated in tmp not being 1430 referenced by tmp, and whatever option cache is referenced 1431 by oc being an actual reference. lookup_option doesn't 1432 generate a reference (this needs to be fixed), so the 1433 preceding goop ensures that if we *didn't* generate a new 1434 option cache, oc still winds up holding an actual reference. */ 1435 1436 /* If no data is available for this option, skip it. */ 1437 if (!oc && !have_encapsulation) { 1438 continue; 1439 } 1440 1441 /* Find the value of the option... */ 1442 od.len = 0; 1443 if (oc) { 1444 /* No need to check the return as we check od.len below */ 1445 (void) evaluate_option_cache (&od, packet, 1446 lease, client_state, in_options, 1447 cfg_options, scope, oc, MDL); 1448 1449 /* If we have encapsulation for this option, and an oc 1450 * lookup succeeded, but the evaluation failed, it is 1451 * either because this is a complex atom (atoms before 1452 * E on format list) and the top half of the option is 1453 * not configured, or this is a simple encapsulated 1454 * space and the evaluator is giving us a NULL. Prefer 1455 * the evaluator's opinion over the subspace. 1456 */ 1457 if (!od.len) { 1458 data_string_forget (&encapsulation, MDL); 1459 data_string_forget (&od, MDL); 1460 continue; 1461 } 1462 } 1463 1464 /* We should now have a constant length for the option. */ 1465 length = od.len; 1466 if (have_encapsulation) { 1467 length += encapsulation.len; 1468 1469 /* od.len can be nonzero if we got here without an 1470 * oc (cache lookup failed), but did have an encapsulated 1471 * simple encapsulation space. 1472 */ 1473 if (!od.len) { 1474 data_string_copy (&od, &encapsulation, MDL); 1475 data_string_forget (&encapsulation, MDL); 1476 } else { 1477 struct buffer *bp = (struct buffer *)0; 1478 if (!buffer_allocate (&bp, length, MDL)) { 1479 option_cache_dereference (&oc, MDL); 1480 data_string_forget (&od, MDL); 1481 data_string_forget (&encapsulation, MDL); 1482 continue; 1483 } 1484 memcpy (&bp -> data [0], od.data, od.len); 1485 memcpy (&bp -> data [od.len], encapsulation.data, 1486 encapsulation.len); 1487 data_string_forget (&od, MDL); 1488 data_string_forget (&encapsulation, MDL); 1489 od.data = &bp -> data [0]; 1490 buffer_reference (&od.buffer, bp, MDL); 1491 buffer_dereference (&bp, MDL); 1492 od.len = length; 1493 od.terminated = 0; 1494 } 1495 } 1496 1497 /* Do we add a NUL? */ 1498 if (terminate && option && format_has_text(option->format)) { 1499 length++; 1500 tto = 1; 1501 } else { 1502 tto = 0; 1503 } 1504 1505 /* Try to store the option. */ 1506 1507 /* If the option's length is more than 255, we must store it 1508 in multiple hunks. Store 255-byte hunks first. However, 1509 in any case, if the option data will cross a buffer 1510 boundary, split it across that boundary. */ 1511 1512 if (length > 255) 1513 splitup = 1; 1514 else 1515 splitup = 0; 1516 1517 ix = 0; 1518 optstart = bufix; 1519 soptstart = six; 1520 toptstart = tix; 1521 while (length) { 1522 unsigned incr = length; 1523 int *pix; 1524 unsigned char *base; 1525 1526 /* Try to fit it in the options buffer. */ 1527 if (!splitup && 1528 ((!six && !tix && (i == priority_len - 1) && 1529 (bufix + 2 + length < bufend)) || 1530 (bufix + 5 + length < bufend))) { 1531 base = buffer; 1532 pix = &bufix; 1533 /* Try to fit it in the second buffer. */ 1534 } else if (!splitup && first_cutoff && 1535 (first_cutoff + six + 3 + length < sbufend)) { 1536 base = &buffer[first_cutoff]; 1537 pix = &six; 1538 /* Try to fit it in the third buffer. */ 1539 } else if (!splitup && second_cutoff && 1540 (second_cutoff + tix + 3 + length < buflen)) { 1541 base = &buffer[second_cutoff]; 1542 pix = &tix; 1543 /* Split the option up into the remaining space. */ 1544 } else { 1545 splitup = 1; 1546 1547 /* Use any remaining options space. */ 1548 if (bufix + 6 < bufend) { 1549 incr = bufend - bufix - 5; 1550 base = buffer; 1551 pix = &bufix; 1552 /* Use any remaining first_cutoff space. */ 1553 } else if (first_cutoff && 1554 (first_cutoff + six + 4 < sbufend)) { 1555 incr = sbufend - (first_cutoff + six) - 3; 1556 base = &buffer[first_cutoff]; 1557 pix = &six; 1558 /* Use any remaining second_cutoff space. */ 1559 } else if (second_cutoff && 1560 (second_cutoff + tix + 4 < buflen)) { 1561 incr = buflen - (second_cutoff + tix) - 3; 1562 base = &buffer[second_cutoff]; 1563 pix = &tix; 1564 /* Give up, roll back this option. */ 1565 } else { 1566 bufix = optstart; 1567 six = soptstart; 1568 tix = toptstart; 1569 break; 1570 } 1571 } 1572 1573 if (incr > length) 1574 incr = length; 1575 if (incr > 255) 1576 incr = 255; 1577 1578 /* Everything looks good - copy it in! */ 1579 base [*pix] = code; 1580 base [*pix + 1] = (unsigned char)incr; 1581 if (tto && incr == length) { 1582 if (incr > 1) 1583 memcpy (base + *pix + 2, 1584 od.data + ix, (unsigned)(incr - 1)); 1585 base [*pix + 2 + incr - 1] = 0; 1586 } else { 1587 memcpy (base + *pix + 2, 1588 od.data + ix, (unsigned)incr); 1589 } 1590 length -= incr; 1591 ix += incr; 1592 *pix += 2 + incr; 1593 } 1594 data_string_forget (&od, MDL); 1595 } 1596 1597 if (option != NULL) 1598 option_dereference(&option, MDL); 1599 1600 /* If we can overload, and we have, then PAD and END those spaces. */ 1601 if (first_cutoff && six) { 1602 if ((first_cutoff + six + 1) < sbufend) 1603 memset (&buffer[first_cutoff + six + 1], DHO_PAD, 1604 sbufend - (first_cutoff + six + 1)); 1605 else if (first_cutoff + six >= sbufend) 1606 log_fatal("Second buffer overflow in overloaded options."); 1607 1608 buffer[first_cutoff + six] = DHO_END; 1609 if (ocount != NULL) 1610 *ocount |= 1; /* So that caller knows there's data there. */ 1611 } 1612 1613 if (second_cutoff && tix) { 1614 if (second_cutoff + tix + 1 < buflen) { 1615 memset (&buffer[second_cutoff + tix + 1], DHO_PAD, 1616 buflen - (second_cutoff + tix + 1)); 1617 } else if (second_cutoff + tix >= buflen) 1618 log_fatal("Third buffer overflow in overloaded options."); 1619 1620 buffer[second_cutoff + tix] = DHO_END; 1621 if (ocount != NULL) 1622 *ocount |= 2; /* So that caller knows there's data there. */ 1623 } 1624 1625 if ((six || tix) && (bufix + 3 > bufend)) 1626 log_fatal("Not enough space for option overload option."); 1627 1628 return bufix; 1629 } 1630 1631 /* Return true if the format string has a variable length text option 1632 * ("t"), return false otherwise. 1633 */ 1634 1635 int 1636 format_has_text(format) 1637 const char *format; 1638 { 1639 const char *p; 1640 1641 p = format; 1642 while (*p != '\0') { 1643 switch (*p++) { 1644 case 't': 1645 case 'k': 1646 return 1; 1647 1648 /* These symbols are arbitrary, not fixed or 1649 * determinable length...text options with them is 1650 * invalid (whatever the case, they are never NULL 1651 * terminated). 1652 */ 1653 case 'A': 1654 case 'a': 1655 case 'X': 1656 case 'x': 1657 case 'D': 1658 case 'd': 1659 return 0; 1660 1661 case 'c': 1662 /* 'c' only follows 'D' atoms, and indicates that 1663 * compression may be used. If there was a 'D' 1664 * atom already, we would have returned. So this 1665 * is an error, but continue looking for 't' anyway. 1666 */ 1667 log_error("format_has_text(%s): 'c' atoms are illegal " 1668 "except after 'D' atoms.", format); 1669 break; 1670 1671 /* 'E' is variable length, but not arbitrary...you 1672 * can find its length if you can find an END option. 1673 * N is (n)-byte in length but trails a name of a 1674 * space defining the enumeration values. So treat 1675 * both the same - valid, fixed-length fields. 1676 */ 1677 case 'E': 1678 case 'N': 1679 /* Consume the space name. */ 1680 while ((*p != '\0') && (*p++ != '.')) 1681 ; 1682 break; 1683 1684 default: 1685 break; 1686 } 1687 } 1688 1689 return 0; 1690 } 1691 1692 /* Determine the minimum length of a DHCP option prior to any variable 1693 * or inconsistent length formats, according to its configured format 1694 * variable (and possibly from supplied option cache contents for variable 1695 * length format symbols). 1696 */ 1697 1698 int 1699 format_min_length(format, oc) 1700 const char *format; 1701 struct option_cache *oc; 1702 { 1703 const char *p, *name; 1704 int min_len = 0; 1705 int last_size = 0; 1706 struct enumeration *espace; 1707 1708 p = format; 1709 while (*p != '\0') { 1710 switch (*p++) { 1711 case '6': /* IPv6 Address */ 1712 min_len += 16; 1713 last_size = 16; 1714 break; 1715 1716 case 'I': /* IPv4 Address */ 1717 case 'l': /* int32_t */ 1718 case 'L': /* uint32_t */ 1719 case 'T': /* Lease Time, uint32_t equivalent */ 1720 min_len += 4; 1721 last_size = 4; 1722 break; 1723 1724 case 's': /* int16_t */ 1725 case 'S': /* uint16_t */ 1726 min_len += 2; 1727 last_size = 2; 1728 break; 1729 1730 case 'N': /* Enumeration value. */ 1731 /* Consume space name. */ 1732 name = p; 1733 p = strchr(p, '.'); 1734 if (p == NULL) 1735 log_fatal("Corrupt format: %s", format); 1736 1737 espace = find_enumeration(name, p - name); 1738 if (espace == NULL) { 1739 log_error("Unknown enumeration: %s", format); 1740 /* Max is safest value to return. */ 1741 return INT_MAX; 1742 } 1743 1744 min_len += espace->width; 1745 last_size = espace->width; 1746 p++; 1747 1748 break; 1749 1750 case 'b': /* int8_t */ 1751 case 'B': /* uint8_t */ 1752 case 'F': /* Flag that is always true. */ 1753 case 'f': /* Flag */ 1754 min_len++; 1755 last_size = 1; 1756 break; 1757 1758 case 'o': /* Last argument is optional. */ 1759 min_len -= last_size; 1760 1761 /* XXX: It MAY be possible to sense the end of an 1762 * encapsulated space, but right now this is too 1763 * hard to support. Return a safe value. 1764 */ 1765 case 'e': /* Encapsulation hint (there is an 'E' later). */ 1766 case 'E': /* Encapsulated options. */ 1767 return min_len; 1768 1769 case 'd': /* "Domain name" */ 1770 case 'D': /* "rfc1035 formatted names" */ 1771 case 't': /* "ASCII Text" */ 1772 case 'X': /* "ASCII or Hex Conditional */ 1773 case 'x': /* "Hex" */ 1774 case 'A': /* Array of all that precedes. */ 1775 case 'a': /* Array of preceding symbol. */ 1776 case 'Z': /* nothing. */ 1777 case 'k': /* key name */ 1778 return min_len; 1779 1780 case 'c': /* Compress flag for D atom. */ 1781 log_error("format_min_length(%s): 'c' atom is illegal " 1782 "except after 'D' atom.", format); 1783 return INT_MAX; 1784 1785 default: 1786 /* No safe value is known. */ 1787 log_error("format_min_length(%s): No safe value " 1788 "for unknown format symbols.", format); 1789 return INT_MAX; 1790 } 1791 } 1792 1793 return min_len; 1794 } 1795 1796 1797 /* Format the specified option so that a human can easily read it. */ 1798 /* Maximum pretty printed size */ 1799 #define MAX_OUTPUT_SIZE 32*1024 1800 const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) 1801 struct option *option; 1802 const unsigned char *data; 1803 unsigned len; 1804 int emit_commas; 1805 int emit_quotes; 1806 { 1807 /* We add 128 byte pad so we don't have to add checks everywhere. */ 1808 static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */ 1809 static char *endbuf = optbuf + MAX_OUTPUT_SIZE; 1810 int hunksize = 0; 1811 int opthunk = 0; 1812 int hunkinc = 0; 1813 int numhunk = -1; 1814 int numelem = 0; 1815 int count; 1816 int i, j, k, l; 1817 char fmtbuf[32] = ""; 1818 struct iaddr iaddr; 1819 struct enumeration *enumbuf[32]; /* MUST be same as fmtbuf */ 1820 char *op = optbuf; 1821 const unsigned char *dp = data; 1822 char comma; 1823 unsigned long tval; 1824 isc_boolean_t a_array = ISC_FALSE; 1825 int len_used; 1826 1827 if (emit_commas) 1828 comma = ','; 1829 else 1830 comma = ' '; 1831 1832 memset (enumbuf, 0, sizeof enumbuf); 1833 1834 /* Figure out the size of the data. */ 1835 for (l = i = 0; option -> format [i]; i++, l++) { 1836 if (l >= sizeof(fmtbuf) - 1) 1837 log_fatal("Bounds failure on internal buffer at " 1838 "%s:%d", MDL); 1839 1840 if (!numhunk) { 1841 log_error ("%s: Extra codes in format string: %s", 1842 option -> name, 1843 &(option -> format [i])); 1844 break; 1845 } 1846 numelem++; 1847 fmtbuf [l] = option -> format [i]; 1848 switch (option -> format [i]) { 1849 case 'a': 1850 a_array = ISC_TRUE; 1851 /* Fall through */ 1852 case 'A': 1853 --numelem; 1854 fmtbuf [l] = 0; 1855 numhunk = 0; 1856 break; 1857 case 'E': 1858 /* Skip the universe name. */ 1859 while (option -> format [i] && 1860 option -> format [i] != '.') 1861 i++; 1862 /* Fall Through! */ 1863 case 'X': 1864 for (k = 0; k < len; k++) { 1865 if (!isascii (data [k]) || 1866 !isprint (data [k])) 1867 break; 1868 } 1869 /* If we found no bogus characters, or the bogus 1870 character we found is a trailing NUL, it's 1871 okay to print this option as text. */ 1872 if (k == len || (k + 1 == len && data [k] == 0)) { 1873 fmtbuf [l] = 't'; 1874 numhunk = -2; 1875 } else { 1876 fmtbuf [l] = 'x'; 1877 hunksize++; 1878 comma = ':'; 1879 numhunk = 0; 1880 a_array = ISC_TRUE; 1881 hunkinc = 1; 1882 } 1883 fmtbuf [l + 1] = 0; 1884 break; 1885 case 'c': 1886 /* The 'c' atom is a 'D' modifier only. */ 1887 log_error("'c' atom not following D atom in format " 1888 "string: %s", option->format); 1889 break; 1890 case 'D': 1891 /* 1892 * Skip the 'c' atom, if present. It does not affect 1893 * how we convert wire->text format (if compression is 1894 * present either way, we still process it). 1895 */ 1896 if (option->format[i+1] == 'c') 1897 i++; 1898 fmtbuf[l + 1] = 0; 1899 numhunk = -2; 1900 break; 1901 case 'd': 1902 /* Should not be optional, array or compressed */ 1903 if ((option->format[i+1] == 'o') || 1904 (option->format[i+1] == 'a') || 1905 (option->format[i+1] == 'A') || 1906 (option->format[i+1] == 'c')) { 1907 log_error("%s: Illegal use of domain name: %s", 1908 option->name, 1909 &(option->format[i-1])); 1910 fmtbuf[l + 1] = 0; 1911 } 1912 k = MRns_name_len(data + len, data + hunksize); 1913 if (k == -1) { 1914 log_error("Invalid domain name."); 1915 return "<error>"; 1916 } 1917 hunksize += k; 1918 break; 1919 1920 case 't': 1921 case 'k': 1922 fmtbuf[l + 1] = 0; 1923 numhunk = -2; 1924 break; 1925 case 'N': 1926 k = i; 1927 while (option -> format [i] && 1928 option -> format [i] != '.') 1929 i++; 1930 enumbuf [l] = 1931 find_enumeration (&option -> format [k] + 1, 1932 i - k - 1); 1933 if (enumbuf[l] == NULL) { 1934 hunksize += 1; 1935 hunkinc = 1; 1936 } else { 1937 hunksize += enumbuf[l]->width; 1938 hunkinc = enumbuf[l]->width; 1939 } 1940 break; 1941 case '6': 1942 hunksize += 16; 1943 hunkinc = 16; 1944 break; 1945 case 'I': 1946 case 'l': 1947 case 'L': 1948 case 'T': 1949 hunksize += 4; 1950 hunkinc = 4; 1951 break; 1952 case 's': 1953 case 'S': 1954 hunksize += 2; 1955 hunkinc = 2; 1956 break; 1957 case 'b': 1958 case 'B': 1959 case 'f': 1960 case 'F': 1961 hunksize++; 1962 hunkinc = 1; 1963 break; 1964 case 'e': 1965 case 'Z': 1966 break; 1967 case 'o': 1968 opthunk += hunkinc; 1969 break; 1970 default: 1971 log_error ("%s: garbage in format string: %s", 1972 option -> name, 1973 &(option -> format [i])); 1974 break; 1975 } 1976 } 1977 1978 /* Check for too few bytes... */ 1979 if (hunksize - opthunk > len) { 1980 log_error ("%s: expecting at least %d bytes; got %d", 1981 option -> name, 1982 hunksize, len); 1983 return "<error>"; 1984 } 1985 /* Check for too many bytes... */ 1986 if (numhunk == -1 && hunksize < len) 1987 log_error ("%s: %d extra bytes", 1988 option -> name, 1989 len - hunksize); 1990 1991 /* If this is an array, compute its size. */ 1992 if (numhunk == 0) { 1993 if (a_array == ISC_TRUE) { 1994 /* 1995 * It is an 'a' type array - we repeat the 1996 * last format type. A binary string for 'X' 1997 * is also like this. hunkinc is the size 1998 * of the last format type and we add 1 to 1999 * cover the entire first record. 2000 */ 2001 2002 /* If format string had no valid entries prior to 2003 * 'a' hunkinc will be 0. Ex: "a", "oa", "aA" */ 2004 if (hunkinc == 0) { 2005 log_error ("%s: invalid 'a' format: %s", 2006 option->name, option->format); 2007 return ("<error>"); 2008 } 2009 2010 numhunk = ((len - hunksize) / hunkinc) + 1; 2011 len_used = hunksize + ((numhunk - 1) * hunkinc); 2012 } else { 2013 /* 2014 * It is an 'A' type array - we repeat the 2015 * entire record 2016 */ 2017 2018 /* If format string had no valid entries prior to 2019 * 'A' hunksize will be 0. Ex: "A", "oA", "foA" */ 2020 if (hunksize == 0) { 2021 log_error ("%s: invalid 'A' format: %s", 2022 option->name, option->format); 2023 return ("<error>"); 2024 } 2025 2026 numhunk = len / hunksize; 2027 len_used = numhunk * hunksize; 2028 } 2029 2030 /* See if we got an exact number of hunks. */ 2031 if (len_used < len) { 2032 log_error ("%s: %d extra bytes at end of array\n", 2033 option -> name, 2034 len - len_used); 2035 } 2036 } 2037 2038 2039 /* A one-hunk array prints the same as a single hunk. */ 2040 if (numhunk < 0) 2041 numhunk = 1; 2042 2043 /* Cycle through the array (or hunk) printing the data. */ 2044 for (i = 0; i < numhunk; i++) { 2045 if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) { 2046 /* 2047 * For 'a' type of arrays we repeat 2048 * only the last format character 2049 * We should never hit the case of numelem == 0 2050 * but let's include the check to be safe. 2051 */ 2052 j = numelem - 1; 2053 } else { 2054 /* 2055 * for other types of arrays or the first 2056 * time through for 'a' types, we go through 2057 * the entire set of format characters. 2058 */ 2059 j = 0; 2060 } 2061 2062 for (; j < numelem; j++) { 2063 switch (fmtbuf [j]) { 2064 case 't': 2065 case 'k': 2066 /* endbuf-1 leaves room for NULL. */ 2067 k = pretty_text(&op, endbuf - 1, &dp, 2068 data + len, emit_quotes); 2069 if (k == -1) { 2070 log_error("Error printing text."); 2071 break; 2072 } 2073 *op = 0; 2074 break; 2075 case 'd': /* RFC1035 format name */ 2076 k = MRns_name_len(data + len, dp); 2077 /* Already tested... */ 2078 if (k == -1) { 2079 log_error("invalid domain name."); 2080 return "<error>"; 2081 } 2082 pretty_dname(&op, endbuf-1, dp, data + len); 2083 /* pretty_dname does not add the nul */ 2084 *op = '\0'; 2085 dp += k; 2086 break; 2087 case 'D': /* RFC1035 format name list */ 2088 for( ; dp < (data + len) ; dp += k) { 2089 unsigned char nbuff[NS_MAXCDNAME]; 2090 const unsigned char *nbp, *nend; 2091 2092 nend = &nbuff[sizeof(nbuff)]; 2093 2094 /* If this is for ISC DHCP consumption 2095 * (emit_quotes), lay it out as a list 2096 * of STRING tokens. Otherwise, it is 2097 * a space-separated list of DNS- 2098 * escaped names as /etc/resolv.conf 2099 * might digest. 2100 */ 2101 if (dp != data) { 2102 if (op + 2 > endbuf) 2103 break; 2104 2105 if (emit_quotes) 2106 *op++ = ','; 2107 *op++ = ' '; 2108 } 2109 2110 /* XXX: if fmtbuf[j+1] != 'c', we 2111 * should warn if the data was 2112 * compressed anyway. 2113 */ 2114 k = MRns_name_unpack(data, 2115 data + len, 2116 dp, nbuff, 2117 sizeof(nbuff)); 2118 2119 if (k == -1) { 2120 log_error("Invalid domain " 2121 "list."); 2122 break; 2123 } 2124 2125 /* If emit_quotes, then use ISC DHCP 2126 * escapes. Otherwise, rely only on 2127 * MRns_name_ntop(). 2128 */ 2129 if (emit_quotes) { 2130 nbp = nbuff; 2131 pretty_domain(&op, endbuf-1, 2132 &nbp, nend); 2133 } else { 2134 /* MRns_name_ntop() includes 2135 * a trailing NUL in its 2136 * count. 2137 */ 2138 count = MRns_name_ntop( 2139 nbuff, op, 2140 (endbuf-op)-1); 2141 2142 if (count <= 0) { 2143 log_error("Invalid " 2144 "domain name."); 2145 break; 2146 } 2147 2148 /* Consume all but the trailing 2149 * NUL. 2150 */ 2151 op += count - 1; 2152 2153 /* Replace the trailing NUL 2154 * with the implicit root 2155 * (in the unlikely event the 2156 * domain name /is/ the root). 2157 */ 2158 *op++ = '.'; 2159 } 2160 } 2161 *op = '\0'; 2162 break; 2163 /* pretty-printing an array of enums is 2164 going to get ugly. */ 2165 case 'N': 2166 if (!enumbuf [j]) { 2167 tval = *dp++; 2168 goto enum_as_num; 2169 } 2170 2171 switch (enumbuf[j]->width) { 2172 case 1: 2173 tval = getUChar(dp); 2174 break; 2175 2176 case 2: 2177 tval = getUShort(dp); 2178 break; 2179 2180 case 4: 2181 tval = getULong(dp); 2182 break; 2183 2184 default: 2185 log_fatal("Impossible case at %s:%d.", 2186 MDL); 2187 return "<double impossible condition>"; 2188 } 2189 2190 for (i = 0; ;i++) { 2191 if (!enumbuf [j] -> values [i].name) 2192 goto enum_as_num; 2193 if (enumbuf [j] -> values [i].value == 2194 tval) 2195 break; 2196 } 2197 strcpy (op, enumbuf [j] -> values [i].name); 2198 dp += enumbuf[j]->width; 2199 break; 2200 2201 enum_as_num: 2202 sprintf(op, "%lu", tval); 2203 break; 2204 2205 case 'I': 2206 iaddr.len = 4; 2207 memcpy(iaddr.iabuf, dp, 4); 2208 strcpy(op, piaddr(iaddr)); 2209 dp += 4; 2210 break; 2211 case '6': 2212 iaddr.len = 16; 2213 memcpy(iaddr.iabuf, dp, 16); 2214 strcpy(op, piaddr(iaddr)); 2215 dp += 16; 2216 break; 2217 case 'l': 2218 sprintf (op, "%ld", (long)getLong (dp)); 2219 dp += 4; 2220 break; 2221 case 'T': 2222 tval = getULong (dp); 2223 if (tval == -1) 2224 sprintf (op, "%s", "infinite"); 2225 else 2226 sprintf(op, "%lu", tval); 2227 break; 2228 case 'L': 2229 sprintf(op, "%lu", 2230 (unsigned long)getULong(dp)); 2231 dp += 4; 2232 break; 2233 case 's': 2234 sprintf (op, "%d", (int)getShort (dp)); 2235 dp += 2; 2236 break; 2237 case 'S': 2238 sprintf(op, "%u", (unsigned)getUShort(dp)); 2239 dp += 2; 2240 break; 2241 case 'b': 2242 sprintf (op, "%d", *(const char *)dp++); 2243 break; 2244 case 'B': 2245 sprintf (op, "%d", *dp++); 2246 break; 2247 case 'X': 2248 case 'x': 2249 sprintf (op, "%x", *dp++); 2250 break; 2251 case 'f': 2252 strcpy (op, *dp++ ? "true" : "false"); 2253 break; 2254 case 'F': 2255 strcpy (op, "true"); 2256 break; 2257 case 'e': 2258 case 'Z': 2259 *op = '\0'; 2260 break; 2261 default: 2262 log_error ("Unexpected format code %c", 2263 fmtbuf [j]); 2264 } 2265 2266 op += strlen (op); 2267 if (op >= endbuf) { 2268 log_error ("Option data exceeds" 2269 " maximum size %d", MAX_OUTPUT_SIZE); 2270 return ("<error>"); 2271 } 2272 2273 if (dp == data + len) 2274 break; 2275 if (j + 1 < numelem && comma != ':') 2276 *op++ = ' '; 2277 } 2278 if (i + 1 < numhunk) { 2279 *op++ = comma; 2280 } 2281 if (dp == data + len) 2282 break; 2283 } 2284 return optbuf; 2285 } 2286 2287 int get_option (result, universe, packet, lease, client_state, 2288 in_options, cfg_options, options, scope, code, file, line) 2289 struct data_string *result; 2290 struct universe *universe; 2291 struct packet *packet; 2292 struct lease *lease; 2293 struct client_state *client_state; 2294 struct option_state *in_options; 2295 struct option_state *cfg_options; 2296 struct option_state *options; 2297 struct binding_scope **scope; 2298 unsigned code; 2299 const char *file; 2300 int line; 2301 { 2302 struct option_cache *oc; 2303 2304 if (!universe -> lookup_func) 2305 return 0; 2306 oc = ((*universe -> lookup_func) (universe, options, code)); 2307 if (!oc) 2308 return 0; 2309 if (!evaluate_option_cache (result, packet, lease, client_state, 2310 in_options, cfg_options, scope, oc, 2311 file, line)) 2312 return 0; 2313 return 1; 2314 } 2315 2316 /* 2317 * Look for the option and dig out the value assoicated with it. 2318 * Currently this is used for 1 byte integers, it maybe expanded 2319 * in the future to handle other integers at which point it will 2320 * need a size argument. 2321 */ 2322 int get_option_int (result, universe, packet, lease, client_state, 2323 in_options, cfg_options, options, scope, code, file, line) 2324 int *result; 2325 struct universe *universe; 2326 struct packet *packet; 2327 struct lease *lease; 2328 struct client_state *client_state; 2329 struct option_state *in_options; 2330 struct option_state *cfg_options; 2331 struct option_state *options; 2332 struct binding_scope **scope; 2333 unsigned code; 2334 const char *file; 2335 int line; 2336 { 2337 struct option_cache *oc; 2338 struct data_string d1; 2339 int rcode = 0; 2340 2341 /* basic sanity checks */ 2342 if ((options == NULL) || (universe->lookup_func == NULL)) 2343 return (0); 2344 2345 /* find the option cache */ 2346 oc = ((*universe->lookup_func)(universe, options, code)); 2347 if (!oc) 2348 return (0); 2349 2350 /* if there is a value get it into the string */ 2351 memset(&d1, 0, sizeof(d1)); 2352 if (!evaluate_option_cache(&d1, packet, lease, client_state, 2353 in_options, cfg_options, scope, oc, 2354 file, line)) 2355 return (0); 2356 2357 /* If the length matches extract the value for the return */ 2358 if (d1.len == 1) { 2359 *result = d1.data[0]; 2360 rcode = 1; 2361 } 2362 data_string_forget(&d1, MDL); 2363 2364 return (rcode); 2365 } 2366 2367 void set_option (universe, options, option, op) 2368 struct universe *universe; 2369 struct option_state *options; 2370 struct option_cache *option; 2371 enum statement_op op; 2372 { 2373 struct option_cache *oc, *noc; 2374 2375 switch (op) { 2376 case if_statement: 2377 case add_statement: 2378 case eval_statement: 2379 case break_statement: 2380 default: 2381 log_error ("bogus statement type in set_option."); 2382 break; 2383 2384 case default_option_statement: 2385 oc = lookup_option (universe, options, 2386 option -> option -> code); 2387 if (oc) 2388 break; 2389 save_option (universe, options, option); 2390 break; 2391 2392 case supersede_option_statement: 2393 case send_option_statement: 2394 /* Install the option, replacing any existing version. */ 2395 save_option (universe, options, option); 2396 break; 2397 2398 case append_option_statement: 2399 case prepend_option_statement: 2400 oc = lookup_option (universe, options, 2401 option -> option -> code); 2402 if (!oc) { 2403 save_option (universe, options, option); 2404 break; 2405 } 2406 /* If it's not an expression, make it into one. */ 2407 if (!oc -> expression && oc -> data.len) { 2408 if (!expression_allocate (&oc -> expression, MDL)) { 2409 log_error ("Can't allocate const expression."); 2410 break; 2411 } 2412 oc -> expression -> op = expr_const_data; 2413 data_string_copy 2414 (&oc -> expression -> data.const_data, 2415 &oc -> data, MDL); 2416 data_string_forget (&oc -> data, MDL); 2417 } 2418 noc = (struct option_cache *)0; 2419 if (!option_cache_allocate (&noc, MDL)) 2420 break; 2421 if (op == append_option_statement) { 2422 if (!make_concat (&noc -> expression, 2423 oc -> expression, 2424 option -> expression)) { 2425 option_cache_dereference (&noc, MDL); 2426 break; 2427 } 2428 } else { 2429 if (!make_concat (&noc -> expression, 2430 option -> expression, 2431 oc -> expression)) { 2432 option_cache_dereference (&noc, MDL); 2433 break; 2434 } 2435 } 2436 2437 /* If we are trying to combine compressed domain-lists then 2438 * we need to change the expression opcode. The lists must 2439 * be decompressed, combined, and then recompressed to work 2440 * correctly. You cannot simply add two compressed lists 2441 * together. */ 2442 switch (((memcmp(option->option->format, "Dc", 2) == 0) + 2443 (memcmp(oc->option->format, "Dc", 2) == 0))) { 2444 case 1: 2445 /* Only one is "Dc", this won't work 2446 * Not sure if you can make this occur, but just 2447 * in case. */ 2448 log_error ("Both options must be Dc format"); 2449 option_cache_dereference (&noc, MDL); 2450 return; 2451 case 2: 2452 /* Both are "Dc", change the code */ 2453 noc->expression->op = expr_concat_dclist; 2454 break; 2455 default: 2456 /* Neither are "Dc", so as you were */ 2457 break; 2458 } 2459 2460 option_reference(&(noc->option), oc->option, MDL); 2461 save_option (universe, options, noc); 2462 option_cache_dereference (&noc, MDL); 2463 break; 2464 } 2465 } 2466 2467 struct option_cache *lookup_option (universe, options, code) 2468 struct universe *universe; 2469 struct option_state *options; 2470 unsigned code; 2471 { 2472 if (!options) 2473 return (struct option_cache *)0; 2474 if (universe -> lookup_func) 2475 return (*universe -> lookup_func) (universe, options, code); 2476 else 2477 log_error ("can't look up options in %s space.", 2478 universe -> name); 2479 return (struct option_cache *)0; 2480 } 2481 2482 struct option_cache *lookup_hashed_option (universe, options, code) 2483 struct universe *universe; 2484 struct option_state *options; 2485 unsigned code; 2486 { 2487 int hashix; 2488 pair bptr; 2489 pair *hash; 2490 2491 /* Make sure there's a hash table. */ 2492 if (universe -> index >= options -> universe_count || 2493 !(options -> universes [universe -> index])) 2494 return (struct option_cache *)0; 2495 2496 hash = options -> universes [universe -> index]; 2497 2498 hashix = compute_option_hash (code); 2499 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) { 2500 if (((struct option_cache *)(bptr -> car)) -> option -> code == 2501 code) 2502 return (struct option_cache *)(bptr -> car); 2503 } 2504 return (struct option_cache *)0; 2505 } 2506 2507 /* Save a specified buffer into an option cache. */ 2508 int 2509 save_option_buffer(struct universe *universe, struct option_state *options, 2510 struct buffer *bp, unsigned char *buffer, unsigned length, 2511 unsigned code, int terminatep) 2512 { 2513 struct option_cache *op = NULL; 2514 int status = 1; 2515 2516 status = prepare_option_buffer(universe, bp, buffer, length, code, 2517 terminatep, &op); 2518 2519 if (status == 0) 2520 goto cleanup; 2521 2522 save_option(universe, options, op); 2523 2524 cleanup: 2525 if (op != NULL) 2526 option_cache_dereference(&op, MDL); 2527 2528 return status; 2529 } 2530 2531 /* Append a specified buffer onto the tail of an option cache. */ 2532 int 2533 append_option_buffer(struct universe *universe, struct option_state *options, 2534 struct buffer *bp, unsigned char *buffer, unsigned length, 2535 unsigned code, int terminatep) 2536 { 2537 struct option_cache *op = NULL; 2538 int status = 1; 2539 2540 status = prepare_option_buffer(universe, bp, buffer, length, code, 2541 terminatep, &op); 2542 2543 if (status == 0) 2544 goto cleanup; 2545 2546 also_save_option(universe, options, op); 2547 2548 cleanup: 2549 if (op != NULL) 2550 option_cache_dereference(&op, MDL); 2551 2552 return status; 2553 } 2554 2555 /* Create/copy a buffer into a new option cache. */ 2556 static int 2557 prepare_option_buffer(struct universe *universe, struct buffer *bp, 2558 unsigned char *buffer, unsigned length, unsigned code, 2559 int terminatep, struct option_cache **opp) 2560 { 2561 struct buffer *lbp = NULL; 2562 struct option *option = NULL; 2563 struct option_cache *op; 2564 int status = 1; 2565 2566 /* Code sizes of 8, 16, and 32 bits are allowed. */ 2567 switch(universe->tag_size) { 2568 case 1: 2569 if (code > 0xff) 2570 return 0; 2571 break; 2572 case 2: 2573 if (code > 0xffff) 2574 return 0; 2575 break; 2576 case 4: 2577 if (code > 0xffffffff) 2578 return 0; 2579 break; 2580 2581 default: 2582 log_fatal("Inconsistent universe tag size at %s:%d.", MDL); 2583 } 2584 2585 option_code_hash_lookup(&option, universe->code_hash, &code, 0, MDL); 2586 2587 /* If we created an option structure for each option a client 2588 * supplied, it's possible we may create > 2^32 option structures. 2589 * That's not feasible. So by failing to enter these option 2590 * structures into the code and name hash tables, references will 2591 * never be more than 1 - when the option cache is destroyed, this 2592 * will be cleaned up. 2593 */ 2594 if (!option) { 2595 char nbuf[sizeof("unknown-4294967295")]; 2596 2597 sprintf(nbuf, "unknown-%u", code); 2598 2599 option = new_option(nbuf, MDL); 2600 2601 if (!option) 2602 return 0; 2603 2604 option->format = default_option_format; 2605 option->universe = universe; 2606 option->code = code; 2607 2608 /* new_option() doesn't set references, pretend. */ 2609 option->refcnt = 1; 2610 } 2611 2612 if (!option_cache_allocate (opp, MDL)) { 2613 log_error("No memory for option code %s.%s.", 2614 universe->name, option->name); 2615 status = 0; 2616 goto cleanup; 2617 } 2618 2619 /* Pointer rather than double pointer makes for less parens. */ 2620 op = *opp; 2621 2622 option_reference(&op->option, option, MDL); 2623 2624 /* If we weren't passed a buffer in which the data are saved and 2625 refcounted, allocate one now. */ 2626 if (!bp) { 2627 if (!buffer_allocate (&lbp, length + terminatep, MDL)) { 2628 log_error ("no memory for option buffer."); 2629 2630 status = 0; 2631 goto cleanup; 2632 } 2633 memcpy (lbp -> data, buffer, length + terminatep); 2634 bp = lbp; 2635 buffer = &bp -> data [0]; /* Refer to saved buffer. */ 2636 } 2637 2638 /* Reference buffer copy to option cache. */ 2639 op -> data.buffer = (struct buffer *)0; 2640 buffer_reference (&op -> data.buffer, bp, MDL); 2641 2642 /* Point option cache into buffer. */ 2643 op -> data.data = buffer; 2644 op -> data.len = length; 2645 2646 if (terminatep) { 2647 /* NUL terminate (we can get away with this because we (or 2648 the caller!) allocated one more than the buffer size, and 2649 because the byte following the end of an option is always 2650 the code of the next option, which the caller is getting 2651 out of the *original* buffer. */ 2652 buffer [length] = 0; 2653 op -> data.terminated = 1; 2654 } else 2655 op -> data.terminated = 0; 2656 2657 /* If this option is ultimately a text option, null determinate to 2658 * comply with RFC2132 section 2. Mark a flag so this can be sensed 2659 * later to echo NULLs back to clients that supplied them (they 2660 * probably expect them). 2661 */ 2662 if (format_has_text(option->format)) { 2663 int min_len = format_min_length(option->format, op); 2664 2665 while ((op->data.len > min_len) && 2666 (op->data.data[op->data.len-1] == '\0')) { 2667 op->data.len--; 2668 op->flags |= OPTION_HAD_NULLS; 2669 } 2670 } 2671 2672 /* And let go of our references. */ 2673 cleanup: 2674 if (lbp != NULL) 2675 buffer_dereference(&lbp, MDL); 2676 option_dereference(&option, MDL); 2677 2678 return status; 2679 } 2680 2681 static void 2682 count_options(struct option_cache *dummy_oc, 2683 struct packet *dummy_packet, 2684 struct lease *dummy_lease, 2685 struct client_state *dummy_client_state, 2686 struct option_state *dummy_opt_state, 2687 struct option_state *opt_state, 2688 struct binding_scope **dummy_binding_scope, 2689 struct universe *dummy_universe, 2690 void *void_accumulator) { 2691 int *accumulator = (int *)void_accumulator; 2692 2693 *accumulator += 1; 2694 } 2695 2696 static void 2697 collect_oro(struct option_cache *oc, 2698 struct packet *dummy_packet, 2699 struct lease *dummy_lease, 2700 struct client_state *dummy_client_state, 2701 struct option_state *dummy_opt_state, 2702 struct option_state *opt_state, 2703 struct binding_scope **dummy_binding_scope, 2704 struct universe *dummy_universe, 2705 void *void_oro) { 2706 struct data_string *oro = (struct data_string *)void_oro; 2707 2708 putUShort(oro->buffer->data + oro->len, oc->option->code); 2709 oro->len += 2; 2710 } 2711 2712 /* build_server_oro() is presently unusued, but may be used at a future date 2713 * with support for Reconfigure messages (as a hint to the client about new 2714 * option value contents). 2715 */ 2716 void 2717 build_server_oro(struct data_string *server_oro, 2718 struct option_state *options, 2719 const char *file, int line) { 2720 int num_opts; 2721 int i; 2722 struct option *o; 2723 2724 /* 2725 * Count the number of options, so we can allocate enough memory. 2726 * We want to mention sub-options too, so check all universes. 2727 */ 2728 num_opts = 0; 2729 option_space_foreach(NULL, NULL, NULL, NULL, options, 2730 NULL, &dhcpv6_universe, (void *)&num_opts, 2731 count_options); 2732 for (i=0; i < options->universe_count; i++) { 2733 if (options->universes[i] != NULL) { 2734 o = universes[i]->enc_opt; 2735 while (o != NULL) { 2736 if (o->universe == &dhcpv6_universe) { 2737 num_opts++; 2738 break; 2739 } 2740 o = o->universe->enc_opt; 2741 } 2742 } 2743 } 2744 2745 /* 2746 * Allocate space. 2747 */ 2748 memset(server_oro, 0, sizeof(*server_oro)); 2749 if (!buffer_allocate(&server_oro->buffer, num_opts * 2, MDL)) { 2750 log_fatal("no memory to build server ORO"); 2751 } 2752 server_oro->data = server_oro->buffer->data; 2753 2754 /* 2755 * Copy the data in. 2756 * We want to mention sub-options too, so check all universes. 2757 */ 2758 server_oro->len = 0; /* gets set in collect_oro */ 2759 option_space_foreach(NULL, NULL, NULL, NULL, options, 2760 NULL, &dhcpv6_universe, (void *)server_oro, 2761 collect_oro); 2762 for (i=0; i < options->universe_count; i++) { 2763 if (options->universes[i] != NULL) { 2764 o = universes[i]->enc_opt; 2765 while (o != NULL) { 2766 if (o->universe == &dhcpv6_universe) { 2767 unsigned char *tmp; 2768 tmp = server_oro->buffer->data; 2769 putUShort(tmp + server_oro->len, 2770 o->code); 2771 server_oro->len += 2; 2772 break; 2773 } 2774 o = o->universe->enc_opt; 2775 } 2776 } 2777 } 2778 } 2779 2780 /* Wrapper function to put an option cache into an option state. */ 2781 void 2782 save_option(struct universe *universe, struct option_state *options, 2783 struct option_cache *oc) 2784 { 2785 if (universe->save_func) 2786 (*universe->save_func)(universe, options, oc, ISC_FALSE); 2787 else 2788 log_error("can't store options in %s space.", universe->name); 2789 } 2790 2791 /* Wrapper function to append an option cache into an option state's list. */ 2792 void 2793 also_save_option(struct universe *universe, struct option_state *options, 2794 struct option_cache *oc) 2795 { 2796 if (universe->save_func) 2797 (*universe->save_func)(universe, options, oc, ISC_TRUE); 2798 else 2799 log_error("can't store options in %s space.", universe->name); 2800 } 2801 2802 void 2803 save_hashed_option(struct universe *universe, struct option_state *options, 2804 struct option_cache *oc, isc_boolean_t appendp) 2805 { 2806 int hashix; 2807 pair bptr; 2808 pair *hash = options -> universes [universe -> index]; 2809 struct option_cache **ocloc; 2810 2811 if (oc -> refcnt == 0) 2812 abort (); 2813 2814 /* Compute the hash. */ 2815 hashix = compute_option_hash (oc -> option -> code); 2816 2817 /* If there's no hash table, make one. */ 2818 if (!hash) { 2819 hash = (pair *)dmalloc (OPTION_HASH_SIZE * sizeof *hash, MDL); 2820 if (!hash) { 2821 log_error ("no memory to store %s.%s", 2822 universe -> name, oc -> option -> name); 2823 return; 2824 } 2825 memset (hash, 0, OPTION_HASH_SIZE * sizeof *hash); 2826 options -> universes [universe -> index] = (void *)hash; 2827 } else { 2828 /* Try to find an existing option matching the new one. */ 2829 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) { 2830 if (((struct option_cache *) 2831 (bptr -> car)) -> option -> code == 2832 oc -> option -> code) 2833 break; 2834 } 2835 2836 /* Deal with collisions on the hash list. */ 2837 if (bptr) { 2838 ocloc = (struct option_cache **)&bptr->car; 2839 2840 /* 2841 * If appendp is set, append it onto the tail of the 2842 * ->next list. If it is not set, rotate it into 2843 * position at the head of the list. 2844 */ 2845 if (appendp) { 2846 do { 2847 ocloc = &(*ocloc)->next; 2848 } while (*ocloc != NULL); 2849 } else { 2850 option_cache_dereference(ocloc, MDL); 2851 } 2852 2853 option_cache_reference(ocloc, oc, MDL); 2854 return; 2855 } 2856 } 2857 2858 /* Otherwise, just put the new one at the head of the list. */ 2859 bptr = new_pair (MDL); 2860 if (!bptr) { 2861 log_error ("No memory for option_cache reference."); 2862 return; 2863 } 2864 bptr -> cdr = hash [hashix]; 2865 bptr -> car = 0; 2866 option_cache_reference ((struct option_cache **)&bptr -> car, oc, MDL); 2867 hash [hashix] = bptr; 2868 } 2869 2870 void delete_option (universe, options, code) 2871 struct universe *universe; 2872 struct option_state *options; 2873 int code; 2874 { 2875 if (universe -> delete_func) 2876 (*universe -> delete_func) (universe, options, code); 2877 else 2878 log_error ("can't delete options from %s space.", 2879 universe -> name); 2880 } 2881 2882 void delete_hashed_option (universe, options, code) 2883 struct universe *universe; 2884 struct option_state *options; 2885 int code; 2886 { 2887 int hashix; 2888 pair bptr, prev = (pair)0; 2889 pair *hash = options -> universes [universe -> index]; 2890 2891 /* There may not be any options in this space. */ 2892 if (!hash) 2893 return; 2894 2895 /* Try to find an existing option matching the new one. */ 2896 hashix = compute_option_hash (code); 2897 for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) { 2898 if (((struct option_cache *)(bptr -> car)) -> option -> code 2899 == code) 2900 break; 2901 prev = bptr; 2902 } 2903 /* If we found one, wipe it out... */ 2904 if (bptr) { 2905 if (prev) 2906 prev -> cdr = bptr -> cdr; 2907 else 2908 hash [hashix] = bptr -> cdr; 2909 option_cache_dereference 2910 ((struct option_cache **)(&bptr -> car), MDL); 2911 free_pair (bptr, MDL); 2912 } 2913 } 2914 2915 extern struct option_cache *free_option_caches; /* XXX */ 2916 2917 int option_cache_dereference (ptr, file, line) 2918 struct option_cache **ptr; 2919 const char *file; 2920 int line; 2921 { 2922 if (!ptr || !*ptr) { 2923 log_error ("Null pointer in option_cache_dereference: %s(%d)", 2924 file, line); 2925 #if defined (POINTER_DEBUG) 2926 abort (); 2927 #else 2928 return 0; 2929 #endif 2930 } 2931 2932 (*ptr) -> refcnt--; 2933 rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC); 2934 if (!(*ptr) -> refcnt) { 2935 if ((*ptr) -> data.buffer) 2936 data_string_forget (&(*ptr) -> data, file, line); 2937 if ((*ptr)->option) 2938 option_dereference(&(*ptr)->option, MDL); 2939 if ((*ptr) -> expression) 2940 expression_dereference (&(*ptr) -> expression, 2941 file, line); 2942 if ((*ptr) -> next) 2943 option_cache_dereference (&((*ptr) -> next), 2944 file, line); 2945 /* Put it back on the free list... */ 2946 (*ptr) -> expression = (struct expression *)free_option_caches; 2947 free_option_caches = *ptr; 2948 dmalloc_reuse (free_option_caches, (char *)0, 0, 0); 2949 } 2950 if ((*ptr) -> refcnt < 0) { 2951 log_error ("%s(%d): negative refcnt!", file, line); 2952 #if defined (DEBUG_RC_HISTORY) 2953 dump_rc_history (*ptr); 2954 #endif 2955 #if defined (POINTER_DEBUG) 2956 abort (); 2957 #else 2958 *ptr = (struct option_cache *)0; 2959 return 0; 2960 #endif 2961 } 2962 *ptr = (struct option_cache *)0; 2963 return 1; 2964 2965 } 2966 2967 int hashed_option_state_dereference (universe, state, file, line) 2968 struct universe *universe; 2969 struct option_state *state; 2970 const char *file; 2971 int line; 2972 { 2973 pair *heads; 2974 pair cp, next; 2975 int i; 2976 2977 /* Get the pointer to the array of hash table bucket heads. */ 2978 heads = (pair *)(state -> universes [universe -> index]); 2979 if (!heads) 2980 return 0; 2981 2982 /* For each non-null head, loop through all the buckets dereferencing 2983 the attached option cache structures and freeing the buckets. */ 2984 for (i = 0; i < OPTION_HASH_SIZE; i++) { 2985 for (cp = heads [i]; cp; cp = next) { 2986 next = cp -> cdr; 2987 option_cache_dereference 2988 ((struct option_cache **)&cp -> car, 2989 file, line); 2990 free_pair (cp, file, line); 2991 } 2992 } 2993 2994 dfree (heads, file, line); 2995 state -> universes [universe -> index] = (void *)0; 2996 return 1; 2997 } 2998 2999 /* The 'data_string' primitive doesn't have an appension mechanism. 3000 * This function must then append a new option onto an existing buffer 3001 * by first duplicating the original buffer and appending the desired 3002 * values, followed by coping the new value into place. 3003 */ 3004 int 3005 append_option(struct data_string *dst, struct universe *universe, 3006 struct option *option, struct data_string *src) 3007 { 3008 struct data_string tmp; 3009 3010 if (src->len == 0 && option->format[0] != 'Z') 3011 return 0; 3012 3013 memset(&tmp, 0, sizeof(tmp)); 3014 3015 /* Allocate a buffer to hold existing data, the current option's 3016 * tag and length, and the option's content. 3017 */ 3018 if (!buffer_allocate(&tmp.buffer, 3019 (dst->len + universe->length_size + 3020 universe->tag_size + src->len), MDL)) { 3021 /* XXX: This kills all options presently stored in the 3022 * destination buffer. This is the way the original code 3023 * worked, and assumes an 'all or nothing' approach to 3024 * eg encapsulated option spaces. It may or may not be 3025 * desirable. 3026 */ 3027 data_string_forget(dst, MDL); 3028 return 0; 3029 } 3030 tmp.data = tmp.buffer->data; 3031 3032 /* Copy the existing data off the destination. */ 3033 if (dst->len != 0) 3034 memcpy(tmp.buffer->data, dst->data, dst->len); 3035 tmp.len = dst->len; 3036 3037 /* Place the new option tag and length. */ 3038 (*universe->store_tag)(tmp.buffer->data + tmp.len, option->code); 3039 tmp.len += universe->tag_size; 3040 (*universe->store_length)(tmp.buffer->data + tmp.len, src->len); 3041 tmp.len += universe->length_size; 3042 3043 /* Copy the option contents onto the end. */ 3044 memcpy(tmp.buffer->data + tmp.len, src->data, src->len); 3045 tmp.len += src->len; 3046 3047 /* Play the shell game. */ 3048 data_string_forget(dst, MDL); 3049 data_string_copy(dst, &tmp, MDL); 3050 data_string_forget(&tmp, MDL); 3051 return 1; 3052 } 3053 3054 int 3055 store_option(struct data_string *result, struct universe *universe, 3056 struct packet *packet, struct lease *lease, 3057 struct client_state *client_state, 3058 struct option_state *in_options, struct option_state *cfg_options, 3059 struct binding_scope **scope, struct option_cache *oc) 3060 { 3061 struct data_string tmp; 3062 struct universe *subu=NULL; 3063 int status; 3064 char *start, *end; 3065 3066 memset(&tmp, 0, sizeof(tmp)); 3067 3068 if (evaluate_option_cache(&tmp, packet, lease, client_state, 3069 in_options, cfg_options, scope, oc, MDL)) { 3070 /* If the option is an extended 'e'ncapsulation (not a 3071 * direct 'E'ncapsulation), append the encapsulated space 3072 * onto the currently prepared value. 3073 */ 3074 do { 3075 if (oc->option->format && 3076 oc->option->format[0] == 'e') { 3077 /* Skip forward to the universe name. */ 3078 start = strchr(oc->option->format, 'E'); 3079 if (start == NULL) 3080 break; 3081 3082 /* Locate the name-terminating '.'. */ 3083 end = strchr(++start, '.'); 3084 3085 /* A zero-length name is not allowed in 3086 * these kinds of encapsulations. 3087 */ 3088 if (end == NULL || start == end) 3089 break; 3090 3091 universe_hash_lookup(&subu, universe_hash, 3092 start, end - start, MDL); 3093 3094 if (subu == NULL) { 3095 log_error("store_option: option %d " 3096 "refers to unknown " 3097 "option space '%.*s'.", 3098 oc->option->code, 3099 (int)(end - start), start); 3100 break; 3101 } 3102 3103 /* Append encapsulations, if any. We 3104 * already have the prepended values, so 3105 * we send those even if there are no 3106 * encapsulated options (and ->encapsulate() 3107 * returns zero). 3108 */ 3109 subu->encapsulate(&tmp, packet, lease, 3110 client_state, in_options, 3111 cfg_options, scope, subu); 3112 subu = NULL; 3113 } 3114 } while (ISC_FALSE); 3115 3116 status = append_option(result, universe, oc->option, &tmp); 3117 data_string_forget(&tmp, MDL); 3118 3119 return status; 3120 } 3121 3122 return 0; 3123 } 3124 3125 int option_space_encapsulate (result, packet, lease, client_state, 3126 in_options, cfg_options, scope, name) 3127 struct data_string *result; 3128 struct packet *packet; 3129 struct lease *lease; 3130 struct client_state *client_state; 3131 struct option_state *in_options; 3132 struct option_state *cfg_options; 3133 struct binding_scope **scope; 3134 struct data_string *name; 3135 { 3136 struct universe *u = NULL; 3137 int status = 0; 3138 3139 universe_hash_lookup(&u, universe_hash, 3140 (const char *)name->data, name->len, MDL); 3141 if (u == NULL) { 3142 log_error("option_space_encapsulate: option space '%.*s' does " 3143 "not exist, but is configured.", 3144 (int)name->len, name->data); 3145 return status; 3146 } 3147 3148 if (u->encapsulate != NULL) { 3149 if (u->encapsulate(result, packet, lease, client_state, 3150 in_options, cfg_options, scope, u)) 3151 status = 1; 3152 } else 3153 log_error("encapsulation requested for '%s' with no support.", 3154 name->data); 3155 3156 return status; 3157 } 3158 3159 /* Attempt to store any 'E'ncapsulated options that have not yet been 3160 * placed on the option buffer by the above (configuring a value in 3161 * the space over-rides any values in the child universe). 3162 * 3163 * Note that there are far fewer universes than there will ever be 3164 * options in any universe. So it is faster to traverse the 3165 * configured universes, checking if each is encapsulated in the 3166 * current universe, and if so attempting to do so. 3167 * 3168 * For each configured universe for this configuration option space, 3169 * which is encapsulated within the current universe, can not be found 3170 * by the lookup function (the universe-specific encapsulation 3171 * functions would already have stored such a value), and encapsulates 3172 * at least one option, append it. 3173 */ 3174 static int 3175 search_subencapsulation(struct data_string *result, struct packet *packet, 3176 struct lease *lease, struct client_state *client_state, 3177 struct option_state *in_options, 3178 struct option_state *cfg_options, 3179 struct binding_scope **scope, 3180 struct universe *universe) 3181 { 3182 struct data_string sub; 3183 struct universe *subu; 3184 int i, status = 0; 3185 3186 memset(&sub, 0, sizeof(sub)); 3187 for (i = 0 ; i < cfg_options->universe_count ; i++) { 3188 subu = universes[i]; 3189 3190 if (subu == NULL) 3191 log_fatal("Impossible condition at %s:%d.", MDL); 3192 3193 if (subu->enc_opt != NULL && 3194 subu->enc_opt->universe == universe && 3195 subu->enc_opt->format != NULL && 3196 subu->enc_opt->format[0] == 'E' && 3197 lookup_option(universe, cfg_options, 3198 subu->enc_opt->code) == NULL && 3199 subu->encapsulate(&sub, packet, lease, client_state, 3200 in_options, cfg_options, 3201 scope, subu)) { 3202 if (append_option(result, universe, 3203 subu->enc_opt, &sub)) 3204 status = 1; 3205 3206 data_string_forget(&sub, MDL); 3207 } 3208 } 3209 3210 return status; 3211 } 3212 3213 int hashed_option_space_encapsulate (result, packet, lease, client_state, 3214 in_options, cfg_options, scope, universe) 3215 struct data_string *result; 3216 struct packet *packet; 3217 struct lease *lease; 3218 struct client_state *client_state; 3219 struct option_state *in_options; 3220 struct option_state *cfg_options; 3221 struct binding_scope **scope; 3222 struct universe *universe; 3223 { 3224 pair p, *hash; 3225 int status; 3226 int i; 3227 3228 if (universe -> index >= cfg_options -> universe_count) 3229 return 0; 3230 3231 hash = cfg_options -> universes [universe -> index]; 3232 if (!hash) 3233 return 0; 3234 3235 /* For each hash bucket, and each configured option cache within 3236 * that bucket, append the option onto the buffer in encapsulated 3237 * format appropriate to the universe. 3238 */ 3239 status = 0; 3240 for (i = 0; i < OPTION_HASH_SIZE; i++) { 3241 for (p = hash [i]; p; p = p -> cdr) { 3242 if (store_option(result, universe, packet, lease, 3243 client_state, in_options, cfg_options, 3244 scope, (struct option_cache *)p->car)) 3245 status = 1; 3246 } 3247 } 3248 3249 if (search_subencapsulation(result, packet, lease, client_state, 3250 in_options, cfg_options, scope, universe)) 3251 status = 1; 3252 3253 return status; 3254 } 3255 3256 int nwip_option_space_encapsulate (result, packet, lease, client_state, 3257 in_options, cfg_options, scope, universe) 3258 struct data_string *result; 3259 struct packet *packet; 3260 struct lease *lease; 3261 struct client_state *client_state; 3262 struct option_state *in_options; 3263 struct option_state *cfg_options; 3264 struct binding_scope **scope; 3265 struct universe *universe; 3266 { 3267 pair ocp; 3268 int status; 3269 static struct option_cache *no_nwip; 3270 struct data_string ds; 3271 struct option_chain_head *head; 3272 3273 if (universe -> index >= cfg_options -> universe_count) 3274 return 0; 3275 head = ((struct option_chain_head *) 3276 cfg_options -> universes [nwip_universe.index]); 3277 if (!head) 3278 return 0; 3279 3280 status = 0; 3281 for (ocp = head -> first; ocp; ocp = ocp -> cdr) { 3282 if (store_option (result, universe, packet, 3283 lease, client_state, in_options, 3284 cfg_options, scope, 3285 (struct option_cache *)ocp -> car)) 3286 status = 1; 3287 } 3288 3289 /* If there's no data, the nwip suboption is supposed to contain 3290 a suboption saying there's no data. */ 3291 if (!status) { 3292 if (!no_nwip) { 3293 unsigned one = 1; 3294 static unsigned char nni [] = { 1, 0 }; 3295 3296 memset (&ds, 0, sizeof ds); 3297 ds.data = nni; 3298 ds.len = 2; 3299 if (option_cache_allocate (&no_nwip, MDL)) 3300 data_string_copy (&no_nwip -> data, &ds, MDL); 3301 if (!option_code_hash_lookup(&no_nwip->option, 3302 nwip_universe.code_hash, 3303 &one, 0, MDL)) 3304 log_fatal("Nwip option hash does not contain " 3305 "1 (%s:%d).", MDL); 3306 } 3307 if (no_nwip) { 3308 if (store_option (result, universe, packet, lease, 3309 client_state, in_options, 3310 cfg_options, scope, no_nwip)) 3311 status = 1; 3312 } 3313 } else { 3314 memset (&ds, 0, sizeof ds); 3315 3316 /* If we have nwip options, the first one has to be the 3317 nwip-exists-in-option-area option. */ 3318 if (!buffer_allocate (&ds.buffer, result -> len + 2, MDL)) { 3319 data_string_forget (result, MDL); 3320 return 0; 3321 } 3322 ds.data = &ds.buffer -> data [0]; 3323 ds.buffer -> data [0] = 2; 3324 ds.buffer -> data [1] = 0; 3325 memcpy (&ds.buffer -> data [2], result -> data, result -> len); 3326 data_string_forget (result, MDL); 3327 data_string_copy (result, &ds, MDL); 3328 data_string_forget (&ds, MDL); 3329 } 3330 3331 return status; 3332 } 3333 3334 /* We don't want to use MRns_name_pton()...it doesn't tell us how many bytes 3335 * it has consumed, and it plays havoc with our escapes. 3336 * 3337 * So this function does DNS encoding, and returns either the number of 3338 * octects consumed (on success), or -1 on failure. 3339 */ 3340 static int 3341 fqdn_encode(unsigned char *dst, int dstlen, const unsigned char *src, 3342 int srclen) 3343 { 3344 unsigned char *out; 3345 int i, j, len, outlen=0; 3346 3347 out = dst; 3348 for (i = 0, j = 0 ; i < srclen ; i = j) { 3349 while ((j < srclen) && (src[j] != '.') && (src[j] != '\0')) 3350 j++; 3351 3352 len = j - i; 3353 if ((outlen + 1 + len) > dstlen) 3354 return -1; 3355 3356 *out++ = len; 3357 outlen++; 3358 3359 /* We only do one FQDN, ending in one root label. */ 3360 if (len == 0) 3361 return outlen; 3362 3363 memcpy(out, src + i, len); 3364 out += len; 3365 outlen += len; 3366 3367 /* Advance past the root label. */ 3368 j++; 3369 } 3370 3371 if ((outlen + 1) > dstlen) 3372 return -1; 3373 3374 /* Place the root label. */ 3375 *out++ = 0; 3376 outlen++; 3377 3378 return outlen; 3379 } 3380 3381 int fqdn_option_space_encapsulate (result, packet, lease, client_state, 3382 in_options, cfg_options, scope, universe) 3383 struct data_string *result; 3384 struct packet *packet; 3385 struct lease *lease; 3386 struct client_state *client_state; 3387 struct option_state *in_options; 3388 struct option_state *cfg_options; 3389 struct binding_scope **scope; 3390 struct universe *universe; 3391 { 3392 pair ocp; 3393 struct data_string results [FQDN_SUBOPTION_COUNT + 1]; 3394 int status = 1; 3395 int i; 3396 unsigned len; 3397 struct buffer *bp = (struct buffer *)0; 3398 struct option_chain_head *head; 3399 3400 /* If there's no FQDN universe, don't encapsulate. */ 3401 if (fqdn_universe.index >= cfg_options -> universe_count) 3402 return 0; 3403 head = ((struct option_chain_head *) 3404 cfg_options -> universes [fqdn_universe.index]); 3405 if (!head) 3406 return 0; 3407 3408 /* Figure out the values of all the suboptions. */ 3409 memset (results, 0, sizeof results); 3410 for (ocp = head -> first; ocp; ocp = ocp -> cdr) { 3411 struct option_cache *oc = (struct option_cache *)(ocp -> car); 3412 if (oc -> option -> code > FQDN_SUBOPTION_COUNT) 3413 continue; 3414 /* No need to check the return code, we check the length later */ 3415 (void) evaluate_option_cache (&results[oc->option->code], 3416 packet, lease, client_state, 3417 in_options, cfg_options, scope, 3418 oc, MDL); 3419 } 3420 /* We add a byte for the flags field. 3421 * We add two bytes for the two RCODE fields. 3422 * We add a byte because we will prepend a label count. 3423 * We add a byte because the input len doesn't count null termination, 3424 * and we will add a root label. 3425 */ 3426 len = 5 + results [FQDN_FQDN].len; 3427 /* Save the contents of the option in a buffer. */ 3428 if (!buffer_allocate (&bp, len, MDL)) { 3429 log_error ("no memory for option buffer."); 3430 status = 0; 3431 goto exit; 3432 } 3433 buffer_reference (&result -> buffer, bp, MDL); 3434 result -> len = 3; 3435 result -> data = &bp -> data [0]; 3436 3437 memset (&bp -> data [0], 0, len); 3438 /* XXX: The server should set bit 4 (yes, 4, not 3) to 1 if it is 3439 * not going to perform any ddns updates. The client should set the 3440 * bit if it doesn't want the server to perform any updates. 3441 * The problem is at this layer of abstraction we have no idea if 3442 * the caller is a client or server. 3443 * 3444 * See RFC4702, Section 3.1, 'The "N" bit'. 3445 * 3446 * if (?) 3447 * bp->data[0] |= 8; 3448 */ 3449 if (results [FQDN_NO_CLIENT_UPDATE].len && 3450 results [FQDN_NO_CLIENT_UPDATE].data [0]) 3451 bp -> data [0] |= 2; 3452 if (results [FQDN_SERVER_UPDATE].len && 3453 results [FQDN_SERVER_UPDATE].data [0]) 3454 bp -> data [0] |= 1; 3455 if (results [FQDN_RCODE1].len) 3456 bp -> data [1] = results [FQDN_RCODE1].data [0]; 3457 if (results [FQDN_RCODE2].len) 3458 bp -> data [2] = results [FQDN_RCODE2].data [0]; 3459 3460 if (results [FQDN_ENCODED].len && 3461 results [FQDN_ENCODED].data [0]) { 3462 bp->data[0] |= 4; 3463 if (results [FQDN_FQDN].len) { 3464 i = fqdn_encode(&bp->data[3], len - 3, 3465 results[FQDN_FQDN].data, 3466 results[FQDN_FQDN].len); 3467 3468 if (i < 0) { 3469 status = 0; 3470 goto exit; 3471 } 3472 3473 result->len += i; 3474 result->terminated = 0; 3475 } 3476 } else { 3477 if (results [FQDN_FQDN].len) { 3478 memcpy (&bp -> data [3], results [FQDN_FQDN].data, 3479 results [FQDN_FQDN].len); 3480 result -> len += results [FQDN_FQDN].len; 3481 result -> terminated = 0; 3482 } 3483 } 3484 exit: 3485 for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) { 3486 data_string_forget (&results[i], MDL); 3487 } 3488 buffer_dereference (&bp, MDL); 3489 if (!status) 3490 data_string_forget(result, MDL); 3491 return status; 3492 } 3493 3494 /* 3495 * Trap invalid attempts to inspect FQND6 contents. 3496 */ 3497 struct option_cache * 3498 lookup_fqdn6_option(struct universe *universe, struct option_state *options, 3499 unsigned code) 3500 { 3501 log_fatal("Impossible condition at %s:%d.", MDL); 3502 return NULL; 3503 } 3504 3505 /* 3506 * Trap invalid attempts to save options directly to FQDN6 rather than FQDN. 3507 */ 3508 void 3509 save_fqdn6_option(struct universe *universe, struct option_state *options, 3510 struct option_cache *oc, isc_boolean_t appendp) 3511 { 3512 log_fatal("Impossible condition at %s:%d.", MDL); 3513 } 3514 3515 /* 3516 * Trap invalid attempts to delete an option out of the FQDN6 universe. 3517 */ 3518 void 3519 delete_fqdn6_option(struct universe *universe, struct option_state *options, 3520 int code) 3521 { 3522 log_fatal("Impossible condition at %s:%d.", MDL); 3523 } 3524 3525 /* Shill to the DHCPv4 fqdn option cache any attempts to traverse the 3526 * V6's option cache entry. 3527 * 3528 * This function is called speculatively by dhclient to setup 3529 * environment variables. But it would have already called the 3530 * foreach on the normal fqdn universe, so this is superfluous. 3531 */ 3532 void 3533 fqdn6_option_space_foreach(struct packet *packet, struct lease *lease, 3534 struct client_state *client_state, 3535 struct option_state *in_options, 3536 struct option_state *cfg_options, 3537 struct binding_scope **scope, 3538 struct universe *u, void *stuff, 3539 void (*func)(struct option_cache *, 3540 struct packet *, 3541 struct lease *, 3542 struct client_state *, 3543 struct option_state *, 3544 struct option_state *, 3545 struct binding_scope **, 3546 struct universe *, void *)) 3547 { 3548 /* Pretend it is empty. */ 3549 return; 3550 } 3551 3552 /* Turn the FQDN option space into a DHCPv6 FQDN option buffer. 3553 */ 3554 int 3555 fqdn6_option_space_encapsulate(struct data_string *result, 3556 struct packet *packet, struct lease *lease, 3557 struct client_state *client_state, 3558 struct option_state *in_options, 3559 struct option_state *cfg_options, 3560 struct binding_scope **scope, 3561 struct universe *universe) 3562 { 3563 pair ocp; 3564 struct option_chain_head *head; 3565 struct option_cache *oc; 3566 unsigned char *data; 3567 int i, len, rval = 0, count; 3568 struct data_string results[FQDN_SUBOPTION_COUNT + 1]; 3569 3570 if (fqdn_universe.index >= cfg_options->universe_count) 3571 return 0; 3572 head = ((struct option_chain_head *) 3573 cfg_options->universes[fqdn_universe.index]); 3574 if (head == NULL) 3575 return 0; 3576 3577 memset(results, 0, sizeof(results)); 3578 for (ocp = head->first ; ocp != NULL ; ocp = ocp->cdr) { 3579 oc = (struct option_cache *)(ocp->car); 3580 if (oc->option->code > FQDN_SUBOPTION_COUNT) 3581 log_fatal("Impossible condition at %s:%d.", MDL); 3582 /* No need to check the return code, we check the length later */ 3583 (void) evaluate_option_cache(&results[oc->option->code], packet, 3584 lease, client_state, in_options, 3585 cfg_options, scope, oc, MDL); 3586 } 3587 3588 /* We add a byte for the flags field at the start of the option. 3589 * We add a byte because we will prepend a label count. 3590 * We add a byte because the input length doesn't include a trailing 3591 * NULL, and we will add a root label. 3592 */ 3593 len = results[FQDN_FQDN].len + 3; 3594 if (!buffer_allocate(&result->buffer, len, MDL)) { 3595 log_error("No memory for virtual option buffer."); 3596 goto exit; 3597 } 3598 data = result->buffer->data; 3599 result->data = data; 3600 3601 /* The first byte is the flags field. */ 3602 result->len = 1; 3603 data[0] = 0; 3604 /* XXX: The server should set bit 3 (yes, 3, not 4) to 1 if we 3605 * are not going to perform any DNS updates. The problem is 3606 * that at this layer of abstraction, we do not know if the caller 3607 * is the client or the server. 3608 * 3609 * See RFC4704 Section 4.1, 'The "N" bit'. 3610 * 3611 * if (?) 3612 * data[0] |= 4; 3613 */ 3614 if (results[FQDN_NO_CLIENT_UPDATE].len && 3615 results[FQDN_NO_CLIENT_UPDATE].data[0]) 3616 data[0] |= 2; 3617 if (results[FQDN_SERVER_UPDATE].len && 3618 results[FQDN_SERVER_UPDATE].data[0]) 3619 data[0] |= 1; 3620 3621 /* If there is no name, we're done. */ 3622 if (results[FQDN_FQDN].len == 0) { 3623 rval = 1; 3624 goto exit; 3625 } 3626 3627 /* Convert textual representation to DNS format. */ 3628 count = fqdn_encode(data + 1, len - 1, 3629 results[FQDN_FQDN].data, results[FQDN_FQDN].len); 3630 3631 if (count < 0) { 3632 rval = 0; 3633 data_string_forget(result, MDL); 3634 goto exit; 3635 } 3636 3637 result->len += count; 3638 result->terminated = 0; 3639 3640 /* Success! */ 3641 rval = 1; 3642 3643 exit: 3644 for (i = 1 ; i <= FQDN_SUBOPTION_COUNT ; i++) { 3645 data_string_forget(&results[i], MDL); 3646 } 3647 3648 return rval; 3649 } 3650 3651 /* Read the DHCPv6 FQDN option's contents into the FQDN virtual space. 3652 */ 3653 int 3654 fqdn6_universe_decode(struct option_state *options, 3655 const unsigned char *buffer, unsigned length, 3656 struct universe *u) 3657 { 3658 struct buffer *bp = NULL; 3659 unsigned char *first_dot; 3660 int len, hlen, dlen; 3661 3662 /* The FQDN option has to be at least 1 byte long. */ 3663 if (length < 1) 3664 return 0; 3665 3666 /* Save the contents of the option in a buffer. There are 3 3667 * one-byte values we record from the packet. The input is 3668 * DNS encoded and to be safe we'll assume that each character 3669 * is non-printable and will be converted to an escaped number: 3670 * "\\nnn". Yes, we'll have dead space pretty much all the time 3671 * but the alternative is to basically dry run the conversion 3672 * first to calculate the precise size or reallocate to a smaller 3673 * buffer later, either of which is a bigger performance hit than 3674 * just doing a generous allocation. */ 3675 unsigned bp_size = 3 + (length * 4); 3676 3677 if (!buffer_allocate(&bp, bp_size, MDL)) { 3678 log_error("No memory for dhcp6.fqdn option buffer."); 3679 return 0; 3680 } 3681 3682 /* The v6 FQDN is always 'encoded' per DNS. */ 3683 bp->data[0] = 1; 3684 if (!save_option_buffer(&fqdn_universe, options, bp, 3685 bp->data, 1, FQDN_ENCODED, 0)) 3686 goto error; 3687 3688 /* XXX: We need to process 'The "N" bit'. */ 3689 if (buffer[0] & 1) /* server-update. */ 3690 bp->data[2] = 1; 3691 else 3692 bp->data[2] = 0; 3693 3694 if (!save_option_buffer(&fqdn_universe, options, bp, bp->data + 2, 1, 3695 FQDN_SERVER_UPDATE, 0)) 3696 goto error; 3697 3698 if (buffer[0] & 2) /* no-client-update. */ 3699 bp->data[1] = 1; 3700 else 3701 bp->data[1] = 0; 3702 3703 if (!save_option_buffer(&fqdn_universe, options, bp, bp->data + 1, 1, 3704 FQDN_NO_CLIENT_UPDATE, 0)) 3705 goto error; 3706 3707 /* Convert the domain name to textual representation for config. */ 3708 len = MRns_name_ntop(buffer + 1, (char *)bp->data + 3, bp_size - 3); 3709 if (len == -1) { 3710 log_error("Unable to convert dhcp6.fqdn domain name to " 3711 "printable form."); 3712 goto error; 3713 } 3714 3715 /* Save the domain name. */ 3716 if (len > 0) { 3717 unsigned char *fqdn_start = bp->data + 3; 3718 3719 if (!save_option_buffer(&fqdn_universe, options, bp, 3720 fqdn_start, len, FQDN_FQDN, 1)) 3721 goto error; 3722 3723 first_dot = (unsigned char *)strchr((char *)fqdn_start, '.'); 3724 3725 if (first_dot != NULL) { 3726 hlen = first_dot - fqdn_start; 3727 dlen = len - hlen; 3728 } else { 3729 hlen = len; 3730 dlen = 0; 3731 } 3732 3733 if (!save_option_buffer(&fqdn_universe, options, bp, 3734 fqdn_start, len, FQDN_FQDN, 1) || 3735 ((hlen > 0) && 3736 !save_option_buffer(&fqdn_universe, options, bp, 3737 fqdn_start, hlen, 3738 FQDN_HOSTNAME, 0)) || 3739 ((dlen > 0) && 3740 !save_option_buffer(&fqdn_universe, options, bp, 3741 first_dot, dlen, FQDN_DOMAINNAME, 0))) 3742 goto error; 3743 } 3744 3745 buffer_dereference(&bp, MDL); 3746 return 1; 3747 3748 error: 3749 buffer_dereference(&bp, MDL); 3750 return 0; 3751 } 3752 3753 void option_space_foreach (struct packet *packet, struct lease *lease, 3754 struct client_state *client_state, 3755 struct option_state *in_options, 3756 struct option_state *cfg_options, 3757 struct binding_scope **scope, 3758 struct universe *u, void *stuff, 3759 void (*func) (struct option_cache *, 3760 struct packet *, 3761 struct lease *, struct client_state *, 3762 struct option_state *, 3763 struct option_state *, 3764 struct binding_scope **, 3765 struct universe *, void *)) 3766 { 3767 if (u -> foreach) 3768 (*u -> foreach) (packet, lease, client_state, in_options, 3769 cfg_options, scope, u, stuff, func); 3770 } 3771 3772 void suboption_foreach (struct packet *packet, struct lease *lease, 3773 struct client_state *client_state, 3774 struct option_state *in_options, 3775 struct option_state *cfg_options, 3776 struct binding_scope **scope, 3777 struct universe *u, void *stuff, 3778 void (*func) (struct option_cache *, 3779 struct packet *, 3780 struct lease *, struct client_state *, 3781 struct option_state *, 3782 struct option_state *, 3783 struct binding_scope **, 3784 struct universe *, void *), 3785 struct option_cache *oc, 3786 const char *vsname) 3787 { 3788 struct universe *universe = find_option_universe (oc -> option, 3789 vsname); 3790 if (universe -> foreach) 3791 (*universe -> foreach) (packet, lease, client_state, 3792 in_options, cfg_options, 3793 scope, universe, stuff, func); 3794 } 3795 3796 void hashed_option_space_foreach (struct packet *packet, struct lease *lease, 3797 struct client_state *client_state, 3798 struct option_state *in_options, 3799 struct option_state *cfg_options, 3800 struct binding_scope **scope, 3801 struct universe *u, void *stuff, 3802 void (*func) (struct option_cache *, 3803 struct packet *, 3804 struct lease *, 3805 struct client_state *, 3806 struct option_state *, 3807 struct option_state *, 3808 struct binding_scope **, 3809 struct universe *, void *)) 3810 { 3811 pair *hash; 3812 int i; 3813 struct option_cache *oc; 3814 3815 if (cfg_options -> universe_count <= u -> index) 3816 return; 3817 3818 hash = cfg_options -> universes [u -> index]; 3819 if (!hash) 3820 return; 3821 for (i = 0; i < OPTION_HASH_SIZE; i++) { 3822 pair p; 3823 /* XXX save _all_ options! XXX */ 3824 for (p = hash [i]; p; p = p -> cdr) { 3825 oc = (struct option_cache *)p -> car; 3826 (*func) (oc, packet, lease, client_state, 3827 in_options, cfg_options, scope, u, stuff); 3828 } 3829 } 3830 } 3831 3832 void 3833 save_linked_option(struct universe *universe, struct option_state *options, 3834 struct option_cache *oc, isc_boolean_t appendp) 3835 { 3836 pair *tail; 3837 struct option_chain_head *head; 3838 struct option_cache **ocloc; 3839 3840 if (universe -> index >= options -> universe_count) 3841 return; 3842 head = ((struct option_chain_head *) 3843 options -> universes [universe -> index]); 3844 if (!head) { 3845 if (!option_chain_head_allocate (((struct option_chain_head **) 3846 &options -> universes 3847 [universe -> index]), MDL)) 3848 return; 3849 head = ((struct option_chain_head *) 3850 options -> universes [universe -> index]); 3851 } 3852 3853 /* Find the tail of the list. */ 3854 for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) { 3855 ocloc = (struct option_cache **)&(*tail)->car; 3856 3857 if (oc->option->code == (*ocloc)->option->code) { 3858 if (appendp) { 3859 do { 3860 ocloc = &(*ocloc)->next; 3861 } while (*ocloc != NULL); 3862 } else { 3863 option_cache_dereference(ocloc, MDL); 3864 } 3865 option_cache_reference(ocloc, oc, MDL); 3866 return; 3867 } 3868 } 3869 3870 *tail = cons (0, 0); 3871 if (*tail) { 3872 option_cache_reference ((struct option_cache **) 3873 (&(*tail) -> car), oc, MDL); 3874 } 3875 } 3876 3877 int linked_option_space_encapsulate (result, packet, lease, client_state, 3878 in_options, cfg_options, scope, universe) 3879 struct data_string *result; 3880 struct packet *packet; 3881 struct lease *lease; 3882 struct client_state *client_state; 3883 struct option_state *in_options; 3884 struct option_state *cfg_options; 3885 struct binding_scope **scope; 3886 struct universe *universe; 3887 { 3888 int status = 0; 3889 pair oc; 3890 struct option_chain_head *head; 3891 3892 if (universe -> index >= cfg_options -> universe_count) 3893 return status; 3894 head = ((struct option_chain_head *) 3895 cfg_options -> universes [universe -> index]); 3896 if (!head) 3897 return status; 3898 3899 for (oc = head -> first; oc; oc = oc -> cdr) { 3900 if (store_option (result, universe, packet, 3901 lease, client_state, in_options, cfg_options, 3902 scope, (struct option_cache *)(oc -> car))) 3903 status = 1; 3904 } 3905 3906 if (search_subencapsulation(result, packet, lease, client_state, 3907 in_options, cfg_options, scope, universe)) 3908 status = 1; 3909 3910 return status; 3911 } 3912 3913 void delete_linked_option (universe, options, code) 3914 struct universe *universe; 3915 struct option_state *options; 3916 int code; 3917 { 3918 pair *tail, tmp = (pair)0; 3919 struct option_chain_head *head; 3920 3921 if (universe -> index >= options -> universe_count) 3922 return; 3923 head = ((struct option_chain_head *) 3924 options -> universes [universe -> index]); 3925 if (!head) 3926 return; 3927 3928 for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) { 3929 if (code == 3930 ((struct option_cache *)(*tail) -> car) -> option -> code) 3931 { 3932 tmp = (*tail) -> cdr; 3933 option_cache_dereference ((struct option_cache **) 3934 (&(*tail) -> car), MDL); 3935 dfree (*tail, MDL); 3936 (*tail) = tmp; 3937 break; 3938 } 3939 } 3940 } 3941 3942 struct option_cache *lookup_linked_option (universe, options, code) 3943 struct universe *universe; 3944 struct option_state *options; 3945 unsigned code; 3946 { 3947 pair oc; 3948 struct option_chain_head *head; 3949 3950 if (universe -> index >= options -> universe_count) 3951 return 0; 3952 head = ((struct option_chain_head *) 3953 options -> universes [universe -> index]); 3954 if (!head) 3955 return 0; 3956 3957 for (oc = head -> first; oc; oc = oc -> cdr) { 3958 if (code == 3959 ((struct option_cache *)(oc -> car)) -> option -> code) { 3960 return (struct option_cache *)(oc -> car); 3961 } 3962 } 3963 3964 return (struct option_cache *)0; 3965 } 3966 3967 int linked_option_state_dereference (universe, state, file, line) 3968 struct universe *universe; 3969 struct option_state *state; 3970 const char *file; 3971 int line; 3972 { 3973 return (option_chain_head_dereference 3974 ((struct option_chain_head **) 3975 (&state -> universes [universe -> index]), MDL)); 3976 } 3977 3978 void linked_option_space_foreach (struct packet *packet, struct lease *lease, 3979 struct client_state *client_state, 3980 struct option_state *in_options, 3981 struct option_state *cfg_options, 3982 struct binding_scope **scope, 3983 struct universe *u, void *stuff, 3984 void (*func) (struct option_cache *, 3985 struct packet *, 3986 struct lease *, 3987 struct client_state *, 3988 struct option_state *, 3989 struct option_state *, 3990 struct binding_scope **, 3991 struct universe *, void *)) 3992 { 3993 pair car; 3994 struct option_chain_head *head; 3995 3996 if (u -> index >= cfg_options -> universe_count) 3997 return; 3998 head = ((struct option_chain_head *) 3999 cfg_options -> universes [u -> index]); 4000 if (!head) 4001 return; 4002 for (car = head -> first; car; car = car -> cdr) { 4003 (*func) ((struct option_cache *)(car -> car), 4004 packet, lease, client_state, 4005 in_options, cfg_options, scope, u, stuff); 4006 } 4007 } 4008 4009 void do_packet (interface, packet, len, from_port, from, hfrom) 4010 struct interface_info *interface; 4011 struct dhcp_packet *packet; 4012 unsigned len; 4013 unsigned int from_port; 4014 struct iaddr from; 4015 struct hardware *hfrom; 4016 { 4017 struct option_cache *op; 4018 struct packet *decoded_packet; 4019 #if defined (DEBUG_MEMORY_LEAKAGE) 4020 unsigned long previous_outstanding = dmalloc_outstanding; 4021 #endif 4022 4023 #if defined (TRACING) 4024 trace_inpacket_stash(interface, packet, len, from_port, from, hfrom); 4025 #endif 4026 4027 decoded_packet = NULL; 4028 if (!packet_allocate(&decoded_packet, MDL)) { 4029 log_error("do_packet: no memory for incoming packet!"); 4030 return; 4031 } 4032 decoded_packet->raw = packet; 4033 decoded_packet->packet_length = len; 4034 decoded_packet->client_port = from_port; 4035 decoded_packet->client_addr = from; 4036 interface_reference(&decoded_packet->interface, interface, MDL); 4037 decoded_packet->haddr = hfrom; 4038 4039 if (packet->hlen > sizeof packet->chaddr) { 4040 packet_dereference(&decoded_packet, MDL); 4041 log_info("Discarding packet with bogus hlen."); 4042 return; 4043 } 4044 4045 /* Allocate packet->options now so it is non-null for all packets */ 4046 decoded_packet->options_valid = 0; 4047 if (!option_state_allocate (&decoded_packet->options, MDL)) { 4048 packet_dereference(&decoded_packet, MDL); 4049 return; 4050 } 4051 4052 /* If there's an option buffer, try to parse it. */ 4053 if (decoded_packet->packet_length >= DHCP_FIXED_NON_UDP + 4) { 4054 if (!parse_options(decoded_packet)) { 4055 packet_dereference (&decoded_packet, MDL); 4056 return; 4057 } 4058 4059 if (decoded_packet->options_valid && 4060 (op = lookup_option(&dhcp_universe, 4061 decoded_packet->options, 4062 DHO_DHCP_MESSAGE_TYPE))) { 4063 struct data_string dp; 4064 memset(&dp, 0, sizeof dp); 4065 evaluate_option_cache(&dp, decoded_packet, NULL, NULL, 4066 decoded_packet->options, NULL, 4067 NULL, op, MDL); 4068 if (dp.len > 0) 4069 decoded_packet->packet_type = dp.data[0]; 4070 else 4071 decoded_packet->packet_type = 0; 4072 data_string_forget(&dp, MDL); 4073 } 4074 } 4075 4076 if (validate_packet(decoded_packet) != 0) { 4077 if (decoded_packet->packet_type) 4078 libdhcp_callbacks.dhcp(decoded_packet); 4079 else 4080 libdhcp_callbacks.bootp(decoded_packet); 4081 } 4082 4083 /* If the caller kept the packet, they'll have upped the refcnt. */ 4084 packet_dereference(&decoded_packet, MDL); 4085 4086 #if defined (DEBUG_MEMORY_LEAKAGE) 4087 log_info("generation %ld: %ld new, %ld outstanding, %ld long-term", 4088 dmalloc_generation, 4089 dmalloc_outstanding - previous_outstanding, 4090 dmalloc_outstanding, dmalloc_longterm); 4091 dmalloc_dump_outstanding(); 4092 #endif 4093 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) 4094 dump_rc_history(0); 4095 #endif 4096 } 4097 4098 int 4099 packet6_len_okay(const char *packet, int len) { 4100 if (len < 1) { 4101 return 0; 4102 } 4103 if ((packet[0] == DHCPV6_RELAY_FORW) || 4104 (packet[0] == DHCPV6_RELAY_REPL)) { 4105 if (len >= offsetof(struct dhcpv6_relay_packet, options)) { 4106 return 1; 4107 } else { 4108 return 0; 4109 } 4110 } else { 4111 if (len >= offsetof(struct dhcpv6_packet, options)) { 4112 return 1; 4113 } else { 4114 return 0; 4115 } 4116 } 4117 } 4118 4119 #ifdef DHCPv6 4120 void 4121 do_packet6(struct interface_info *interface, const char *packet, 4122 int len, int from_port, const struct iaddr *from, 4123 isc_boolean_t was_unicast) { 4124 unsigned char msg_type; 4125 const struct dhcpv6_packet *msg; 4126 const struct dhcpv6_relay_packet *relay; 4127 #ifdef DHCP4o6 4128 const struct dhcpv4_over_dhcpv6_packet *msg46; 4129 #endif 4130 struct packet *decoded_packet; 4131 #if defined (DEBUG_MEMORY_LEAKAGE) 4132 unsigned long previous_outstanding = dmalloc_outstanding; 4133 #endif 4134 4135 if (!packet6_len_okay(packet, len)) { 4136 log_info("do_packet6: " 4137 "short packet from %s port %d, len %d, dropped", 4138 piaddr(*from), from_port, len); 4139 return; 4140 } 4141 4142 decoded_packet = NULL; 4143 if (!packet_allocate(&decoded_packet, MDL)) { 4144 log_error("do_packet6: no memory for incoming packet."); 4145 return; 4146 } 4147 4148 if (!option_state_allocate(&decoded_packet->options, MDL)) { 4149 log_error("do_packet6: no memory for options."); 4150 packet_dereference(&decoded_packet, MDL); 4151 return; 4152 } 4153 4154 /* IPv4 information, already set to 0 */ 4155 /* decoded_packet->packet_type = 0; */ 4156 /* memset(&decoded_packet->haddr, 0, sizeof(decoded_packet->haddr)); */ 4157 /* decoded_packet->circuit_id = NULL; */ 4158 /* decoded_packet->circuit_id_len = 0; */ 4159 /* decoded_packet->remote_id = NULL; */ 4160 /* decoded_packet->remote_id_len = 0; */ 4161 decoded_packet->raw = (struct dhcp_packet *)packet; 4162 decoded_packet->packet_length = (unsigned)len; 4163 decoded_packet->client_port = from_port; 4164 decoded_packet->client_addr = *from; 4165 interface_reference(&decoded_packet->interface, interface, MDL); 4166 4167 decoded_packet->unicast = was_unicast; 4168 4169 msg_type = packet[0]; 4170 if ((msg_type == DHCPV6_RELAY_FORW) || 4171 (msg_type == DHCPV6_RELAY_REPL)) { 4172 int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options)); 4173 relay = (const struct dhcpv6_relay_packet *)packet; 4174 decoded_packet->dhcpv6_msg_type = relay->msg_type; 4175 4176 /* relay-specific data */ 4177 decoded_packet->dhcpv6_hop_count = relay->hop_count; 4178 memcpy(&decoded_packet->dhcpv6_link_address, 4179 relay->link_address, sizeof(relay->link_address)); 4180 memcpy(&decoded_packet->dhcpv6_peer_address, 4181 relay->peer_address, sizeof(relay->peer_address)); 4182 4183 if (!parse_option_buffer(decoded_packet->options, 4184 relay->options, len - relaylen, 4185 &dhcpv6_universe)) { 4186 /* no logging here, as parse_option_buffer() logs all 4187 cases where it fails */ 4188 packet_dereference(&decoded_packet, MDL); 4189 return; 4190 } 4191 #ifdef DHCP4o6 4192 } else if ((msg_type == DHCPV6_DHCPV4_QUERY) || 4193 (msg_type == DHCPV6_DHCPV4_RESPONSE)) { 4194 int msglen = 4195 (int)(offsetof(struct dhcpv4_over_dhcpv6_packet, options)); 4196 msg46 = (struct dhcpv4_over_dhcpv6_packet *)packet; 4197 decoded_packet->dhcpv6_msg_type = msg46->msg_type; 4198 4199 /* message-specific data */ 4200 memcpy(decoded_packet->dhcp4o6_flags, 4201 msg46->flags, 4202 sizeof(decoded_packet->dhcp4o6_flags)); 4203 4204 if (!parse_option_buffer(decoded_packet->options, 4205 msg46->options, len - msglen, 4206 &dhcpv6_universe)) { 4207 /* no logging here, as parse_option_buffer() logs all 4208 cases where it fails */ 4209 packet_dereference(&decoded_packet, MDL); 4210 return; 4211 } 4212 #endif 4213 } else { 4214 int msglen = (int)(offsetof(struct dhcpv6_packet, options)); 4215 msg = (const struct dhcpv6_packet *)packet; 4216 decoded_packet->dhcpv6_msg_type = msg->msg_type; 4217 4218 /* message-specific data */ 4219 memcpy(decoded_packet->dhcpv6_transaction_id, 4220 msg->transaction_id, 4221 sizeof(decoded_packet->dhcpv6_transaction_id)); 4222 4223 if (!parse_option_buffer(decoded_packet->options, 4224 msg->options, len - msglen, 4225 &dhcpv6_universe)) { 4226 /* no logging here, as parse_option_buffer() logs all 4227 cases where it fails */ 4228 packet_dereference(&decoded_packet, MDL); 4229 return; 4230 } 4231 } 4232 4233 libdhcp_callbacks.dhcpv6(decoded_packet); 4234 4235 packet_dereference(&decoded_packet, MDL); 4236 4237 #if defined (DEBUG_MEMORY_LEAKAGE) 4238 log_info("generation %ld: %ld new, %ld outstanding, %ld long-term", 4239 dmalloc_generation, 4240 dmalloc_outstanding - previous_outstanding, 4241 dmalloc_outstanding, dmalloc_longterm); 4242 dmalloc_dump_outstanding(); 4243 #endif 4244 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) 4245 dump_rc_history(0); 4246 #endif 4247 } 4248 #endif /* DHCPv6 */ 4249 4250 int 4251 pretty_escape(char **dst, char *dend, const unsigned char **src, 4252 const unsigned char *send) 4253 { 4254 int count = 0; 4255 4256 /* If there aren't as many bytes left as there are in the source 4257 * buffer, don't even bother entering the loop. 4258 */ 4259 if (dst == NULL || dend == NULL || src == NULL || send == NULL || 4260 *dst == NULL || *src == NULL || (*dst >= dend) || (*src > send) || 4261 ((send - *src) > (dend - *dst))) 4262 return -1; 4263 4264 for ( ; *src < send ; (*src)++) { 4265 if (!isascii (**src) || !isprint (**src)) { 4266 /* Skip trailing NUL. */ 4267 if ((*src + 1) != send || **src != '\0') { 4268 if (*dst + 4 > dend) 4269 return -1; 4270 4271 sprintf(*dst, "\\%03o", 4272 **src); 4273 (*dst) += 4; 4274 count += 4; 4275 } 4276 } else if (**src == '"' || **src == '\'' || **src == '$' || 4277 **src == '`' || **src == '\\' || **src == '|' || 4278 **src == '&') { 4279 if (*dst + 2 > dend) 4280 return -1; 4281 4282 **dst = '\\'; 4283 (*dst)++; 4284 **dst = **src; 4285 (*dst)++; 4286 count += 2; 4287 } else { 4288 if (*dst + 1 > dend) 4289 return -1; 4290 4291 **dst = **src; 4292 (*dst)++; 4293 count++; 4294 } 4295 } 4296 4297 return count; 4298 } 4299 4300 static int 4301 pretty_text(char **dst, char *dend, const unsigned char **src, 4302 const unsigned char *send, int emit_quotes) 4303 { 4304 int count; 4305 4306 if (dst == NULL || dend == NULL || src == NULL || send == NULL || 4307 *dst == NULL || *src == NULL || 4308 ((*dst + (emit_quotes ? 2 : 0)) > dend) || (*src > send)) 4309 return -1; 4310 4311 if (emit_quotes) { 4312 **dst = '"'; 4313 (*dst)++; 4314 } 4315 4316 /* dend-1 leaves 1 byte for the closing quote. */ 4317 count = pretty_escape(dst, dend - (emit_quotes ? 1 : 0), src, send); 4318 4319 if (count == -1) 4320 return -1; 4321 4322 if (emit_quotes && (*dst < dend)) { 4323 **dst = '"'; 4324 (*dst)++; 4325 4326 /* Includes quote prior to pretty_escape(); */ 4327 count += 2; 4328 } 4329 4330 return count; 4331 } 4332 4333 static int 4334 pretty_dname(char **dst, char *dend, const unsigned char *src, 4335 const unsigned char *send) 4336 { 4337 const unsigned char *tend; 4338 const unsigned char *srcp = src; 4339 int count = 0; 4340 int tsiz, status; 4341 4342 if (dst == NULL || dend == NULL || src == NULL || send == NULL || 4343 *dst == NULL || ((*dst + 1) > dend) || (src >= send)) 4344 return -1; 4345 4346 do { 4347 /* Continue loop until end of src buffer. */ 4348 if (srcp >= send) 4349 break; 4350 4351 /* Consume tag size. */ 4352 tsiz = *srcp; 4353 srcp++; 4354 4355 /* At root, finis. */ 4356 if (tsiz == 0) 4357 break; 4358 4359 tend = srcp + tsiz; 4360 4361 /* If the tag exceeds the source buffer, it's illegal. 4362 * This should also trap compression pointers (which should 4363 * not be in these buffers). 4364 */ 4365 if (tend > send) 4366 return -1; 4367 4368 /* dend-1 leaves room for a trailing dot and quote. */ 4369 status = pretty_escape(dst, dend-1, &srcp, tend); 4370 4371 if ((status == -1) || ((*dst + 1) > dend)) 4372 return -1; 4373 4374 **dst = '.'; 4375 (*dst)++; 4376 count += status + 1; 4377 } 4378 while(1); 4379 4380 return count; 4381 } 4382 4383 static int 4384 pretty_domain(char **dst, char *dend, const unsigned char **src, 4385 const unsigned char *send) 4386 { 4387 const unsigned char *tend; 4388 int count = 2; 4389 int tsiz, status; 4390 4391 if (dst == NULL || dend == NULL || src == NULL || send == NULL || 4392 *dst == NULL || *src == NULL || 4393 ((*dst + 2) > dend) || (*src >= send)) 4394 return -1; 4395 4396 **dst = '"'; 4397 (*dst)++; 4398 4399 do { 4400 /* Continue loop until end of src buffer. */ 4401 if (*src >= send) 4402 break; 4403 4404 /* Consume tag size. */ 4405 tsiz = **src; 4406 (*src)++; 4407 4408 /* At root, finis. */ 4409 if (tsiz == 0) 4410 break; 4411 4412 tend = (*src) + tsiz; 4413 4414 /* If the tag exceeds the source buffer, it's illegal. 4415 * This should also trap compression pointers (which should 4416 * not be in these buffers). 4417 */ 4418 if (tend > send) 4419 return -1; 4420 4421 /* dend-2 leaves room for a trailing dot and quote. */ 4422 status = pretty_escape(dst, dend-2, src, tend); 4423 4424 if ((status == -1) || ((*dst + 2) > dend)) 4425 return -1; 4426 4427 **dst = '.'; 4428 (*dst)++; 4429 count += status + 1; 4430 } 4431 while(1); 4432 4433 **dst = '"'; 4434 (*dst)++; 4435 4436 return count; 4437 } 4438 4439 /* 4440 * Add the option identified with the option number and data to the 4441 * options state. 4442 */ 4443 int 4444 add_option(struct option_state *options, 4445 unsigned int option_num, 4446 void *data, 4447 unsigned int data_len) 4448 { 4449 struct option_cache *oc; 4450 struct option *option; 4451 4452 /* INSIST(options != NULL); */ 4453 /* INSIST(data != NULL); */ 4454 4455 option = NULL; 4456 if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, 4457 &option_num, 0, MDL)) { 4458 log_error("Attempting to add unknown option %d.", option_num); 4459 return 0; 4460 } 4461 4462 oc = NULL; 4463 if (!option_cache_allocate(&oc, MDL)) { 4464 log_error("No memory for option cache adding %s (option %d).", 4465 option->name, option_num); 4466 return 0; 4467 } 4468 4469 if (!make_const_data(&oc->expression, 4470 data, 4471 data_len, 4472 0, 4473 0, 4474 MDL)) { 4475 log_error("No memory for constant data adding %s (option %d).", 4476 option->name, option_num); 4477 option_cache_dereference(&oc, MDL); 4478 return 0; 4479 } 4480 4481 option_reference(&(oc->option), option, MDL); 4482 save_option(&dhcp_universe, options, oc); 4483 option_cache_dereference(&oc, MDL); 4484 4485 return 1; 4486 } 4487 4488 /** 4489 * Checks if received BOOTP/DHCPv4 packet is sane 4490 * 4491 * @param packet received, decoded packet 4492 * 4493 * @return 1 if packet is sane, 0 if it is not 4494 */ 4495 int validate_packet(struct packet *packet) 4496 { 4497 struct option_cache *oc = NULL; 4498 4499 oc = lookup_option (&dhcp_universe, packet->options, 4500 DHO_DHCP_CLIENT_IDENTIFIER); 4501 if (oc) { 4502 /* Let's check if client-identifier is sane */ 4503 if (oc->data.len == 0) { 4504 log_debug("Dropped DHCPv4 packet with zero-length client-id"); 4505 return (0); 4506 4507 } else if (oc->data.len == 1) { 4508 /* 4509 * RFC2132, section 9.14 states that minimum length of client-id 4510 * is 2. We will allow single-character client-ids for now (for 4511 * backwards compatibility), but warn the user that support for 4512 * this is against the standard. 4513 */ 4514 log_debug("Accepted DHCPv4 packet with one-character client-id - " 4515 "a future version of ISC DHCP will reject this"); 4516 } 4517 } else { 4518 /* 4519 * If hlen is 0 we don't have any identifier, we warn the user 4520 * but continue processing the packet as we can. 4521 */ 4522 if (packet->raw->hlen == 0) { 4523 log_debug("Received DHCPv4 packet without client-id" 4524 " option and empty hlen field."); 4525 } 4526 } 4527 4528 /* @todo: Add checks for other received options */ 4529 4530 return (1); 4531 } 4532 /*! 4533 * 4534 * \brief Parse a vendor option (option 43) 4535 * 4536 * After the server has parsed most of the options and presented the result 4537 * to the user the user can set the proper vendor option space using 4538 * vendor-option-space in the config file and then cause this routine to be 4539 * called via parse-vendor-option in the config file. This routine will 4540 * then try and find the proper universe for the vendor-option-space and 4541 * parse the vendor option string based on that universe. 4542 * 4543 * If the information isn't available (no vendor space, no universe for the 4544 * vendor space, no vendor option in the options) or the decode fails we 4545 * simply ignore the option and continue processing. 4546 * 4547 * \param packet - structure to hold information about the packet being 4548 * processed 4549 * \param lease - lease structure 4550 * \param client_state 4551 * \param in_options - The incoming options, we expect to find the 4552 * vendor-option (option 43, containing the string 4553 * to parse) there. We shall attach decoded options 4554 * there. 4555 * \param out_options - The options we have added as we process the packet. 4556 * We expect to find the vendor-option-space there and 4557 * use that to find the name of the vendor universe to use 4558 * \param scope 4559 * 4560 * \return - void as there isn't much we can do about failures. 4561 */ 4562 void parse_vendor_option(packet, lease, client_state, in_options, 4563 out_options, scope) 4564 struct packet *packet; 4565 struct lease *lease; 4566 struct client_state *client_state; 4567 struct option_state *in_options; 4568 struct option_state *out_options; 4569 struct binding_scope **scope; 4570 { 4571 struct option_cache *oc = NULL; 4572 struct data_string name; 4573 struct option *option = NULL; 4574 unsigned int code = DHO_VENDOR_ENCAPSULATED_OPTIONS; 4575 4576 /* check if we are processing a packet, if not we can return */ 4577 if ((packet == NULL) || (in_options == NULL) || (out_options == NULL)) 4578 return; 4579 4580 /* Do we have any vendor option spaces? */ 4581 if (vendor_cfg_option == NULL) 4582 return; 4583 4584 /* See if the admin has set a vendor option space name */ 4585 oc = lookup_option(vendor_cfg_option->universe, 4586 out_options, vendor_cfg_option->code); 4587 if (oc == NULL) 4588 return; 4589 4590 memset(&name, 0, sizeof(name)); 4591 (void) evaluate_option_cache(&name, packet, lease, client_state, 4592 in_options, out_options, scope, oc, MDL); 4593 4594 /* No name, all done */ 4595 if (name.len == 0) { 4596 data_string_forget(&name, MDL); 4597 return; 4598 } 4599 4600 /* Get any vendor option information from the request */ 4601 oc = lookup_option(&dhcp_universe, in_options, code); 4602 4603 /* No vendor option, all done */ 4604 if ((oc == NULL) || (oc->data.len == 0)) { 4605 data_string_forget(&name, MDL); 4606 return; 4607 } 4608 4609 /* Get the proper option to pass to the parse routine */ 4610 option_code_hash_lookup(&option, dhcp_universe.code_hash, 4611 &code, 0, MDL); 4612 4613 /* Now that we have the data from the vendor option and a vendor 4614 * option space try to parse things. On success the parsed options 4615 * will be added to the in_options list for future use. A return 4616 * return of 1 indicates success, but not much we can do on error */ 4617 (void) parse_encapsulated_suboptions(in_options, option, 4618 oc->data.data, oc->data.len, 4619 &dhcp_universe, 4620 (const char *)name.data); 4621 4622 /* Lastly clean up any left overs */ 4623 data_string_forget(&name, MDL); 4624 option_dereference(&option, MDL); 4625 return; 4626 } 4627