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