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