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