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