1 /* $OpenBSD: dhcp.c,v 1.40 2014/11/10 13:03:51 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 == 4) 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 == 4 && 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 * Do not ACK a REQUEST intended for another server. 326 */ 327 if (packet->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) { 328 if (memcmp(packet->options[DHO_DHCP_SERVER_IDENTIFIER].data, 329 &packet->interface->primary_address, 4)) 330 return; 331 } 332 333 /* 334 * If we own the lease that the client is asking for, 335 * and it's already been assigned to the client, ack it. 336 */ 337 if (lease && 338 ((lease->uid_len && lease->uid_len == 339 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len && 340 !memcmp(packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 341 lease->uid, lease->uid_len)) || 342 (lease->hardware_addr.hlen == packet->raw->hlen && 343 lease->hardware_addr.htype == packet->raw->htype && 344 !memcmp(lease->hardware_addr.haddr, packet->raw->chaddr, 345 packet->raw->hlen)))) { 346 ack_lease(packet, lease, DHCPACK, 0); 347 sync_lease(lease); 348 return; 349 } 350 351 /* 352 * At this point, the client has requested a lease, and it's 353 * available, but it wasn't assigned to the client, which 354 * means that the client probably hasn't gone through the 355 * DHCPDISCOVER part of the protocol. We are within our 356 * rights to send a DHCPNAK. We can also send a DHCPACK. 357 * The thing we probably should not do is to remain silent. 358 * For now, we'll just assign the lease to the client anyway. 359 */ 360 if (lease) { 361 ack_lease(packet, lease, DHCPACK, 0); 362 sync_lease(lease); 363 } 364 } 365 366 void 367 dhcprelease(struct packet *packet) 368 { 369 struct lease *lease; 370 struct iaddr cip; 371 int i; 372 373 /* 374 * DHCPRELEASE must not specify address in requested-address 375 * option, but old protocol specs weren't explicit about this, 376 * so let it go. 377 */ 378 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len) { 379 note("DHCPRELEASE from %s specified requested-address.", 380 print_hw_addr(packet->raw->htype, packet->raw->hlen, 381 packet->raw->chaddr)); 382 } 383 384 i = DHO_DHCP_CLIENT_IDENTIFIER; 385 if (packet->options[i].len) { 386 lease = find_lease_by_uid(packet->options[i].data, 387 packet->options[i].len); 388 389 /* 390 * See if we can find a lease that matches the 391 * IP address the client is claiming. 392 */ 393 for (; lease; lease = lease->n_uid) { 394 if (!memcmp(&packet->raw->ciaddr, 395 lease->ip_addr.iabuf, 4)) { 396 break; 397 } 398 } 399 } else { 400 /* 401 * The client is supposed to pass a valid client-identifier, 402 * but the spec on this has changed historically, so try the 403 * IP address in ciaddr if the client-identifier fails. 404 */ 405 cip.len = 4; 406 memcpy(cip.iabuf, &packet->raw->ciaddr, 4); 407 lease = find_lease_by_ip_addr(cip); 408 } 409 410 note("DHCPRELEASE of %s from %s via %s (%sfound)", 411 inet_ntoa(packet->raw->ciaddr), 412 print_hw_addr(packet->raw->htype, packet->raw->hlen, 413 packet->raw->chaddr), 414 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 415 packet->interface->name, 416 lease ? "" : "not "); 417 418 /* If we're already acking this lease, don't do it again. */ 419 if (lease && lease->state) { 420 note("DHCPRELEASE already acking lease %s", 421 piaddr(lease->ip_addr)); 422 return; 423 } 424 425 /* If we found a lease, release it. */ 426 if (lease && lease->ends > cur_time) { 427 /* 428 * First, we ping this lease to see if it's still 429 * there. if it is, we don't release it. This avoids 430 * the problem of spoofed releases being used to liberate 431 * addresses from the server. 432 */ 433 if (!lease->releasing) { 434 note("DHCPRELEASE of %s from %s via %s (found)", 435 inet_ntoa(packet->raw->ciaddr), 436 print_hw_addr(packet->raw->htype, 437 packet->raw->hlen, packet->raw->chaddr), 438 packet->raw->giaddr.s_addr ? 439 inet_ntoa(packet->raw->giaddr) : 440 packet->interface->name); 441 442 lease->releasing = 1; 443 add_timeout(cur_time + 1, lease_ping_timeout, lease); 444 icmp_echorequest(&(lease->ip_addr)); 445 ++outstanding_pings; 446 } else { 447 note("DHCPRELEASE of %s from %s via %s ignored " 448 "(release already pending)", 449 inet_ntoa(packet->raw->ciaddr), 450 print_hw_addr(packet->raw->htype, 451 packet->raw->hlen, packet->raw->chaddr), 452 packet->raw->giaddr.s_addr ? 453 inet_ntoa(packet->raw->giaddr) : 454 packet->interface->name); 455 } 456 } else { 457 note("DHCPRELEASE of %s from %s via %s for nonexistent lease", 458 inet_ntoa(packet->raw->ciaddr), 459 print_hw_addr(packet->raw->htype, packet->raw->hlen, 460 packet->raw->chaddr), 461 packet->raw->giaddr.s_addr ? 462 inet_ntoa(packet->raw->giaddr) : 463 packet->interface->name); 464 } 465 } 466 467 void 468 dhcpdecline(struct packet *packet) 469 { 470 struct lease *lease; 471 struct iaddr cip; 472 473 /* DHCPDECLINE must specify address. */ 474 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len != 4) 475 return; 476 477 cip.len = 4; 478 memcpy(cip.iabuf, 479 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 4); 480 lease = find_lease_by_ip_addr(cip); 481 482 note("DHCPDECLINE on %s from %s via %s", 483 piaddr(cip), print_hw_addr(packet->raw->htype, 484 packet->raw->hlen, packet->raw->chaddr), 485 packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) : 486 packet->interface->name); 487 488 /* If we're already acking this lease, don't do it again. */ 489 if (lease && lease->state) { 490 note("DHCPDECLINE already acking lease %s", 491 piaddr(lease->ip_addr)); 492 return; 493 } 494 495 /* If we found a lease, mark it as unusable and complain. */ 496 if (lease) 497 abandon_lease(lease, "declined."); 498 } 499 500 void 501 dhcpinform(struct packet *packet) 502 { 503 struct lease lease; 504 struct iaddr cip; 505 struct subnet *subnet; 506 507 /* 508 * ciaddr should be set to client's IP address but 509 * not all clients are standards compliant. 510 */ 511 cip.len = 4; 512 if (packet->raw->ciaddr.s_addr) { 513 if (memcmp(&packet->raw->ciaddr.s_addr, 514 packet->client_addr.iabuf, 4) != 0) { 515 note("DHCPINFORM from %s but ciaddr %s is not " 516 "consistent with actual address", 517 piaddr(packet->client_addr), 518 inet_ntoa(packet->raw->ciaddr)); 519 return; 520 } 521 memcpy(cip.iabuf, &packet->raw->ciaddr.s_addr, 4); 522 } else 523 memcpy(cip.iabuf, &packet->client_addr.iabuf, 4); 524 525 note("DHCPINFORM from %s", piaddr(cip)); 526 527 /* Find the lease that matches the address requested by the client. */ 528 subnet = find_subnet(cip); 529 if (!subnet) 530 return; 531 532 /* Sourceless packets don't make sense here. */ 533 if (!subnet->shared_network) { 534 note("Packet from unknown subnet: %s", 535 inet_ntoa(packet->raw->giaddr)); 536 return; 537 } 538 539 /* Use a fake lease entry */ 540 memset(&lease, 0, sizeof(lease)); 541 lease.subnet = subnet; 542 lease.shared_network = subnet->shared_network; 543 544 if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) 545 lease.host = find_hosts_by_uid( 546 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 547 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 548 549 lease.starts = lease.timestamp = lease.ends = MIN_TIME; 550 lease.flags = INFORM_NOLEASE; 551 ack_lease(packet, &lease, DHCPACK, 0); 552 if (lease.state != NULL) 553 free_lease_state(lease.state, "ack_lease"); 554 } 555 556 void 557 nak_lease(struct packet *packet, struct iaddr *cip) 558 { 559 struct sockaddr_in to; 560 struct in_addr from; 561 ssize_t result; 562 int i; 563 struct dhcp_packet raw; 564 unsigned char nak = DHCPNAK; 565 struct packet outgoing; 566 struct tree_cache *options[256], dhcpnak_tree, dhcpmsg_tree, server_tree; 567 568 memset(options, 0, sizeof options); 569 memset(&outgoing, 0, sizeof outgoing); 570 memset(&raw, 0, sizeof raw); 571 outgoing.raw = &raw; 572 573 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */ 574 options[DHO_DHCP_MESSAGE_TYPE] = &dhcpnak_tree; 575 options[DHO_DHCP_MESSAGE_TYPE]->value = &nak; 576 options[DHO_DHCP_MESSAGE_TYPE]->len = sizeof nak; 577 options[DHO_DHCP_MESSAGE_TYPE]->buf_size = sizeof nak; 578 options[DHO_DHCP_MESSAGE_TYPE]->timeout = -1; 579 options[DHO_DHCP_MESSAGE_TYPE]->tree = NULL; 580 options[DHO_DHCP_MESSAGE_TYPE]->flags = 0; 581 582 /* Set DHCP_MESSAGE to whatever the message is */ 583 options[DHO_DHCP_MESSAGE] = &dhcpmsg_tree; 584 options[DHO_DHCP_MESSAGE]->value = (unsigned char *)dhcp_message; 585 options[DHO_DHCP_MESSAGE]->len = strlen(dhcp_message); 586 options[DHO_DHCP_MESSAGE]->buf_size = strlen(dhcp_message); 587 options[DHO_DHCP_MESSAGE]->timeout = -1; 588 options[DHO_DHCP_MESSAGE]->tree = NULL; 589 options[DHO_DHCP_MESSAGE]->flags = 0; 590 591 /* Include server identifier in the NAK. At least one 592 * router vendor depends on it when using dhcp relay proxy mode. 593 */ 594 if (packet->options[DHO_DHCP_SERVER_IDENTIFIER].len) { 595 options[DHO_DHCP_SERVER_IDENTIFIER] = &server_tree; 596 options[DHO_DHCP_SERVER_IDENTIFIER]->value = 597 packet->options[DHO_DHCP_SERVER_IDENTIFIER].data, 598 options[DHO_DHCP_SERVER_IDENTIFIER]->len = 599 packet->options[DHO_DHCP_SERVER_IDENTIFIER].len; 600 options[DHO_DHCP_SERVER_IDENTIFIER]->buf_size = 601 packet->options[DHO_DHCP_SERVER_IDENTIFIER].len; 602 options[DHO_DHCP_SERVER_IDENTIFIER]->timeout = -1; 603 options[DHO_DHCP_SERVER_IDENTIFIER]->tree = NULL; 604 options[DHO_DHCP_SERVER_IDENTIFIER]->flags = 0; 605 } 606 607 /* Do not use the client's requested parameter list. */ 608 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 609 if (packet->options[i].data) { 610 packet->options[i].len = 0; 611 free(packet->options[i].data); 612 packet->options[i].data = NULL; 613 } 614 615 /* Set up the option buffer... */ 616 outgoing.packet_length = cons_options(packet, outgoing.raw, 617 0, options, 0, 0, 0, NULL, 0); 618 619 /* memset(&raw.ciaddr, 0, sizeof raw.ciaddr);*/ 620 raw.siaddr = packet->interface->primary_address; 621 raw.giaddr = packet->raw->giaddr; 622 memcpy(raw.chaddr, packet->raw->chaddr, sizeof raw.chaddr); 623 raw.hlen = packet->raw->hlen; 624 raw.htype = packet->raw->htype; 625 raw.xid = packet->raw->xid; 626 raw.secs = packet->raw->secs; 627 raw.flags = packet->raw->flags | htons(BOOTP_BROADCAST); 628 raw.hops = packet->raw->hops; 629 raw.op = BOOTREPLY; 630 631 /* Report what we're sending... */ 632 note("DHCPNAK on %s to %s via %s", piaddr(*cip), 633 print_hw_addr(packet->raw->htype, packet->raw->hlen, 634 packet->raw->chaddr), packet->raw->giaddr.s_addr ? 635 inet_ntoa(packet->raw->giaddr) : packet->interface->name); 636 637 /* Set up the common stuff... */ 638 memset(&to, 0, sizeof to); 639 to.sin_family = AF_INET; 640 to.sin_len = sizeof to; 641 642 from = packet->interface->primary_address; 643 644 /* Make sure that the packet is at least as big as a BOOTP packet. */ 645 if (outgoing.packet_length < BOOTP_MIN_LEN) 646 outgoing.packet_length = BOOTP_MIN_LEN; 647 648 /* 649 * If this was gatewayed, send it back to the gateway. 650 * Otherwise, broadcast it on the local network. 651 */ 652 if (raw.giaddr.s_addr) { 653 to.sin_addr = raw.giaddr; 654 to.sin_port = server_port; 655 656 result = packet->interface->send_packet(packet->interface, &raw, 657 outgoing.packet_length, from, &to, packet->haddr); 658 if (result == -1) 659 warning("send_fallback: %m"); 660 return; 661 } else { 662 to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 663 to.sin_port = client_port; 664 } 665 666 errno = 0; 667 result = packet->interface->send_packet(packet->interface, &raw, 668 outgoing.packet_length, from, &to, NULL); 669 } 670 671 void 672 ack_lease(struct packet *packet, struct lease *lease, unsigned int offer, 673 time_t when) 674 { 675 struct lease lt; 676 struct lease_state *state; 677 time_t lease_time, offered_lease_time, max_lease_time, default_lease_time; 678 struct class *vendor_class, *user_class; 679 int ulafdr, i; 680 681 /* If we're already acking this lease, don't do it again. */ 682 if (lease->state) { 683 if ((lease->flags & STATIC_LEASE) || 684 cur_time - lease->timestamp < 60) { 685 note("already acking lease %s", piaddr(lease->ip_addr)); 686 return; 687 } 688 free_lease_state(lease->state, "ACK timed out"); 689 lease->state = NULL; 690 } 691 692 if (packet->options[DHO_DHCP_CLASS_IDENTIFIER].len) { 693 vendor_class = find_class(0, 694 packet->options[DHO_DHCP_CLASS_IDENTIFIER].data, 695 packet->options[DHO_DHCP_CLASS_IDENTIFIER].len); 696 } else 697 vendor_class = NULL; 698 699 if (packet->options[DHO_DHCP_USER_CLASS_ID].len) { 700 user_class = find_class(1, 701 packet->options[DHO_DHCP_USER_CLASS_ID].data, 702 packet->options[DHO_DHCP_USER_CLASS_ID].len); 703 } else 704 user_class = NULL; 705 706 /* 707 * If there is not a specific host entry, and either the 708 * vendor class or user class (if they exist) deny booting, 709 * then bug out. 710 */ 711 if (!lease->host) { 712 if (vendor_class && !vendor_class->group->allow_booting) { 713 debug("Booting denied by vendor class"); 714 return; 715 } 716 717 if (user_class && !user_class->group->allow_booting) { 718 debug("Booting denied by user class"); 719 return; 720 } 721 } 722 723 /* Allocate a lease state structure... */ 724 state = new_lease_state("ack_lease"); 725 if (!state) 726 error("unable to allocate lease state!"); 727 memset(state, 0, sizeof *state); 728 state->got_requested_address = packet->got_requested_address; 729 state->shared_network = packet->interface->shared_network; 730 731 /* Remember if we got a server identifier option. */ 732 if (packet->options[DHO_DHCP_SERVER_IDENTIFIER].len) 733 state->got_server_identifier = 1; 734 735 /* Replace the old lease hostname with the new one, if it's changed. */ 736 if (packet->options[DHO_HOST_NAME].len && 737 lease->client_hostname && 738 (strlen(lease->client_hostname) == packet->options[DHO_HOST_NAME].len) && 739 !memcmp(lease->client_hostname, packet->options[DHO_HOST_NAME].data, 740 packet->options[DHO_HOST_NAME].len)) { 741 } else if (packet->options[DHO_HOST_NAME].len) { 742 if (lease->client_hostname) 743 free(lease->client_hostname); 744 lease->client_hostname = malloc( 745 packet->options[DHO_HOST_NAME].len + 1); 746 if (!lease->client_hostname) 747 error("no memory for client hostname.\n"); 748 memcpy(lease->client_hostname, 749 packet->options[DHO_HOST_NAME].data, 750 packet->options[DHO_HOST_NAME].len); 751 lease->client_hostname[packet->options[DHO_HOST_NAME].len] = 0; 752 } else if (lease->client_hostname) { 753 free(lease->client_hostname); 754 lease->client_hostname = 0; 755 } 756 757 /* 758 * Choose a filename; first from the host_decl, if any, then from 759 * the user class, then from the vendor class. 760 */ 761 if (lease->host && lease->host->group->filename) 762 strlcpy(state->filename, lease->host->group->filename, 763 sizeof state->filename); 764 else if (user_class && user_class->group->filename) 765 strlcpy(state->filename, user_class->group->filename, 766 sizeof state->filename); 767 else if (vendor_class && vendor_class->group->filename) 768 strlcpy(state->filename, vendor_class->group->filename, 769 sizeof state->filename); 770 else if (packet->raw->file[0]) 771 strlcpy(state->filename, packet->raw->file, 772 sizeof state->filename); 773 else if (lease->subnet->group->filename) 774 strlcpy(state->filename, lease->subnet->group->filename, 775 sizeof state->filename); 776 else 777 strlcpy(state->filename, "", sizeof state->filename); 778 779 /* Choose a server name as above. */ 780 if (lease->host && lease->host->group->server_name) 781 state->server_name = lease->host->group->server_name; 782 else if (user_class && user_class->group->server_name) 783 state->server_name = user_class->group->server_name; 784 else if (vendor_class && vendor_class->group->server_name) 785 state->server_name = vendor_class->group->server_name; 786 else if (lease->subnet->group->server_name) 787 state->server_name = lease->subnet->group->server_name; 788 else state->server_name = NULL; 789 790 /* 791 * At this point, we have a lease that we can offer the client. 792 * Now we construct a lease structure that contains what we want, 793 * and call supersede_lease to do the right thing with it. 794 */ 795 memset(<, 0, sizeof lt); 796 797 /* 798 * Use the ip address of the lease that we finally found in 799 * the database. 800 */ 801 lt.ip_addr = lease->ip_addr; 802 803 /* Start now. */ 804 lt.starts = cur_time; 805 806 /* Figure out maximum lease time. */ 807 if (lease->host && lease->host->group->max_lease_time) 808 max_lease_time = lease->host->group->max_lease_time; 809 else 810 max_lease_time = lease->subnet->group->max_lease_time; 811 812 /* Figure out default lease time. */ 813 if (lease->host && lease->host->group->default_lease_time) 814 default_lease_time = lease->host->group->default_lease_time; 815 else 816 default_lease_time = lease->subnet->group->default_lease_time; 817 818 /* 819 * Figure out how long a lease to assign. If this is a 820 * dynamic BOOTP lease, its duration must be infinite. 821 */ 822 if (offer) { 823 if (packet->options[DHO_DHCP_LEASE_TIME].len == 4) { 824 lease_time = getULong( 825 packet->options[DHO_DHCP_LEASE_TIME].data); 826 827 /* 828 * Don't let the client ask for a longer lease than 829 * is supported for this subnet or host. 830 * 831 * time_t is signed, so really large numbers come 832 * back as negative. Don't allow lease_time of 0, 833 * either. 834 */ 835 if (lease_time < 1 || lease_time > max_lease_time) 836 lease_time = max_lease_time; 837 } else 838 lease_time = default_lease_time; 839 840 state->offered_expiry = cur_time + lease_time; 841 if (when) 842 lt.ends = when; 843 else 844 lt.ends = state->offered_expiry; 845 } else { 846 if (lease->host && 847 lease->host->group->bootp_lease_length) 848 lt.ends = (cur_time + 849 lease->host->group->bootp_lease_length); 850 else if (lease->subnet->group->bootp_lease_length) 851 lt.ends = (cur_time + 852 lease->subnet->group->bootp_lease_length); 853 else if (lease->host && 854 lease->host->group->bootp_lease_cutoff) 855 lt.ends = lease->host->group->bootp_lease_cutoff; 856 else 857 lt.ends = lease->subnet->group->bootp_lease_cutoff; 858 state->offered_expiry = lt.ends; 859 lt.flags = BOOTP_LEASE; 860 } 861 862 /* Record the uid, if given... */ 863 i = DHO_DHCP_CLIENT_IDENTIFIER; 864 if (packet->options[i].len) { 865 if (packet->options[i].len <= sizeof lt.uid_buf) { 866 memcpy(lt.uid_buf, packet->options[i].data, 867 packet->options[i].len); 868 lt.uid = lt.uid_buf; 869 lt.uid_max = sizeof lt.uid_buf; 870 lt.uid_len = packet->options[i].len; 871 } else { 872 lt.uid_max = lt.uid_len = packet->options[i].len; 873 lt.uid = (unsigned char *)malloc(lt.uid_max); 874 if (!lt.uid) 875 error("can't allocate memory for large uid."); 876 memcpy(lt.uid, packet->options[i].data, lt.uid_len); 877 } 878 } 879 880 lt.host = lease->host; 881 lt.subnet = lease->subnet; 882 lt.shared_network = lease->shared_network; 883 884 /* Don't call supersede_lease on a mocked-up lease. */ 885 if (lease->flags & (STATIC_LEASE | INFORM_NOLEASE)) { 886 /* Copy the hardware address into the static lease 887 structure. */ 888 lease->hardware_addr.hlen = packet->raw->hlen; 889 lease->hardware_addr.htype = packet->raw->htype; 890 memcpy(lease->hardware_addr.haddr, packet->raw->chaddr, 891 sizeof packet->raw->chaddr); /* XXX */ 892 } else { 893 /* Record the hardware address, if given... */ 894 lt.hardware_addr.hlen = packet->raw->hlen; 895 lt.hardware_addr.htype = packet->raw->htype; 896 memcpy(lt.hardware_addr.haddr, packet->raw->chaddr, 897 sizeof packet->raw->chaddr); 898 899 /* Install the new information about this lease in the 900 database. If this is a DHCPACK or a dynamic BOOTREPLY 901 and we can't write the lease, don't ACK it (or BOOTREPLY 902 it) either. */ 903 904 if (!(supersede_lease(lease, <, !offer || offer == DHCPACK) || 905 (offer && offer != DHCPACK))) { 906 free_lease_state(state, "ack_lease: !supersede_lease"); 907 return; 908 } 909 } 910 911 /* Remember the interface on which the packet arrived. */ 912 state->ip = packet->interface; 913 914 /* Set a flag if this client is a lame Microsoft client that NUL 915 terminates string options and expects us to do likewise. */ 916 if (packet->options[DHO_HOST_NAME].len && 917 packet->options[DHO_HOST_NAME].data[ 918 packet->options[DHO_HOST_NAME].len - 1] == '\0') 919 lease->flags |= MS_NULL_TERMINATION; 920 else 921 lease->flags &= ~MS_NULL_TERMINATION; 922 923 /* Remember the giaddr, xid, secs, flags and hops. */ 924 state->giaddr = packet->raw->giaddr; 925 state->ciaddr = packet->raw->ciaddr; 926 state->xid = packet->raw->xid; 927 state->secs = packet->raw->secs; 928 state->bootp_flags = packet->raw->flags; 929 state->hops = packet->raw->hops; 930 state->offer = offer; 931 memcpy(&state->haddr, packet->haddr, sizeof state->haddr); 932 933 /* Figure out what options to send to the client: */ 934 935 /* Start out with the subnet options... */ 936 memcpy(state->options, lease->subnet->group->options, 937 sizeof state->options); 938 939 /* Vendor and user classes are only supported for DHCP clients. */ 940 if (state->offer) { 941 /* If we have a vendor class, install those options, 942 superseding any subnet options. */ 943 if (vendor_class) { 944 for (i = 0; i < 256; i++) 945 if (vendor_class->group->options[i]) 946 state->options[i] = 947 vendor_class->group->options[i]; 948 } 949 950 /* If we have a user class, install those options, 951 superseding any subnet and vendor class options. */ 952 if (user_class) { 953 for (i = 0; i < 256; i++) 954 if (user_class->group->options[i]) 955 state->options[i] = 956 user_class->group->options[i]; 957 } 958 959 } 960 961 /* If we have a host_decl structure, install the associated 962 options, superseding anything that's in the way. */ 963 if (lease->host) { 964 for (i = 0; i < 256; i++) 965 if (lease->host->group->options[i]) 966 state->options[i] = 967 lease->host->group->options[i]; 968 } 969 970 /* Get the Maximum Message Size option from the packet, if one 971 was sent. */ 972 i = DHO_DHCP_MAX_MESSAGE_SIZE; 973 if (packet->options[i].data && 974 packet->options[i].len == sizeof(u_int16_t)) 975 state->max_message_size = getUShort(packet->options[i].data); 976 /* Otherwise, if a maximum message size was specified, use that. */ 977 else if (state->options[i] && state->options[i]->value) 978 state->max_message_size = getUShort(state->options[i]->value); 979 980 /* Save the parameter request list if there is one. */ 981 i = DHO_DHCP_PARAMETER_REQUEST_LIST; 982 if (packet->options[i].data) { 983 state->prl = calloc(1, packet->options[i].len); 984 if (!state->prl) 985 warning("no memory for parameter request list"); 986 else { 987 memcpy(state->prl, packet->options[i].data, 988 packet->options[i].len); 989 state->prl_len = packet->options[i].len; 990 } 991 } 992 993 /* If we didn't get a hostname from an option somewhere, see if 994 we can get one from the lease. */ 995 i = DHO_HOST_NAME; 996 if (!state->options[i] && lease->hostname) { 997 state->options[i] = new_tree_cache("hostname"); 998 state->options[i]->flags = TC_TEMPORARY; 999 state->options[i]->value = (unsigned char *)lease->hostname; 1000 state->options[i]->len = strlen(lease->hostname); 1001 state->options[i]->buf_size = state->options[i]->len; 1002 state->options[i]->timeout = -1; 1003 state->options[i]->tree = NULL; 1004 } 1005 1006 /* 1007 * Now, if appropriate, put in DHCP-specific options that 1008 * override those. 1009 */ 1010 if (state->offer) { 1011 i = DHO_DHCP_MESSAGE_TYPE; 1012 state->options[i] = new_tree_cache("message-type"); 1013 state->options[i]->flags = TC_TEMPORARY; 1014 state->options[i]->value = &state->offer; 1015 state->options[i]->len = sizeof state->offer; 1016 state->options[i]->buf_size = sizeof state->offer; 1017 state->options[i]->timeout = -1; 1018 state->options[i]->tree = NULL; 1019 1020 i = DHO_DHCP_SERVER_IDENTIFIER; 1021 if (!state->options[i]) { 1022 use_primary: 1023 state->options[i] = new_tree_cache("server-id"); 1024 state->options[i]->value = 1025 (unsigned char *)&state->ip->primary_address; 1026 state->options[i]->len = 1027 sizeof state->ip->primary_address; 1028 state->options[i]->buf_size = 1029 state->options[i]->len; 1030 state->options[i]->timeout = -1; 1031 state->options[i]->tree = NULL; 1032 state->from.len = sizeof state->ip->primary_address; 1033 memcpy(state->from.iabuf, &state->ip->primary_address, 1034 state->from.len); 1035 } else { 1036 /* Find the value of the server identifier... */ 1037 if (!tree_evaluate(state->options[i])) 1038 goto use_primary; 1039 if (!state->options[i]->value || 1040 (state->options[i]->len > sizeof state->from.iabuf)) 1041 goto use_primary; 1042 1043 state->from.len = state->options[i]->len; 1044 memcpy(state->from.iabuf, state->options[i]->value, 1045 state->from.len); 1046 } 1047 /* If we used the vendor class the client specified, we 1048 have to return it. */ 1049 if (vendor_class) { 1050 i = DHO_DHCP_CLASS_IDENTIFIER; 1051 state->options[i] = 1052 new_tree_cache("class-identifier"); 1053 state->options[i]->flags = TC_TEMPORARY; 1054 state->options[i]->value = 1055 (unsigned char *)vendor_class->name; 1056 state->options[i]->len = 1057 strlen(vendor_class->name); 1058 state->options[i]->buf_size = 1059 state->options[i]->len; 1060 state->options[i]->timeout = -1; 1061 state->options[i]->tree = NULL; 1062 } 1063 1064 /* If we used the user class the client specified, we 1065 have to return it. */ 1066 if (user_class) { 1067 i = DHO_DHCP_USER_CLASS_ID; 1068 state->options[i] = new_tree_cache("user-class"); 1069 state->options[i]->flags = TC_TEMPORARY; 1070 state->options[i]->value = 1071 (unsigned char *)user_class->name; 1072 state->options[i]->len = 1073 strlen(user_class->name); 1074 state->options[i]->buf_size = 1075 state->options[i]->len; 1076 state->options[i]->timeout = -1; 1077 state->options[i]->tree = NULL; 1078 } 1079 } 1080 1081 /* for DHCPINFORM, don't include lease time parameters */ 1082 if (state->offer && (lease->flags & INFORM_NOLEASE) == 0) { 1083 1084 /* Sanity check the lease time. */ 1085 if ((state->offered_expiry - cur_time) < 15) 1086 offered_lease_time = default_lease_time; 1087 else if (state->offered_expiry - cur_time > max_lease_time) 1088 offered_lease_time = max_lease_time; 1089 else 1090 offered_lease_time = 1091 state->offered_expiry - cur_time; 1092 1093 putULong((unsigned char *)&state->expiry, 1094 offered_lease_time); 1095 i = DHO_DHCP_LEASE_TIME; 1096 state->options[i] = new_tree_cache("lease-expiry"); 1097 state->options[i]->flags = TC_TEMPORARY; 1098 state->options[i]->value = (unsigned char *)&state->expiry; 1099 state->options[i]->len = sizeof state->expiry; 1100 state->options[i]->buf_size = sizeof state->expiry; 1101 state->options[i]->timeout = -1; 1102 state->options[i]->tree = NULL; 1103 1104 /* Renewal time is lease time * 0.5. */ 1105 offered_lease_time /= 2; 1106 putULong((unsigned char *)&state->renewal, 1107 offered_lease_time); 1108 i = DHO_DHCP_RENEWAL_TIME; 1109 state->options[i] = new_tree_cache("renewal-time"); 1110 state->options[i]->flags = TC_TEMPORARY; 1111 state->options[i]->value = 1112 (unsigned char *)&state->renewal; 1113 state->options[i]->len = sizeof state->renewal; 1114 state->options[i]->buf_size = sizeof state->renewal; 1115 state->options[i]->timeout = -1; 1116 state->options[i]->tree = NULL; 1117 1118 1119 /* Rebinding time is lease time * 0.875. */ 1120 offered_lease_time += (offered_lease_time / 2 + 1121 offered_lease_time / 4); 1122 putULong((unsigned char *)&state->rebind, 1123 offered_lease_time); 1124 i = DHO_DHCP_REBINDING_TIME; 1125 state->options[i] = new_tree_cache("rebind-time"); 1126 state->options[i]->flags = TC_TEMPORARY; 1127 state->options[i]->value = 1128 (unsigned char *)&state->rebind; 1129 state->options[i]->len = sizeof state->rebind; 1130 state->options[i]->buf_size = sizeof state->rebind; 1131 state->options[i]->timeout = -1; 1132 state->options[i]->tree = NULL; 1133 } 1134 1135 /* Use the subnet mask from the subnet declaration if no other 1136 mask has been provided. */ 1137 i = DHO_SUBNET_MASK; 1138 if (!state->options[i]) { 1139 state->options[i] = new_tree_cache("subnet-mask"); 1140 state->options[i]->flags = TC_TEMPORARY; 1141 state->options[i]->value = 1142 lease->subnet->netmask.iabuf; 1143 state->options[i]->len = lease->subnet->netmask.len; 1144 state->options[i]->buf_size = 1145 lease->subnet->netmask.len; 1146 state->options[i]->timeout = -1; 1147 state->options[i]->tree = NULL; 1148 } 1149 1150 /* If so directed, use the leased IP address as the router address. 1151 This supposedly makes Win95 machines ARP for all IP addresses, 1152 so if the local router does proxy arp, you win. */ 1153 1154 ulafdr = 0; 1155 if (lease->host) { 1156 if (lease->host->group->use_lease_addr_for_default_route) 1157 ulafdr = 1; 1158 } else if (user_class) { 1159 if (user_class->group->use_lease_addr_for_default_route) 1160 ulafdr = 1; 1161 } else if (vendor_class) { 1162 if (vendor_class->group->use_lease_addr_for_default_route) 1163 ulafdr = 1; 1164 } else if (lease->subnet->group->use_lease_addr_for_default_route) 1165 ulafdr = 1; 1166 else 1167 ulafdr = 0; 1168 1169 i = DHO_ROUTERS; 1170 if (ulafdr && !state->options[i]) { 1171 state->options[i] = new_tree_cache("routers"); 1172 state->options[i]->flags = TC_TEMPORARY; 1173 state->options[i]->value = lease->ip_addr.iabuf; 1174 state->options[i]->len = lease->ip_addr.len; 1175 state->options[i]->buf_size = lease->ip_addr.len; 1176 state->options[i]->timeout = -1; 1177 state->options[i]->tree = NULL; 1178 } 1179 1180 /* Echo back the relay agent information, if present */ 1181 i = DHO_RELAY_AGENT_INFORMATION; 1182 if (state->giaddr.s_addr && !state->options[i] && 1183 packet->options[i].data && packet->options[i].len) { 1184 state->options[i] = new_tree_cache("relay-agent-information"); 1185 state->options[i]->flags = TC_TEMPORARY; 1186 state->options[i]->value = packet->options[i].data; 1187 state->options[i]->len = packet->options[i].len; 1188 state->options[i]->buf_size = packet->options[i].len; 1189 state->options[i]->timeout = -1; 1190 state->options[i]->tree = NULL; 1191 } 1192 1193 /* RFC 2131: MUST NOT send client identifier option in OFFER/ACK! */ 1194 i = DHO_DHCP_CLIENT_IDENTIFIER; 1195 memset(&state->options[i], 0, sizeof(state->options[i])); 1196 1197 lease->state = state; 1198 1199 /* If this is a DHCPOFFER, ping the lease address before actually 1200 sending the offer. */ 1201 if (offer == DHCPOFFER && !(lease->flags & STATIC_LEASE) && 1202 cur_time - lease->timestamp > 60) { 1203 lease->timestamp = cur_time; 1204 icmp_echorequest(&lease->ip_addr); 1205 add_timeout(cur_time + 1, lease_ping_timeout, lease); 1206 ++outstanding_pings; 1207 } else { 1208 lease->timestamp = cur_time; 1209 dhcp_reply(lease); 1210 } 1211 } 1212 1213 void 1214 dhcp_reply(struct lease *lease) 1215 { 1216 int bufs = 0, packet_length, i; 1217 struct dhcp_packet raw; 1218 struct sockaddr_in to; 1219 struct in_addr from; 1220 struct lease_state *state = lease->state; 1221 int nulltp, bootpp; 1222 u_int8_t *prl; 1223 int prl_len; 1224 1225 if (!state) 1226 error("dhcp_reply was supplied lease with no state!"); 1227 1228 /* Compose a response for the client... */ 1229 memset(&raw, 0, sizeof raw); 1230 1231 /* Copy in the filename if given; otherwise, flag the filename 1232 buffer as available for options. */ 1233 if (state->filename[0]) 1234 strlcpy(raw.file, state->filename, sizeof raw.file); 1235 else 1236 bufs |= 1; 1237 1238 /* Copy in the server name if given; otherwise, flag the 1239 server_name buffer as available for options. */ 1240 if (state->server_name) 1241 strlcpy(raw.sname, state->server_name, sizeof raw.sname); 1242 else 1243 bufs |= 2; /* XXX */ 1244 1245 memcpy(raw.chaddr, lease->hardware_addr.haddr, sizeof raw.chaddr); 1246 raw.hlen = lease->hardware_addr.hlen; 1247 raw.htype = lease->hardware_addr.htype; 1248 1249 /* See if this is a Microsoft client that NUL-terminates its 1250 strings and expects us to do likewise... */ 1251 if (lease->flags & MS_NULL_TERMINATION) 1252 nulltp = 1; 1253 else 1254 nulltp = 0; 1255 1256 /* See if this is a bootp client... */ 1257 if (state->offer) 1258 bootpp = 0; 1259 else 1260 bootpp = 1; 1261 1262 if (state->options[DHO_DHCP_PARAMETER_REQUEST_LIST] && 1263 state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value) { 1264 prl = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value; 1265 prl_len = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->len; 1266 } else if (state->prl) { 1267 prl = state->prl; 1268 prl_len = state->prl_len; 1269 } else { 1270 prl = NULL; 1271 prl_len = 0; 1272 } 1273 1274 /* Insert such options as will fit into the buffer. */ 1275 packet_length = cons_options(NULL, &raw, state->max_message_size, 1276 state->options, bufs, nulltp, bootpp, prl, prl_len); 1277 1278 /* Having done the cons_options(), we can release the tree_cache 1279 entries. */ 1280 for (i = 0; i < 256; i++) { 1281 if (state->options[i] && 1282 state->options[i]->flags & TC_TEMPORARY) 1283 free_tree_cache(state->options[i]); 1284 } 1285 1286 memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr); 1287 if ((lease->flags & INFORM_NOLEASE) == 0) 1288 memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4); 1289 1290 /* Figure out the address of the next server. */ 1291 if (lease->host && lease->host->group->next_server.len) 1292 memcpy(&raw.siaddr, lease->host->group->next_server.iabuf, 4); 1293 else if (lease->subnet->group->next_server.len) 1294 memcpy(&raw.siaddr, lease->subnet->group->next_server.iabuf, 4); 1295 else if (lease->subnet->interface_address.len) 1296 memcpy(&raw.siaddr, lease->subnet->interface_address.iabuf, 4); 1297 else 1298 raw.siaddr = state->ip->primary_address; 1299 1300 raw.giaddr = state->giaddr; 1301 1302 raw.xid = state->xid; 1303 raw.secs = state->secs; 1304 raw.flags = state->bootp_flags; 1305 raw.hops = state->hops; 1306 raw.op = BOOTREPLY; 1307 1308 /* Say what we're doing... */ 1309 note("%s on %s to %s via %s", 1310 (state->offer ? (state->offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") : 1311 "BOOTREPLY"), 1312 piaddr(lease->ip_addr), 1313 print_hw_addr(lease->hardware_addr.htype, lease->hardware_addr.hlen, 1314 lease->hardware_addr.haddr), 1315 state->giaddr.s_addr ? inet_ntoa(state->giaddr) : state->ip->name); 1316 1317 memset(&to, 0, sizeof to); 1318 to.sin_family = AF_INET; 1319 #ifdef HAVE_SA_LEN 1320 to.sin_len = sizeof to; 1321 #endif 1322 1323 /* Make sure outgoing packets are at least as big 1324 as a BOOTP packet. */ 1325 if (packet_length < BOOTP_MIN_LEN) 1326 packet_length = BOOTP_MIN_LEN; 1327 1328 /* If this was gatewayed, send it back to the gateway... */ 1329 if (raw.giaddr.s_addr) { 1330 to.sin_addr = raw.giaddr; 1331 to.sin_port = server_port; 1332 1333 memcpy(&from, state->from.iabuf, sizeof from); 1334 1335 (void) state->ip->send_packet(state->ip, &raw, 1336 packet_length, from, &to, &state->haddr); 1337 1338 free_lease_state(state, "dhcp_reply gateway"); 1339 lease->state = NULL; 1340 return; 1341 1342 /* If the client is RENEWING, unicast to the client using the 1343 regular IP stack. Some clients, particularly those that 1344 follow RFC1541, are buggy, and send both ciaddr and 1345 server-identifier. We deal with this situation by assuming 1346 that if we got both dhcp-server-identifier and ciaddr, and 1347 giaddr was not set, then the client is on the local 1348 network, and we can therefore unicast or broadcast to it 1349 successfully. A client in REQUESTING state on another 1350 network that's making this mistake will have set giaddr, 1351 and will therefore get a relayed response from the above 1352 code. */ 1353 } else if (raw.ciaddr.s_addr && 1354 !((state->got_server_identifier || 1355 (raw.flags & htons(BOOTP_BROADCAST))) && 1356 /* XXX This won't work if giaddr isn't zero, but it is: */ 1357 (state->shared_network == lease->shared_network)) && 1358 state->offer == DHCPACK) { 1359 to.sin_addr = raw.ciaddr; 1360 to.sin_port = client_port; 1361 1362 /* If it comes from a client that already knows its address 1363 and is not requesting a broadcast response, and we can 1364 unicast to a client without using the ARP protocol, sent it 1365 directly to that client. */ 1366 } else if (!(raw.flags & htons(BOOTP_BROADCAST))) { 1367 to.sin_addr = raw.yiaddr; 1368 to.sin_port = client_port; 1369 1370 /* Otherwise, broadcast it on the local network. */ 1371 } else { 1372 to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 1373 to.sin_port = client_port; 1374 memset(&state->haddr, 0xff, sizeof state->haddr); 1375 } 1376 1377 memcpy(&from, state->from.iabuf, sizeof from); 1378 1379 (void) state->ip->send_packet(state->ip, &raw, packet_length, 1380 from, &to, &state->haddr); 1381 1382 free_lease_state(state, "dhcp_reply"); 1383 lease->state = NULL; 1384 } 1385 1386 struct lease * 1387 find_lease(struct packet *packet, struct shared_network *share, 1388 int *ours) 1389 { 1390 struct lease *uid_lease, *ip_lease, *hw_lease; 1391 struct lease *lease = NULL; 1392 struct iaddr cip; 1393 struct host_decl *hp, *host = NULL; 1394 struct lease *fixed_lease; 1395 1396 /* Figure out what IP address the client is requesting, if any. */ 1397 if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4) { 1398 packet->got_requested_address = 1; 1399 cip.len = 4; 1400 memcpy(cip.iabuf, 1401 packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 1402 cip.len); 1403 } else if (packet->raw->ciaddr.s_addr) { 1404 cip.len = 4; 1405 memcpy(cip.iabuf, &packet->raw->ciaddr, 4); 1406 } else 1407 cip.len = 0; 1408 1409 /* Try to find a host or lease that's been assigned to the 1410 specified unique client identifier. */ 1411 if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) { 1412 /* First, try to find a fixed host entry for the specified 1413 client identifier... */ 1414 hp = find_hosts_by_uid( 1415 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1416 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1417 if (hp) { 1418 host = hp; 1419 fixed_lease = mockup_lease(packet, share, hp); 1420 uid_lease = NULL; 1421 } else { 1422 uid_lease = find_lease_by_uid( 1423 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data, 1424 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len); 1425 /* Find the lease matching this uid that's on the 1426 network the packet came from (if any). */ 1427 for (; uid_lease; uid_lease = uid_lease->n_uid) 1428 if (uid_lease->shared_network == share) 1429 break; 1430 fixed_lease = NULL; 1431 if (uid_lease && (uid_lease->flags & ABANDONED_LEASE)) 1432 uid_lease = NULL; 1433 } 1434 } else { 1435 uid_lease = NULL; 1436 fixed_lease = NULL; 1437 } 1438 1439 /* If we didn't find a fixed lease using the uid, try doing 1440 it with the hardware address... */ 1441 if (!fixed_lease) { 1442 hp = find_hosts_by_haddr(packet->raw->htype, 1443 packet->raw->chaddr, packet->raw->hlen); 1444 if (hp) { 1445 host = hp; /* Save it for later. */ 1446 fixed_lease = mockup_lease(packet, share, hp); 1447 } 1448 } 1449 1450 /* If fixed_lease is present but does not match the requested 1451 IP address, and this is a DHCPREQUEST, then we can't return 1452 any other lease, so we might as well return now. */ 1453 if (packet->packet_type == DHCPREQUEST && fixed_lease && 1454 (fixed_lease->ip_addr.len != cip.len || 1455 memcmp(fixed_lease->ip_addr.iabuf, cip.iabuf, cip.len))) { 1456 if (ours) 1457 *ours = 1; 1458 strlcpy(dhcp_message, "requested address is incorrect", 1459 sizeof(dhcp_message)); 1460 return NULL; 1461 } 1462 1463 /* Try to find a lease that's been attached to the client's 1464 hardware address... */ 1465 hw_lease = find_lease_by_hw_addr(packet->raw->chaddr, 1466 packet->raw->hlen); 1467 /* Find the lease that's on the network the packet came from 1468 (if any). */ 1469 for (; hw_lease; hw_lease = hw_lease->n_hw) { 1470 if (hw_lease->shared_network == share) { 1471 if ((hw_lease->flags & ABANDONED_LEASE)) 1472 continue; 1473 if (packet->packet_type) 1474 break; 1475 if (hw_lease->flags & 1476 (BOOTP_LEASE | DYNAMIC_BOOTP_OK)) 1477 break; 1478 } 1479 } 1480 1481 /* Try to find a lease that's been allocated to the client's 1482 IP address. */ 1483 if (cip.len) 1484 ip_lease = find_lease_by_ip_addr(cip); 1485 else 1486 ip_lease = NULL; 1487 1488 /* If ip_lease is valid at this point, set ours to one, so that 1489 even if we choose a different lease, we know that the address 1490 the client was requesting was ours, and thus we can NAK it. */ 1491 if (ip_lease && ours) 1492 *ours = 1; 1493 1494 /* If the requested IP address isn't on the network the packet 1495 came from, don't use it. Allow abandoned leases to be matched 1496 here - if the client is requesting it, there's a decent chance 1497 that it's because the lease database got trashed and a client 1498 that thought it had this lease answered an ARP or PING, causing the 1499 lease to be abandoned. If so, this request probably came from 1500 that client. */ 1501 if (ip_lease && (ip_lease->shared_network != share)) { 1502 ip_lease = NULL; 1503 strlcpy(dhcp_message, "requested address on bad subnet", 1504 sizeof(dhcp_message)); 1505 } 1506 1507 /* Toss ip_lease if it hasn't yet expired and isn't owned by the 1508 client. */ 1509 if (ip_lease && ip_lease->ends >= cur_time && ip_lease != uid_lease) { 1510 int i = DHO_DHCP_CLIENT_IDENTIFIER; 1511 1512 /* Make sure that ip_lease actually belongs to the client, 1513 and toss it if not. */ 1514 if ((ip_lease->uid_len && packet->options[i].data && 1515 ip_lease->uid_len == packet->options[i].len && 1516 !memcmp(packet->options[i].data, ip_lease->uid, 1517 ip_lease->uid_len)) || 1518 (!ip_lease->uid_len && 1519 ip_lease->hardware_addr.htype == packet->raw->htype && 1520 ip_lease->hardware_addr.hlen == packet->raw->hlen && 1521 !memcmp(ip_lease->hardware_addr.haddr, packet->raw->chaddr, 1522 ip_lease->hardware_addr.hlen))) { 1523 if (uid_lease) { 1524 if (uid_lease->ends > cur_time) { 1525 warning("client %s has duplicate leases on %s", 1526 print_hw_addr(packet->raw->htype, 1527 packet->raw->hlen, packet->raw->chaddr), 1528 ip_lease->shared_network->name); 1529 1530 if (uid_lease && !packet->raw->ciaddr.s_addr) 1531 release_lease(uid_lease); 1532 } 1533 uid_lease = ip_lease; 1534 } 1535 } else { 1536 strlcpy(dhcp_message, "requested address is not available", 1537 sizeof(dhcp_message)); 1538 ip_lease = NULL; 1539 } 1540 1541 /* If we get to here and fixed_lease is not null, that means 1542 that there are both a dynamic lease and a fixed-address 1543 declaration for the same IP address. */ 1544 if (packet->packet_type == DHCPREQUEST && fixed_lease) { 1545 fixed_lease = NULL; 1546 db_conflict: 1547 warning("Both dynamic and static leases present for %s.", 1548 piaddr(cip)); 1549 warning("Either remove host declaration %s or remove %s", 1550 (fixed_lease && fixed_lease->host ? 1551 (fixed_lease->host->name ? fixed_lease->host->name : 1552 piaddr(cip)) : piaddr(cip)), piaddr(cip)); 1553 warning("from the dynamic address pool for %s", 1554 share->name); 1555 if (fixed_lease) 1556 ip_lease = NULL; 1557 strlcpy(dhcp_message, "database conflict - call for help!", 1558 sizeof(dhcp_message)); 1559 } 1560 } 1561 1562 /* If we get to here with both fixed_lease and ip_lease not 1563 null, then we have a configuration file bug. */ 1564 if (packet->packet_type == DHCPREQUEST && fixed_lease && ip_lease) 1565 goto db_conflict; 1566 1567 /* Toss hw_lease if it hasn't yet expired and the uid doesn't 1568 match, except that if the hardware address matches and the 1569 client is now doing dynamic BOOTP (and thus hasn't provided 1570 a uid) we let the client get away with it. */ 1571 if (hw_lease && hw_lease->ends >= cur_time && hw_lease->uid && 1572 packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len && 1573 hw_lease != uid_lease) 1574 hw_lease = NULL; 1575 1576 /* Toss extra pointers to the same lease... */ 1577 if (hw_lease == uid_lease) 1578 hw_lease = NULL; 1579 if (ip_lease == hw_lease) 1580 hw_lease = NULL; 1581 if (ip_lease == uid_lease) 1582 uid_lease = NULL; 1583 1584 /* If we've already eliminated the lease, it wasn't there to 1585 begin with. If we have come up with a matching lease, 1586 set the message to bad network in case we have to throw it out. */ 1587 if (!ip_lease) { 1588 strlcpy(dhcp_message, "requested address not available", 1589 sizeof(dhcp_message)); 1590 } 1591 1592 /* Now eliminate leases that are on the wrong network... */ 1593 if (ip_lease && share != ip_lease->shared_network) { 1594 if (packet->packet_type == DHCPREQUEST) 1595 release_lease(ip_lease); 1596 ip_lease = NULL; 1597 } 1598 if (uid_lease && share != uid_lease->shared_network) { 1599 if (packet->packet_type == DHCPREQUEST) 1600 release_lease(uid_lease); 1601 uid_lease = NULL; 1602 } 1603 if (hw_lease && share != hw_lease->shared_network) { 1604 if (packet->packet_type == DHCPREQUEST) 1605 release_lease(hw_lease); 1606 hw_lease = NULL; 1607 } 1608 1609 /* If this is a DHCPREQUEST, make sure the lease we're going to return 1610 matches the requested IP address. If it doesn't, don't return a 1611 lease at all. */ 1612 if (packet->packet_type == DHCPREQUEST && !ip_lease && !fixed_lease) 1613 return NULL; 1614 1615 /* At this point, if fixed_lease is nonzero, we can assign it to 1616 this client. */ 1617 if (fixed_lease) 1618 lease = fixed_lease; 1619 1620 /* If we got a lease that matched the ip address and don't have 1621 a better offer, use that; otherwise, release it. */ 1622 if (ip_lease) { 1623 if (lease) { 1624 if (packet->packet_type == DHCPREQUEST) 1625 release_lease(ip_lease); 1626 } else { 1627 lease = ip_lease; 1628 lease->host = NULL; 1629 } 1630 } 1631 1632 /* If we got a lease that matched the client identifier, we may want 1633 to use it, but if we already have a lease we like, we must free 1634 the lease that matched the client identifier. */ 1635 if (uid_lease) { 1636 if (lease) { 1637 if (packet->packet_type == DHCPREQUEST) 1638 release_lease(uid_lease); 1639 } else { 1640 lease = uid_lease; 1641 lease->host = NULL; 1642 } 1643 } 1644 1645 /* The lease that matched the hardware address is treated likewise. */ 1646 if (hw_lease) { 1647 if (lease) { 1648 if (packet->packet_type == DHCPREQUEST) 1649 release_lease(hw_lease); 1650 } else { 1651 lease = hw_lease; 1652 lease->host = NULL; 1653 } 1654 } 1655 1656 /* If we found a host_decl but no matching address, try to 1657 find a host_decl that has no address, and if there is one, 1658 hang it off the lease so that we can use the supplied 1659 options. */ 1660 if (lease && host && !lease->host) { 1661 for (; host; host = host->n_ipaddr) { 1662 if (!host->fixed_addr) { 1663 lease->host = host; 1664 break; 1665 } 1666 } 1667 } 1668 1669 /* If we find an abandoned lease, take it, but print a 1670 warning message, so that if it continues to lose, 1671 the administrator will eventually investigate. */ 1672 if (lease && (lease->flags & ABANDONED_LEASE)) { 1673 if (packet->packet_type == DHCPREQUEST) { 1674 warning("Reclaiming REQUESTed abandoned IP address %s.", 1675 piaddr(lease->ip_addr)); 1676 lease->flags &= ~ABANDONED_LEASE; 1677 } else 1678 lease = NULL; 1679 } 1680 return lease; 1681 } 1682 1683 /* 1684 * Search the provided host_decl structure list for an address that's on 1685 * the specified shared network. If one is found, mock up and return a 1686 * lease structure for it; otherwise return the null pointer. 1687 */ 1688 struct lease * 1689 mockup_lease(struct packet *packet, struct shared_network *share, 1690 struct host_decl *hp) 1691 { 1692 static struct lease mock; 1693 1694 mock.subnet = find_host_for_network(&hp, &mock.ip_addr, share); 1695 if (!mock.subnet) 1696 return (NULL); 1697 mock.next = mock.prev = NULL; 1698 mock.shared_network = mock.subnet->shared_network; 1699 mock.host = hp; 1700 1701 if (hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]) { 1702 mock.uid = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->value; 1703 mock.uid_len = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->len; 1704 } else { 1705 mock.uid = NULL; 1706 mock.uid_len = 0; 1707 } 1708 1709 mock.hardware_addr = hp->interface; 1710 mock.starts = mock.timestamp = mock.ends = MIN_TIME; 1711 mock.flags = STATIC_LEASE; 1712 return &mock; 1713 } 1714