dhcp.c revision 1.7
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 * time_t is signed, so really large numbers come 745 * back as negative. Don't allow lease_time of 0, 746 * either. 747 */ 748 if (lease_time < 1 || lease_time > max_lease_time) 749 lease_time = max_lease_time; 750 } else 751 lease_time = default_lease_time; 752 753 state->offered_expiry = cur_time + lease_time; 754 if (when) 755 lt.ends = when; 756 else 757 lt.ends = state->offered_expiry; 758 } else { 759 if (lease->host && 760 lease->host->group->bootp_lease_length) 761 lt.ends = (cur_time + 762 lease->host->group->bootp_lease_length); 763 else if (lease->subnet->group->bootp_lease_length) 764 lt.ends = (cur_time + 765 lease->subnet->group->bootp_lease_length); 766 else if (lease->host && 767 lease->host->group->bootp_lease_cutoff) 768 lt.ends = lease->host->group->bootp_lease_cutoff; 769 else 770 lt.ends = lease->subnet->group->bootp_lease_cutoff; 771 state->offered_expiry = lt.ends; 772 lt.flags = BOOTP_LEASE; 773 } 774 775 /* Record the uid, if given... */ 776 i = DHO_DHCP_CLIENT_IDENTIFIER; 777 if (packet->options[i].len) { 778 if (packet->options[i].len <= sizeof lt.uid_buf) { 779 memcpy(lt.uid_buf, packet->options[i].data, 780 packet->options[i].len); 781 lt.uid = lt.uid_buf; 782 lt.uid_max = sizeof lt.uid_buf; 783 lt.uid_len = packet->options[i].len; 784 } else { 785 lt.uid_max = lt.uid_len = packet->options[i].len; 786 lt.uid = (unsigned char *)malloc(lt.uid_max); 787 if (!lt.uid) 788 error("can't allocate memory for large uid."); 789 memcpy(lt.uid, packet->options[i].data, lt.uid_len); 790 } 791 } 792 793 lt.host = lease->host; 794 lt.subnet = lease->subnet; 795 lt.shared_network = lease->shared_network; 796 797 /* Don't call supersede_lease on a mocked-up lease. */ 798 if (lease->flags & STATIC_LEASE) { 799 /* Copy the hardware address into the static lease 800 structure. */ 801 lease->hardware_addr.hlen = packet->raw->hlen; 802 lease->hardware_addr.htype = packet->raw->htype; 803 memcpy(lease->hardware_addr.haddr, packet->raw->chaddr, 804 sizeof packet->raw->chaddr); /* XXX */ 805 } else { 806 /* Record the hardware address, if given... */ 807 lt.hardware_addr.hlen = packet->raw->hlen; 808 lt.hardware_addr.htype = packet->raw->htype; 809 memcpy(lt.hardware_addr.haddr, packet->raw->chaddr, 810 sizeof packet->raw->chaddr); 811 812 /* Install the new information about this lease in the 813 database. If this is a DHCPACK or a dynamic BOOTREPLY 814 and we can't write the lease, don't ACK it (or BOOTREPLY 815 it) either. */ 816 817 if (!(supersede_lease(lease, <, !offer || offer == DHCPACK) || 818 (offer && offer != DHCPACK))) 819 return; 820 } 821 822 /* Remember the interface on which the packet arrived. */ 823 state->ip = packet->interface; 824 825 /* Set a flag if this client is a lame Microsoft client that NUL 826 terminates string options and expects us to do likewise. */ 827 if (packet->options[DHO_HOST_NAME].data && 828 packet->options[DHO_HOST_NAME].data[ 829 packet->options[DHO_HOST_NAME].len - 1] == '\0') 830 lease->flags |= MS_NULL_TERMINATION; 831 else 832 lease->flags &= ~MS_NULL_TERMINATION; 833 834 /* Remember the giaddr, xid, secs, flags and hops. */ 835 state->giaddr = packet->raw->giaddr; 836 state->ciaddr = packet->raw->ciaddr; 837 state->xid = packet->raw->xid; 838 state->secs = packet->raw->secs; 839 state->bootp_flags = packet->raw->flags; 840 state->hops = packet->raw->hops; 841 state->offer = offer; 842 843 /* Figure out what options to send to the client: */ 844 845 /* Start out with the subnet options... */ 846 memcpy(state->options, lease->subnet->group->options, 847 sizeof state->options); 848 849 /* Vendor and user classes are only supported for DHCP clients. */ 850 if (state->offer) { 851 /* If we have a vendor class, install those options, 852 superseding any subnet options. */ 853 if (vendor_class) { 854 for (i = 0; i < 256; i++) 855 if (vendor_class->group->options[i]) 856 state->options[i] = 857 vendor_class->group->options[i]; 858 } 859 860 /* If we have a user class, install those options, 861 superseding any subnet and vendor class options. */ 862 if (user_class) { 863 for (i = 0; i < 256; i++) 864 if (user_class->group->options[i]) 865 state->options[i] = 866 user_class->group->options[i]; 867 } 868 869 } 870 871 /* If we have a host_decl structure, install the associated 872 options, superseding anything that's in the way. */ 873 if (lease->host) { 874 for (i = 0; i < 256; i++) 875 if (lease->host->group->options[i]) 876 state->options[i] = 877 lease->host->group->options[i]; 878 } 879 880 /* Get the Maximum Message Size option from the packet, if one 881 was sent. */ 882 i = DHO_DHCP_MAX_MESSAGE_SIZE; 883 if (packet->options[i].data && 884 packet->options[i].len == sizeof (u_int16_t)) 885 state->max_message_size = getUShort(packet->options[i].data); 886 /* Otherwise, if a maximum message size was specified, use that. */ 887 else if (state->options[i] && state->options[i]->value) 888 state->max_message_size = getUShort(state->options[i]->value); 889 890 /* Save the parameter request list if there is one. */ 891 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 892 if (packet->options[i].data) { 893 state->prl = dmalloc(packet->options[i].len, "ack_lease: prl"); 894 if (!state->prl) 895 warn("no memory for parameter request list"); 896 else { 897 memcpy(state->prl, packet->options[i].data, 898 packet->options[i].len); 899 state->prl_len = packet->options[i].len; 900 } 901 } 902 903 /* If we didn't get a hostname from an option somewhere, see if 904 we can get one from the lease. */ 905 i = DHO_HOST_NAME; 906 if (!state->options[i] && lease->hostname) { 907 state->options[i] = new_tree_cache("hostname"); 908 state->options[i]->flags = TC_TEMPORARY; 909 state->options[i]->value = (unsigned char *)lease->hostname; 910 state->options[i]->len = strlen (lease->hostname); 911 state->options[i]->buf_size = state->options[i]->len; 912 state->options[i]->timeout = 0xFFFFFFFF; 913 state->options[i]->tree = NULL; 914 } 915 916 /* 917 * Now, if appropriate, put in DHCP-specific options that 918 * override those. 919 */ 920 if (state->offer) { 921 i = DHO_DHCP_MESSAGE_TYPE; 922 state->options[i] = new_tree_cache("message-type"); 923 state->options[i]->flags = TC_TEMPORARY; 924 state->options[i]->value = &state->offer; 925 state->options[i]->len = sizeof state->offer; 926 state->options[i]->buf_size = sizeof state->offer; 927 state->options[i]->timeout = 0xFFFFFFFF; 928 state->options[i]->tree = NULL; 929 930 i = DHO_DHCP_SERVER_IDENTIFIER; 931 if (!state->options[i]) { 932 use_primary: 933 state->options[i] = new_tree_cache("server-id"); 934 state->options[i]->value = 935 (unsigned char *)&state->ip->primary_address; 936 state->options[i]->len = 937 sizeof state->ip->primary_address; 938 state->options[i]->buf_size = 939 state->options[i]->len; 940 state->options[i]->timeout = 0xFFFFFFFF; 941 state->options[i]->tree = NULL; 942 state->from.len = sizeof state->ip->primary_address; 943 memcpy(state->from.iabuf, &state->ip->primary_address, 944 state->from.len); 945 } else { 946 /* Find the value of the server identifier... */ 947 if (!tree_evaluate (state->options[i])) 948 goto use_primary; 949 if (!state->options[i]->value || 950 (state->options[i]->len > sizeof state->from.iabuf)) 951 goto use_primary; 952 953 state->from.len = state->options[i]->len; 954 memcpy(state->from.iabuf, state->options[i]->value, 955 state->from.len); 956 } 957 958 /* Sanity check the lease time. */ 959 if ((state->offered_expiry - cur_time) < 15) 960 offered_lease_time = default_lease_time; 961 else if (state->offered_expiry - cur_time > max_lease_time) 962 offered_lease_time = max_lease_time; 963 else 964 offered_lease_time = 965 state->offered_expiry - cur_time; 966 967 putULong((unsigned char *)&state->expiry, 968 offered_lease_time); 969 i = DHO_DHCP_LEASE_TIME; 970 state->options[i] = new_tree_cache ("lease-expiry"); 971 state->options[i]->flags = TC_TEMPORARY; 972 state->options[i]->value = (unsigned char *)&state->expiry; 973 state->options[i]->len = sizeof state->expiry; 974 state->options[i]->buf_size = sizeof state->expiry; 975 state->options[i]->timeout = 0xFFFFFFFF; 976 state->options[i]->tree = NULL; 977 978 /* Renewal time is lease time * 0.5. */ 979 offered_lease_time /= 2; 980 putULong ((unsigned char *)&state->renewal, 981 offered_lease_time); 982 i = DHO_DHCP_RENEWAL_TIME; 983 state->options[i] = new_tree_cache ("renewal-time"); 984 state->options[i]->flags = TC_TEMPORARY; 985 state->options[i]->value = 986 (unsigned char *)&state->renewal; 987 state->options[i]->len = sizeof state->renewal; 988 state->options[i]->buf_size = sizeof state->renewal; 989 state->options[i]->timeout = 0xFFFFFFFF; 990 state->options[i]->tree = NULL; 991 992 993 /* Rebinding time is lease time * 0.875. */ 994 offered_lease_time += (offered_lease_time / 2 + 995 offered_lease_time / 4); 996 putULong ((unsigned char *)&state->rebind, 997 offered_lease_time); 998 i = DHO_DHCP_REBINDING_TIME; 999 state->options[i] = new_tree_cache ("rebind-time"); 1000 state->options[i]->flags = TC_TEMPORARY; 1001 state->options[i]->value = 1002 (unsigned char *)&state->rebind; 1003 state->options[i]->len = sizeof state->rebind; 1004 state->options[i]->buf_size = sizeof state->rebind; 1005 state->options[i]->timeout = 0xFFFFFFFF; 1006 state->options[i]->tree = NULL; 1007 1008 /* If we used the vendor class the client specified, we 1009 have to return it. */ 1010 if (vendor_class) { 1011 i = DHO_DHCP_CLASS_IDENTIFIER; 1012 state->options[i] = 1013 new_tree_cache ("class-identifier"); 1014 state->options[i]->flags = TC_TEMPORARY; 1015 state->options[i]->value = 1016 (unsigned char *)vendor_class->name; 1017 state->options[i]->len = 1018 strlen (vendor_class->name); 1019 state->options[i]->buf_size = 1020 state->options[i]->len; 1021 state->options[i]->timeout = 0xFFFFFFFF; 1022 state->options[i]->tree = NULL; 1023 } 1024 1025 /* If we used the user class the client specified, we 1026 have to return it. */ 1027 if (user_class) { 1028 i = DHO_DHCP_USER_CLASS_ID; 1029 state->options[i] = new_tree_cache ("user-class"); 1030 state->options[i]->flags = TC_TEMPORARY; 1031 state->options[i]->value = 1032 (unsigned char *)user_class->name; 1033 state->options[i]->len = 1034 strlen (user_class->name); 1035 state->options[i]->buf_size = 1036 state->options[i]->len; 1037 state->options[i]->timeout = 0xFFFFFFFF; 1038 state->options[i]->tree = NULL; 1039 } 1040 } 1041 1042 /* Use the subnet mask from the subnet declaration if no other 1043 mask has been provided. */ 1044 i = DHO_SUBNET_MASK; 1045 if (!state->options[i]) { 1046 state->options[i] = new_tree_cache ("subnet-mask"); 1047 state->options[i]->flags = TC_TEMPORARY; 1048 state->options[i]->value = 1049 lease->subnet->netmask.iabuf; 1050 state->options[i]->len = lease->subnet->netmask.len; 1051 state->options[i]->buf_size = 1052 lease->subnet->netmask.len; 1053 state->options[i]->timeout = 0xFFFFFFFF; 1054 state->options[i]->tree = NULL; 1055 } 1056 1057 /* If so directed, use the leased IP address as the router address. 1058 This supposedly makes Win95 machines ARP for all IP addresses, 1059 so if the local router does proxy arp, you win. */ 1060 1061 ulafdr = 0; 1062 if (lease->host) { 1063 if (lease->host->group->use_lease_addr_for_default_route) 1064 ulafdr = 1; 1065 } else if (user_class) { 1066 if (user_class->group->use_lease_addr_for_default_route) 1067 ulafdr = 1; 1068 } else if (vendor_class) { 1069 if (vendor_class->group->use_lease_addr_for_default_route) 1070 ulafdr = 1; 1071 } else if (lease->subnet->group->use_lease_addr_for_default_route) 1072 ulafdr = 1; 1073 else 1074 ulafdr = 0; 1075 1076 i = DHO_ROUTERS; 1077 if (ulafdr && !state->options[i]) { 1078 state->options[i] = new_tree_cache ("routers"); 1079 state->options[i]->flags = TC_TEMPORARY; 1080 state->options[i]->value = lease->ip_addr.iabuf; 1081 state->options[i]->len = lease->ip_addr.len; 1082 state->options[i]->buf_size = lease->ip_addr.len; 1083 state->options[i]->timeout = 0xFFFFFFFF; 1084 state->options[i]->tree = NULL; 1085 } 1086 1087#ifdef DEBUG_PACKET 1088 dump_packet(packet); 1089 dump_raw((unsigned char *)packet->raw, packet->packet_length); 1090#endif 1091 1092 lease->state = state; 1093 1094 /* If this is a DHCPOFFER, ping the lease address before actually 1095 sending the offer. */ 1096 if (offer == DHCPOFFER && !(lease->flags & STATIC_LEASE) && 1097 cur_time - lease->timestamp > 60) { 1098 lease->timestamp = cur_time; 1099 icmp_echorequest (&lease->ip_addr); 1100 add_timeout (cur_time + 1, lease_ping_timeout, lease); 1101 ++outstanding_pings; 1102 } else { 1103 lease->timestamp = cur_time; 1104 dhcp_reply (lease); 1105 } 1106} 1107 1108void 1109dhcp_reply(struct lease *lease) 1110{ 1111 int bufs = 0, packet_length, result, i; 1112 struct dhcp_packet raw; 1113 struct sockaddr_in to; 1114 struct in_addr from; 1115 struct hardware hto; 1116 struct lease_state *state = lease->state; 1117 int nulltp, bootpp; 1118 u_int8_t *prl; 1119 int prl_len; 1120 1121 if (!state) 1122 error("dhcp_reply was supplied lease with no state!"); 1123 1124 /* Compose a response for the client... */ 1125 memset(&raw, 0, sizeof raw); 1126 1127 /* Copy in the filename if given; otherwise, flag the filename 1128 buffer as available for options. */ 1129 if (state->filename[0]) 1130 strlcpy(raw.file, state->filename, sizeof raw.file); 1131 else 1132 bufs |= 1; 1133 1134 /* Copy in the server name if given; otherwise, flag the 1135 server_name buffer as available for options. */ 1136 if (state->server_name) 1137 strlcpy(raw.sname, state->server_name, sizeof raw.sname); 1138 else 1139 bufs |= 2; /* XXX */ 1140 1141 memcpy(raw.chaddr, lease->hardware_addr.haddr, sizeof raw.chaddr); 1142 raw.hlen = lease->hardware_addr.hlen; 1143 raw.htype = lease->hardware_addr.htype; 1144 1145 /* See if this is a Microsoft client that NUL-terminates its 1146 strings and expects us to do likewise... */ 1147 if (lease->flags & MS_NULL_TERMINATION) 1148 nulltp = 1; 1149 else 1150 nulltp = 0; 1151 1152 /* See if this is a bootp client... */ 1153 if (state->offer) 1154 bootpp = 0; 1155 else 1156 bootpp = 1; 1157 1158 if (state->options[DHO_DHCP_PARAMETER_REQUEST_LIST] && 1159 state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value) { 1160 prl = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value; 1161 prl_len = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->len; 1162 } else if (state->prl) { 1163 prl = state->prl; 1164 prl_len = state->prl_len; 1165 } else { 1166 prl = NULL; 1167 prl_len = 0; 1168 } 1169 1170 /* Insert such options as will fit into the buffer. */ 1171 packet_length = cons_options(NULL, &raw, state->max_message_size, 1172 state->options, bufs, nulltp, bootpp, prl, prl_len); 1173 1174 /* Having done the cons_options(), we can release the tree_cache 1175 entries. */ 1176 for (i = 0; i < 256; i++) { 1177 if (state->options[i] && 1178 state->options[i]->flags & TC_TEMPORARY) 1179 free_tree_cache(state->options[i], "dhcp_reply"); 1180 } 1181 1182 memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr); 1183 memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4); 1184 1185 /* Figure out the address of the next server. */ 1186 if (lease->host && lease->host->group->next_server.len) 1187 memcpy(&raw.siaddr, lease->host->group->next_server.iabuf, 4); 1188 else if (lease->subnet->group->next_server.len) 1189 memcpy(&raw.siaddr, lease->subnet->group->next_server.iabuf, 4); 1190 else if (lease->subnet->interface_address.len) 1191 memcpy(&raw.siaddr, lease->subnet->interface_address.iabuf, 4); 1192 else 1193 raw.siaddr = state->ip->primary_address; 1194 1195 raw.giaddr = state->giaddr; 1196 1197 raw.xid = state->xid; 1198 raw.secs = state->secs; 1199 raw.flags = state->bootp_flags; 1200 raw.hops = state->hops; 1201 raw.op = BOOTREPLY; 1202 1203 /* Say what we're doing... */ 1204 note("%s on %s to %s via %s", 1205 (state->offer ? (state->offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") : 1206 "BOOTREPLY"), 1207 piaddr(lease->ip_addr), 1208 print_hw_addr(lease->hardware_addr.htype, lease->hardware_addr.hlen, 1209 lease->hardware_addr.haddr), 1210 state->giaddr.s_addr ? inet_ntoa(state->giaddr) : state->ip->name); 1211 1212 /* Set up the hardware address... */ 1213 hto.htype = lease->hardware_addr.htype; 1214 hto.hlen = lease->hardware_addr.hlen; 1215 memcpy(hto.haddr, lease->hardware_addr.haddr, hto.hlen); 1216 1217 memset(&to, 0, sizeof to); 1218 to.sin_family = AF_INET; 1219#ifdef HAVE_SA_LEN 1220 to.sin_len = sizeof to; 1221#endif 1222 1223#ifdef DEBUG_PACKET 1224 dump_raw((unsigned char *)&raw, packet_length); 1225#endif 1226 1227 /* Make sure outgoing packets are at least as big 1228 as a BOOTP packet. */ 1229 if (packet_length < BOOTP_MIN_LEN) 1230 packet_length = BOOTP_MIN_LEN; 1231 1232 /* If this was gatewayed, send it back to the gateway... */ 1233 if (raw.giaddr.s_addr) { 1234 to.sin_addr = raw.giaddr; 1235 to.sin_port = local_port; 1236 1237 if (fallback_interface) { 1238 result = send_packet(fallback_interface, NULL, 1239 &raw, packet_length,raw.siaddr, &to, NULL); 1240 1241 free_lease_state(state, "dhcp_reply fallback 1"); 1242 lease->state = NULL; 1243 return; 1244 } 1245 1246 /* If the client is RENEWING, unicast to the client using the 1247 regular IP stack. Some clients, particularly those that 1248 follow RFC1541, are buggy, and send both ciaddr and 1249 server-identifier. We deal with this situation by assuming 1250 that if we got both dhcp-server-identifier and ciaddr, and 1251 giaddr was not set, then the client is on the local 1252 network, and we can therefore unicast or broadcast to it 1253 successfully. A client in REQUESTING state on another 1254 network that's making this mistake will have set giaddr, 1255 and will therefore get a relayed response from the above 1256 code. */ 1257 } else if (raw.ciaddr.s_addr && 1258 !((state->got_server_identifier || 1259 (raw.flags & htons(BOOTP_BROADCAST))) && 1260 /* XXX This won't work if giaddr isn't zero, but it is: */ 1261 (state->shared_network == lease->shared_network)) && 1262 state->offer == DHCPACK) { 1263 to.sin_addr = raw.ciaddr; 1264 to.sin_port = remote_port; 1265 1266 if (fallback_interface) { 1267 result = send_packet(fallback_interface, NULL, 1268 &raw, packet_length, raw.siaddr, &to, NULL); 1269 free_lease_state(state, "dhcp_reply fallback 2"); 1270 lease->state = NULL; 1271 return; 1272 } 1273 1274 /* If it comes from a client that already knows its address 1275 and is not requesting a broadcast response, and we can 1276 unicast to a client without using the ARP protocol, sent it 1277 directly to that client. */ 1278 } else if (!(raw.flags & htons (BOOTP_BROADCAST))) { 1279 to.sin_addr = raw.yiaddr; 1280 to.sin_port = remote_port; 1281 1282 /* Otherwise, broadcast it on the local network. */ 1283 } else { 1284 to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 1285 to.sin_port = remote_port; 1286 } 1287 1288 memcpy(&from, state->from.iabuf, sizeof from); 1289 1290 result = send_packet(state->ip, NULL, &raw, packet_length, 1291 from, &to, &hto); 1292 1293 free_lease_state(state, "dhcp_reply"); 1294 lease->state = NULL; 1295} 1296 1297struct lease * 1298find_lease(struct packet *packet, struct shared_network *share, 1299 int *ours) 1300{ 1301 struct lease *uid_lease, *ip_lease, *hw_lease; 1302 struct lease *lease = NULL; 1303 struct iaddr cip; 1304 struct host_decl *hp, *host = NULL; 1305 struct lease *fixed_lease; 1306 1307 /* Figure out what IP address the client is requesting, if any. */ 1308 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len && 1309 packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4) { 1310 packet->got_requested_address = 1; 1311 cip.len = 4; 1312 memcpy(cip.iabuf, 1313 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 1314 cip.len); 1315 } else if (packet->raw->ciaddr.s_addr) { 1316 cip.len = 4; 1317 memcpy(cip.iabuf, &packet->raw->ciaddr, 4); 1318 } else 1319 cip.len = 0; 1320 1321 /* Try to find a host or lease that's been assigned to the 1322 specified unique client identifier. */ 1323 if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) { 1324 /* First, try to find a fixed host entry for the specified 1325 client identifier... */ 1326 hp = find_hosts_by_uid( 1327 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1328 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1329 if (hp) { 1330 host = hp; 1331 fixed_lease = mockup_lease(packet, share, hp); 1332 uid_lease = NULL; 1333 } else { 1334 uid_lease = find_lease_by_uid( 1335 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1336 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1337 /* Find the lease matching this uid that's on the 1338 network the packet came from (if any). */ 1339 for (; uid_lease; uid_lease = uid_lease->n_uid) 1340 if (uid_lease->shared_network == share) 1341 break; 1342 fixed_lease = NULL; 1343 if (uid_lease && (uid_lease->flags & ABANDONED_LEASE)) 1344 uid_lease = NULL; 1345 } 1346 } else { 1347 uid_lease = NULL; 1348 fixed_lease = NULL; 1349 } 1350 1351 /* If we didn't find a fixed lease using the uid, try doing 1352 it with the hardware address... */ 1353 if (!fixed_lease) { 1354 hp = find_hosts_by_haddr(packet->raw->htype, 1355 packet->raw->chaddr, packet->raw->hlen); 1356 if (hp) { 1357 host = hp; /* Save it for later. */ 1358 fixed_lease = mockup_lease (packet, share, hp); 1359 } 1360 } 1361 1362 /* If fixed_lease is present but does not match the requested 1363 IP address, and this is a DHCPREQUEST, then we can't return 1364 any other lease, so we might as well return now. */ 1365 if (packet->packet_type == DHCPREQUEST && fixed_lease && 1366 (fixed_lease->ip_addr.len != cip.len || 1367 memcmp(fixed_lease->ip_addr.iabuf, cip.iabuf, cip.len))) { 1368 if (ours) 1369 *ours = 1; 1370 strlcpy(dhcp_message, "requested address is incorrect", 1371 sizeof (dhcp_message)); 1372 return NULL; 1373 } 1374 1375 /* Try to find a lease that's been attached to the client's 1376 hardware address... */ 1377 hw_lease = find_lease_by_hw_addr(packet->raw->chaddr, 1378 packet->raw->hlen); 1379 /* Find the lease that's on the network the packet came from 1380 (if any). */ 1381 for (; hw_lease; hw_lease = hw_lease->n_hw) { 1382 if (hw_lease->shared_network == share) { 1383 if ((hw_lease->flags & ABANDONED_LEASE)) 1384 continue; 1385 if (packet->packet_type) 1386 break; 1387 if (hw_lease->flags & 1388 (BOOTP_LEASE | DYNAMIC_BOOTP_OK)) 1389 break; 1390 } 1391 } 1392 1393 /* Try to find a lease that's been allocated to the client's 1394 IP address. */ 1395 if (cip.len) 1396 ip_lease = find_lease_by_ip_addr(cip); 1397 else 1398 ip_lease = NULL; 1399 1400 /* If ip_lease is valid at this point, set ours to one, so that 1401 even if we choose a different lease, we know that the address 1402 the client was requesting was ours, and thus we can NAK it. */ 1403 if (ip_lease && ours) 1404 *ours = 1; 1405 1406 /* If the requested IP address isn't on the network the packet 1407 came from, don't use it. Allow abandoned leases to be matched 1408 here - if the client is requesting it, there's a decent chance 1409 that it's because the lease database got trashed and a client 1410 that thought it had this lease answered an ARP or PING, causing the 1411 lease to be abandoned. If so, this request probably came from 1412 that client. */ 1413 if (ip_lease && (ip_lease->shared_network != share)) { 1414 ip_lease = NULL; 1415 strlcpy(dhcp_message, "requested address on bad subnet", 1416 sizeof(dhcp_message)); 1417 } 1418 1419 /* Toss ip_lease if it hasn't yet expired and isn't owned by the 1420 client. */ 1421 if (ip_lease && ip_lease->ends >= cur_time && ip_lease != uid_lease) { 1422 int i = DHO_DHCP_CLIENT_IDENTIFIER; 1423 1424 /* Make sure that ip_lease actually belongs to the client, 1425 and toss it if not. */ 1426 if ((ip_lease->uid_len && packet->options[i].data && 1427 ip_lease->uid_len == packet->options[i].len && 1428 !memcmp(packet->options[i].data, ip_lease->uid, 1429 ip_lease->uid_len)) || 1430 (!ip_lease->uid_len && 1431 ip_lease->hardware_addr.htype == packet->raw->htype && 1432 ip_lease->hardware_addr.hlen == packet->raw->hlen && 1433 !memcmp(ip_lease->hardware_addr.haddr, packet->raw->chaddr, 1434 ip_lease->hardware_addr.hlen))) { 1435 if (uid_lease) { 1436 if (uid_lease->ends > cur_time) { 1437 warn("client %s has duplicate leases on %s", 1438 print_hw_addr(packet->raw->htype, 1439 packet->raw->hlen, packet->raw->chaddr), 1440 ip_lease->shared_network->name); 1441 1442 if (uid_lease && !packet->raw->ciaddr.s_addr) 1443 release_lease (uid_lease); 1444 } 1445 uid_lease = ip_lease; 1446 } 1447 } else { 1448 strlcpy(dhcp_message, "requested address is not available", 1449 sizeof(dhcp_message)); 1450 ip_lease = NULL; 1451 } 1452 1453 /* If we get to here and fixed_lease is not null, that means 1454 that there are both a dynamic lease and a fixed-address 1455 declaration for the same IP address. */ 1456 if (packet->packet_type == DHCPREQUEST && fixed_lease) { 1457 fixed_lease = NULL; 1458db_conflict: 1459 warn("Both dynamic and static leases present for %s.", 1460 piaddr(cip)); 1461 warn("Either remove host declaration %s or remove %s", 1462 (fixed_lease && fixed_lease->host ? 1463 (fixed_lease->host->name ? fixed_lease->host->name : 1464 piaddr(cip)) : piaddr(cip)), piaddr(cip)); 1465 warn("from the dynamic address pool for %s", 1466 share->name); 1467 if (fixed_lease) 1468 ip_lease = NULL; 1469 strlcpy(dhcp_message, "database conflict - call for help!", 1470 sizeof(dhcp_message)); 1471 } 1472 } 1473 1474 /* If we get to here with both fixed_lease and ip_lease not 1475 null, then we have a configuration file bug. */ 1476 if (packet->packet_type == DHCPREQUEST && fixed_lease && ip_lease) 1477 goto db_conflict; 1478 1479 /* Toss hw_lease if it hasn't yet expired and the uid doesn't 1480 match, except that if the hardware address matches and the 1481 client is now doing dynamic BOOTP (and thus hasn't provided 1482 a uid) we let the client get away with it. */ 1483 if (hw_lease && hw_lease->ends >= cur_time && hw_lease->uid && 1484 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len && 1485 hw_lease != uid_lease) 1486 hw_lease = NULL; 1487 1488 /* Toss extra pointers to the same lease... */ 1489 if (hw_lease == uid_lease) 1490 hw_lease = NULL; 1491 if (ip_lease == hw_lease) 1492 hw_lease = NULL; 1493 if (ip_lease == uid_lease) 1494 uid_lease = NULL; 1495 1496 /* If we've already eliminated the lease, it wasn't there to 1497 begin with. If we have come up with a matching lease, 1498 set the message to bad network in case we have to throw it out. */ 1499 if (!ip_lease) { 1500 strlcpy(dhcp_message, "requested address not available", 1501 sizeof(dhcp_message)); 1502 } 1503 1504 /* Now eliminate leases that are on the wrong network... */ 1505 if (ip_lease && share != ip_lease->shared_network) { 1506 if (packet->packet_type == DHCPREQUEST) 1507 release_lease(ip_lease); 1508 ip_lease = NULL; 1509 } 1510 if (uid_lease && share != uid_lease->shared_network) { 1511 if (packet->packet_type == DHCPREQUEST) 1512 release_lease(uid_lease); 1513 uid_lease = NULL; 1514 } 1515 if (hw_lease && share != hw_lease->shared_network) { 1516 if (packet->packet_type == DHCPREQUEST) 1517 release_lease(hw_lease); 1518 hw_lease = NULL; 1519 } 1520 1521 /* If this is a DHCPREQUEST, make sure the lease we're going to return 1522 matches the requested IP address. If it doesn't, don't return a 1523 lease at all. */ 1524 if (packet->packet_type == DHCPREQUEST && !ip_lease && !fixed_lease) 1525 return NULL; 1526 1527 /* At this point, if fixed_lease is nonzero, we can assign it to 1528 this client. */ 1529 if (fixed_lease) 1530 lease = fixed_lease; 1531 1532 /* If we got a lease that matched the ip address and don't have 1533 a better offer, use that; otherwise, release it. */ 1534 if (ip_lease) { 1535 if (lease) { 1536 if (packet->packet_type == DHCPREQUEST) 1537 release_lease(ip_lease); 1538 } else { 1539 lease = ip_lease; 1540 lease->host = NULL; 1541 } 1542 } 1543 1544 /* If we got a lease that matched the client identifier, we may want 1545 to use it, but if we already have a lease we like, we must free 1546 the lease that matched the client identifier. */ 1547 if (uid_lease) { 1548 if (lease) { 1549 if (packet->packet_type == DHCPREQUEST) 1550 release_lease(uid_lease); 1551 } else { 1552 lease = uid_lease; 1553 lease->host = NULL; 1554 } 1555 } 1556 1557 /* The lease that matched the hardware address is treated likewise. */ 1558 if (hw_lease) { 1559 if (lease) { 1560 if (packet->packet_type == DHCPREQUEST) 1561 release_lease(hw_lease); 1562 } else { 1563 lease = hw_lease; 1564 lease->host = NULL; 1565 } 1566 } 1567 1568 /* If we found a host_decl but no matching address, try to 1569 find a host_decl that has no address, and if there is one, 1570 hang it off the lease so that we can use the supplied 1571 options. */ 1572 if (lease && host && !lease->host) { 1573 for (; host; host = host->n_ipaddr) { 1574 if (!host->fixed_addr) { 1575 lease->host = host; 1576 break; 1577 } 1578 } 1579 } 1580 1581 /* If we find an abandoned lease, take it, but print a 1582 warning message, so that if it continues to lose, 1583 the administrator will eventually investigate. */ 1584 if (lease && (lease->flags & ABANDONED_LEASE)) { 1585 if (packet->packet_type == DHCPREQUEST) { 1586 warn("Reclaiming REQUESTed abandoned IP address %s.", 1587 piaddr(lease->ip_addr)); 1588 lease->flags &= ~ABANDONED_LEASE; 1589 } else 1590 lease = NULL; 1591 } 1592 return lease; 1593} 1594 1595/* 1596 * Search the provided host_decl structure list for an address that's on 1597 * the specified shared network. If one is found, mock up and return a 1598 * lease structure for it; otherwise return the null pointer. 1599 */ 1600struct lease * 1601mockup_lease(struct packet *packet, struct shared_network *share, 1602 struct host_decl *hp) 1603{ 1604 static struct lease mock; 1605 1606 mock.subnet = find_host_for_network(&hp, &mock.ip_addr, share); 1607 if (!mock.subnet) 1608 return (NULL); 1609 mock.next = mock.prev = NULL; 1610 mock.shared_network = mock.subnet->shared_network; 1611 mock.host = hp; 1612 1613 if (hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]) { 1614 mock.uid = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->value; 1615 mock.uid_len = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->len; 1616 } else { 1617 mock.uid = NULL; 1618 mock.uid_len = 0; 1619 } 1620 1621 mock.hardware_addr = hp->interface; 1622 mock.starts = mock.timestamp = mock.ends = MIN_TIME; 1623 mock.flags = STATIC_LEASE; 1624 return &mock; 1625} 1626