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