dhcp.c revision 1.19
1/* $OpenBSD: dhcp.c,v 1.19 2005/01/31 22:21:44 claudio Exp $ */ 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 warning("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're already acking this lease, don't do it again. */ 404 if (lease && lease->state) { 405 note("DHCPRELEASE already acking lease %s", 406 piaddr(lease->ip_addr)); 407 return; 408 } 409 410 /* If we found a lease, release it. */ 411 if (lease && lease->ends > cur_time) { 412 /* 413 * First, we ping this lease to see if it's still 414 * there. if it is, we don't release it. This avoids 415 * the problem of spoofed releases being used to liberate 416 * addresses from the server. 417 */ 418 if (!lease->releasing) { 419 note("DHCPRELEASE of %s from %s via %s (found)", 420 inet_ntoa(packet->raw->ciaddr), 421 print_hw_addr(packet->raw->htype, 422 packet->raw->hlen, packet->raw->chaddr), 423 packet->raw->giaddr.s_addr ? 424 inet_ntoa(packet->raw->giaddr) : 425 packet->interface->name); 426 427 lease->releasing = 1; 428 add_timeout(cur_time + 1, lease_ping_timeout, lease); 429 icmp_echorequest(&(lease->ip_addr)); 430 ++outstanding_pings; 431 } else { 432 note("DHCPRELEASE of %s from %s via %s ignored " 433 "(release already pending)", 434 inet_ntoa(packet->raw->ciaddr), 435 print_hw_addr(packet->raw->htype, 436 packet->raw->hlen, packet->raw->chaddr), 437 packet->raw->giaddr.s_addr ? 438 inet_ntoa(packet->raw->giaddr) : 439 packet->interface->name); 440 } 441 } else { 442 note("DHCPRELEASE of %s from %s via %s for nonexistent lease", 443 inet_ntoa(packet->raw->ciaddr), 444 print_hw_addr(packet->raw->htype, packet->raw->hlen, 445 packet->raw->chaddr), 446 packet->raw->giaddr.s_addr ? 447 inet_ntoa(packet->raw->giaddr) : 448 packet->interface->name); 449 } 450} 451 452void 453dhcpdecline(struct packet *packet) 454{ 455 struct lease *lease; 456 struct iaddr cip; 457 458 /* DHCPDECLINE must specify address. */ 459 if (!packet->options[DHO_DHCP_REQUESTED_ADDRESS].len) 460 return; 461 462 cip.len = 4; 463 memcpy(cip.iabuf, 464 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 4); 465 lease = find_lease_by_ip_addr(cip); 466 467 note("DHCPDECLINE on %s from %s via %s", 468 piaddr(cip), print_hw_addr(packet->raw->htype, 469 packet->raw->hlen, packet->raw->chaddr), 470 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 471 packet->interface->name); 472 473 /* If we're already acking this lease, don't do it again. */ 474 if (lease && lease->state) { 475 note("DHCPDECLINE already acking lease %s", 476 piaddr(lease->ip_addr)); 477 return; 478 } 479 480 /* If we found a lease, mark it as unusable and complain. */ 481 if (lease) 482 abandon_lease(lease, "declined."); 483} 484 485void 486dhcpinform(struct packet *packet) 487{ 488 note("DHCPINFORM from %s", inet_ntoa(packet->raw->ciaddr)); 489} 490 491void 492nak_lease(struct packet *packet, struct iaddr *cip) 493{ 494 struct sockaddr_in to; 495 struct in_addr from; 496 int result, i; 497 struct dhcp_packet raw; 498 unsigned char nak = DHCPNAK; 499 struct packet outgoing; 500 struct tree_cache *options[256], dhcpnak_tree, dhcpmsg_tree; 501 502 memset(options, 0, sizeof options); 503 memset(&outgoing, 0, sizeof outgoing); 504 memset(&raw, 0, sizeof raw); 505 outgoing.raw = &raw; 506 507 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */ 508 options[DHO_DHCP_MESSAGE_TYPE] = &dhcpnak_tree; 509 options[DHO_DHCP_MESSAGE_TYPE]->value = &nak; 510 options[DHO_DHCP_MESSAGE_TYPE]->len = sizeof nak; 511 options[DHO_DHCP_MESSAGE_TYPE]->buf_size = sizeof nak; 512 options[DHO_DHCP_MESSAGE_TYPE]->timeout = 0xFFFFFFFF; 513 options[DHO_DHCP_MESSAGE_TYPE]->tree = NULL; 514 515 /* Set DHCP_MESSAGE to whatever the message is */ 516 options[DHO_DHCP_MESSAGE] = &dhcpmsg_tree; 517 options[DHO_DHCP_MESSAGE]->value = (unsigned char *)dhcp_message; 518 options[DHO_DHCP_MESSAGE]->len = strlen(dhcp_message); 519 options[DHO_DHCP_MESSAGE]->buf_size = strlen(dhcp_message); 520 options[DHO_DHCP_MESSAGE]->timeout = 0xFFFFFFFF; 521 options[DHO_DHCP_MESSAGE]->tree = NULL; 522 523 /* Do not use the client's requested parameter list. */ 524 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 525 if (packet->options[i].data) { 526 packet->options[i].len = 0; 527 dfree(packet->options[i].data, "nak_lease"); 528 packet->options[i].data = NULL; 529 } 530 531 /* Set up the option buffer... */ 532 outgoing.packet_length = cons_options(packet, outgoing.raw, 533 0, options, 0, 0, 0, NULL, 0); 534 535/* memset(&raw.ciaddr, 0, sizeof raw.ciaddr);*/ 536 raw.siaddr = packet->interface->primary_address; 537 raw.giaddr = packet->raw->giaddr; 538 memcpy(raw.chaddr, packet->raw->chaddr, sizeof raw.chaddr); 539 raw.hlen = packet->raw->hlen; 540 raw.htype = packet->raw->htype; 541 raw.xid = packet->raw->xid; 542 raw.secs = packet->raw->secs; 543 raw.flags = packet->raw->flags | htons(BOOTP_BROADCAST); 544 raw.hops = packet->raw->hops; 545 raw.op = BOOTREPLY; 546 547 /* Report what we're sending... */ 548 note("DHCPNAK on %s to %s via %s", piaddr(*cip), 549 print_hw_addr(packet->raw->htype, packet->raw->hlen, 550 packet->raw->chaddr), packet->raw->giaddr.s_addr ? 551 inet_ntoa(packet->raw->giaddr) : packet->interface->name); 552 553 /* Set up the common stuff... */ 554 memset(&to, 0, sizeof to); 555 to.sin_family = AF_INET; 556 to.sin_len = sizeof to; 557 558 from = packet->interface->primary_address; 559 560 /* Make sure that the packet is at least as big as a BOOTP packet. */ 561 if (outgoing.packet_length < BOOTP_MIN_LEN) 562 outgoing.packet_length = BOOTP_MIN_LEN; 563 564 /* 565 * If this was gatewayed, send it back to the gateway. 566 * Otherwise, broadcast it on the local network. 567 */ 568 if (raw.giaddr.s_addr) { 569 to.sin_addr = raw.giaddr; 570 to.sin_port = server_port; 571 572 result = send_packet(packet->interface, &raw, 573 outgoing.packet_length, from, &to, packet->haddr); 574 if (result == -1) 575 warning("send_fallback: %m"); 576 return; 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, &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 free_lease_state(state, "ack_lease: !supersede_lease"); 818 return; 819 } 820 } 821 822 /* Remember the interface on which the packet arrived. */ 823 state->ip = packet->interface; 824 825 /* Set a flag if this client is a lame Microsoft client that NUL 826 terminates string options and expects us to do likewise. */ 827 if (packet->options[DHO_HOST_NAME].data && 828 packet->options[DHO_HOST_NAME].data[ 829 packet->options[DHO_HOST_NAME].len - 1] == '\0') 830 lease->flags |= MS_NULL_TERMINATION; 831 else 832 lease->flags &= ~MS_NULL_TERMINATION; 833 834 /* Remember the giaddr, xid, secs, flags and hops. */ 835 state->giaddr = packet->raw->giaddr; 836 state->ciaddr = packet->raw->ciaddr; 837 state->xid = packet->raw->xid; 838 state->secs = packet->raw->secs; 839 state->bootp_flags = packet->raw->flags; 840 state->hops = packet->raw->hops; 841 state->offer = offer; 842 memcpy(&state->haddr, packet->haddr, sizeof state->haddr); 843 844 /* Figure out what options to send to the client: */ 845 846 /* Start out with the subnet options... */ 847 memcpy(state->options, lease->subnet->group->options, 848 sizeof state->options); 849 850 /* Vendor and user classes are only supported for DHCP clients. */ 851 if (state->offer) { 852 /* If we have a vendor class, install those options, 853 superseding any subnet options. */ 854 if (vendor_class) { 855 for (i = 0; i < 256; i++) 856 if (vendor_class->group->options[i]) 857 state->options[i] = 858 vendor_class->group->options[i]; 859 } 860 861 /* If we have a user class, install those options, 862 superseding any subnet and vendor class options. */ 863 if (user_class) { 864 for (i = 0; i < 256; i++) 865 if (user_class->group->options[i]) 866 state->options[i] = 867 user_class->group->options[i]; 868 } 869 870 } 871 872 /* If we have a host_decl structure, install the associated 873 options, superseding anything that's in the way. */ 874 if (lease->host) { 875 for (i = 0; i < 256; i++) 876 if (lease->host->group->options[i]) 877 state->options[i] = 878 lease->host->group->options[i]; 879 } 880 881 /* Get the Maximum Message Size option from the packet, if one 882 was sent. */ 883 i = DHO_DHCP_MAX_MESSAGE_SIZE; 884 if (packet->options[i].data && 885 packet->options[i].len == sizeof (u_int16_t)) 886 state->max_message_size = getUShort(packet->options[i].data); 887 /* Otherwise, if a maximum message size was specified, use that. */ 888 else if (state->options[i] && state->options[i]->value) 889 state->max_message_size = getUShort(state->options[i]->value); 890 891 /* Save the parameter request list if there is one. */ 892 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 893 if (packet->options[i].data) { 894 state->prl = dmalloc(packet->options[i].len, "ack_lease: prl"); 895 if (!state->prl) 896 warning("no memory for parameter request list"); 897 else { 898 memcpy(state->prl, packet->options[i].data, 899 packet->options[i].len); 900 state->prl_len = packet->options[i].len; 901 } 902 } 903 904 /* If we didn't get a hostname from an option somewhere, see if 905 we can get one from the lease. */ 906 i = DHO_HOST_NAME; 907 if (!state->options[i] && lease->hostname) { 908 state->options[i] = new_tree_cache("hostname"); 909 state->options[i]->flags = TC_TEMPORARY; 910 state->options[i]->value = (unsigned char *)lease->hostname; 911 state->options[i]->len = strlen (lease->hostname); 912 state->options[i]->buf_size = state->options[i]->len; 913 state->options[i]->timeout = 0xFFFFFFFF; 914 state->options[i]->tree = NULL; 915 } 916 917 /* 918 * Now, if appropriate, put in DHCP-specific options that 919 * override those. 920 */ 921 if (state->offer) { 922 i = DHO_DHCP_MESSAGE_TYPE; 923 state->options[i] = new_tree_cache("message-type"); 924 state->options[i]->flags = TC_TEMPORARY; 925 state->options[i]->value = &state->offer; 926 state->options[i]->len = sizeof state->offer; 927 state->options[i]->buf_size = sizeof state->offer; 928 state->options[i]->timeout = 0xFFFFFFFF; 929 state->options[i]->tree = NULL; 930 931 i = DHO_DHCP_SERVER_IDENTIFIER; 932 if (!state->options[i]) { 933 use_primary: 934 state->options[i] = new_tree_cache("server-id"); 935 state->options[i]->value = 936 (unsigned char *)&state->ip->primary_address; 937 state->options[i]->len = 938 sizeof state->ip->primary_address; 939 state->options[i]->buf_size = 940 state->options[i]->len; 941 state->options[i]->timeout = 0xFFFFFFFF; 942 state->options[i]->tree = NULL; 943 state->from.len = sizeof state->ip->primary_address; 944 memcpy(state->from.iabuf, &state->ip->primary_address, 945 state->from.len); 946 } else { 947 /* Find the value of the server identifier... */ 948 if (!tree_evaluate (state->options[i])) 949 goto use_primary; 950 if (!state->options[i]->value || 951 (state->options[i]->len > sizeof state->from.iabuf)) 952 goto use_primary; 953 954 state->from.len = state->options[i]->len; 955 memcpy(state->from.iabuf, state->options[i]->value, 956 state->from.len); 957 } 958 959 /* Sanity check the lease time. */ 960 if ((state->offered_expiry - cur_time) < 15) 961 offered_lease_time = default_lease_time; 962 else if (state->offered_expiry - cur_time > max_lease_time) 963 offered_lease_time = max_lease_time; 964 else 965 offered_lease_time = 966 state->offered_expiry - cur_time; 967 968 putULong((unsigned char *)&state->expiry, 969 offered_lease_time); 970 i = DHO_DHCP_LEASE_TIME; 971 state->options[i] = new_tree_cache ("lease-expiry"); 972 state->options[i]->flags = TC_TEMPORARY; 973 state->options[i]->value = (unsigned char *)&state->expiry; 974 state->options[i]->len = sizeof state->expiry; 975 state->options[i]->buf_size = sizeof state->expiry; 976 state->options[i]->timeout = 0xFFFFFFFF; 977 state->options[i]->tree = NULL; 978 979 /* Renewal time is lease time * 0.5. */ 980 offered_lease_time /= 2; 981 putULong ((unsigned char *)&state->renewal, 982 offered_lease_time); 983 i = DHO_DHCP_RENEWAL_TIME; 984 state->options[i] = new_tree_cache ("renewal-time"); 985 state->options[i]->flags = TC_TEMPORARY; 986 state->options[i]->value = 987 (unsigned char *)&state->renewal; 988 state->options[i]->len = sizeof state->renewal; 989 state->options[i]->buf_size = sizeof state->renewal; 990 state->options[i]->timeout = 0xFFFFFFFF; 991 state->options[i]->tree = NULL; 992 993 994 /* Rebinding time is lease time * 0.875. */ 995 offered_lease_time += (offered_lease_time / 2 + 996 offered_lease_time / 4); 997 putULong ((unsigned char *)&state->rebind, 998 offered_lease_time); 999 i = DHO_DHCP_REBINDING_TIME; 1000 state->options[i] = new_tree_cache ("rebind-time"); 1001 state->options[i]->flags = TC_TEMPORARY; 1002 state->options[i]->value = 1003 (unsigned char *)&state->rebind; 1004 state->options[i]->len = sizeof state->rebind; 1005 state->options[i]->buf_size = sizeof state->rebind; 1006 state->options[i]->timeout = 0xFFFFFFFF; 1007 state->options[i]->tree = NULL; 1008 1009 /* If we used the vendor class the client specified, we 1010 have to return it. */ 1011 if (vendor_class) { 1012 i = DHO_DHCP_CLASS_IDENTIFIER; 1013 state->options[i] = 1014 new_tree_cache ("class-identifier"); 1015 state->options[i]->flags = TC_TEMPORARY; 1016 state->options[i]->value = 1017 (unsigned char *)vendor_class->name; 1018 state->options[i]->len = 1019 strlen (vendor_class->name); 1020 state->options[i]->buf_size = 1021 state->options[i]->len; 1022 state->options[i]->timeout = 0xFFFFFFFF; 1023 state->options[i]->tree = NULL; 1024 } 1025 1026 /* If we used the user class the client specified, we 1027 have to return it. */ 1028 if (user_class) { 1029 i = DHO_DHCP_USER_CLASS_ID; 1030 state->options[i] = new_tree_cache ("user-class"); 1031 state->options[i]->flags = TC_TEMPORARY; 1032 state->options[i]->value = 1033 (unsigned char *)user_class->name; 1034 state->options[i]->len = 1035 strlen (user_class->name); 1036 state->options[i]->buf_size = 1037 state->options[i]->len; 1038 state->options[i]->timeout = 0xFFFFFFFF; 1039 state->options[i]->tree = NULL; 1040 } 1041 } 1042 1043 /* Use the subnet mask from the subnet declaration if no other 1044 mask has been provided. */ 1045 i = DHO_SUBNET_MASK; 1046 if (!state->options[i]) { 1047 state->options[i] = new_tree_cache ("subnet-mask"); 1048 state->options[i]->flags = TC_TEMPORARY; 1049 state->options[i]->value = 1050 lease->subnet->netmask.iabuf; 1051 state->options[i]->len = lease->subnet->netmask.len; 1052 state->options[i]->buf_size = 1053 lease->subnet->netmask.len; 1054 state->options[i]->timeout = 0xFFFFFFFF; 1055 state->options[i]->tree = NULL; 1056 } 1057 1058 /* If so directed, use the leased IP address as the router address. 1059 This supposedly makes Win95 machines ARP for all IP addresses, 1060 so if the local router does proxy arp, you win. */ 1061 1062 ulafdr = 0; 1063 if (lease->host) { 1064 if (lease->host->group->use_lease_addr_for_default_route) 1065 ulafdr = 1; 1066 } else if (user_class) { 1067 if (user_class->group->use_lease_addr_for_default_route) 1068 ulafdr = 1; 1069 } else if (vendor_class) { 1070 if (vendor_class->group->use_lease_addr_for_default_route) 1071 ulafdr = 1; 1072 } else if (lease->subnet->group->use_lease_addr_for_default_route) 1073 ulafdr = 1; 1074 else 1075 ulafdr = 0; 1076 1077 i = DHO_ROUTERS; 1078 if (ulafdr && !state->options[i]) { 1079 state->options[i] = new_tree_cache ("routers"); 1080 state->options[i]->flags = TC_TEMPORARY; 1081 state->options[i]->value = lease->ip_addr.iabuf; 1082 state->options[i]->len = lease->ip_addr.len; 1083 state->options[i]->buf_size = lease->ip_addr.len; 1084 state->options[i]->timeout = 0xFFFFFFFF; 1085 state->options[i]->tree = NULL; 1086 } 1087 1088 lease->state = state; 1089 1090 /* If this is a DHCPOFFER, ping the lease address before actually 1091 sending the offer. */ 1092 if (offer == DHCPOFFER && !(lease->flags & STATIC_LEASE) && 1093 cur_time - lease->timestamp > 60) { 1094 lease->timestamp = cur_time; 1095 icmp_echorequest (&lease->ip_addr); 1096 add_timeout (cur_time + 1, lease_ping_timeout, lease); 1097 ++outstanding_pings; 1098 } else { 1099 lease->timestamp = cur_time; 1100 dhcp_reply (lease); 1101 } 1102} 1103 1104void 1105dhcp_reply(struct lease *lease) 1106{ 1107 int bufs = 0, packet_length, i; 1108 struct dhcp_packet raw; 1109 struct sockaddr_in to; 1110 struct in_addr from; 1111 struct lease_state *state = lease->state; 1112 int nulltp, bootpp; 1113 u_int8_t *prl; 1114 int prl_len; 1115 1116 if (!state) 1117 error("dhcp_reply was supplied lease with no state!"); 1118 1119 /* Compose a response for the client... */ 1120 memset(&raw, 0, sizeof raw); 1121 1122 /* Copy in the filename if given; otherwise, flag the filename 1123 buffer as available for options. */ 1124 if (state->filename[0]) 1125 strlcpy(raw.file, state->filename, sizeof raw.file); 1126 else 1127 bufs |= 1; 1128 1129 /* Copy in the server name if given; otherwise, flag the 1130 server_name buffer as available for options. */ 1131 if (state->server_name) 1132 strlcpy(raw.sname, state->server_name, sizeof raw.sname); 1133 else 1134 bufs |= 2; /* XXX */ 1135 1136 memcpy(raw.chaddr, lease->hardware_addr.haddr, sizeof raw.chaddr); 1137 raw.hlen = lease->hardware_addr.hlen; 1138 raw.htype = lease->hardware_addr.htype; 1139 1140 /* See if this is a Microsoft client that NUL-terminates its 1141 strings and expects us to do likewise... */ 1142 if (lease->flags & MS_NULL_TERMINATION) 1143 nulltp = 1; 1144 else 1145 nulltp = 0; 1146 1147 /* See if this is a bootp client... */ 1148 if (state->offer) 1149 bootpp = 0; 1150 else 1151 bootpp = 1; 1152 1153 if (state->options[DHO_DHCP_PARAMETER_REQUEST_LIST] && 1154 state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value) { 1155 prl = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value; 1156 prl_len = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->len; 1157 } else if (state->prl) { 1158 prl = state->prl; 1159 prl_len = state->prl_len; 1160 } else { 1161 prl = NULL; 1162 prl_len = 0; 1163 } 1164 1165 /* Insert such options as will fit into the buffer. */ 1166 packet_length = cons_options(NULL, &raw, state->max_message_size, 1167 state->options, bufs, nulltp, bootpp, prl, prl_len); 1168 1169 /* Having done the cons_options(), we can release the tree_cache 1170 entries. */ 1171 for (i = 0; i < 256; i++) { 1172 if (state->options[i] && 1173 state->options[i]->flags & TC_TEMPORARY) 1174 free_tree_cache(state->options[i]); 1175 } 1176 1177 memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr); 1178 memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4); 1179 1180 /* Figure out the address of the next server. */ 1181 if (lease->host && lease->host->group->next_server.len) 1182 memcpy(&raw.siaddr, lease->host->group->next_server.iabuf, 4); 1183 else if (lease->subnet->group->next_server.len) 1184 memcpy(&raw.siaddr, lease->subnet->group->next_server.iabuf, 4); 1185 else if (lease->subnet->interface_address.len) 1186 memcpy(&raw.siaddr, lease->subnet->interface_address.iabuf, 4); 1187 else 1188 raw.siaddr = state->ip->primary_address; 1189 1190 raw.giaddr = state->giaddr; 1191 1192 raw.xid = state->xid; 1193 raw.secs = state->secs; 1194 raw.flags = state->bootp_flags; 1195 raw.hops = state->hops; 1196 raw.op = BOOTREPLY; 1197 1198 /* Say what we're doing... */ 1199 note("%s on %s to %s via %s", 1200 (state->offer ? (state->offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") : 1201 "BOOTREPLY"), 1202 piaddr(lease->ip_addr), 1203 print_hw_addr(lease->hardware_addr.htype, lease->hardware_addr.hlen, 1204 lease->hardware_addr.haddr), 1205 state->giaddr.s_addr ? inet_ntoa(state->giaddr) : state->ip->name); 1206 1207 memset(&to, 0, sizeof to); 1208 to.sin_family = AF_INET; 1209#ifdef HAVE_SA_LEN 1210 to.sin_len = sizeof to; 1211#endif 1212 1213 /* Make sure outgoing packets are at least as big 1214 as a BOOTP packet. */ 1215 if (packet_length < BOOTP_MIN_LEN) 1216 packet_length = BOOTP_MIN_LEN; 1217 1218 /* If this was gatewayed, send it back to the gateway... */ 1219 if (raw.giaddr.s_addr) { 1220 to.sin_addr = raw.giaddr; 1221 to.sin_port = server_port; 1222 1223 memcpy(&from, state->from.iabuf, sizeof from); 1224 1225 (void) send_packet(state->ip, &raw, 1226 packet_length, from, &to, &state->haddr); 1227 1228 free_lease_state(state, "dhcp_reply gateway"); 1229 lease->state = NULL; 1230 return; 1231 1232 /* If the client is RENEWING, unicast to the client using the 1233 regular IP stack. Some clients, particularly those that 1234 follow RFC1541, are buggy, and send both ciaddr and 1235 server-identifier. We deal with this situation by assuming 1236 that if we got both dhcp-server-identifier and ciaddr, and 1237 giaddr was not set, then the client is on the local 1238 network, and we can therefore unicast or broadcast to it 1239 successfully. A client in REQUESTING state on another 1240 network that's making this mistake will have set giaddr, 1241 and will therefore get a relayed response from the above 1242 code. */ 1243 } else if (raw.ciaddr.s_addr && 1244 !((state->got_server_identifier || 1245 (raw.flags & htons(BOOTP_BROADCAST))) && 1246 /* XXX This won't work if giaddr isn't zero, but it is: */ 1247 (state->shared_network == lease->shared_network)) && 1248 state->offer == DHCPACK) { 1249 to.sin_addr = raw.ciaddr; 1250 to.sin_port = client_port; 1251 1252 /* If it comes from a client that already knows its address 1253 and is not requesting a broadcast response, and we can 1254 unicast to a client without using the ARP protocol, sent it 1255 directly to that client. */ 1256 } else if (!(raw.flags & htons (BOOTP_BROADCAST))) { 1257 to.sin_addr = raw.yiaddr; 1258 to.sin_port = client_port; 1259 1260 /* Otherwise, broadcast it on the local network. */ 1261 } else { 1262 to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 1263 to.sin_port = client_port; 1264 } 1265 1266 memcpy(&from, state->from.iabuf, sizeof from); 1267 1268 (void) send_packet(state->ip, &raw, packet_length, 1269 from, &to, &state->haddr); 1270 1271 free_lease_state(state, "dhcp_reply"); 1272 lease->state = NULL; 1273} 1274 1275struct lease * 1276find_lease(struct packet *packet, struct shared_network *share, 1277 int *ours) 1278{ 1279 struct lease *uid_lease, *ip_lease, *hw_lease; 1280 struct lease *lease = NULL; 1281 struct iaddr cip; 1282 struct host_decl *hp, *host = NULL; 1283 struct lease *fixed_lease; 1284 1285 /* Figure out what IP address the client is requesting, if any. */ 1286 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len && 1287 packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4) { 1288 packet->got_requested_address = 1; 1289 cip.len = 4; 1290 memcpy(cip.iabuf, 1291 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 1292 cip.len); 1293 } else if (packet->raw->ciaddr.s_addr) { 1294 cip.len = 4; 1295 memcpy(cip.iabuf, &packet->raw->ciaddr, 4); 1296 } else 1297 cip.len = 0; 1298 1299 /* Try to find a host or lease that's been assigned to the 1300 specified unique client identifier. */ 1301 if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) { 1302 /* First, try to find a fixed host entry for the specified 1303 client identifier... */ 1304 hp = find_hosts_by_uid( 1305 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1306 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1307 if (hp) { 1308 host = hp; 1309 fixed_lease = mockup_lease(packet, share, hp); 1310 uid_lease = NULL; 1311 } else { 1312 uid_lease = find_lease_by_uid( 1313 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1314 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1315 /* Find the lease matching this uid that's on the 1316 network the packet came from (if any). */ 1317 for (; uid_lease; uid_lease = uid_lease->n_uid) 1318 if (uid_lease->shared_network == share) 1319 break; 1320 fixed_lease = NULL; 1321 if (uid_lease && (uid_lease->flags & ABANDONED_LEASE)) 1322 uid_lease = NULL; 1323 } 1324 } else { 1325 uid_lease = NULL; 1326 fixed_lease = NULL; 1327 } 1328 1329 /* If we didn't find a fixed lease using the uid, try doing 1330 it with the hardware address... */ 1331 if (!fixed_lease) { 1332 hp = find_hosts_by_haddr(packet->raw->htype, 1333 packet->raw->chaddr, packet->raw->hlen); 1334 if (hp) { 1335 host = hp; /* Save it for later. */ 1336 fixed_lease = mockup_lease (packet, share, hp); 1337 } 1338 } 1339 1340 /* If fixed_lease is present but does not match the requested 1341 IP address, and this is a DHCPREQUEST, then we can't return 1342 any other lease, so we might as well return now. */ 1343 if (packet->packet_type == DHCPREQUEST && fixed_lease && 1344 (fixed_lease->ip_addr.len != cip.len || 1345 memcmp(fixed_lease->ip_addr.iabuf, cip.iabuf, cip.len))) { 1346 if (ours) 1347 *ours = 1; 1348 strlcpy(dhcp_message, "requested address is incorrect", 1349 sizeof (dhcp_message)); 1350 return NULL; 1351 } 1352 1353 /* Try to find a lease that's been attached to the client's 1354 hardware address... */ 1355 hw_lease = find_lease_by_hw_addr(packet->raw->chaddr, 1356 packet->raw->hlen); 1357 /* Find the lease that's on the network the packet came from 1358 (if any). */ 1359 for (; hw_lease; hw_lease = hw_lease->n_hw) { 1360 if (hw_lease->shared_network == share) { 1361 if ((hw_lease->flags & ABANDONED_LEASE)) 1362 continue; 1363 if (packet->packet_type) 1364 break; 1365 if (hw_lease->flags & 1366 (BOOTP_LEASE | DYNAMIC_BOOTP_OK)) 1367 break; 1368 } 1369 } 1370 1371 /* Try to find a lease that's been allocated to the client's 1372 IP address. */ 1373 if (cip.len) 1374 ip_lease = find_lease_by_ip_addr(cip); 1375 else 1376 ip_lease = NULL; 1377 1378 /* If ip_lease is valid at this point, set ours to one, so that 1379 even if we choose a different lease, we know that the address 1380 the client was requesting was ours, and thus we can NAK it. */ 1381 if (ip_lease && ours) 1382 *ours = 1; 1383 1384 /* If the requested IP address isn't on the network the packet 1385 came from, don't use it. Allow abandoned leases to be matched 1386 here - if the client is requesting it, there's a decent chance 1387 that it's because the lease database got trashed and a client 1388 that thought it had this lease answered an ARP or PING, causing the 1389 lease to be abandoned. If so, this request probably came from 1390 that client. */ 1391 if (ip_lease && (ip_lease->shared_network != share)) { 1392 ip_lease = NULL; 1393 strlcpy(dhcp_message, "requested address on bad subnet", 1394 sizeof(dhcp_message)); 1395 } 1396 1397 /* Toss ip_lease if it hasn't yet expired and isn't owned by the 1398 client. */ 1399 if (ip_lease && ip_lease->ends >= cur_time && ip_lease != uid_lease) { 1400 int i = DHO_DHCP_CLIENT_IDENTIFIER; 1401 1402 /* Make sure that ip_lease actually belongs to the client, 1403 and toss it if not. */ 1404 if ((ip_lease->uid_len && packet->options[i].data && 1405 ip_lease->uid_len == packet->options[i].len && 1406 !memcmp(packet->options[i].data, ip_lease->uid, 1407 ip_lease->uid_len)) || 1408 (!ip_lease->uid_len && 1409 ip_lease->hardware_addr.htype == packet->raw->htype && 1410 ip_lease->hardware_addr.hlen == packet->raw->hlen && 1411 !memcmp(ip_lease->hardware_addr.haddr, packet->raw->chaddr, 1412 ip_lease->hardware_addr.hlen))) { 1413 if (uid_lease) { 1414 if (uid_lease->ends > cur_time) { 1415 warning("client %s has duplicate leases on %s", 1416 print_hw_addr(packet->raw->htype, 1417 packet->raw->hlen, packet->raw->chaddr), 1418 ip_lease->shared_network->name); 1419 1420 if (uid_lease && !packet->raw->ciaddr.s_addr) 1421 release_lease (uid_lease); 1422 } 1423 uid_lease = ip_lease; 1424 } 1425 } else { 1426 strlcpy(dhcp_message, "requested address is not available", 1427 sizeof(dhcp_message)); 1428 ip_lease = NULL; 1429 } 1430 1431 /* If we get to here and fixed_lease is not null, that means 1432 that there are both a dynamic lease and a fixed-address 1433 declaration for the same IP address. */ 1434 if (packet->packet_type == DHCPREQUEST && fixed_lease) { 1435 fixed_lease = NULL; 1436db_conflict: 1437 warning("Both dynamic and static leases present for %s.", 1438 piaddr(cip)); 1439 warning("Either remove host declaration %s or remove %s", 1440 (fixed_lease && fixed_lease->host ? 1441 (fixed_lease->host->name ? fixed_lease->host->name : 1442 piaddr(cip)) : piaddr(cip)), piaddr(cip)); 1443 warning("from the dynamic address pool for %s", 1444 share->name); 1445 if (fixed_lease) 1446 ip_lease = NULL; 1447 strlcpy(dhcp_message, "database conflict - call for help!", 1448 sizeof(dhcp_message)); 1449 } 1450 } 1451 1452 /* If we get to here with both fixed_lease and ip_lease not 1453 null, then we have a configuration file bug. */ 1454 if (packet->packet_type == DHCPREQUEST && fixed_lease && ip_lease) 1455 goto db_conflict; 1456 1457 /* Toss hw_lease if it hasn't yet expired and the uid doesn't 1458 match, except that if the hardware address matches and the 1459 client is now doing dynamic BOOTP (and thus hasn't provided 1460 a uid) we let the client get away with it. */ 1461 if (hw_lease && hw_lease->ends >= cur_time && hw_lease->uid && 1462 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len && 1463 hw_lease != uid_lease) 1464 hw_lease = NULL; 1465 1466 /* Toss extra pointers to the same lease... */ 1467 if (hw_lease == uid_lease) 1468 hw_lease = NULL; 1469 if (ip_lease == hw_lease) 1470 hw_lease = NULL; 1471 if (ip_lease == uid_lease) 1472 uid_lease = NULL; 1473 1474 /* If we've already eliminated the lease, it wasn't there to 1475 begin with. If we have come up with a matching lease, 1476 set the message to bad network in case we have to throw it out. */ 1477 if (!ip_lease) { 1478 strlcpy(dhcp_message, "requested address not available", 1479 sizeof(dhcp_message)); 1480 } 1481 1482 /* Now eliminate leases that are on the wrong network... */ 1483 if (ip_lease && share != ip_lease->shared_network) { 1484 if (packet->packet_type == DHCPREQUEST) 1485 release_lease(ip_lease); 1486 ip_lease = NULL; 1487 } 1488 if (uid_lease && share != uid_lease->shared_network) { 1489 if (packet->packet_type == DHCPREQUEST) 1490 release_lease(uid_lease); 1491 uid_lease = NULL; 1492 } 1493 if (hw_lease && share != hw_lease->shared_network) { 1494 if (packet->packet_type == DHCPREQUEST) 1495 release_lease(hw_lease); 1496 hw_lease = NULL; 1497 } 1498 1499 /* If this is a DHCPREQUEST, make sure the lease we're going to return 1500 matches the requested IP address. If it doesn't, don't return a 1501 lease at all. */ 1502 if (packet->packet_type == DHCPREQUEST && !ip_lease && !fixed_lease) 1503 return NULL; 1504 1505 /* At this point, if fixed_lease is nonzero, we can assign it to 1506 this client. */ 1507 if (fixed_lease) 1508 lease = fixed_lease; 1509 1510 /* If we got a lease that matched the ip address and don't have 1511 a better offer, use that; otherwise, release it. */ 1512 if (ip_lease) { 1513 if (lease) { 1514 if (packet->packet_type == DHCPREQUEST) 1515 release_lease(ip_lease); 1516 } else { 1517 lease = ip_lease; 1518 lease->host = NULL; 1519 } 1520 } 1521 1522 /* If we got a lease that matched the client identifier, we may want 1523 to use it, but if we already have a lease we like, we must free 1524 the lease that matched the client identifier. */ 1525 if (uid_lease) { 1526 if (lease) { 1527 if (packet->packet_type == DHCPREQUEST) 1528 release_lease(uid_lease); 1529 } else { 1530 lease = uid_lease; 1531 lease->host = NULL; 1532 } 1533 } 1534 1535 /* The lease that matched the hardware address is treated likewise. */ 1536 if (hw_lease) { 1537 if (lease) { 1538 if (packet->packet_type == DHCPREQUEST) 1539 release_lease(hw_lease); 1540 } else { 1541 lease = hw_lease; 1542 lease->host = NULL; 1543 } 1544 } 1545 1546 /* If we found a host_decl but no matching address, try to 1547 find a host_decl that has no address, and if there is one, 1548 hang it off the lease so that we can use the supplied 1549 options. */ 1550 if (lease && host && !lease->host) { 1551 for (; host; host = host->n_ipaddr) { 1552 if (!host->fixed_addr) { 1553 lease->host = host; 1554 break; 1555 } 1556 } 1557 } 1558 1559 /* If we find an abandoned lease, take it, but print a 1560 warning message, so that if it continues to lose, 1561 the administrator will eventually investigate. */ 1562 if (lease && (lease->flags & ABANDONED_LEASE)) { 1563 if (packet->packet_type == DHCPREQUEST) { 1564 warning("Reclaiming REQUESTed abandoned IP address %s.", 1565 piaddr(lease->ip_addr)); 1566 lease->flags &= ~ABANDONED_LEASE; 1567 } else 1568 lease = NULL; 1569 } 1570 return lease; 1571} 1572 1573/* 1574 * Search the provided host_decl structure list for an address that's on 1575 * the specified shared network. If one is found, mock up and return a 1576 * lease structure for it; otherwise return the null pointer. 1577 */ 1578struct lease * 1579mockup_lease(struct packet *packet, struct shared_network *share, 1580 struct host_decl *hp) 1581{ 1582 static struct lease mock; 1583 1584 mock.subnet = find_host_for_network(&hp, &mock.ip_addr, share); 1585 if (!mock.subnet) 1586 return (NULL); 1587 mock.next = mock.prev = NULL; 1588 mock.shared_network = mock.subnet->shared_network; 1589 mock.host = hp; 1590 1591 if (hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]) { 1592 mock.uid = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->value; 1593 mock.uid_len = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->len; 1594 } else { 1595 mock.uid = NULL; 1596 mock.uid_len = 0; 1597 } 1598 1599 mock.hardware_addr = hp->interface; 1600 mock.starts = mock.timestamp = mock.ends = MIN_TIME; 1601 mock.flags = STATIC_LEASE; 1602 return &mock; 1603} 1604