dhcp.c revision 1.9
1/* $OpenBSD */ 2 3/* 4 * Copyright (c) 1995, 1996, 1997, 1998, 1999 5 * The Internet Software Consortium. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of The Internet Software Consortium nor the names 17 * of its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND 21 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * This software has been written for the Internet Software Consortium 35 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie 36 * Enterprises. To learn more about the Internet Software Consortium, 37 * see ``http://www.vix.com/isc''. To learn more about Vixie 38 * Enterprises, see ``http://www.vix.com''. 39 */ 40 41#include "dhcpd.h" 42 43int outstanding_pings; 44 45static char dhcp_message[256]; 46 47void 48dhcp(struct packet *packet) 49{ 50 if (!locate_network(packet) && packet->packet_type != DHCPREQUEST) 51 return; 52 53 switch (packet->packet_type) { 54 case DHCPDISCOVER: 55 dhcpdiscover(packet); 56 break; 57 58 case DHCPREQUEST: 59 dhcprequest(packet); 60 break; 61 62 case DHCPRELEASE: 63 dhcprelease(packet); 64 break; 65 66 case DHCPDECLINE: 67 dhcpdecline(packet); 68 break; 69 70 case DHCPINFORM: 71 dhcpinform(packet); 72 break; 73 74 default: 75 break; 76 } 77} 78 79void 80dhcpdiscover(struct packet *packet) 81{ 82 struct lease *lease = find_lease(packet, packet->shared_network, 0); 83 struct host_decl *hp; 84 85 note("DHCPDISCOVER from %s via %s", 86 print_hw_addr(packet->raw->htype, packet->raw->hlen, 87 packet->raw->chaddr), 88 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 89 packet->interface->name); 90 91 /* Sourceless packets don't make sense here. */ 92 if (!packet->shared_network) { 93 note("Packet from unknown subnet: %s", 94 inet_ntoa(packet->raw->giaddr)); 95 return; 96 } 97 98 /* If we didn't find a lease, try to allocate one... */ 99 if (!lease) { 100 lease = packet->shared_network->last_lease; 101 102 /* 103 * If there are no leases in that subnet that have 104 * expired, we have nothing to offer this client. 105 */ 106 if (!lease || lease->ends > cur_time) { 107 note("no free leases on subnet %s", 108 packet->shared_network->name); 109 return; 110 } 111 112 /* 113 * If we find an abandoned lease, take it, but print a 114 * warning message, so that if it continues to lose, 115 * the administrator will eventually investigate. 116 */ 117 if ((lease->flags & ABANDONED_LEASE)) { 118 struct lease *lp; 119 120 /* See if we can find an unabandoned lease first. */ 121 for (lp = lease; lp; lp = lp->prev) { 122 if (lp->ends > cur_time) 123 break; 124 if (!(lp->flags & ABANDONED_LEASE)) { 125 lease = lp; 126 break; 127 } 128 } 129 130 /* 131 * If we can't find an unabandoned lease, 132 * reclaim the abandoned lease. 133 */ 134 if ((lease->flags & ABANDONED_LEASE)) { 135 warn("Reclaiming abandoned IP address %s.", 136 piaddr(lease->ip_addr)); 137 lease->flags &= ~ABANDONED_LEASE; 138 } 139 } 140 141 /* Try to find a host_decl that matches the client 142 identifier or hardware address on the packet, and 143 has no fixed IP address. If there is one, hang 144 it off the lease so that its option definitions 145 can be used. */ 146 if (((packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len != 0) && 147 ((hp = find_hosts_by_uid( 148 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 149 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len)) != NULL)) || 150 ((hp = find_hosts_by_haddr(packet->raw->htype, 151 packet->raw->chaddr, packet->raw->hlen)) != NULL)) { 152 for (; hp; hp = hp->n_ipaddr) { 153 if (!hp->fixed_addr) { 154 lease->host = hp; 155 break; 156 } 157 } 158 } else 159 lease->host = NULL; 160 } 161 162 /* If this subnet won't boot unknown clients, ignore the 163 request. */ 164 if (!lease->host && 165 !lease->subnet->group->boot_unknown_clients) { 166 note("Ignoring unknown client %s", 167 print_hw_addr(packet->raw->htype, packet->raw->hlen, 168 packet->raw->chaddr)); 169 } else if (lease->host && !lease->host->group->allow_booting) { 170 note("Declining to boot client %s", 171 lease->host->name ? lease->host->name : 172 print_hw_addr(packet->raw->htype, packet->raw->hlen, 173 packet->raw->chaddr)); 174 } else 175 ack_lease(packet, lease, DHCPOFFER, cur_time + 120); 176} 177 178void 179dhcprequest(struct packet *packet) 180{ 181 struct lease *lease; 182 struct iaddr cip; 183 struct subnet *subnet; 184 int ours = 0; 185 186 cip.len = 4; 187 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len) 188 memcpy(cip.iabuf, 189 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 4); 190 else 191 memcpy(cip.iabuf, &packet->raw->ciaddr.s_addr, 4); 192 subnet = find_subnet(cip); 193 194 /* Find the lease that matches the address requested by the client. */ 195 196 if (subnet) 197 lease = find_lease(packet, subnet->shared_network, &ours); 198 else 199 lease = NULL; 200 201 note("DHCPREQUEST for %s from %s via %s", piaddr(cip), 202 print_hw_addr(packet->raw->htype, packet->raw->hlen, 203 packet->raw->chaddr), 204 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 205 packet->interface->name); 206 207 /* If a client on a given network REQUESTs a lease on an 208 * address on a different network, NAK it. If the Requested 209 * Address option was used, the protocol says that it must 210 * have been broadcast, so we can trust the source network 211 * information. 212 * 213 * If ciaddr was specified and Requested Address was not, then 214 * we really only know for sure what network a packet came from 215 * if it came through a BOOTP gateway - if it came through an 216 * IP router, we'll just have to assume that it's cool. 217 * 218 * If we don't think we know where the packet came from, it 219 * came through a gateway from an unknown network, so it's not 220 * from a RENEWING client. If we recognize the network it 221 * *thinks* it's on, we can NAK it even though we don't 222 * recognize the network it's *actually* on; otherwise we just 223 * have to ignore it. 224 * 225 * We don't currently try to take advantage of access to the 226 * raw packet, because it's not available on all platforms. 227 * So a packet that was unicast to us through a router from a 228 * RENEWING client is going to look exactly like a packet that 229 * was broadcast to us from an INIT-REBOOT client. 230 * 231 * Since we can't tell the difference between these two kinds 232 * of packets, if the packet appears to have come in off the 233 * local wire, we have to treat it as if it's a RENEWING 234 * client. This means that we can't NAK a RENEWING client on 235 * the local wire that has a bogus address. The good news is 236 * that we won't ACK it either, so it should revert to INIT 237 * state and send us a DHCPDISCOVER, which we *can* work with. 238 * 239 * Because we can't detect that a RENEWING client is on the 240 * wrong wire, it's going to sit there trying to renew until 241 * it gets to the REBIND state, when we *can* NAK it because 242 * the packet will get to us through a BOOTP gateway. We 243 * shouldn't actually see DHCPREQUEST packets from RENEWING 244 * clients on the wrong wire anyway, since their idea of their 245 * local router will be wrong. In any case, the protocol 246 * doesn't really allow us to NAK a DHCPREQUEST from a 247 * RENEWING client, so we can punt on this issue. 248 */ 249 if (!packet->shared_network || 250 (packet->raw->ciaddr.s_addr && packet->raw->giaddr.s_addr) || 251 (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len && 252 !packet->raw->ciaddr.s_addr)) { 253 254 /* 255 * If we don't know where it came from but we do know 256 * where it claims to have come from, it didn't come 257 * from there. Fry it. 258 */ 259 if (!packet->shared_network) { 260 if (subnet && 261 subnet->shared_network->group->authoritative) { 262 nak_lease(packet, &cip); 263 return; 264 } 265 /* Otherwise, ignore it. */ 266 return; 267 } 268 269 /* 270 * If we do know where it came from and it asked for an 271 * address that is not on that shared network, nak it. 272 */ 273 subnet = find_grouped_subnet(packet->shared_network, cip); 274 if (!subnet) { 275 if (packet->shared_network->group->authoritative) 276 nak_lease(packet, &cip); 277 return; 278 } 279 } 280 281 /* 282 * If we found a lease for the client but it's not the one the 283 * client asked for, don't send it - some other server probably 284 * made the cut. 285 */ 286 if (lease && !addr_eq(lease->ip_addr, cip)) { 287 /* 288 * If we found the address the client asked for, but 289 * it wasn't what got picked, the lease belongs to us, 290 * so we should NAK it. 291 */ 292 if (ours) 293 nak_lease(packet, &cip); 294 return; 295 } 296 297 /* 298 * If the address the client asked for is ours, but it wasn't 299 * available for the client, NAK it. 300 */ 301 if (!lease && ours) { 302 nak_lease(packet, &cip); 303 return; 304 } 305 306 /* If we're not allowed to serve this client anymore, don't. */ 307 if (lease && !lease->host && 308 !lease->subnet->group->boot_unknown_clients) { 309 note("Ignoring unknown client %s", 310 print_hw_addr(packet->raw->htype, packet->raw->hlen, 311 packet->raw->chaddr)); 312 return; 313 } else if (lease && lease->host && !lease->host->group->allow_booting) { 314 note("Declining to renew client %s", 315 lease->host->name ? lease->host->name : 316 print_hw_addr(packet->raw->htype, packet->raw->hlen, 317 packet->raw->chaddr)); 318 return; 319 } 320 321 /* 322 * If we own the lease that the client is asking for, 323 * and it's already been assigned to the client, ack it. 324 */ 325 if (lease && 326 ((lease->uid_len && lease->uid_len == 327 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len && 328 !memcmp(packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 329 lease->uid, lease->uid_len)) || 330 (lease->hardware_addr.hlen == packet->raw->hlen && 331 lease->hardware_addr.htype == packet->raw->htype && 332 !memcmp(lease->hardware_addr.haddr, packet->raw->chaddr, 333 packet->raw->hlen)))) { 334 ack_lease(packet, lease, DHCPACK, 0); 335 return; 336 } 337 338 /* 339 * At this point, the client has requested a lease, and it's 340 * available, but it wasn't assigned to the client, which 341 * means that the client probably hasn't gone through the 342 * DHCPDISCOVER part of the protocol. We are within our 343 * rights to send a DHCPNAK. We can also send a DHCPACK. 344 * The thing we probably should not do is to remain silent. 345 * For now, we'll just assign the lease to the client anyway. 346 */ 347 if (lease) 348 ack_lease(packet, lease, DHCPACK, 0); 349} 350 351void 352dhcprelease(struct packet *packet) 353{ 354 struct lease *lease; 355 struct iaddr cip; 356 int i; 357 358 /* 359 * DHCPRELEASE must not specify address in requested-address 360 * option, but old protocol specs weren't explicit about this, 361 * so let it go. 362 */ 363 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len) { 364 note("DHCPRELEASE from %s specified requested-address.", 365 print_hw_addr(packet->raw->htype, packet->raw->hlen, 366 packet->raw->chaddr)); 367 } 368 369 i = DHO_DHCP_CLIENT_IDENTIFIER; 370 if (packet->options[i].len) { 371 lease = find_lease_by_uid(packet->options[i].data, 372 packet->options[i].len); 373 374 /* 375 * See if we can find a lease that matches the 376 * IP address the client is claiming. 377 */ 378 for (; lease; lease = lease->n_uid) { 379 if (!memcmp(&packet->raw->ciaddr, 380 lease->ip_addr.iabuf, 4)) { 381 break; 382 } 383 } 384 } else { 385 /* 386 * The client is supposed to pass a valid client-identifier, 387 * but the spec on this has changed historically, so try the 388 * IP address in ciaddr if the client-identifier fails. 389 */ 390 cip.len = 4; 391 memcpy(cip.iabuf, &packet->raw->ciaddr, 4); 392 lease = find_lease_by_ip_addr(cip); 393 } 394 395 note("DHCPRELEASE of %s from %s via %s (%sfound)", 396 inet_ntoa(packet->raw->ciaddr), 397 print_hw_addr(packet->raw->htype, packet->raw->hlen, 398 packet->raw->chaddr), 399 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 400 packet->interface->name, 401 lease ? "" : "not "); 402 403 /* If we found a lease, release it. */ 404 if (lease && lease->ends > cur_time) { 405 /* 406 * First, we ping this lease to see if it's still 407 * there. if it is, we don't release it. This avoids 408 * the problem of spoofed releases being used to liberate 409 * addresses from the server. 410 */ 411 if (!lease->releasing) { 412 note("DHCPRELEASE of %s from %s via %s (found)", 413 inet_ntoa(packet->raw->ciaddr), 414 print_hw_addr(packet->raw->htype, 415 packet->raw->hlen, packet->raw->chaddr), 416 packet->raw->giaddr.s_addr ? 417 inet_ntoa(packet->raw->giaddr) : 418 packet->interface->name); 419 420 lease->releasing = 1; 421 add_timeout(cur_time + 1, lease_ping_timeout, lease); 422 icmp_echorequest(&(lease->ip_addr)); 423 ++outstanding_pings; 424 } else { 425 note("DHCPRELEASE of %s from %s via %s ignored " 426 "(release already pending)", 427 inet_ntoa(packet->raw->ciaddr), 428 print_hw_addr(packet->raw->htype, 429 packet->raw->hlen, packet->raw->chaddr), 430 packet->raw->giaddr.s_addr ? 431 inet_ntoa(packet->raw->giaddr) : 432 packet->interface->name); 433 } 434 } else { 435 note("DHCPRELEASE of %s from %s via %s for nonexistent lease", 436 inet_ntoa(packet->raw->ciaddr), 437 print_hw_addr(packet->raw->htype, packet->raw->hlen, 438 packet->raw->chaddr), 439 packet->raw->giaddr.s_addr ? 440 inet_ntoa(packet->raw->giaddr) : 441 packet->interface->name); 442 } 443} 444 445void 446dhcpdecline(struct packet *packet) 447{ 448 struct lease *lease; 449 struct iaddr cip; 450 451 /* DHCPDECLINE must specify address. */ 452 if (!packet->options[DHO_DHCP_REQUESTED_ADDRESS].len) 453 return; 454 455 cip.len = 4; 456 memcpy(cip.iabuf, 457 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 4); 458 lease = find_lease_by_ip_addr(cip); 459 460 note("DHCPDECLINE on %s from %s via %s", 461 piaddr(cip), print_hw_addr(packet->raw->htype, 462 packet->raw->hlen, packet->raw->chaddr), 463 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 464 packet->interface->name); 465 466 /* If we found a lease, mark it as unusable and complain. */ 467 if (lease) 468 abandon_lease(lease, "declined."); 469} 470 471void 472dhcpinform(struct packet *packet) 473{ 474 note("DHCPINFORM from %s", inet_ntoa(packet->raw->ciaddr)); 475} 476 477void 478nak_lease(struct packet *packet, struct iaddr *cip) 479{ 480 struct sockaddr_in to; 481 struct in_addr from; 482 int result, i; 483 struct dhcp_packet raw; 484 unsigned char nak = DHCPNAK; 485 struct packet outgoing; 486 struct hardware hto; 487 struct tree_cache *options[256], dhcpnak_tree, dhcpmsg_tree; 488 489 memset(options, 0, sizeof options); 490 memset(&outgoing, 0, sizeof outgoing); 491 memset(&raw, 0, sizeof raw); 492 outgoing.raw = &raw; 493 494 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */ 495 options[DHO_DHCP_MESSAGE_TYPE] = &dhcpnak_tree; 496 options[DHO_DHCP_MESSAGE_TYPE]->value = &nak; 497 options[DHO_DHCP_MESSAGE_TYPE]->len = sizeof nak; 498 options[DHO_DHCP_MESSAGE_TYPE]->buf_size = sizeof nak; 499 options[DHO_DHCP_MESSAGE_TYPE]->timeout = 0xFFFFFFFF; 500 options[DHO_DHCP_MESSAGE_TYPE]->tree = NULL; 501 502 /* Set DHCP_MESSAGE to whatever the message is */ 503 options[DHO_DHCP_MESSAGE] = &dhcpmsg_tree; 504 options[DHO_DHCP_MESSAGE]->value = (unsigned char *)dhcp_message; 505 options[DHO_DHCP_MESSAGE]->len = strlen(dhcp_message); 506 options[DHO_DHCP_MESSAGE]->buf_size = strlen(dhcp_message); 507 options[DHO_DHCP_MESSAGE]->timeout = 0xFFFFFFFF; 508 options[DHO_DHCP_MESSAGE]->tree = NULL; 509 510 /* Do not use the client's requested parameter list. */ 511 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 512 if (packet->options[i].data) { 513 packet->options[i].len = 0; 514 dfree(packet->options[i].data, "nak_lease"); 515 packet->options[i].data = NULL; 516 } 517 518 /* Set up the option buffer... */ 519 outgoing.packet_length = cons_options(packet, outgoing.raw, 520 0, options, 0, 0, 0, NULL, 0); 521 522/* memset(&raw.ciaddr, 0, sizeof raw.ciaddr);*/ 523 raw.siaddr = packet->interface->primary_address; 524 raw.giaddr = packet->raw->giaddr; 525 memcpy(raw.chaddr, packet->raw->chaddr, sizeof raw.chaddr); 526 raw.hlen = packet->raw->hlen; 527 raw.htype = packet->raw->htype; 528 raw.xid = packet->raw->xid; 529 raw.secs = packet->raw->secs; 530 raw.flags = packet->raw->flags | htons(BOOTP_BROADCAST); 531 raw.hops = packet->raw->hops; 532 raw.op = BOOTREPLY; 533 534 /* Report what we're sending... */ 535 note("DHCPNAK on %s to %s via %s", piaddr(*cip), 536 print_hw_addr(packet->raw->htype, packet->raw->hlen, 537 packet->raw->chaddr), packet->raw->giaddr.s_addr ? 538 inet_ntoa(packet->raw->giaddr) : packet->interface->name); 539 540#ifdef DEBUG_PACKET 541 dump_packet(packet); 542 dump_raw((unsigned char *)packet->raw, packet->packet_length); 543 dump_packet(&outgoing); 544 dump_raw((unsigned char *)&raw, outgoing.packet_length); 545#endif 546 547 hto.htype = packet->raw->htype; 548 hto.hlen = packet->raw->hlen; 549 memcpy(hto.haddr, packet->raw->chaddr, hto.hlen); 550 551 /* Set up the common stuff... */ 552 memset(&to, 0, sizeof to); 553 to.sin_family = AF_INET; 554 to.sin_len = sizeof to; 555 556 from = packet->interface->primary_address; 557 558 /* Make sure that the packet is at least as big as a BOOTP packet. */ 559 if (outgoing.packet_length < BOOTP_MIN_LEN) 560 outgoing.packet_length = BOOTP_MIN_LEN; 561 562 /* 563 * If this was gatewayed, send it back to the gateway. 564 * Otherwise, broadcast it on the local network. 565 */ 566 if (raw.giaddr.s_addr) { 567 to.sin_addr = raw.giaddr; 568 to.sin_port = server_port; 569 570 if (fallback_interface) { 571 result = send_packet(fallback_interface, packet, &raw, 572 outgoing.packet_length, from, &to, &hto); 573 if (result == -1) 574 warn("send_fallback: %m"); 575 return; 576 } 577 } else { 578 to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 579 to.sin_port = client_port; 580 } 581 582 errno = 0; 583 result = send_packet(packet->interface, packet, &raw, 584 outgoing.packet_length, from, &to, NULL); 585} 586 587void 588ack_lease(struct packet *packet, struct lease *lease, unsigned int offer, 589 time_t when) 590{ 591 struct lease lt; 592 struct lease_state *state; 593 time_t lease_time, offered_lease_time, max_lease_time, default_lease_time; 594 struct class *vendor_class, *user_class; 595 int ulafdr, i; 596 597 /* If we're already acking this lease, don't do it again. */ 598 if (lease->state) { 599 note("already acking lease %s", piaddr(lease->ip_addr)); 600 return; 601 } 602 603 if (packet->options[DHO_DHCP_CLASS_IDENTIFIER].len) { 604 vendor_class =find_class(0, 605 packet->options[DHO_DHCP_CLASS_IDENTIFIER].data, 606 packet->options[DHO_DHCP_CLASS_IDENTIFIER].len); 607 } else 608 vendor_class = NULL; 609 610 if (packet->options[DHO_DHCP_USER_CLASS_ID].len) { 611 user_class = find_class(1, 612 packet->options[DHO_DHCP_USER_CLASS_ID].data, 613 packet->options[DHO_DHCP_USER_CLASS_ID].len); 614 } else 615 user_class = NULL; 616 617 /* 618 * If there is not a specific host entry, and either the 619 * vendor class or user class (if they exist) deny booting, 620 * then bug out. 621 */ 622 if (!lease->host) { 623 if (vendor_class && !vendor_class->group->allow_booting) { 624 debug("Booting denied by vendor class"); 625 return; 626 } 627 628 if (user_class && !user_class->group->allow_booting) { 629 debug("Booting denied by user class"); 630 return; 631 } 632 } 633 634 /* Allocate a lease state structure... */ 635 state = new_lease_state("ack_lease"); 636 if (!state) 637 error("unable to allocate lease state!"); 638 memset(state, 0, sizeof *state); 639 state->got_requested_address = packet->got_requested_address; 640 state->shared_network = packet->interface->shared_network; 641 642 /* Remember if we got a server identifier option. */ 643 if (packet->options[DHO_DHCP_SERVER_IDENTIFIER].len) 644 state->got_server_identifier = 1; 645 646 /* Replace the old lease hostname with the new one, if it's changed. */ 647 if (packet->options[DHO_HOST_NAME].len && 648 lease->client_hostname && 649 (strlen (lease->client_hostname) == packet->options[DHO_HOST_NAME].len) && 650 !memcmp(lease->client_hostname, packet->options[DHO_HOST_NAME].data, 651 packet->options[DHO_HOST_NAME].len)) { 652 } else if (packet->options[DHO_HOST_NAME].len) { 653 if (lease->client_hostname) 654 free(lease->client_hostname); 655 lease->client_hostname = malloc( 656 packet->options[DHO_HOST_NAME].len + 1); 657 if (!lease->client_hostname) 658 error("no memory for client hostname.\n"); 659 memcpy(lease->client_hostname, 660 packet->options[DHO_HOST_NAME].data, 661 packet->options[DHO_HOST_NAME].len); 662 lease->client_hostname[packet->options[DHO_HOST_NAME].len] = 0; 663 } else if (lease->client_hostname) { 664 free(lease->client_hostname); 665 lease->client_hostname = 0; 666 } 667 668 /* 669 * Choose a filename; first from the host_decl, if any, then from 670 * the user class, then from the vendor class. 671 */ 672 if (lease->host && lease->host->group->filename) 673 strlcpy(state->filename, lease->host->group->filename, 674 sizeof state->filename); 675 else if (user_class && user_class->group->filename) 676 strlcpy(state->filename, user_class->group->filename, 677 sizeof state->filename); 678 else if (vendor_class && vendor_class->group->filename) 679 strlcpy(state->filename, vendor_class->group->filename, 680 sizeof state->filename); 681 else if (packet->raw->file[0]) 682 strlcpy(state->filename, packet->raw->file, 683 sizeof state->filename); 684 else if (lease->subnet->group->filename) 685 strlcpy(state->filename, lease->subnet->group->filename, 686 sizeof state->filename); 687 else 688 strlcpy(state->filename, "", sizeof state->filename); 689 690 /* Choose a server name as above. */ 691 if (lease->host && lease->host->group->server_name) 692 state->server_name = lease->host->group->server_name; 693 else if (user_class && user_class->group->server_name) 694 state->server_name = user_class->group->server_name; 695 else if (vendor_class && vendor_class->group->server_name) 696 state->server_name = vendor_class->group->server_name; 697 else if (lease->subnet->group->server_name) 698 state->server_name = lease->subnet->group->server_name; 699 else state->server_name = NULL; 700 701 /* 702 * At this point, we have a lease that we can offer the client. 703 * Now we construct a lease structure that contains what we want, 704 * and call supersede_lease to do the right thing with it. 705 */ 706 memset(<, 0, sizeof lt); 707 708 /* 709 * Use the ip address of the lease that we finally found in 710 * the database. 711 */ 712 lt.ip_addr = lease->ip_addr; 713 714 /* Start now. */ 715 lt.starts = cur_time; 716 717 /* Figure out maximum lease time. */ 718 if (lease->host && lease->host->group->max_lease_time) 719 max_lease_time = lease->host->group->max_lease_time; 720 else 721 max_lease_time = lease->subnet->group->max_lease_time; 722 723 /* Figure out default lease time. */ 724 if (lease->host && lease->host->group->default_lease_time) 725 default_lease_time = lease->host->group->default_lease_time; 726 else 727 default_lease_time = lease->subnet->group->default_lease_time; 728 729 /* 730 * Figure out how long a lease to assign. If this is a 731 * dynamic BOOTP lease, its duration must be infinite. 732 */ 733 if (offer) { 734 if (packet->options[DHO_DHCP_LEASE_TIME].len == 4) { 735 lease_time = getULong( 736 packet->options[DHO_DHCP_LEASE_TIME].data); 737 738 /* 739 * Don't let the client ask for a longer lease than 740 * is supported for this subnet or host. 741 * 742 * time_t is signed, so really large numbers come 743 * back as negative. Don't allow lease_time of 0, 744 * either. 745 */ 746 if (lease_time < 1 || lease_time > max_lease_time) 747 lease_time = max_lease_time; 748 } else 749 lease_time = default_lease_time; 750 751 state->offered_expiry = cur_time + lease_time; 752 if (when) 753 lt.ends = when; 754 else 755 lt.ends = state->offered_expiry; 756 } else { 757 if (lease->host && 758 lease->host->group->bootp_lease_length) 759 lt.ends = (cur_time + 760 lease->host->group->bootp_lease_length); 761 else if (lease->subnet->group->bootp_lease_length) 762 lt.ends = (cur_time + 763 lease->subnet->group->bootp_lease_length); 764 else if (lease->host && 765 lease->host->group->bootp_lease_cutoff) 766 lt.ends = lease->host->group->bootp_lease_cutoff; 767 else 768 lt.ends = lease->subnet->group->bootp_lease_cutoff; 769 state->offered_expiry = lt.ends; 770 lt.flags = BOOTP_LEASE; 771 } 772 773 /* Record the uid, if given... */ 774 i = DHO_DHCP_CLIENT_IDENTIFIER; 775 if (packet->options[i].len) { 776 if (packet->options[i].len <= sizeof lt.uid_buf) { 777 memcpy(lt.uid_buf, packet->options[i].data, 778 packet->options[i].len); 779 lt.uid = lt.uid_buf; 780 lt.uid_max = sizeof lt.uid_buf; 781 lt.uid_len = packet->options[i].len; 782 } else { 783 lt.uid_max = lt.uid_len = packet->options[i].len; 784 lt.uid = (unsigned char *)malloc(lt.uid_max); 785 if (!lt.uid) 786 error("can't allocate memory for large uid."); 787 memcpy(lt.uid, packet->options[i].data, lt.uid_len); 788 } 789 } 790 791 lt.host = lease->host; 792 lt.subnet = lease->subnet; 793 lt.shared_network = lease->shared_network; 794 795 /* Don't call supersede_lease on a mocked-up lease. */ 796 if (lease->flags & STATIC_LEASE) { 797 /* Copy the hardware address into the static lease 798 structure. */ 799 lease->hardware_addr.hlen = packet->raw->hlen; 800 lease->hardware_addr.htype = packet->raw->htype; 801 memcpy(lease->hardware_addr.haddr, packet->raw->chaddr, 802 sizeof packet->raw->chaddr); /* XXX */ 803 } else { 804 /* Record the hardware address, if given... */ 805 lt.hardware_addr.hlen = packet->raw->hlen; 806 lt.hardware_addr.htype = packet->raw->htype; 807 memcpy(lt.hardware_addr.haddr, packet->raw->chaddr, 808 sizeof packet->raw->chaddr); 809 810 /* Install the new information about this lease in the 811 database. If this is a DHCPACK or a dynamic BOOTREPLY 812 and we can't write the lease, don't ACK it (or BOOTREPLY 813 it) either. */ 814 815 if (!(supersede_lease(lease, <, !offer || offer == DHCPACK) || 816 (offer && offer != DHCPACK))) 817 return; 818 } 819 820 /* Remember the interface on which the packet arrived. */ 821 state->ip = packet->interface; 822 823 /* Set a flag if this client is a lame Microsoft client that NUL 824 terminates string options and expects us to do likewise. */ 825 if (packet->options[DHO_HOST_NAME].data && 826 packet->options[DHO_HOST_NAME].data[ 827 packet->options[DHO_HOST_NAME].len - 1] == '\0') 828 lease->flags |= MS_NULL_TERMINATION; 829 else 830 lease->flags &= ~MS_NULL_TERMINATION; 831 832 /* Remember the giaddr, xid, secs, flags and hops. */ 833 state->giaddr = packet->raw->giaddr; 834 state->ciaddr = packet->raw->ciaddr; 835 state->xid = packet->raw->xid; 836 state->secs = packet->raw->secs; 837 state->bootp_flags = packet->raw->flags; 838 state->hops = packet->raw->hops; 839 state->offer = offer; 840 841 /* Figure out what options to send to the client: */ 842 843 /* Start out with the subnet options... */ 844 memcpy(state->options, lease->subnet->group->options, 845 sizeof state->options); 846 847 /* Vendor and user classes are only supported for DHCP clients. */ 848 if (state->offer) { 849 /* If we have a vendor class, install those options, 850 superseding any subnet options. */ 851 if (vendor_class) { 852 for (i = 0; i < 256; i++) 853 if (vendor_class->group->options[i]) 854 state->options[i] = 855 vendor_class->group->options[i]; 856 } 857 858 /* If we have a user class, install those options, 859 superseding any subnet and vendor class options. */ 860 if (user_class) { 861 for (i = 0; i < 256; i++) 862 if (user_class->group->options[i]) 863 state->options[i] = 864 user_class->group->options[i]; 865 } 866 867 } 868 869 /* If we have a host_decl structure, install the associated 870 options, superseding anything that's in the way. */ 871 if (lease->host) { 872 for (i = 0; i < 256; i++) 873 if (lease->host->group->options[i]) 874 state->options[i] = 875 lease->host->group->options[i]; 876 } 877 878 /* Get the Maximum Message Size option from the packet, if one 879 was sent. */ 880 i = DHO_DHCP_MAX_MESSAGE_SIZE; 881 if (packet->options[i].data && 882 packet->options[i].len == sizeof (u_int16_t)) 883 state->max_message_size = getUShort(packet->options[i].data); 884 /* Otherwise, if a maximum message size was specified, use that. */ 885 else if (state->options[i] && state->options[i]->value) 886 state->max_message_size = getUShort(state->options[i]->value); 887 888 /* Save the parameter request list if there is one. */ 889 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 890 if (packet->options[i].data) { 891 state->prl = dmalloc(packet->options[i].len, "ack_lease: prl"); 892 if (!state->prl) 893 warn("no memory for parameter request list"); 894 else { 895 memcpy(state->prl, packet->options[i].data, 896 packet->options[i].len); 897 state->prl_len = packet->options[i].len; 898 } 899 } 900 901 /* If we didn't get a hostname from an option somewhere, see if 902 we can get one from the lease. */ 903 i = DHO_HOST_NAME; 904 if (!state->options[i] && lease->hostname) { 905 state->options[i] = new_tree_cache("hostname"); 906 state->options[i]->flags = TC_TEMPORARY; 907 state->options[i]->value = (unsigned char *)lease->hostname; 908 state->options[i]->len = strlen (lease->hostname); 909 state->options[i]->buf_size = state->options[i]->len; 910 state->options[i]->timeout = 0xFFFFFFFF; 911 state->options[i]->tree = NULL; 912 } 913 914 /* 915 * Now, if appropriate, put in DHCP-specific options that 916 * override those. 917 */ 918 if (state->offer) { 919 i = DHO_DHCP_MESSAGE_TYPE; 920 state->options[i] = new_tree_cache("message-type"); 921 state->options[i]->flags = TC_TEMPORARY; 922 state->options[i]->value = &state->offer; 923 state->options[i]->len = sizeof state->offer; 924 state->options[i]->buf_size = sizeof state->offer; 925 state->options[i]->timeout = 0xFFFFFFFF; 926 state->options[i]->tree = NULL; 927 928 i = DHO_DHCP_SERVER_IDENTIFIER; 929 if (!state->options[i]) { 930 use_primary: 931 state->options[i] = new_tree_cache("server-id"); 932 state->options[i]->value = 933 (unsigned char *)&state->ip->primary_address; 934 state->options[i]->len = 935 sizeof state->ip->primary_address; 936 state->options[i]->buf_size = 937 state->options[i]->len; 938 state->options[i]->timeout = 0xFFFFFFFF; 939 state->options[i]->tree = NULL; 940 state->from.len = sizeof state->ip->primary_address; 941 memcpy(state->from.iabuf, &state->ip->primary_address, 942 state->from.len); 943 } else { 944 /* Find the value of the server identifier... */ 945 if (!tree_evaluate (state->options[i])) 946 goto use_primary; 947 if (!state->options[i]->value || 948 (state->options[i]->len > sizeof state->from.iabuf)) 949 goto use_primary; 950 951 state->from.len = state->options[i]->len; 952 memcpy(state->from.iabuf, state->options[i]->value, 953 state->from.len); 954 } 955 956 /* Sanity check the lease time. */ 957 if ((state->offered_expiry - cur_time) < 15) 958 offered_lease_time = default_lease_time; 959 else if (state->offered_expiry - cur_time > max_lease_time) 960 offered_lease_time = max_lease_time; 961 else 962 offered_lease_time = 963 state->offered_expiry - cur_time; 964 965 putULong((unsigned char *)&state->expiry, 966 offered_lease_time); 967 i = DHO_DHCP_LEASE_TIME; 968 state->options[i] = new_tree_cache ("lease-expiry"); 969 state->options[i]->flags = TC_TEMPORARY; 970 state->options[i]->value = (unsigned char *)&state->expiry; 971 state->options[i]->len = sizeof state->expiry; 972 state->options[i]->buf_size = sizeof state->expiry; 973 state->options[i]->timeout = 0xFFFFFFFF; 974 state->options[i]->tree = NULL; 975 976 /* Renewal time is lease time * 0.5. */ 977 offered_lease_time /= 2; 978 putULong ((unsigned char *)&state->renewal, 979 offered_lease_time); 980 i = DHO_DHCP_RENEWAL_TIME; 981 state->options[i] = new_tree_cache ("renewal-time"); 982 state->options[i]->flags = TC_TEMPORARY; 983 state->options[i]->value = 984 (unsigned char *)&state->renewal; 985 state->options[i]->len = sizeof state->renewal; 986 state->options[i]->buf_size = sizeof state->renewal; 987 state->options[i]->timeout = 0xFFFFFFFF; 988 state->options[i]->tree = NULL; 989 990 991 /* Rebinding time is lease time * 0.875. */ 992 offered_lease_time += (offered_lease_time / 2 + 993 offered_lease_time / 4); 994 putULong ((unsigned char *)&state->rebind, 995 offered_lease_time); 996 i = DHO_DHCP_REBINDING_TIME; 997 state->options[i] = new_tree_cache ("rebind-time"); 998 state->options[i]->flags = TC_TEMPORARY; 999 state->options[i]->value = 1000 (unsigned char *)&state->rebind; 1001 state->options[i]->len = sizeof state->rebind; 1002 state->options[i]->buf_size = sizeof state->rebind; 1003 state->options[i]->timeout = 0xFFFFFFFF; 1004 state->options[i]->tree = NULL; 1005 1006 /* If we used the vendor class the client specified, we 1007 have to return it. */ 1008 if (vendor_class) { 1009 i = DHO_DHCP_CLASS_IDENTIFIER; 1010 state->options[i] = 1011 new_tree_cache ("class-identifier"); 1012 state->options[i]->flags = TC_TEMPORARY; 1013 state->options[i]->value = 1014 (unsigned char *)vendor_class->name; 1015 state->options[i]->len = 1016 strlen (vendor_class->name); 1017 state->options[i]->buf_size = 1018 state->options[i]->len; 1019 state->options[i]->timeout = 0xFFFFFFFF; 1020 state->options[i]->tree = NULL; 1021 } 1022 1023 /* If we used the user class the client specified, we 1024 have to return it. */ 1025 if (user_class) { 1026 i = DHO_DHCP_USER_CLASS_ID; 1027 state->options[i] = new_tree_cache ("user-class"); 1028 state->options[i]->flags = TC_TEMPORARY; 1029 state->options[i]->value = 1030 (unsigned char *)user_class->name; 1031 state->options[i]->len = 1032 strlen (user_class->name); 1033 state->options[i]->buf_size = 1034 state->options[i]->len; 1035 state->options[i]->timeout = 0xFFFFFFFF; 1036 state->options[i]->tree = NULL; 1037 } 1038 } 1039 1040 /* Use the subnet mask from the subnet declaration if no other 1041 mask has been provided. */ 1042 i = DHO_SUBNET_MASK; 1043 if (!state->options[i]) { 1044 state->options[i] = new_tree_cache ("subnet-mask"); 1045 state->options[i]->flags = TC_TEMPORARY; 1046 state->options[i]->value = 1047 lease->subnet->netmask.iabuf; 1048 state->options[i]->len = lease->subnet->netmask.len; 1049 state->options[i]->buf_size = 1050 lease->subnet->netmask.len; 1051 state->options[i]->timeout = 0xFFFFFFFF; 1052 state->options[i]->tree = NULL; 1053 } 1054 1055 /* If so directed, use the leased IP address as the router address. 1056 This supposedly makes Win95 machines ARP for all IP addresses, 1057 so if the local router does proxy arp, you win. */ 1058 1059 ulafdr = 0; 1060 if (lease->host) { 1061 if (lease->host->group->use_lease_addr_for_default_route) 1062 ulafdr = 1; 1063 } else if (user_class) { 1064 if (user_class->group->use_lease_addr_for_default_route) 1065 ulafdr = 1; 1066 } else if (vendor_class) { 1067 if (vendor_class->group->use_lease_addr_for_default_route) 1068 ulafdr = 1; 1069 } else if (lease->subnet->group->use_lease_addr_for_default_route) 1070 ulafdr = 1; 1071 else 1072 ulafdr = 0; 1073 1074 i = DHO_ROUTERS; 1075 if (ulafdr && !state->options[i]) { 1076 state->options[i] = new_tree_cache ("routers"); 1077 state->options[i]->flags = TC_TEMPORARY; 1078 state->options[i]->value = lease->ip_addr.iabuf; 1079 state->options[i]->len = lease->ip_addr.len; 1080 state->options[i]->buf_size = lease->ip_addr.len; 1081 state->options[i]->timeout = 0xFFFFFFFF; 1082 state->options[i]->tree = NULL; 1083 } 1084 1085#ifdef DEBUG_PACKET 1086 dump_packet(packet); 1087 dump_raw((unsigned char *)packet->raw, packet->packet_length); 1088#endif 1089 1090 lease->state = state; 1091 1092 /* If this is a DHCPOFFER, ping the lease address before actually 1093 sending the offer. */ 1094 if (offer == DHCPOFFER && !(lease->flags & STATIC_LEASE) && 1095 cur_time - lease->timestamp > 60) { 1096 lease->timestamp = cur_time; 1097 icmp_echorequest (&lease->ip_addr); 1098 add_timeout (cur_time + 1, lease_ping_timeout, lease); 1099 ++outstanding_pings; 1100 } else { 1101 lease->timestamp = cur_time; 1102 dhcp_reply (lease); 1103 } 1104} 1105 1106void 1107dhcp_reply(struct lease *lease) 1108{ 1109 int bufs = 0, packet_length, result, i; 1110 struct dhcp_packet raw; 1111 struct sockaddr_in to; 1112 struct in_addr from; 1113 struct hardware hto; 1114 struct lease_state *state = lease->state; 1115 int nulltp, bootpp; 1116 u_int8_t *prl; 1117 int prl_len; 1118 1119 if (!state) 1120 error("dhcp_reply was supplied lease with no state!"); 1121 1122 /* Compose a response for the client... */ 1123 memset(&raw, 0, sizeof raw); 1124 1125 /* Copy in the filename if given; otherwise, flag the filename 1126 buffer as available for options. */ 1127 if (state->filename[0]) 1128 strlcpy(raw.file, state->filename, sizeof raw.file); 1129 else 1130 bufs |= 1; 1131 1132 /* Copy in the server name if given; otherwise, flag the 1133 server_name buffer as available for options. */ 1134 if (state->server_name) 1135 strlcpy(raw.sname, state->server_name, sizeof raw.sname); 1136 else 1137 bufs |= 2; /* XXX */ 1138 1139 memcpy(raw.chaddr, lease->hardware_addr.haddr, sizeof raw.chaddr); 1140 raw.hlen = lease->hardware_addr.hlen; 1141 raw.htype = lease->hardware_addr.htype; 1142 1143 /* See if this is a Microsoft client that NUL-terminates its 1144 strings and expects us to do likewise... */ 1145 if (lease->flags & MS_NULL_TERMINATION) 1146 nulltp = 1; 1147 else 1148 nulltp = 0; 1149 1150 /* See if this is a bootp client... */ 1151 if (state->offer) 1152 bootpp = 0; 1153 else 1154 bootpp = 1; 1155 1156 if (state->options[DHO_DHCP_PARAMETER_REQUEST_LIST] && 1157 state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value) { 1158 prl = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value; 1159 prl_len = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->len; 1160 } else if (state->prl) { 1161 prl = state->prl; 1162 prl_len = state->prl_len; 1163 } else { 1164 prl = NULL; 1165 prl_len = 0; 1166 } 1167 1168 /* Insert such options as will fit into the buffer. */ 1169 packet_length = cons_options(NULL, &raw, state->max_message_size, 1170 state->options, bufs, nulltp, bootpp, prl, prl_len); 1171 1172 /* Having done the cons_options(), we can release the tree_cache 1173 entries. */ 1174 for (i = 0; i < 256; i++) { 1175 if (state->options[i] && 1176 state->options[i]->flags & TC_TEMPORARY) 1177 free_tree_cache(state->options[i], "dhcp_reply"); 1178 } 1179 1180 memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr); 1181 memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4); 1182 1183 /* Figure out the address of the next server. */ 1184 if (lease->host && lease->host->group->next_server.len) 1185 memcpy(&raw.siaddr, lease->host->group->next_server.iabuf, 4); 1186 else if (lease->subnet->group->next_server.len) 1187 memcpy(&raw.siaddr, lease->subnet->group->next_server.iabuf, 4); 1188 else if (lease->subnet->interface_address.len) 1189 memcpy(&raw.siaddr, lease->subnet->interface_address.iabuf, 4); 1190 else 1191 raw.siaddr = state->ip->primary_address; 1192 1193 raw.giaddr = state->giaddr; 1194 1195 raw.xid = state->xid; 1196 raw.secs = state->secs; 1197 raw.flags = state->bootp_flags; 1198 raw.hops = state->hops; 1199 raw.op = BOOTREPLY; 1200 1201 /* Say what we're doing... */ 1202 note("%s on %s to %s via %s", 1203 (state->offer ? (state->offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") : 1204 "BOOTREPLY"), 1205 piaddr(lease->ip_addr), 1206 print_hw_addr(lease->hardware_addr.htype, lease->hardware_addr.hlen, 1207 lease->hardware_addr.haddr), 1208 state->giaddr.s_addr ? inet_ntoa(state->giaddr) : state->ip->name); 1209 1210 /* Set up the hardware address... */ 1211 hto.htype = lease->hardware_addr.htype; 1212 hto.hlen = lease->hardware_addr.hlen; 1213 memcpy(hto.haddr, lease->hardware_addr.haddr, hto.hlen); 1214 1215 memset(&to, 0, sizeof to); 1216 to.sin_family = AF_INET; 1217#ifdef HAVE_SA_LEN 1218 to.sin_len = sizeof to; 1219#endif 1220 1221#ifdef DEBUG_PACKET 1222 dump_raw((unsigned char *)&raw, packet_length); 1223#endif 1224 1225 /* Make sure outgoing packets are at least as big 1226 as a BOOTP packet. */ 1227 if (packet_length < BOOTP_MIN_LEN) 1228 packet_length = BOOTP_MIN_LEN; 1229 1230 /* If this was gatewayed, send it back to the gateway... */ 1231 if (raw.giaddr.s_addr) { 1232 to.sin_addr = raw.giaddr; 1233 to.sin_port = server_port; 1234 1235 if (fallback_interface) { 1236 result = send_packet(fallback_interface, NULL, 1237 &raw, packet_length,raw.siaddr, &to, NULL); 1238 1239 free_lease_state(state, "dhcp_reply fallback 1"); 1240 lease->state = NULL; 1241 return; 1242 } 1243 1244 /* If the client is RENEWING, unicast to the client using the 1245 regular IP stack. Some clients, particularly those that 1246 follow RFC1541, are buggy, and send both ciaddr and 1247 server-identifier. We deal with this situation by assuming 1248 that if we got both dhcp-server-identifier and ciaddr, and 1249 giaddr was not set, then the client is on the local 1250 network, and we can therefore unicast or broadcast to it 1251 successfully. A client in REQUESTING state on another 1252 network that's making this mistake will have set giaddr, 1253 and will therefore get a relayed response from the above 1254 code. */ 1255 } else if (raw.ciaddr.s_addr && 1256 !((state->got_server_identifier || 1257 (raw.flags & htons(BOOTP_BROADCAST))) && 1258 /* XXX This won't work if giaddr isn't zero, but it is: */ 1259 (state->shared_network == lease->shared_network)) && 1260 state->offer == DHCPACK) { 1261 to.sin_addr = raw.ciaddr; 1262 to.sin_port = client_port; 1263 1264 if (fallback_interface) { 1265 result = send_packet(fallback_interface, NULL, 1266 &raw, packet_length, raw.siaddr, &to, NULL); 1267 free_lease_state(state, "dhcp_reply fallback 2"); 1268 lease->state = NULL; 1269 return; 1270 } 1271 1272 /* If it comes from a client that already knows its address 1273 and is not requesting a broadcast response, and we can 1274 unicast to a client without using the ARP protocol, sent it 1275 directly to that client. */ 1276 } else if (!(raw.flags & htons (BOOTP_BROADCAST))) { 1277 to.sin_addr = raw.yiaddr; 1278 to.sin_port = client_port; 1279 1280 /* Otherwise, broadcast it on the local network. */ 1281 } else { 1282 to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 1283 to.sin_port = client_port; 1284 } 1285 1286 memcpy(&from, state->from.iabuf, sizeof from); 1287 1288 result = send_packet(state->ip, NULL, &raw, packet_length, 1289 from, &to, &hto); 1290 1291 free_lease_state(state, "dhcp_reply"); 1292 lease->state = NULL; 1293} 1294 1295struct lease * 1296find_lease(struct packet *packet, struct shared_network *share, 1297 int *ours) 1298{ 1299 struct lease *uid_lease, *ip_lease, *hw_lease; 1300 struct lease *lease = NULL; 1301 struct iaddr cip; 1302 struct host_decl *hp, *host = NULL; 1303 struct lease *fixed_lease; 1304 1305 /* Figure out what IP address the client is requesting, if any. */ 1306 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len && 1307 packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4) { 1308 packet->got_requested_address = 1; 1309 cip.len = 4; 1310 memcpy(cip.iabuf, 1311 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 1312 cip.len); 1313 } else if (packet->raw->ciaddr.s_addr) { 1314 cip.len = 4; 1315 memcpy(cip.iabuf, &packet->raw->ciaddr, 4); 1316 } else 1317 cip.len = 0; 1318 1319 /* Try to find a host or lease that's been assigned to the 1320 specified unique client identifier. */ 1321 if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) { 1322 /* First, try to find a fixed host entry for the specified 1323 client identifier... */ 1324 hp = find_hosts_by_uid( 1325 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1326 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1327 if (hp) { 1328 host = hp; 1329 fixed_lease = mockup_lease(packet, share, hp); 1330 uid_lease = NULL; 1331 } else { 1332 uid_lease = find_lease_by_uid( 1333 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1334 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1335 /* Find the lease matching this uid that's on the 1336 network the packet came from (if any). */ 1337 for (; uid_lease; uid_lease = uid_lease->n_uid) 1338 if (uid_lease->shared_network == share) 1339 break; 1340 fixed_lease = NULL; 1341 if (uid_lease && (uid_lease->flags & ABANDONED_LEASE)) 1342 uid_lease = NULL; 1343 } 1344 } else { 1345 uid_lease = NULL; 1346 fixed_lease = NULL; 1347 } 1348 1349 /* If we didn't find a fixed lease using the uid, try doing 1350 it with the hardware address... */ 1351 if (!fixed_lease) { 1352 hp = find_hosts_by_haddr(packet->raw->htype, 1353 packet->raw->chaddr, packet->raw->hlen); 1354 if (hp) { 1355 host = hp; /* Save it for later. */ 1356 fixed_lease = mockup_lease (packet, share, hp); 1357 } 1358 } 1359 1360 /* If fixed_lease is present but does not match the requested 1361 IP address, and this is a DHCPREQUEST, then we can't return 1362 any other lease, so we might as well return now. */ 1363 if (packet->packet_type == DHCPREQUEST && fixed_lease && 1364 (fixed_lease->ip_addr.len != cip.len || 1365 memcmp(fixed_lease->ip_addr.iabuf, cip.iabuf, cip.len))) { 1366 if (ours) 1367 *ours = 1; 1368 strlcpy(dhcp_message, "requested address is incorrect", 1369 sizeof (dhcp_message)); 1370 return NULL; 1371 } 1372 1373 /* Try to find a lease that's been attached to the client's 1374 hardware address... */ 1375 hw_lease = find_lease_by_hw_addr(packet->raw->chaddr, 1376 packet->raw->hlen); 1377 /* Find the lease that's on the network the packet came from 1378 (if any). */ 1379 for (; hw_lease; hw_lease = hw_lease->n_hw) { 1380 if (hw_lease->shared_network == share) { 1381 if ((hw_lease->flags & ABANDONED_LEASE)) 1382 continue; 1383 if (packet->packet_type) 1384 break; 1385 if (hw_lease->flags & 1386 (BOOTP_LEASE | DYNAMIC_BOOTP_OK)) 1387 break; 1388 } 1389 } 1390 1391 /* Try to find a lease that's been allocated to the client's 1392 IP address. */ 1393 if (cip.len) 1394 ip_lease = find_lease_by_ip_addr(cip); 1395 else 1396 ip_lease = NULL; 1397 1398 /* If ip_lease is valid at this point, set ours to one, so that 1399 even if we choose a different lease, we know that the address 1400 the client was requesting was ours, and thus we can NAK it. */ 1401 if (ip_lease && ours) 1402 *ours = 1; 1403 1404 /* If the requested IP address isn't on the network the packet 1405 came from, don't use it. Allow abandoned leases to be matched 1406 here - if the client is requesting it, there's a decent chance 1407 that it's because the lease database got trashed and a client 1408 that thought it had this lease answered an ARP or PING, causing the 1409 lease to be abandoned. If so, this request probably came from 1410 that client. */ 1411 if (ip_lease && (ip_lease->shared_network != share)) { 1412 ip_lease = NULL; 1413 strlcpy(dhcp_message, "requested address on bad subnet", 1414 sizeof(dhcp_message)); 1415 } 1416 1417 /* Toss ip_lease if it hasn't yet expired and isn't owned by the 1418 client. */ 1419 if (ip_lease && ip_lease->ends >= cur_time && ip_lease != uid_lease) { 1420 int i = DHO_DHCP_CLIENT_IDENTIFIER; 1421 1422 /* Make sure that ip_lease actually belongs to the client, 1423 and toss it if not. */ 1424 if ((ip_lease->uid_len && packet->options[i].data && 1425 ip_lease->uid_len == packet->options[i].len && 1426 !memcmp(packet->options[i].data, ip_lease->uid, 1427 ip_lease->uid_len)) || 1428 (!ip_lease->uid_len && 1429 ip_lease->hardware_addr.htype == packet->raw->htype && 1430 ip_lease->hardware_addr.hlen == packet->raw->hlen && 1431 !memcmp(ip_lease->hardware_addr.haddr, packet->raw->chaddr, 1432 ip_lease->hardware_addr.hlen))) { 1433 if (uid_lease) { 1434 if (uid_lease->ends > cur_time) { 1435 warn("client %s has duplicate leases on %s", 1436 print_hw_addr(packet->raw->htype, 1437 packet->raw->hlen, packet->raw->chaddr), 1438 ip_lease->shared_network->name); 1439 1440 if (uid_lease && !packet->raw->ciaddr.s_addr) 1441 release_lease (uid_lease); 1442 } 1443 uid_lease = ip_lease; 1444 } 1445 } else { 1446 strlcpy(dhcp_message, "requested address is not available", 1447 sizeof(dhcp_message)); 1448 ip_lease = NULL; 1449 } 1450 1451 /* If we get to here and fixed_lease is not null, that means 1452 that there are both a dynamic lease and a fixed-address 1453 declaration for the same IP address. */ 1454 if (packet->packet_type == DHCPREQUEST && fixed_lease) { 1455 fixed_lease = NULL; 1456db_conflict: 1457 warn("Both dynamic and static leases present for %s.", 1458 piaddr(cip)); 1459 warn("Either remove host declaration %s or remove %s", 1460 (fixed_lease && fixed_lease->host ? 1461 (fixed_lease->host->name ? fixed_lease->host->name : 1462 piaddr(cip)) : piaddr(cip)), piaddr(cip)); 1463 warn("from the dynamic address pool for %s", 1464 share->name); 1465 if (fixed_lease) 1466 ip_lease = NULL; 1467 strlcpy(dhcp_message, "database conflict - call for help!", 1468 sizeof(dhcp_message)); 1469 } 1470 } 1471 1472 /* If we get to here with both fixed_lease and ip_lease not 1473 null, then we have a configuration file bug. */ 1474 if (packet->packet_type == DHCPREQUEST && fixed_lease && ip_lease) 1475 goto db_conflict; 1476 1477 /* Toss hw_lease if it hasn't yet expired and the uid doesn't 1478 match, except that if the hardware address matches and the 1479 client is now doing dynamic BOOTP (and thus hasn't provided 1480 a uid) we let the client get away with it. */ 1481 if (hw_lease && hw_lease->ends >= cur_time && hw_lease->uid && 1482 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len && 1483 hw_lease != uid_lease) 1484 hw_lease = NULL; 1485 1486 /* Toss extra pointers to the same lease... */ 1487 if (hw_lease == uid_lease) 1488 hw_lease = NULL; 1489 if (ip_lease == hw_lease) 1490 hw_lease = NULL; 1491 if (ip_lease == uid_lease) 1492 uid_lease = NULL; 1493 1494 /* If we've already eliminated the lease, it wasn't there to 1495 begin with. If we have come up with a matching lease, 1496 set the message to bad network in case we have to throw it out. */ 1497 if (!ip_lease) { 1498 strlcpy(dhcp_message, "requested address not available", 1499 sizeof(dhcp_message)); 1500 } 1501 1502 /* Now eliminate leases that are on the wrong network... */ 1503 if (ip_lease && share != ip_lease->shared_network) { 1504 if (packet->packet_type == DHCPREQUEST) 1505 release_lease(ip_lease); 1506 ip_lease = NULL; 1507 } 1508 if (uid_lease && share != uid_lease->shared_network) { 1509 if (packet->packet_type == DHCPREQUEST) 1510 release_lease(uid_lease); 1511 uid_lease = NULL; 1512 } 1513 if (hw_lease && share != hw_lease->shared_network) { 1514 if (packet->packet_type == DHCPREQUEST) 1515 release_lease(hw_lease); 1516 hw_lease = NULL; 1517 } 1518 1519 /* If this is a DHCPREQUEST, make sure the lease we're going to return 1520 matches the requested IP address. If it doesn't, don't return a 1521 lease at all. */ 1522 if (packet->packet_type == DHCPREQUEST && !ip_lease && !fixed_lease) 1523 return NULL; 1524 1525 /* At this point, if fixed_lease is nonzero, we can assign it to 1526 this client. */ 1527 if (fixed_lease) 1528 lease = fixed_lease; 1529 1530 /* If we got a lease that matched the ip address and don't have 1531 a better offer, use that; otherwise, release it. */ 1532 if (ip_lease) { 1533 if (lease) { 1534 if (packet->packet_type == DHCPREQUEST) 1535 release_lease(ip_lease); 1536 } else { 1537 lease = ip_lease; 1538 lease->host = NULL; 1539 } 1540 } 1541 1542 /* If we got a lease that matched the client identifier, we may want 1543 to use it, but if we already have a lease we like, we must free 1544 the lease that matched the client identifier. */ 1545 if (uid_lease) { 1546 if (lease) { 1547 if (packet->packet_type == DHCPREQUEST) 1548 release_lease(uid_lease); 1549 } else { 1550 lease = uid_lease; 1551 lease->host = NULL; 1552 } 1553 } 1554 1555 /* The lease that matched the hardware address is treated likewise. */ 1556 if (hw_lease) { 1557 if (lease) { 1558 if (packet->packet_type == DHCPREQUEST) 1559 release_lease(hw_lease); 1560 } else { 1561 lease = hw_lease; 1562 lease->host = NULL; 1563 } 1564 } 1565 1566 /* If we found a host_decl but no matching address, try to 1567 find a host_decl that has no address, and if there is one, 1568 hang it off the lease so that we can use the supplied 1569 options. */ 1570 if (lease && host && !lease->host) { 1571 for (; host; host = host->n_ipaddr) { 1572 if (!host->fixed_addr) { 1573 lease->host = host; 1574 break; 1575 } 1576 } 1577 } 1578 1579 /* If we find an abandoned lease, take it, but print a 1580 warning message, so that if it continues to lose, 1581 the administrator will eventually investigate. */ 1582 if (lease && (lease->flags & ABANDONED_LEASE)) { 1583 if (packet->packet_type == DHCPREQUEST) { 1584 warn("Reclaiming REQUESTed abandoned IP address %s.", 1585 piaddr(lease->ip_addr)); 1586 lease->flags &= ~ABANDONED_LEASE; 1587 } else 1588 lease = NULL; 1589 } 1590 return lease; 1591} 1592 1593/* 1594 * Search the provided host_decl structure list for an address that's on 1595 * the specified shared network. If one is found, mock up and return a 1596 * lease structure for it; otherwise return the null pointer. 1597 */ 1598struct lease * 1599mockup_lease(struct packet *packet, struct shared_network *share, 1600 struct host_decl *hp) 1601{ 1602 static struct lease mock; 1603 1604 mock.subnet = find_host_for_network(&hp, &mock.ip_addr, share); 1605 if (!mock.subnet) 1606 return (NULL); 1607 mock.next = mock.prev = NULL; 1608 mock.shared_network = mock.subnet->shared_network; 1609 mock.host = hp; 1610 1611 if (hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]) { 1612 mock.uid = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->value; 1613 mock.uid_len = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->len; 1614 } else { 1615 mock.uid = NULL; 1616 mock.uid_len = 0; 1617 } 1618 1619 mock.hardware_addr = hp->interface; 1620 mock.starts = mock.timestamp = mock.ends = MIN_TIME; 1621 mock.flags = STATIC_LEASE; 1622 return &mock; 1623} 1624