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