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