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