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