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