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