README for Princeton Patch 12 July 5 2017 irwin at princeton dot edu This file accompanies Princeton Patch 12 to CMU-dhcpd 3.3.7; it describes how to apply the patch, and what has changed. After you have applied the patch, you no longer need this file, since the information in it also appears in the RELEASE_NOTES file which results from applying the patch. This patch (as well as the complete pre-patched current distribution) is available via: http://www.net.princeton.edu/software/dhcpd/ ========================================================================= UPDATING FROM PATCHLEVEL 11 The patch is against dhcpd version 3.3.7 as distributed by CMU, with Princeton patches 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, and 11 already applied. Assuming you have already applied the previous patches, you can apply this patch as follows: 0. Since this patch introduces new behavior as well as bug fixes, review the "WHAT'S CHANGED" section below before proceeding. 1. Make a record of any local customizations you have made to the product, such as changes you have made to 'Makefile' (or possibly 'Makefile.in') and 'defaults.h'. If you did customize either 'Makefile.in' or 'defaults.h' files, put the original version back to ensure the patch will apply cleanly. 2. Change to the directory containing the dhcpd source, and feed the patch file to the 'patch' program. (The 'patch' program is not supplied here; it is included with many operating systems, and is freely available from many software libraries.) E.g. using GNU patch: patch -p0 < CMU-dhcpd-3.3.7-PU-patch12 3. Run 'make distclean' to remove old object files, Makefiles and configuration info. 4. If you had previously customized any 'Makefile.in' files (as opposed to customizing any 'Makefile' files) , now's the time to re-apply your customizations if necessary. (You *did* make a record of them, right?) Most of the definitions that were once in Makefile.in moved in the past to defaults.h, so you may not need to make any changes to any 'Makefile.in' files at this time. Before re-apply any of your old customizations, first check to see if you can now accomplish what you need with a commandline option instead of a compile-time definition; most defaults and features that once required a compile-time definition can now be overridden using commandline options. Commandline options are covered in the in the dhcpd.8 man page. If you do change any 'Makefile.in' files, save the originals first, so you'll have clean copies available when it comes time to apply the next patch. 5. Run './configure' to figure out your system's configuration and generate new 'Makefile' files from the 'Makefile.in' files. 6. If you had previously customized any 'Makefile' files (as opposed to any 'Makefile.in' files), now's the time to re-apply your customizations. if necessary. (You *did* make a record of them, right?) Most of the definitions that were once in 'Makefile' files moved in the past to defaults.h, so you may not need to make any changes to 'Makefile' files at this time. Before re-apply any of your old customizations, first check to see if you can now accomplish what you need with a commandline option instead of a compile-time definition; most defaults and features that once required a compile-time definition can now be overridden using commandline options. Commandline options are covered in the dhcpd.8 man page. 7. Examine the 'defaults.h' file and customize it if necessary. This file now contains many of the definitions that previously lived in Makefile.in. Avoid changing items that can also be set using a commandline option. If you do change the 'defaults.h file, save the original first, so you'll have a clean copy available when it comes time to apply the next patch. 8. Run 'make' to compile the program. If you receive any compile-time errors, review the INSTALL document for tips. 9. Kill any running dhcpd, then install the new dhcpd executable. (It often lives in /etc/dhcpd or /usr/local/etc/dhcpd, but you may install it elsewhere.) You'll probably want to back up your old dhcpd executable before installing the new one. 10. Optionally install the new dhcpd.8, bootptab.5, dhcpd.conf.5, and dhcp-bindings-tool.8 man pages manually. 11. Optionally update any startup script you may use to take advantage of new commandline options added in this patch. 12. Optionally update your bootptab file to take advantage of new tags added in this patch. 13. Optionally update your dhcpd.conf file to take advantage of new configuration features added in this patch. 14. Start the new dhcpd executable. --------------------------------------------------------------------- BUILDING FROM SCRATCH You can get the current version of the source from http://www.net.princeton.edu/software/dhcpd/ Then see the INSTALL document for instructions. --------------------------------------------------------------------- PLATFORMS This code is currently in production at Princeton, but has NOT been tested extensively in all environments. In particular, I'm presently compiling and running on: Solaris 10 SPARC, with gcc 4.2.4 --------------------------------------------------------------------- WHAT'S CHANGED Changes since PU patch 11: ***IRWIN: SEE NOTE AT END** -- We were performing an extra level of backslash interpretation, apparently unintentionally. The code's comments indicate that the intent was that you may enter a literal backslash into a bootptab tag by escaping the backslash; for example: foo: .... :bf=foo\\bar.txt: But the extra level of backslash interpretation were causing both backslashes above to be removed, resulting in the server actually storing the value 'foobar.txt'. To store the value 'foo\bar.txt', you had to enter: foo: .... :bf=foo\\\\bar.txt: We have removed one level of backslash interpretation, so now you should enter the data as was originally intended, that is, as: foo: .... :bf=foo\\bar.txt: -- Support has been added for the WPAD option (option 252). The tag for this option is 'wp'. Although the specification for the WPAD option is that the value is a string, in practice it is common to include a NUL byte at the end. In support of the need to specify arbi trary binary values in this tag, we require you specify the wp tag as a hexadecimal string. For example, to specify the value http://192.168.0.1/foo followed by a newline and a NUL byte, specify the following in bootptab: wp=0x687474703a2f2f3139322e3136382e302e312f666f6f0a00 If you erroneously specify the wp tag as a string, we make no guarantees as to how the server will treat this value. -- Modified some existing log messages generated by processing DHCPREQUEST packets. These are some of the messages produced when the DHCP client is requesting something that doesn't make sense, for example, to renew a lease that has already expired. While the Client Identifier does already appear in the log (in an earlier message generated as we began parsing the request packet), we now also include the Client Identifier in the text of the log message reporting the unexpected condition. This is to make it easier to spot these when searching the log file for a Client Identifier. -- Modified the human-readable message sent in most DHCPNAK packets, to add the requested IP address. Reworded some of these messages. Because at some debuglevels, the human-readable message included in a DHCPNAK is logged while the server's own associated debug messages for the transaction are suppressed, this change can make it easier to understand (in such logs) what has transpired. In such cases, it also make it possible to spot these when searching the log file an IP address. -- Modified the handling for DHCPREQUEST when the client is in the INIT-REBOOT state. When the server already has an unexpired lease on IP address 'A' for this client, and the client requests a lease on a different IP address 'B', and IP address 'B' is one that is available and permitted for this client to lease, and the requested IP address is a dynamic (not static) IP address AND both the existing and dynamic IP addresses are appropriate for use on the network to which the client is presently attached, the server used to assume the client had abandoned the lease on IP address 'A'. The server would discard the binding on IP address 'A', and grant a new lease on IP address 'B'. This was a problem when the client is one that is broken in such a way that it is running multiple simultaneous DHCP client instances on the same interface with the same Client ID. In such cases (which seems to be the ones that get into this situation in the first place), the client continues using both IP addresses 'A' and 'B'. But the server has discarded the binding on IP address 'A'. The server's behavior has been changed. Now it will DHCPNAK the request for IP address 'B'. It will retain the binding for IP address 'A'. Note if IP address 'B' is a static IP address, the server still retains the old behavior. Retaining the old behavior in this case can lead to the problem described above. Despite that, we retain the old behavior because NAK'ing the client in this situation could interfere with the ability of a client to migrate from a dynamically-assigned IP address 'A' to a statically-assigned IP address 'B' when there are multiple DHCP servers. That is, the client may have obtained dynamically-assigned IP address 'A' from our server, then (due to a bootptab change) obtain a lease on statically-assigned IP address 'B' from another server. If the client enters INIT-REBOOT for lease B prior to lease A expiring, and our server were to DHCPNAK the client's request, that DHCPNAK could prevent the client from obtaining a lease on 'B' from another server. It makes sense to allow the client to obtain a lease on 'B' from another server, as our philosophy has always been to prefer that a client obtain a lease on a statically-assigned IP address rather than a dynamically-assigned IP address, when an appropriate statically-assigned IP address is available for the client. -- The log message dhcp_inform() not implemented, ignoring previously produced at debug levels > 1 is instead produced at debug levels > 3. -- Previously we intialized a socket for ICMP each time we needed to ping an IP address. Any error doing so was a soft failure causing us to skip PING. Now we initialize the socket once at daemon start time, and any error doing so as a hard failure. -- You may now tune the parameters dhcpd uses when it pings an dynamically-assigned IP address before sending a DHCPOFFER containing that IP address. There are new configuration file statements: # Before sending a DHCPOFFER containing a dynamically-allocated IP address, # how many times should we ping the IP address to verify it is not in-use? # Any response terminates the timeout and cancels any further tries. # Specifying 0 disables the ping attempt. # Default is 3. ping_offer_dynamic_tries 2 # When we perform each ping try specified by ping_off_dyn_tries, how long should we wait (at most) for a response # to each ping request? # Not used when ping_offer_dynamic_tries is 0. # Timeout is sum of ping_off_dyn_timeout_secs (seconds) + ping_off_dyn_timeout_us (microseconds). # Default is 0 seconds + 500000 microseconds (= 0.5 seconds). ping_offer_dynamic_timeout_secs 0 ping_offer_dynamic_timeout_us 400000 The default values (3 tries, 0.5 second timeout for each try) remain the same as in the past. -- The two-line message: ping says address is already in use: 192.168.10.11 ...will not try to assign this address was consolidated to: ping found IP address 192.168.10.11 in use; will not assign it -- When we receive a DHCPREQUEST from a client in SELECTING state specifying *our* Server Identifier, and the IP address requested by the client is not one we have offered to the client, and we have a binding for this client to a different IP address, we used to NAK the client and discard the existing binding we had for the client. We discarded the existing binding because the client has apparently abandoned the old binding; a client can't both be BOUND and SELECTING on the same network. But there are a number of badly broken DHCP client implementations which do exactly that, sending erroneous DHCPREQUEST in SELECTING state messages (for IP addresses which have expired, for example) at the same time these clients are also in BOUND, RENEWING, REBINDING, INIT, INIT-REBOOT and SELECTING states. Regardless of how we respond to these bogus SELECTING messages, these clients often continue to use the IP address they are presently bound to. So discarding the existing binding for these clients results in additional problems. We no longer discard the existing binding for those clients. We NAK the erroneous DHCPREQUEST in SELECTING state, but retain the existing binding. Upgraded from autoconf 2.65 to 2.69. Replaced install-sh version 2009-04-28.21 from automake 1.11.1 with version 2013-12-25.23 from automake 1.15. Replaced config.guess version 2009-11-20 from automake 1.11.1 with version 2014-11-04 from automake 1.15. Replaced config.sub version 2009-11-20 from automake 1.11.1 with version 2014-12-03 from automake 1.15. Replaced missing version 2009-04-28.21 from automake 1.11.1 with version 2013-10-28.13 from automake 1.15.