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