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