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