From 332084e62c18680e0bd1d2d0b36ecc62f2bdb99e Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 3 May 2016 09:00:10 +0200 Subject: [PATCH] Moved from SourceForge to Github --- .gitignore | 4 + CHANGELOG.md | 58 + README.md | 46 + config.ini | 9 + contrib/rfc1533.txt | 1683 +++++++++++ contrib/rfc2131.txt | 2523 +++++++++++++++++ pom.xml | 61 + .../edu/bucknell/net/JDHCP/DHCPMessage.java | 876 ++++++ .../edu/bucknell/net/JDHCP/DHCPOptions.java | 232 ++ .../edu/bucknell/net/JDHCP/DHCPSocket.java | 106 + .../java/eu/fraho/jdhcpd/Application.java | 642 +++++ src/main/java/eu/fraho/jdhcpd/Gui.java | 168 ++ src/main/java/eu/fraho/jdhcpd/IniParser.java | 357 +++ src/main/java/eu/fraho/jdhcpd/MyThread.java | 122 + src/main/java/eu/fraho/jdhcpd/Server.java | 825 ++++++ src/main/java/eu/fraho/jdhcpd/Tools.java | 344 +++ 16 files changed, 8056 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 config.ini create mode 100644 contrib/rfc1533.txt create mode 100644 contrib/rfc2131.txt create mode 100644 pom.xml create mode 100644 src/main/java/edu/bucknell/net/JDHCP/DHCPMessage.java create mode 100644 src/main/java/edu/bucknell/net/JDHCP/DHCPOptions.java create mode 100644 src/main/java/edu/bucknell/net/JDHCP/DHCPSocket.java create mode 100644 src/main/java/eu/fraho/jdhcpd/Application.java create mode 100644 src/main/java/eu/fraho/jdhcpd/Gui.java create mode 100644 src/main/java/eu/fraho/jdhcpd/IniParser.java create mode 100644 src/main/java/eu/fraho/jdhcpd/MyThread.java create mode 100644 src/main/java/eu/fraho/jdhcpd/Server.java create mode 100644 src/main/java/eu/fraho/jdhcpd/Tools.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34f9ada --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.classpath +.project +.settings/ +target/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2f31779 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,58 @@ +Release history and changes of JDHCPD +=========================================== + +0.10 (2010-05-09) + - Added an option to serve one or more dns server + - Moved some parts from the Application class into the Server class + - Changed some comments in the classes to remove some warnings + - Removed the stupid version number from the classes + (I always forget to increment them) + - The hostname is now displayed if sent in an request + - Updated the README file to explain all possible settings inside the + config.ini file + + +0.9 (2010-04-28) + - Completed the list of DHCP-Options + - Included the important RFCs which define the protocol + - Removed some redundancy in the server + + +0.8 (2010-04-21) + - Changed the visility of some inner classes from Server + - Moved some methods from Server to the Tools class + - User interface parts separated to a new class + - Some commands printed their messages only to the console + and ignored the gui + - Bugfix: A NullPointerException killed the server if a requested + ip adress is out of the defined range + - Bugfix: Bug mentioned in v0.7 finally fixed and tested + + +0.7 (2010-04-19) + - Updated the comments + - Sorted the source code + - Improved the GUI + - Bugfix: If an offered ip-adress is already in use, the client + responded with a DHCPNACK message, which was not handeled. + So the same (invalid) ip adress was offered as often as the + client asked for one. + Need further tests to confirm fix! + - Replaced JDialog by a JFrame, now it is displayed in the taskbar + + +0.6 (2010-03-16) + - Created the CHANGELOG file + - Completed the javadoc comments in all classes + - Replaced the german console help, so the complete project + is now written in english + - Notified messages from the server are now written synchronized + to the console + - Removed an unused method from the Tools class + - Changed socket timeout to 1 second so it responds faster + - Implemented a very simple gui, currently only displays the log. + Can be disabled via the parameter --nogui. + + +0.5 (2010-03-15) + - Initial release on sourceforge.net diff --git a/README.md b/README.md new file mode 100644 index 0000000..50b8af4 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +This project provides a lightweight, simple and easy to use +DHCP server written in 100% java code. + +It can be configured either via the config.ini file or +live via console. +Currently it is just an simple tool to provide IP-Adresses +in a given range and a subnet. + +This project was started as i realized that there was no free and +easy to use dhcp server for windows that i can use at my lan-partys. +A sample config.ini is present which distribute ip adresses from +192.168.0.20 to 192.168.0.200 in a class C net (255.255.255.0) + +The project is hosted an sourceforge and can be found via the +following url: http://sourceforge.net/projects/jdhcpd/ + +You can contact me via the service provided by sourceforge.net + +The config.ini is a simple textfile, which is used to configure +the server. It contains only one section (the "global" section) +and provides the following options: + +renewal_time: + When the client should try to renew the lease. Defined in seconds. + default: 77760 +lease_time: + How long the lease is valid. Defined in seconds. + default: 86400 + +server_ip: + Defines which ip-adress the server got. + default: 192.168.0.1 +first_ip: + The first ip to provide to the clients. + default: 192.168.0.20 +last_ip: + The last ip to provide to the clients. + default: 192.168.0.200 +netmask: + The netmask of this network. CIDR notation is NOT allowed. + default: 255.255.255.0 +dns_servers: + A list of DNS-Servers responsible for this network. Each IP is + separated by a space. + default: 192.168.0.1 + diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..0edd0cf --- /dev/null +++ b/config.ini @@ -0,0 +1,9 @@ +[global] +lease_time=86400 +last_ip=192.168.0.200 +server_ip=192.168.0.1 +first_ip=192.168.0.20 +netmask=255.255.255.0 +renewal_time=77760 +dns_servers=192.168.0.1 + diff --git a/contrib/rfc1533.txt b/contrib/rfc1533.txt new file mode 100644 index 0000000..3967778 --- /dev/null +++ b/contrib/rfc1533.txt @@ -0,0 +1,1683 @@ + + + + + + +Network Working Group S. Alexander +Request for Comments: 1533 Lachman Technology, Inc. +Obsoletes: 1497, 1395, 1084, 1048 R. Droms +Category: Standards Track Bucknell University + October 1993 + + + DHCP Options and BOOTP Vendor Extensions + +Status of this Memo + + This RFC specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" for the standardization state and status + of this protocol. Distribution of this memo is unlimited. + +Abstract + + The Dynamic Host Configuration Protocol (DHCP) [1] provides a + framework for passing configuration information to hosts on a TCP/IP + network. Configuration parameters and other control information are + carried in tagged data items that are stored in the "options" field + of the DHCP message. The data items themselves are also called + "options." + + This document specifies the current set of DHCP options. This + document will be periodically updated as new options are defined. + Each superseding document will include the entire current list of + valid options. + + All of the vendor information extensions defined in RFC 1497 [2] may + be used as DHCP options. The definitions given in RFC 1497 are + included in this document, which supersedes RFC 1497. All of the + DHCP options defined in this document, except for those specific to + DHCP as defined in section 9, may be used as BOOTP vendor information + extensions. + +Table of Contents + + 1. Introduction .............................................. 2 + 2. BOOTP Extension/DHCP Option Field Format .................. 2 + 3. RFC 1497 Vendor Extensions ................................ 3 + 4. IP Layer Parameters per Host .............................. 10 + 5. IP Layer Parameters per Interface ........................ 13 + 6. Link Layer Parameters per Interface ....................... 16 + 7. TCP Parameters ............................................ 17 + 8. Application and Service Parameters ........................ 18 + + + +Alexander & Droms [Page 1] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + 9. DHCP Extensions ........................................... 23 + 10. Extensions ................................................ 27 + 11. Acknowledgements .......................................... 28 + 12. References ................................................ 28 + 13. Security Considerations ................................... 19 + 14. Authors' Addresses ........................................ 30 + +1. Introduction + + This document specifies options for use with both the Dynamic Host + Configuration Protocol and the Bootstrap Protocol. + + The full description of DHCP packet formats may be found in the DHCP + specification document [1], and the full description of BOOTP packet + formats may be found in the BOOTP specification document [3]. This + document defines the format of information in the last field of DHCP + packets ('options') and of BOOTP packets ('vend'). The remainder of + this section defines a generalized use of this area for giving + information useful to a wide class of machines, operating systems and + configurations. Sites with a single DHCP or BOOTP server that is + shared among heterogeneous clients may choose to define other, site- + specific formats for the use of the 'options' field. + + Section 2 of this memo describes the formats of DHCP options and + BOOTP vendor extensions. Section 3 describes options defined in + previous documents for use with BOOTP (all may also be used with + DHCP). Sections 4-8 define new options intended for use with both + DHCP and BOOTP. Section 9 defines options used only in DHCP. + + References further describing most of the options defined in sections + 2-6 can be found in section 12. The use of the options defined in + section 9 is described in the DHCP specification [1]. + + Information on registering new options is contained in section 10. + +2. BOOTP Extension/DHCP Option Field Format + + DHCP options have the same format as the BOOTP "vendor extensions" + defined in RFC 1497 [2]. Options may be fixed length or variable + length. All options begin with a tag octet, which uniquely + identifies the option. Fixed-length options without data consist of + only a tag octet. Only options 0 and 255 are fixed length. All + other options are variable-length with a length octet following the + tag octet. The value of the length octet does not include the two + octets specifying the tag and length. The length octet is followed + by "length" octets of data. In the case of some variable-length + options the length field is a constant but must still be specified. + + + + +Alexander & Droms [Page 2] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + Any options defined subsequent to this document should contain a + length octet even if the length is fixed or zero. + + All multi-octet quantities are in network byte-order. + + When used with BOOTP, the first four octets of the vendor information + field have been assigned to the "magic cookie" (as suggested in RFC + 951). This field identifies the mode in which the succeeding data is + to be interpreted. The value of the magic cookie is the 4 octet + dotted decimal 99.130.83.99 (or hexadecimal number 63.82.53.63) in + network byte order. + + All of the "vendor extensions" defined in RFC 1497 are also DHCP + options. + + Option codes 128 to 254 (decimal) are reserved for site-specific + options. + + Except for the options in section 9, all options may be used with + either DHCP or BOOTP. + + Many of these options have their default values specified in other + documents. In particular, RFC 1122 [4] specifies default values for + most IP and TCP configuration parameters. + +3. RFC 1497 Vendor Extensions + + This section lists the vendor extensions as defined in RFC 1497. + They are defined here for completeness. + +3.1. Pad Option + + The pad option can be used to cause subsequent fields to align on + word boundaries. + + The code for the pad option is 0, and its length is 1 octet. + + Code + +-----+ + | 0 | + +-----+ + + + + + + + + + + +Alexander & Droms [Page 3] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.2. End Option + + The end option marks the end of valid information in the vendor + field. Subsequent octets should be filled with pad options. + + The code for the end option is 255, and its length is 1 octet. + + Code + +-----+ + | 255 | + +-----+ + +3.3. Subnet Mask + + The subnet mask option specifies the client's subnet mask as per RFC + 950 [5]. + + If both the subnet mask and the router option are specified in a DHCP + reply, the subnet mask option MUST be first. + + The code for the subnet mask option is 1, and its length is 4 octets. + + Code Len Subnet Mask + +-----+-----+-----+-----+-----+-----+ + | 1 | 4 | m1 | m2 | m3 | m4 | + +-----+-----+-----+-----+-----+-----+ + +3.4. Time Offset + + The time offset field specifies the offset of the client's subnet in + seconds from Coordinated Universal Time (UTC). The offset is + expressed as a signed 32-bit integer. + + The code for the time offset option is 2, and its length is 4 octets. + + Code Len Time Offset + +-----+-----+-----+-----+-----+-----+ + | 2 | 4 | n1 | n2 | n3 | n4 | + +-----+-----+-----+-----+-----+-----+ + + + + + + + + + + + + +Alexander & Droms [Page 4] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.5. Router Option + + The router option specifies a list of IP addresses for routers on the + client's subnet. Routers SHOULD be listed in order of preference. + + The code for the router option is 3. The minimum length for the + router option is 4 octets, and the length MUST always be a multiple + of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 3 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.6. Time Server Option + + The time server option specifies a list of RFC 868 [6] time servers + available to the client. Servers SHOULD be listed in order of + preference. + + The code for the time server option is 4. The minimum length for + this option is 4 octets, and the length MUST always be a multiple of + 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 4 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.7. Name Server Option + + The name server option specifies a list of IEN 116 [7] name servers + available to the client. Servers SHOULD be listed in order of + preference. + + The code for the name server option is 5. The minimum length for + this option is 4 octets, and the length MUST always be a multiple of + 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 5 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + + + + + + + + +Alexander & Droms [Page 5] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.8. Domain Name Server Option + + The domain name server option specifies a list of Domain Name System + (STD 13, RFC 1035 [8]) name servers available to the client. Servers + SHOULD be listed in order of preference. + + The code for the domain name server option is 6. The minimum length + for this option is 4 octets, and the length MUST always be a multiple + of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.9. Log Server Option + + The log server option specifies a list of MIT-LCS UDP log servers + available to the client. Servers SHOULD be listed in order of + preference. + + The code for the log server option is 7. The minimum length for this + option is 4 octets, and the length MUST always be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 7 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.10. Cookie Server Option + + The cookie server option specifies a list of RFC 865 [9] cookie + servers available to the client. Servers SHOULD be listed in order + of preference. + + The code for the log server option is 8. The minimum length for this + option is 4 octets, and the length MUST always be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 8 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + + + + + + + + + +Alexander & Droms [Page 6] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.11. LPR Server Option + + The LPR server option specifies a list of RFC 1179 [10] line printer + servers available to the client. Servers SHOULD be listed in order + of preference. + + The code for the LPR server option is 9. The minimum length for this + option is 4 octets, and the length MUST always be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 9 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.12. Impress Server Option + + The Impress server option specifies a list of Imagen Impress servers + available to the client. Servers SHOULD be listed in order of + preference. + + The code for the Impress server option is 10. The minimum length for + this option is 4 octets, and the length MUST always be a multiple of + 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 10 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.13. Resource Location Server Option + + This option specifies a list of RFC 887 [11] Resource Location + servers available to the client. Servers SHOULD be listed in order + of preference. + + The code for this option is 11. The minimum length for this option + is 4 octets, and the length MUST always be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 11 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + + + + + + + + + +Alexander & Droms [Page 7] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.14. Host Name Option + + This option specifies the name of the client. The name may or may + not be qualified with the local domain name (see section 3.17 for the + preferred way to retrieve the domain name). See RFC 1035 for + character set restrictions. + + The code for this option is 12, and its minimum length is 1. + + Code Len Host Name + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +3.15. Boot File Size Option + + This option specifies the length in 512-octet blocks of the default + boot image for the client. The file length is specified as an + unsigned 16-bit integer. + + The code for this option is 13, and its length is 2. + + Code Len File Size + +-----+-----+-----+-----+ + | 13 | 2 | l1 | l2 | + +-----+-----+-----+-----+ + +3.16. Merit Dump File + + This option specifies the path-name of a file to which the client's + core image should be dumped in the event the client crashes. The + path is formatted as a character string consisting of characters from + the NVT ASCII character set. + + The code for this option is 14. Its minimum length is 1. + + Code Len Dump File Pathname + +-----+-----+-----+-----+-----+-----+--- + | 14 | n | n1 | n2 | n3 | n4 | ... + +-----+-----+-----+-----+-----+-----+--- + + + + + + + + + + + +Alexander & Droms [Page 8] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.17. Domain Name + + This option specifies the domain name that client should use when + resolving hostnames via the Domain Name System. + + The code for this option is 15. Its minimum length is 1. + + Code Len Domain Name + +-----+-----+-----+-----+-----+-----+-- + | 15 | n | d1 | d2 | d3 | d4 | ... + +-----+-----+-----+-----+-----+-----+-- + +3.18. Swap Server + + This specifies the IP address of the client's swap server. + + The code for this option is 16 and its length is 4. + + Code Len Swap Server Address + +-----+-----+-----+-----+-----+-----+ + | 16 | n | a1 | a2 | a3 | a4 | + +-----+-----+-----+-----+-----+-----+ + +3.19. Root Path + + This option specifies the path-name that contains the client's root + disk. The path is formatted as a character string consisting of + characters from the NVT ASCII character set. + + The code for this option is 17. Its minimum length is 1. + + Code Len Root Disk Pathname + +-----+-----+-----+-----+-----+-----+--- + | 17 | n | n1 | n2 | n3 | n4 | ... + +-----+-----+-----+-----+-----+-----+--- + + + + + + + + + + + + + + + + +Alexander & Droms [Page 9] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +3.20. Extensions Path + + A string to specify a file, retrievable via TFTP, which contains + information which can be interpreted in the same way as the 64-octet + vendor-extension field within the BOOTP response, with the following + exceptions: + + - the length of the file is unconstrained; + - all references to Tag 18 (i.e., instances of the + BOOTP Extensions Path field) within the file are + ignored. + + The code for this option is 18. Its minimum length is 1. + + Code Len Extensions Pathname + +-----+-----+-----+-----+-----+-----+--- + | 18 | n | n1 | n2 | n3 | n4 | ... + +-----+-----+-----+-----+-----+-----+--- + +4. IP Layer Parameters per Host + + This section details the options that affect the operation of the IP + layer on a per-host basis. + +4.1. IP Forwarding Enable/Disable Option + + This option specifies whether the client should configure its IP + layer for packet forwarding. A value of 0 means disable IP + forwarding, and a value of 1 means enable IP forwarding. + + The code for this option is 19, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 19 | 1 | 0/1 | + +-----+-----+-----+ + + + + + + + + + + + + + + + +Alexander & Droms [Page 10] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +4.2. Non-Local Source Routing Enable/Disable Option + + This option specifies whether the client should configure its IP + layer to allow forwarding of datagrams with non-local source routes + (see Section 3.3.5 of [4] for a discussion of this topic). A value + of 0 means disallow forwarding of such datagrams, and a value of 1 + means allow forwarding. + + The code for this option is 20, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 20 | 1 | 0/1 | + +-----+-----+-----+ + +4.3. Policy Filter Option + + This option specifies policy filters for non-local source routing. + The filters consist of a list of IP addresses and masks which specify + destination/mask pairs with which to filter incoming source routes. + + Any source routed datagram whose next-hop address does not match one + of the filters should be discarded by the client. + + See [4] for further information. + + The code for this option is 21. The minimum length of this option is + 8, and the length MUST be a multiple of 8. + + Code Len Address 1 Mask 1 + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ + | 21 | n | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 | + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ + Address 2 Mask 2 + +-----+-----+-----+-----+-----+-----+-----+-----+--- + | a1 | a2 | a3 | a4 | m1 | m2 | m3 | m4 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+--- + + + + + + + + + + + + + + +Alexander & Droms [Page 11] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +4.4. Maximum Datagram Reassembly Size + + This option specifies the maximum size datagram that the client + should be prepared to reassemble. The size is specified as a 16-bit + unsigned integer. The minimum value legal value is 576. + + The code for this option is 22, and its length is 2. + + Code Len Size + +-----+-----+-----+-----+ + | 22 | 2 | s1 | s2 | + +-----+-----+-----+-----+ + +4.5. Default IP Time-to-live + + This option specifies the default time-to-live that the client should + use on outgoing datagrams. The TTL is specified as an octet with a + value between 1 and 255. + + The code for this option is 23, and its length is 1. + + Code Len TTL + +-----+-----+-----+ + | 23 | 1 | ttl | + +-----+-----+-----+ + +4.6. Path MTU Aging Timeout Option + + This option specifies the timeout (in seconds) to use when aging Path + MTU values discovered by the mechanism defined in RFC 1191 [12]. The + timeout is specified as a 32-bit unsigned integer. + + The code for this option is 24, and its length is 4. + + Code Len Timeout + +-----+-----+-----+-----+-----+-----+ + | 24 | 4 | t1 | t2 | t3 | t4 | + +-----+-----+-----+-----+-----+-----+ + + + + + + + + + + + + + +Alexander & Droms [Page 12] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +4.7. Path MTU Plateau Table Option + + This option specifies a table of MTU sizes to use when performing + Path MTU Discovery as defined in RFC 1191. The table is formatted as + a list of 16-bit unsigned integers, ordered from smallest to largest. + The minimum MTU value cannot be smaller than 68. + + The code for this option is 25. Its minimum length is 2, and the + length MUST be a multiple of 2. + + Code Len Size 1 Size 2 + +-----+-----+-----+-----+-----+-----+--- + | 25 | n | s1 | s2 | s1 | s2 | ... + +-----+-----+-----+-----+-----+-----+--- + +5. IP Layer Parameters per Interface + + This section details the options that affect the operation of the IP + layer on a per-interface basis. It is expected that a client can + issue multiple requests, one per interface, in order to configure + interfaces with their specific parameters. + +5.1. Interface MTU Option + + This option specifies the MTU to use on this interface. The MTU is + specified as a 16-bit unsigned integer. The minimum legal value for + the MTU is 68. + + The code for this option is 26, and its length is 2. + + Code Len MTU + +-----+-----+-----+-----+ + | 26 | 2 | m1 | m2 | + +-----+-----+-----+-----+ + + + + + + + + + + + + + + + + + +Alexander & Droms [Page 13] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +5.2. All Subnets are Local Option + + This option specifies whether or not the client may assume that all + subnets of the IP network to which the client is connected use the + same MTU as the subnet of that network to which the client is + directly connected. A value of 1 indicates that all subnets share + the same MTU. A value of 0 means that the client should assume that + some subnets of the directly connected network may have smaller MTUs. + + The code for this option is 27, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 27 | 1 | 0/1 | + +-----+-----+-----+ + +5.3. Broadcast Address Option + + This option specifies the broadcast address in use on the client's + subnet. Legal values for broadcast addresses are specified in + section 3.2.1.3 of [4]. + + The code for this option is 28, and its length is 4. + + Code Len Broadcast Address + +-----+-----+-----+-----+-----+-----+ + | 28 | 4 | b1 | b2 | b3 | b4 | + +-----+-----+-----+-----+-----+-----+ + +5.4. Perform Mask Discovery Option + + This option specifies whether or not the client should perform subnet + mask discovery using ICMP. A value of 0 indicates that the client + should not perform mask discovery. A value of 1 means that the + client should perform mask discovery. + + The code for this option is 29, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 29 | 1 | 0/1 | + +-----+-----+-----+ + + + + + + + + + +Alexander & Droms [Page 14] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +5.5. Mask Supplier Option + + This option specifies whether or not the client should respond to + subnet mask requests using ICMP. A value of 0 indicates that the + client should not respond. A value of 1 means that the client should + respond. + + The code for this option is 30, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 30 | 1 | 0/1 | + +-----+-----+-----+ + +5.6. Perform Router Discovery Option + + This option specifies whether or not the client should solicit + routers using the Router Discovery mechanism defined in RFC 1256 + [13]. A value of 0 indicates that the client should not perform + router discovery. A value of 1 means that the client should perform + router discovery. + + The code for this option is 31, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 31 | 1 | 0/1 | + +-----+-----+-----+ + +5.7. Router Solicitation Address Option + + This option specifies the address to which the client should transmit + router solicitation requests. + + The code for this option is 32, and its length is 4. + + Code Len Address + +-----+-----+-----+-----+-----+-----+ + | 32 | 4 | a1 | a2 | a3 | a4 | + +-----+-----+-----+-----+-----+-----+ + + + + + + + + + + + +Alexander & Droms [Page 15] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +5.8. Static Route Option + + This option specifies a list of static routes that the client should + install in its routing cache. If multiple routes to the same + destination are specified, they are listed in descending order of + priority. + + The routes consist of a list of IP address pairs. The first address + is the destination address, and the second address is the router for + the destination. + + The default route (0.0.0.0) is an illegal destination for a static + route. See section 3.5 for information about the router option. + + The code for this option is 33. The minimum length of this option is + 8, and the length MUST be a multiple of 8. + + Code Len Destination 1 Router 1 + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ + | 33 | n | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 | + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ + Destination 2 Router 2 + +-----+-----+-----+-----+-----+-----+-----+-----+--- + | d1 | d2 | d3 | d4 | r1 | r2 | r3 | r4 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+--- + +6. Link Layer Parameters per Interface + + This section lists the options that affect the operation of the data + link layer on a per-interface basis. + +6.1. Trailer Encapsulation Option + + This option specifies whether or not the client should negotiate the + use of trailers (RFC 893 [14]) when using the ARP protocol. A value + of 0 indicates that the client should not attempt to use trailers. A + value of 1 means that the client should attempt to use trailers. + + The code for this option is 34, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 34 | 1 | 0/1 | + +-----+-----+-----+ + + + + + + + +Alexander & Droms [Page 16] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +6.2. ARP Cache Timeout Option + + This option specifies the timeout in seconds for ARP cache entries. + The time is specified as a 32-bit unsigned integer. + + The code for this option is 35, and its length is 4. + + Code Len Time + +-----+-----+-----+-----+-----+-----+ + | 35 | 4 | t1 | t2 | t3 | t4 | + +-----+-----+-----+-----+-----+-----+ + +6.3. Ethernet Encapsulation Option + + This option specifies whether or not the client should use Ethernet + Version 2 (RFC 894 [15]) or IEEE 802.3 (RFC 1042 [16]) encapsulation + if the interface is an Ethernet. A value of 0 indicates that the + client should use RFC 894 encapsulation. A value of 1 means that the + client should use RFC 1042 encapsulation. + + The code for this option is 36, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 36 | 1 | 0/1 | + +-----+-----+-----+ + +7. TCP Parameters + + This section lists the options that affect the operation of the TCP + layer on a per-interface basis. + +7.1. TCP Default TTL Option + + This option specifies the default TTL that the client should use when + sending TCP segments. The value is represented as an 8-bit unsigned + integer. The minimum value is 1. + + The code for this option is 37, and its length is 1. + + Code Len TTL + +-----+-----+-----+ + | 37 | 1 | n | + +-----+-----+-----+ + + + + + + + +Alexander & Droms [Page 17] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +7.2. TCP Keepalive Interval Option + + This option specifies the interval (in seconds) that the client TCP + should wait before sending a keepalive message on a TCP connection. + The time is specified as a 32-bit unsigned integer. A value of zero + indicates that the client should not generate keepalive messages on + connections unless specifically requested by an application. + + The code for this option is 38, and its length is 4. + + Code Len Time + +-----+-----+-----+-----+-----+-----+ + | 38 | 4 | t1 | t2 | t3 | t4 | + +-----+-----+-----+-----+-----+-----+ + +7.3. TCP Keepalive Garbage Option + + This option specifies the whether or not the client should send TCP + keepalive messages with a octet of garbage for compatibility with + older implementations. A value of 0 indicates that a garbage octet + should not be sent. A value of 1 indicates that a garbage octet + should be sent. + + The code for this option is 39, and its length is 1. + + Code Len Value + +-----+-----+-----+ + | 39 | 1 | 0/1 | + +-----+-----+-----+ + +8. Application and Service Parameters + + This section details some miscellaneous options used to configure + miscellaneous applications and services. + +8.1. Network Information Service Domain Option + + This option specifies the name of the client's NIS [17] domain. The + domain is formatted as a character string consisting of characters + from the NVT ASCII character set. + + The code for this option is 40. Its minimum length is 1. + + Code Len NIS Domain Name + +-----+-----+-----+-----+-----+-----+--- + | 40 | n | n1 | n2 | n3 | n4 | ... + +-----+-----+-----+-----+-----+-----+--- + + + + +Alexander & Droms [Page 18] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +8.2. Network Information Servers Option + + This option specifies a list of IP addresses indicating NIS servers + available to the client. Servers SHOULD be listed in order of + preference. + + The code for this option is 41. Its minimum length is 4, and the + length MUST be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 41 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +8.3. Network Time Protocol Servers Option + + This option specifies a list of IP addresses indicating NTP [18] + servers available to the client. Servers SHOULD be listed in order + of preference. + + The code for this option is 42. Its minimum length is 4, and the + length MUST be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-- + | 42 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-- + +8.4. Vendor Specific Information + + This option is used by clients and servers to exchange vendor- + specific information. The information is an opaque object of n + octets, presumably interpreted by vendor-specific code on the clients + and servers. The definition of this information is vendor specific. + The vendor is indicated in the class-identifier option. Servers not + equipped to interpret the vendor-specific information sent by a + client MUST ignore it (although it may be reported). Clients which + do not receive desired vendor-specific information SHOULD make an + attempt to operate without it, although they may do so (and announce + they are doing so) in a degraded mode. + + If a vendor potentially encodes more than one item of information in + this option, then the vendor SHOULD encode the option using + "Encapsulated vendor-specific options" as described below: + + The Encapsulated vendor-specific options field SHOULD be encoded as a + sequence of code/length/value fields of identical syntax to the DHCP + options field with the following exceptions: + + + +Alexander & Droms [Page 19] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + 1) There SHOULD NOT be a "magic cookie" field in the encapsulated + vendor-specific extensions field. + + 2) Codes other than 0 or 255 MAY be redefined by the vendor within + the encapsulated vendor-specific extensions field, but SHOULD + conform to the tag-length-value syntax defined in section 2. + + 3) Code 255 (END), if present, signifies the end of the + encapsulated vendor extensions, not the end of the vendor + extensions field. If no code 255 is present, then the end of + the enclosing vendor-specific information field is taken as the + end of the encapsulated vendor-specific extensions field. + + The code for this option is 43 and its minimum length is 1. + + Code Len Vendor-specific information + +-----+-----+-----+-----+--- + | 43 | n | i1 | i2 | ... + +-----+-----+-----+-----+--- + + When encapsulated vendor-specific extensions are used, the + information bytes 1-n have the following format: + + Code Len Data item Code Len Data item Code + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ + | T1 | n | d1 | d2 | ... | T2 | n | D1 | D2 | ... | ... | + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ + +8.5. NetBIOS over TCP/IP Name Server Option + + The NetBIOS name server (NBNS) option specifies a list of RFC + 1001/1002 [19] [20] NBNS name servers listed in order of preference. + + The code for this option is 44. The minimum length of the option is + 4 octets, and the length must always be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + | 44 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + + + + + + + + + + + +Alexander & Droms [Page 20] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +8.6. NetBIOS over TCP/IP Datagram Distribution Server Option + + The NetBIOS datagram distribution server (NBDD) option specifies a + list of RFC 1001/1002 NBDD servers listed in order of preference. The + code for this option is 45. The minimum length of the option is 4 + octets, and the length must always be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + | 45 | n | a1 | a2 | a3 | a4 | b1 | b2 | b3 | b4 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + +8.7. NetBIOS over TCP/IP Node Type Option + + The NetBIOS node type option allows NetBIOS over TCP/IP clients which + are configurable to be configured as described in RFC 1001/1002. The + value is specified as a single octet which identifies the client type + as follows: + + Value Node Type + ----- --------- + 0x1 B-node + 0x2 P-node + 0x4 M-node + 0x8 H-node + + In the above chart, the notation '0x' indicates a number in base-16 + (hexadecimal). + + The code for this option is 46. The length of this option is always + 1. + + Code Len Node Type + +-----+-----+-----------+ + | 46 | 1 | see above | + +-----+-----+-----------+ + + + + + + + + + + + + + + + +Alexander & Droms [Page 21] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +8.8. NetBIOS over TCP/IP Scope Option + + The NetBIOS scope option specifies the NetBIOS over TCP/IP scope + parameter for the client as specified in RFC 1001/1002. See [19], + [20], and [8] for character-set restrictions. + + The code for this option is 47. The minimum length of this option is + 1. + + Code Len NetBIOS Scope + +-----+-----+-----+-----+-----+-----+---- + | 47 | n | s1 | s2 | s3 | s4 | ... + +-----+-----+-----+-----+-----+-----+---- + +8.9. X Window System Font Server Option + + This option specifies a list of X Window System [21] Font servers + available to the client. Servers SHOULD be listed in order of + preference. + + The code for this option is 48. The minimum length of this option is + 4 octets, and the length MUST be a multiple of 4. + + Code Len Address 1 Address 2 + +-----+-----+-----+-----+-----+-----+-----+-----+--- + | 48 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+--- + +8.10. X Window System Display Manager Option + + This option specifies a list of IP addresses of systems that are + running the X Window System Display Manager and are available to the + client. + + Addresses SHOULD be listed in order of preference. + + The code for the this option is 49. The minimum length of this option + is 4, and the length MUST be a multiple of 4. + + Code Len Address 1 Address 2 + + +-----+-----+-----+-----+-----+-----+-----+-----+--- + | 49 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... + +-----+-----+-----+-----+-----+-----+-----+-----+--- + + + + + + + +Alexander & Droms [Page 22] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +9. DHCP Extensions + + This section details the options that are specific to DHCP. + +9.1. Requested IP Address + + This option is used in a client request (DHCPDISCOVER) to allow the + client to request that a particular IP address be assigned. + + The code for this option is 50, and its length is 4. + + Code Len Address + +-----+-----+-----+-----+-----+-----+ + | 50 | 4 | a1 | a2 | a3 | a4 | + +-----+-----+-----+-----+-----+-----+ + +9.2. IP Address Lease Time + + This option is used in a client request (DHCPDISCOVER or DHCPREQUEST) + to allow the client to request a lease time for the IP address. In a + server reply (DHCPOFFER), a DHCP server uses this option to specify + the lease time it is willing to offer. + + The time is in units of seconds, and is specified as a 32-bit + unsigned integer. + + The code for this option is 51, and its length is 4. + + Code Len Lease Time + +-----+-----+-----+-----+-----+-----+ + | 51 | 4 | t1 | t2 | t3 | t4 | + +-----+-----+-----+-----+-----+-----+ + +9.3. Option Overload + + This option is used to indicate that the DHCP "sname" or "file" + fields are being overloaded by using them to carry DHCP options. A + DHCP server inserts this option if the returned parameters will + exceed the usual space allotted for options. + + If this option is present, the client interprets the specified + additional fields after it concludes interpretation of the standard + option fields. + + The code for this option is 52, and its length is 1. Legal values + for this option are: + + + + + +Alexander & Droms [Page 23] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + Value Meaning + ----- -------- + 1 the "file" field is used to hold options + 2 the "sname" field is used to hold options + 3 both fields are used to hold options + + Code Len Value + +-----+-----+-----+ + | 52 | 1 |1/2/3| + +-----+-----+-----+ + +9.4. DHCP Message Type + + This option is used to convey the type of the DHCP message. The code + for this option is 53, and its length is 1. Legal values for this + option are: + + Value Message Type + ----- ------------ + 1 DHCPDISCOVER + 2 DHCPOFFER + 3 DHCPREQUEST + 4 DHCPDECLINE + 5 DHCPACK + 6 DHCPNAK + 7 DHCPRELEASE + + Code Len Type + +-----+-----+-----+ + | 53 | 1 | 1-7 | + +-----+-----+-----+ + +9.5. Server Identifier + + This option is used in DHCPOFFER and DHCPREQUEST messages, and may + optionally be included in the DHCPACK and DHCPNAK messages. DHCP + servers include this option in the DHCPOFFER in order to allow the + client to distinguish between lease offers. DHCP clients indicate + which of several lease offers is being accepted by including this + option in a DHCPREQUEST message. + + The identifier is the IP address of the selected server. + + + + + + + + + +Alexander & Droms [Page 24] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + The code for this option is 54, and its length is 4. + + Code Len Address + +-----+-----+-----+-----+-----+-----+ + | 54 | 4 | a1 | a2 | a3 | a4 | + +-----+-----+-----+-----+-----+-----+ + +9.6. Parameter Request List + + This option is used by a DHCP client to request values for specified + configuration parameters. The list of requested parameters is + specified as n octets, where each octet is a valid DHCP option code + as defined in this document. + + The client MAY list the options in order of preference. The DHCP + server is not required to return the options in the requested order, + but MUST try to insert the requested options in the order requested + by the client. + + The code for this option is 55. Its minimum length is 1. + + Code Len Option Codes + +-----+-----+-----+-----+--- + | 55 | n | c1 | c2 | ... + +-----+-----+-----+-----+--- + +9.7. Message + + This option is used by a DHCP server to provide an error message to a + DHCP client in a DHCPNAK message in the event of a failure. A client + may use this option in a DHCPDECLINE message to indicate the why the + client declined the offered parameters. The message consists of n + octets of NVT ASCII text, which the client may display on an + available output device. + + The code for this option is 56 and its minimum length is 1. + + Code Len Text + +-----+-----+-----+-----+--- + | 56 | n | c1 | c2 | ... + +-----+-----+-----+-----+--- + + + + + + + + + + +Alexander & Droms [Page 25] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +9.8. Maximum DHCP Message Size + + This option specifies the maximum length DHCP message that it is + willing to accept. The length is specified as an unsigned 16-bit + integer. A client may use the maximum DHCP message size option in + DHCPDISCOVER or DHCPREQUEST messages, but should not use the option + in DHCPDECLINE messages. + + The code for this option is 57, and its length is 2. The minimum + legal value is 576 octets. + + Code Len Length + +-----+-----+-----+-----+ + | 57 | 2 | l1 | l2 | + +-----+-----+-----+-----+ + +9.9. Renewal (T1) Time Value + + This option specifies the time interval from address assignment until + the client transitions to the RENEWING state. + + The value is in units of seconds, and is specified as a 32-bit + unsigned integer. + + The code for this option is 58, and its length is 4. + + Code Len T1 Interval + +-----+-----+-----+-----+-----+-----+ + | 58 | 4 | t1 | t2 | t3 | t4 | + +-----+-----+-----+-----+-----+-----+ + +9.10. Rebinding (T2) Time Value + + This option specifies the time interval from address assignment until + the client transitions to the REBINDING state. + + The value is in units of seconds, and is specified as a 32-bit + unsigned integer. + + The code for this option is 59, and its length is 4. + + Code Len T2 Interval + +-----+-----+-----+-----+-----+-----+ + | 59 | 4 | t1 | t2 | t3 | t4 | + +-----+-----+-----+-----+-----+-----+ + + + + + + +Alexander & Droms [Page 26] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +9.11. Class-identifier + + This option is used by DHCP clients to optionally identify the type + and configuration of a DHCP client. The information is a string of n + octets, interpreted by servers. Vendors and sites may choose to + define specific class identifiers to convey particular configuration + or other identification information about a client. For example, the + identifier may encode the client's hardware configuration. Servers + not equipped to interpret the class-specific information sent by a + client MUST ignore it (although it may be reported). + + The code for this option is 60, and its minimum length is 1. + + Code Len Class-Identifier + +-----+-----+-----+-----+--- + | 60 | n | i1 | i2 | ... + +-----+-----+-----+-----+--- + +9.12. Client-identifier + + This option is used by DHCP clients to specify their unique + identifier. DHCP servers use this value to index their database of + address bindings. This value is expected to be unique for all + clients in an administrative domain. + + Identifiers consist of a type-value pair, similar to the + + It is expected that this field will typically contain a hardware type + and hardware address, but this is not required. Current legal values + for hardware types are defined in [22]. + + The code for this option is 61, and its minimum length is 2. + + Code Len Type Client-Identifier + +-----+-----+-----+-----+-----+--- + | 61 | n | t1 | i1 | i2 | ... + +-----+-----+-----+-----+-----+--- + +10. Extensions + + Additional generic data fields may be registered by contacting: + + Internet Assigned Numbers Authority (IANA) + USC/Information Sciences Institute + 4676 Admiralty Way + Marina del Rey, California 90292-6695 + + or by email as: iana@isi.edu + + + +Alexander & Droms [Page 27] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + Implementation specific use of undefined generic types (those in the + range 61-127) may conflict with other implementations, and + registration is required. + +11. Acknowledgements + + The authors would like to thank Philip Almquist for his feedback on + this document. The comments of the DHCP Working Group are also + gratefully acknowledged. In particular, Mike Carney and Jon Dreyer + from SunSelect suggested the current format of the Vendor-specific + Information option. + + RFC 1497 is based on earlier work by Philip Prindeville, with help + from Drew Perkins, Bill Croft, and Steve Deering. + +12. References + + [1] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531, + Bucknell University, October 1993. + + [2] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497, + USC/Information Sciences Institute, August 1993. + + [3] Croft, W., and J. Gilmore, "Bootstrap Protocol", RFC 951, + Stanford University and Sun Microsystems, September 1985. + + [4] Braden, R., Editor, "Requirements for Internet Hosts - + Communication Layers", STD 3, RFC 1122, USC/Information Sciences + Institute, October 1989. + + [5] Mogul, J., and J. Postel, "Internet Standard Subnetting + Procedure", STD 5, RFC 950, USC/Information Sciences Institute, + August 1985. + + [6] Postel, J., and K. Harrenstien, "Time Protocol", STD 26, RFC + 868, USC/Information Sciences Institute, SRI, May 1983. + + [7] Postel, J., "Name Server", IEN 116, USC/Information Sciences + Institute, August 1979. + + [8] Mockapetris, P., "Domain Names - Implementation and + Specification", STD 13, RFC 1035, USC/Information Sciences + Institute, November 1987. + + [9] Postel, J., "Quote of the Day Protocol", STD 23, RFC 865, + USC/Information Sciences Institute, May 1983. + + + + + +Alexander & Droms [Page 28] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + + [10] McLaughlin, L., "Line Printer Daemon Protocol", RFC 1179, The + Wollongong Group, August 1990. + + [11] Accetta, M., "Resource Location Protocol", RFC 887, CMU, + December 1983. + + [12] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191, + DECWRL, Stanford University, November 1990. + + [13] Deering, S., "ICMP Router Discovery Messages", RFC 1256, + Xerox PARC, September 1991. + + [14] Leffler, S. and M. Karels, "Trailer Encapsulations", RFC 893, + U. C. Berkeley, April 1984. + + [15] Hornig, C., "Standard for the Transmission of IP Datagrams over + Ethernet Networks", RFC 894, Symbolics, April 1984. + + [16] Postel, J. and J. Reynolds, "Standard for the Transmission of + IP Datagrams Over IEEE 802 Networks", RFC 1042, USC/Information + Sciences Institute, February 1988. + + [17] Sun Microsystems, "System and Network Administration", March + 1990. + + [18] Mills, D., "Internet Time Synchronization: The Network Time + Protocol", RFC 1305, UDEL, March 1992. + + [19] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service + on a TCP/UDP transport: Concepts and Methods", STD 19, RFC 1001, + March 1987. + + [20] NetBIOS Working Group, "Protocol Standard for a NetBIOS Service + on a TCP/UDP transport: Detailed Specifications", STD 19, RFC + 1002, March 1987. + + [21] Scheifler, R., "FYI On the X Window System", FYI 6, RFC 1198, + MIT Laboratory for Computer Science, January 1991. + + [22] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1340, + USC/Information Sciences Institute, July 1992. + +13. Security Considerations + + Security issues are not discussed in this memo. + + + + + + +Alexander & Droms [Page 29] + +RFC 1533 DHCP Options and BOOTP Vendor Extensions October 1993 + + +14. Authors' Addresses + + Steve Alexander + Lachman Technology, Inc. + 1901 North Naper Boulevard + Naperville, IL 60563-8895 + + Phone: (708) 505-9555 x256 + EMail: stevea@lachman.com + + + Ralph Droms + Computer Science Department + 323 Dana Engineering + Bucknell University + Lewisburg, PA 17837 + + Phone: (717) 524-1145 + EMail: droms@bucknell.edu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Alexander & Droms [Page 30] + \ No newline at end of file diff --git a/contrib/rfc2131.txt b/contrib/rfc2131.txt new file mode 100644 index 0000000..f45d9b8 --- /dev/null +++ b/contrib/rfc2131.txt @@ -0,0 +1,2523 @@ + + + + + + +Network Working Group R. Droms +Request for Comments: 2131 Bucknell University +Obsoletes: 1541 March 1997 +Category: Standards Track + + Dynamic Host Configuration Protocol + +Status of this memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Abstract + + The Dynamic Host Configuration Protocol (DHCP) provides a framework + for passing configuration information to hosts on a TCPIP network. + DHCP is based on the Bootstrap Protocol (BOOTP) [7], adding the + capability of automatic allocation of reusable network addresses and + additional configuration options [19]. DHCP captures the behavior of + BOOTP relay agents [7, 21], and DHCP participants can interoperate + with BOOTP participants [9]. + +Table of Contents + + 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . 2 + 1.1 Changes to RFC1541. . . . . . . . . . . . . . . . . . . . . . 3 + 1.2 Related Work. . . . . . . . . . . . . . . . . . . . . . . . . 4 + 1.3 Problem definition and issues . . . . . . . . . . . . . . . . 4 + 1.4 Requirements. . . . . . . . . . . . . . . . . . . . . . . . . 5 + 1.5 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 1.6 Design goals. . . . . . . . . . . . . . . . . . . . . . . . . 6 + 2. Protocol Summary. . . . . . . . . . . . . . . . . . . . . . . 8 + 2.1 Configuration parameters repository . . . . . . . . . . . . . 11 + 2.2 Dynamic allocation of network addresses . . . . . . . . . . . 12 + 3. The Client-Server Protocol. . . . . . . . . . . . . . . . . . 13 + 3.1 Client-server interaction - allocating a network address. . . 13 + 3.2 Client-server interaction - reusing a previously allocated + network address . . . . . . . . . . . . . . . . . . . . . . . 17 + 3.3 Interpretation and representation of time values. . . . . . . 20 + 3.4 Obtaining parameters with externally configured network + address . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 + 3.5 Client parameters in DHCP . . . . . . . . . . . . . . . . . . 21 + 3.6 Use of DHCP in clients with multiple interfaces . . . . . . . 22 + 3.7 When clients should use DHCP. . . . . . . . . . . . . . . . . 22 + 4. Specification of the DHCP client-server protocol. . . . . . . 22 + + + +Droms Standards Track [Page 1] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + 4.1 Constructing and sending DHCP messages. . . . . . . . . . . . 22 + 4.2 DHCP server administrative controls . . . . . . . . . . . . . 25 + 4.3 DHCP server behavior. . . . . . . . . . . . . . . . . . . . . 26 + 4.4 DHCP client behavior. . . . . . . . . . . . . . . . . . . . . 34 + 5. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . .42 + 6. References . . . . . . . . . . . . . . . . . . . . . . . . . .42 + 7. Security Considerations. . . . . . . . . . . . . . . . . . . .43 + 8. Author's Address . . . . . . . . . . . . . . . . . . . . . . .44 + A. Host Configuration Parameters . . . . . . . . . . . . . . . .45 +List of Figures + 1. Format of a DHCP message . . . . . . . . . . . . . . . . . . . 9 + 2. Format of the 'flags' field. . . . . . . . . . . . . . . . . . 11 + 3. Timeline diagram of messages exchanged between DHCP client and + servers when allocating a new network address. . . . . . . . . 15 + 4. Timeline diagram of messages exchanged between DHCP client and + servers when reusing a previously allocated network address. . 18 + 5. State-transition diagram for DHCP clients. . . . . . . . . . . 34 +List of Tables + 1. Description of fields in a DHCP message. . . . . . . . . . . . 10 + 2. DHCP messages. . . . . . . . . . . . . . . . . . . . . . . . . 14 + 3. Fields and options used by DHCP servers. . . . . . . . . . . . 28 + 4. Client messages from various states. . . . . . . . . . . . . . 33 + 5. Fields and options used by DHCP clients. . . . . . . . . . . . 37 + +1. Introduction + + The Dynamic Host Configuration Protocol (DHCP) provides configuration + parameters to Internet hosts. DHCP consists of two components: a + protocol for delivering host-specific configuration parameters from a + DHCP server to a host and a mechanism for allocation of network + addresses to hosts. + + DHCP is built on a client-server model, where designated DHCP server + hosts allocate network addresses and deliver configuration parameters + to dynamically configured hosts. Throughout the remainder of this + document, the term "server" refers to a host providing initialization + parameters through DHCP, and the term "client" refers to a host + requesting initialization parameters from a DHCP server. + + A host should not act as a DHCP server unless explicitly configured + to do so by a system administrator. The diversity of hardware and + protocol implementations in the Internet would preclude reliable + operation if random hosts were allowed to respond to DHCP requests. + For example, IP requires the setting of many parameters within the + protocol implementation software. Because IP can be used on many + dissimilar kinds of network hardware, values for those parameters + cannot be guessed or assumed to have correct defaults. Also, + distributed address allocation schemes depend on a polling/defense + + + +Droms Standards Track [Page 2] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + mechanism for discovery of addresses that are already in use. IP + hosts may not always be able to defend their network addresses, so + that such a distributed address allocation scheme cannot be + guaranteed to avoid allocation of duplicate network addresses. + + DHCP supports three mechanisms for IP address allocation. In + "automatic allocation", DHCP assigns a permanent IP address to a + client. In "dynamic allocation", DHCP assigns an IP address to a + client for a limited period of time (or until the client explicitly + relinquishes the address). In "manual allocation", a client's IP + address is assigned by the network administrator, and DHCP is used + simply to convey the assigned address to the client. A particular + network will use one or more of these mechanisms, depending on the + policies of the network administrator. + + Dynamic allocation is the only one of the three mechanisms that + allows automatic reuse of an address that is no longer needed by the + client to which it was assigned. Thus, dynamic allocation is + particularly useful for assigning an address to a client that will be + connected to the network only temporarily or for sharing a limited + pool of IP addresses among a group of clients that do not need + permanent IP addresses. Dynamic allocation may also be a good choice + for assigning an IP address to a new client being permanently + connected to a network where IP addresses are sufficiently scarce + that it is important to reclaim them when old clients are retired. + Manual allocation allows DHCP to be used to eliminate the error-prone + process of manually configuring hosts with IP addresses in + environments where (for whatever reasons) it is desirable to manage + IP address assignment outside of the DHCP mechanisms. + + The format of DHCP messages is based on the format of BOOTP messages, + to capture the BOOTP relay agent behavior described as part of the + BOOTP specification [7, 21] and to allow interoperability of existing + BOOTP clients with DHCP servers. Using BOOTP relay agents eliminates + the necessity of having a DHCP server on each physical network + segment. + +1.1 Changes to RFC 1541 + + This document updates the DHCP protocol specification that appears in + RFC1541. A new DHCP message type, DHCPINFORM, has been added; see + section 3.4, 4.3 and 4.4 for details. The classing mechanism for + identifying DHCP clients to DHCP servers has been extended to include + "vendor" classes as defined in sections 4.2 and 4.3. The minimum + lease time restriction has been removed. Finally, many editorial + changes have been made to clarify the text as a result of experience + gained in DHCP interoperability tests. + + + + +Droms Standards Track [Page 3] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +1.2 Related Work + + There are several Internet protocols and related mechanisms that + address some parts of the dynamic host configuration problem. The + Reverse Address Resolution Protocol (RARP) [10] (through the + extensions defined in the Dynamic RARP (DRARP) [5]) explicitly + addresses the problem of network address discovery, and includes an + automatic IP address assignment mechanism. The Trivial File Transfer + Protocol (TFTP) [20] provides for transport of a boot image from a + boot server. The Internet Control Message Protocol (ICMP) [16] + provides for informing hosts of additional routers via "ICMP + redirect" messages. ICMP also can provide subnet mask information + through the "ICMP mask request" message and other information through + the (obsolete) "ICMP information request" message. Hosts can locate + routers through the ICMP router discovery mechanism [8]. + + BOOTP is a transport mechanism for a collection of configuration + information. BOOTP is also extensible, and official extensions [17] + have been defined for several configuration parameters. Morgan has + proposed extensions to BOOTP for dynamic IP address assignment [15]. + The Network Information Protocol (NIP), used by the Athena project at + MIT, is a distributed mechanism for dynamic IP address assignment + [19]. The Resource Location Protocol RLP [1] provides for location + of higher level services. Sun Microsystems diskless workstations use + a boot procedure that employs RARP, TFTP and an RPC mechanism called + "bootparams" to deliver configuration information and operating + system code to diskless hosts. (Sun Microsystems, Sun Workstation + and SunOS are trademarks of Sun Microsystems, Inc.) Some Sun + networks also use DRARP and an auto-installation mechanism to + automate the configuration of new hosts in an existing network. + + In other related work, the path minimum transmission unit (MTU) + discovery algorithm can determine the MTU of an arbitrary internet + path [14]. The Address Resolution Protocol (ARP) has been proposed + as a transport protocol for resource location and selection [6]. + Finally, the Host Requirements RFCs [3, 4] mention specific + requirements for host reconfiguration and suggest a scenario for + initial configuration of diskless hosts. + +1.3 Problem definition and issues + + DHCP is designed to supply DHCP clients with the configuration + parameters defined in the Host Requirements RFCs. After obtaining + parameters via DHCP, a DHCP client should be able to exchange packets + with any other host in the Internet. The TCP/IP stack parameters + supplied by DHCP are listed in Appendix A. + + + + + +Droms Standards Track [Page 4] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + Not all of these parameters are required for a newly initialized + client. A client and server may negotiate for the transmission of + only those parameters required by the client or specific to a + particular subnet. + + DHCP allows but does not require the configuration of client + parameters not directly related to the IP protocol. DHCP also does + not address registration of newly configured clients with the Domain + Name System (DNS) [12, 13]. + + DHCP is not intended for use in configuring routers. + +1.4 Requirements + + Throughout this document, the words that are used to define the + significance of particular requirements are capitalized. These words + are: + + o "MUST" + + This word or the adjective "REQUIRED" means that the + item is an absolute requirement of this specification. + + o "MUST NOT" + + This phrase means that the item is an absolute prohibition + of this specification. + + o "SHOULD" + + This word or the adjective "RECOMMENDED" means that there + may exist valid reasons in particular circumstances to ignore + this item, but the full implications should be understood and + the case carefully weighed before choosing a different course. + + o "SHOULD NOT" + + This phrase means that there may exist valid reasons in + particular circumstances when the listed behavior is acceptable + or even useful, but the full implications should be understood + and the case carefully weighed before implementing any behavior + described with this label. + + + + + + + + + +Droms Standards Track [Page 5] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + o "MAY" + + This word or the adjective "OPTIONAL" means that this item is + truly optional. One vendor may choose to include the item + because a particular marketplace requires it or because it + enhances the product, for example; another vendor may omit the + same item. + +1.5 Terminology + + This document uses the following terms: + + o "DHCP client" + + A DHCP client is an Internet host using DHCP to obtain + configuration parameters such as a network address. + + o "DHCP server" + + A DHCP server is an Internet host that returns configuration + parameters to DHCP clients. + + o "BOOTP relay agent" + + A BOOTP relay agent or relay agent is an Internet host or router + that passes DHCP messages between DHCP clients and DHCP servers. + DHCP is designed to use the same relay agent behavior as specified + in the BOOTP protocol specification. + + o "binding" + + A binding is a collection of configuration parameters, including + at least an IP address, associated with or "bound to" a DHCP + client. Bindings are managed by DHCP servers. + +1.6 Design goals + + The following list gives general design goals for DHCP. + + o DHCP should be a mechanism rather than a policy. DHCP must + allow local system administrators control over configuration + parameters where desired; e.g., local system administrators + should be able to enforce local policies concerning allocation + and access to local resources where desired. + + + + + + + +Droms Standards Track [Page 6] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + o Clients should require no manual configuration. Each client + should be able to discover appropriate local configuration + parameters without user intervention and incorporate those + parameters into its own configuration. + + o Networks should require no manual configuration for individual + clients. Under normal circumstances, the network manager + should not have to enter any per-client configuration + parameters. + + o DHCP should not require a server on each subnet. To allow for + scale and economy, DHCP must work across routers or through the + intervention of BOOTP relay agents. + + o A DHCP client must be prepared to receive multiple responses + to a request for configuration parameters. Some installations + may include multiple, overlapping DHCP servers to enhance + reliability and increase performance. + + o DHCP must coexist with statically configured, non-participating + hosts and with existing network protocol implementations. + + o DHCP must interoperate with the BOOTP relay agent behavior as + described by RFC 951 and by RFC 1542 [21]. + + o DHCP must provide service to existing BOOTP clients. + + The following list gives design goals specific to the transmission of + the network layer parameters. DHCP must: + + o Guarantee that any specific network address will not be in + use by more than one DHCP client at a time, + + o Retain DHCP client configuration across DHCP client reboot. A + DHCP client should, whenever possible, be assigned the same + configuration parameters (e.g., network address) in response + to each request, + + o Retain DHCP client configuration across server reboots, and, + whenever possible, a DHCP client should be assigned the same + configuration parameters despite restarts of the DHCP mechanism, + + o Allow automated assignment of configuration parameters to new + clients to avoid hand configuration for new clients, + + o Support fixed or permanent allocation of configuration + parameters to specific clients. + + + + +Droms Standards Track [Page 7] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +2. Protocol Summary + + From the client's point of view, DHCP is an extension of the BOOTP + mechanism. This behavior allows existing BOOTP clients to + interoperate with DHCP servers without requiring any change to the + clients' initialization software. RFC 1542 [2] details the + interactions between BOOTP and DHCP clients and servers [9]. There + are some new, optional transactions that optimize the interaction + between DHCP clients and servers that are described in sections 3 and + 4. + + Figure 1 gives the format of a DHCP message and table 1 describes + each of the fields in the DHCP message. The numbers in parentheses + indicate the size of each field in octets. The names for the fields + given in the figure will be used throughout this document to refer to + the fields in DHCP messages. + + There are two primary differences between DHCP and BOOTP. First, + DHCP defines mechanisms through which clients can be assigned a + network address for a finite lease, allowing for serial reassignment + of network addresses to different clients. Second, DHCP provides the + mechanism for a client to acquire all of the IP configuration + parameters that it needs in order to operate. + + DHCP introduces a small change in terminology intended to clarify the + meaning of one of the fields. What was the "vendor extensions" field + in BOOTP has been re-named the "options" field in DHCP. Similarly, + the tagged data items that were used inside the BOOTP "vendor + extensions" field, which were formerly referred to as "vendor + extensions," are now termed simply "options." + + + + + + + + + + + + + + + + + + + + + +Droms Standards Track [Page 8] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | op (1) | htype (1) | hlen (1) | hops (1) | + +---------------+---------------+---------------+---------------+ + | xid (4) | + +-------------------------------+-------------------------------+ + | secs (2) | flags (2) | + +-------------------------------+-------------------------------+ + | ciaddr (4) | + +---------------------------------------------------------------+ + | yiaddr (4) | + +---------------------------------------------------------------+ + | siaddr (4) | + +---------------------------------------------------------------+ + | giaddr (4) | + +---------------------------------------------------------------+ + | | + | chaddr (16) | + | | + | | + +---------------------------------------------------------------+ + | | + | sname (64) | + +---------------------------------------------------------------+ + | | + | file (128) | + +---------------------------------------------------------------+ + | | + | options (variable) | + +---------------------------------------------------------------+ + + Figure 1: Format of a DHCP message + + DHCP defines a new 'client identifier' option that is used to pass an + explicit client identifier to a DHCP server. This change eliminates + the overloading of the 'chaddr' field in BOOTP messages, where + 'chaddr' is used both as a hardware address for transmission of BOOTP + reply messages and as a client identifier. The 'client identifier' + is an opaque key, not to be interpreted by the server; for example, + the 'client identifier' may contain a hardware address, identical to + the contents of the 'chaddr' field, or it may contain another type of + identifier, such as a DNS name. The 'client identifier' chosen by a + DHCP client MUST be unique to that client within the subnet to which + the client is attached. If the client uses a 'client identifier' in + one message, it MUST use that same identifier in all subsequent + messages, to ensure that all servers correctly identify the client. + + + + +Droms Standards Track [Page 9] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + DHCP clarifies the interpretation of the 'siaddr' field as the + address of the server to use in the next step of the client's + bootstrap process. A DHCP server may return its own address in the + 'siaddr' field, if the server is prepared to supply the next + bootstrap service (e.g., delivery of an operating system executable + image). A DHCP server always returns its own address in the 'server + identifier' option. + + FIELD OCTETS DESCRIPTION + ----- ------ ----------- + + op 1 Message op code / message type. + 1 = BOOTREQUEST, 2 = BOOTREPLY + htype 1 Hardware address type, see ARP section in "Assigned + Numbers" RFC; e.g., '1' = 10mb ethernet. + hlen 1 Hardware address length (e.g. '6' for 10mb + ethernet). + hops 1 Client sets to zero, optionally used by relay agents + when booting via a relay agent. + xid 4 Transaction ID, a random number chosen by the + client, used by the client and server to associate + messages and responses between a client and a + server. + secs 2 Filled in by client, seconds elapsed since client + began address acquisition or renewal process. + flags 2 Flags (see figure 2). + ciaddr 4 Client IP address; only filled in if client is in + BOUND, RENEW or REBINDING state and can respond + to ARP requests. + yiaddr 4 'your' (client) IP address. + siaddr 4 IP address of next server to use in bootstrap; + returned in DHCPOFFER, DHCPACK by server. + giaddr 4 Relay agent IP address, used in booting via a + relay agent. + chaddr 16 Client hardware address. + sname 64 Optional server host name, null terminated string. + file 128 Boot file name, null terminated string; "generic" + name or null in DHCPDISCOVER, fully qualified + directory-path name in DHCPOFFER. + options var Optional parameters field. See the options + documents for a list of defined options. + + Table 1: Description of fields in a DHCP message + + The 'options' field is now variable length. A DHCP client must be + prepared to receive DHCP messages with an 'options' field of at least + length 312 octets. This requirement implies that a DHCP client must + be prepared to receive a message of up to 576 octets, the minimum IP + + + +Droms Standards Track [Page 10] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + datagram size an IP host must be prepared to accept [3]. DHCP + clients may negotiate the use of larger DHCP messages through the + 'maximum DHCP message size' option. The options field may be further + extended into the 'file' and 'sname' fields. + + In the case of a client using DHCP for initial configuration (before + the client's TCP/IP software has been completely configured), DHCP + requires creative use of the client's TCP/IP software and liberal + interpretation of RFC 1122. The TCP/IP software SHOULD accept and + forward to the IP layer any IP packets delivered to the client's + hardware address before the IP address is configured; DHCP servers + and BOOTP relay agents may not be able to deliver DHCP messages to + clients that cannot accept hardware unicast datagrams before the + TCP/IP software is configured. + + To work around some clients that cannot accept IP unicast datagrams + before the TCP/IP software is configured as discussed in the previous + paragraph, DHCP uses the 'flags' field [21]. The leftmost bit is + defined as the BROADCAST (B) flag. The semantics of this flag are + discussed in section 4.1 of this document. The remaining bits of the + flags field are reserved for future use. They MUST be set to zero by + clients and ignored by servers and relay agents. Figure 2 gives the + format of the 'flags' field. + + 1 1 1 1 1 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |B| MBZ | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + B: BROADCAST flag + + MBZ: MUST BE ZERO (reserved for future use) + + Figure 2: Format of the 'flags' field + +2.1 Configuration parameters repository + + The first service provided by DHCP is to provide persistent storage + of network parameters for network clients. The model of DHCP + persistent storage is that the DHCP service stores a key-value entry + for each client, where the key is some unique identifier (for + example, an IP subnet number and a unique identifier within the + subnet) and the value contains the configuration parameters for the + client. + + For example, the key might be the pair (IP-subnet-number, hardware- + address) (note that the "hardware-address" should be typed by the + + + +Droms Standards Track [Page 11] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + type of hardware to accommodate possible duplication of hardware + addresses resulting from bit-ordering problems in a mixed-media, + bridged network) allowing for serial or concurrent reuse of a + hardware address on different subnets, and for hardware addresses + that may not be globally unique. Alternately, the key might be the + pair (IP-subnet-number, hostname), allowing the server to assign + parameters intelligently to a DHCP client that has been moved to a + different subnet or has changed hardware addresses (perhaps because + the network interface failed and was replaced). The protocol defines + that the key will be (IP-subnet-number, hardware-address) unless the + client explicitly supplies an identifier using the 'client + identifier' option. A client can query the DHCP service to + retrieve its configuration parameters. The client interface to the + configuration parameters repository consists of protocol messages to + request configuration parameters and responses from the server + carrying the configuration parameters. + +2.2 Dynamic allocation of network addresses + + The second service provided by DHCP is the allocation of temporary or + permanent network (IP) addresses to clients. The basic mechanism for + the dynamic allocation of network addresses is simple: a client + requests the use of an address for some period of time. The + allocation mechanism (the collection of DHCP servers) guarantees not + to reallocate that address within the requested time and attempts to + return the same network address each time the client requests an + address. In this document, the period over which a network address + is allocated to a client is referred to as a "lease" [11]. The + client may extend its lease with subsequent requests. The client may + issue a message to release the address back to the server when the + client no longer needs the address. The client may ask for a + permanent assignment by asking for an infinite lease. Even when + assigning "permanent" addresses, a server may choose to give out + lengthy but non-infinite leases to allow detection of the fact that + the client has been retired. + + In some environments it will be necessary to reassign network + addresses due to exhaustion of available addresses. In such + environments, the allocation mechanism will reuse addresses whose + lease has expired. The server should use whatever information is + available in the configuration information repository to choose an + address to reuse. For example, the server may choose the least + recently assigned address. As a consistency check, the allocating + server SHOULD probe the reused address before allocating the address, + e.g., with an ICMP echo request, and the client SHOULD probe the + newly received address, e.g., with ARP. + + + + + +Droms Standards Track [Page 12] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +3. The Client-Server Protocol + + DHCP uses the BOOTP message format defined in RFC 951 and given in + table 1 and figure 1. The 'op' field of each DHCP message sent from + a client to a server contains BOOTREQUEST. BOOTREPLY is used in the + 'op' field of each DHCP message sent from a server to a client. + + The first four octets of the 'options' field of the DHCP message + contain the (decimal) values 99, 130, 83 and 99, respectively (this + is the same magic cookie as is defined in RFC 1497 [17]). The + remainder of the 'options' field consists of a list of tagged + parameters that are called "options". All of the "vendor extensions" + listed in RFC 1497 are also DHCP options. RFC 1533 gives the + complete set of options defined for use with DHCP. + + Several options have been defined so far. One particular option - + the "DHCP message type" option - must be included in every DHCP + message. This option defines the "type" of the DHCP message. + Additional options may be allowed, required, or not allowed, + depending on the DHCP message type. + + Throughout this document, DHCP messages that include a 'DHCP message + type' option will be referred to by the type of the message; e.g., a + DHCP message with 'DHCP message type' option type 1 will be referred + to as a "DHCPDISCOVER" message. + +3.1 Client-server interaction - allocating a network address + + The following summary of the protocol exchanges between clients and + servers refers to the DHCP messages described in table 2. The + timeline diagram in figure 3 shows the timing relationships in a + typical client-server interaction. If the client already knows its + address, some steps may be omitted; this abbreviated interaction is + described in section 3.2. + + 1. The client broadcasts a DHCPDISCOVER message on its local physical + subnet. The DHCPDISCOVER message MAY include options that suggest + values for the network address and lease duration. BOOTP relay + agents may pass the message on to DHCP servers not on the same + physical subnet. + + 2. Each server may respond with a DHCPOFFER message that includes an + available network address in the 'yiaddr' field (and other + configuration parameters in DHCP options). Servers need not + reserve the offered network address, although the protocol will + work more efficiently if the server avoids allocating the offered + network address to another client. When allocating a new address, + servers SHOULD check that the offered network address is not + + + +Droms Standards Track [Page 13] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + already in use; e.g., the server may probe the offered address + with an ICMP Echo Request. Servers SHOULD be implemented so that + network administrators MAY choose to disable probes of newly + allocated addresses. The server transmits the DHCPOFFER message + to the client, using the BOOTP relay agent if necessary. + + Message Use + ------- --- + + DHCPDISCOVER - Client broadcast to locate available servers. + + DHCPOFFER - Server to client in response to DHCPDISCOVER with + offer of configuration parameters. + + DHCPREQUEST - Client message to servers either (a) requesting + offered parameters from one server and implicitly + declining offers from all others, (b) confirming + correctness of previously allocated address after, + e.g., system reboot, or (c) extending the lease on a + particular network address. + + DHCPACK - Server to client with configuration parameters, + including committed network address. + + DHCPNAK - Server to client indicating client's notion of network + address is incorrect (e.g., client has moved to new + subnet) or client's lease as expired + + DHCPDECLINE - Client to server indicating network address is already + in use. + + DHCPRELEASE - Client to server relinquishing network address and + cancelling remaining lease. + + DHCPINFORM - Client to server, asking only for local configuration + parameters; client already has externally configured + network address. + + Table 2: DHCP messages + + + + + + + + + + + + +Droms Standards Track [Page 14] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + Server Client Server + (not selected) (selected) + + v v v + | | | + | Begins initialization | + | | | + | _____________/|\____________ | + |/DHCPDISCOVER | DHCPDISCOVER \| + | | | + Determines | Determines + configuration | configuration + | | | + |\ | ____________/ | + | \________ | /DHCPOFFER | + | DHCPOFFER\ |/ | + | \ | | + | Collects replies | + | \| | + | Selects configuration | + | | | + | _____________/|\____________ | + |/ DHCPREQUEST | DHCPREQUEST\ | + | | | + | | Commits configuration + | | | + | | _____________/| + | |/ DHCPACK | + | | | + | Initialization complete | + | | | + . . . + . . . + | | | + | Graceful shutdown | + | | | + | |\ ____________ | + | | DHCPRELEASE \| + | | | + | | Discards lease + | | | + v v v + Figure 3: Timeline diagram of messages exchanged between DHCP + client and servers when allocating a new network address + + + + + + + +Droms Standards Track [Page 15] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + 3. The client receives one or more DHCPOFFER messages from one or more + servers. The client may choose to wait for multiple responses. + The client chooses one server from which to request configuration + parameters, based on the configuration parameters offered in the + DHCPOFFER messages. The client broadcasts a DHCPREQUEST message + that MUST include the 'server identifier' option to indicate which + server it has selected, and that MAY include other options + specifying desired configuration values. The 'requested IP + address' option MUST be set to the value of 'yiaddr' in the + DHCPOFFER message from the server. This DHCPREQUEST message is + broadcast and relayed through DHCP/BOOTP relay agents. To help + ensure that any BOOTP relay agents forward the DHCPREQUEST message + to the same set of DHCP servers that received the original + DHCPDISCOVER message, the DHCPREQUEST message MUST use the same + value in the DHCP message header's 'secs' field and be sent to the + same IP broadcast address as the original DHCPDISCOVER message. + The client times out and retransmits the DHCPDISCOVER message if + the client receives no DHCPOFFER messages. + + 4. The servers receive the DHCPREQUEST broadcast from the client. + Those servers not selected by the DHCPREQUEST message use the + message as notification that the client has declined that server's + offer. The server selected in the DHCPREQUEST message commits the + binding for the client to persistent storage and responds with a + DHCPACK message containing the configuration parameters for the + requesting client. The combination of 'client identifier' or + 'chaddr' and assigned network address constitute a unique + identifier for the client's lease and are used by both the client + and server to identify a lease referred to in any DHCP messages. + Any configuration parameters in the DHCPACK message SHOULD NOT + conflict with those in the earlier DHCPOFFER message to which the + client is responding. The server SHOULD NOT check the offered + network address at this point. The 'yiaddr' field in the DHCPACK + messages is filled in with the selected network address. + + If the selected server is unable to satisfy the DHCPREQUEST message + (e.g., the requested network address has been allocated), the + server SHOULD respond with a DHCPNAK message. + + A server MAY choose to mark addresses offered to clients in + DHCPOFFER messages as unavailable. The server SHOULD mark an + address offered to a client in a DHCPOFFER message as available if + the server receives no DHCPREQUEST message from that client. + + 5. The client receives the DHCPACK message with configuration + parameters. The client SHOULD perform a final check on the + parameters (e.g., ARP for allocated network address), and notes the + duration of the lease specified in the DHCPACK message. At this + + + +Droms Standards Track [Page 16] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + point, the client is configured. If the client detects that the + address is already in use (e.g., through the use of ARP), the + client MUST send a DHCPDECLINE message to the server and restarts + the configuration process. The client SHOULD wait a minimum of ten + seconds before restarting the configuration process to avoid + excessive network traffic in case of looping. + + If the client receives a DHCPNAK message, the client restarts the + configuration process. + + The client times out and retransmits the DHCPREQUEST message if the + client receives neither a DHCPACK or a DHCPNAK message. The client + retransmits the DHCPREQUEST according to the retransmission + algorithm in section 4.1. The client should choose to retransmit + the DHCPREQUEST enough times to give adequate probability of + contacting the server without causing the client (and the user of + that client) to wait overly long before giving up; e.g., a client + retransmitting as described in section 4.1 might retransmit the + DHCPREQUEST message four times, for a total delay of 60 seconds, + before restarting the initialization procedure. If the client + receives neither a DHCPACK or a DHCPNAK message after employing the + retransmission algorithm, the client reverts to INIT state and + restarts the initialization process. The client SHOULD notify the + user that the initialization process has failed and is restarting. + + 6. The client may choose to relinquish its lease on a network address + by sending a DHCPRELEASE message to the server. The client + identifies the lease to be released with its 'client identifier', + or 'chaddr' and network address in the DHCPRELEASE message. If the + client used a 'client identifier' when it obtained the lease, it + MUST use the same 'client identifier' in the DHCPRELEASE message. + +3.2 Client-server interaction - reusing a previously allocated network + address + + If a client remembers and wishes to reuse a previously allocated + network address, a client may choose to omit some of the steps + described in the previous section. The timeline diagram in figure 4 + shows the timing relationships in a typical client-server interaction + for a client reusing a previously allocated network address. + + + + + + + + + + + +Droms Standards Track [Page 17] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + 1. The client broadcasts a DHCPREQUEST message on its local subnet. + The message includes the client's network address in the + 'requested IP address' option. As the client has not received its + network address, it MUST NOT fill in the 'ciaddr' field. BOOTP + relay agents pass the message on to DHCP servers not on the same + subnet. If the client used a 'client identifier' to obtain its + address, the client MUST use the same 'client identifier' in the + DHCPREQUEST message. + + 2. Servers with knowledge of the client's configuration parameters + respond with a DHCPACK message to the client. Servers SHOULD NOT + check that the client's network address is already in use; the + client may respond to ICMP Echo Request messages at this point. + + Server Client Server + + v v v + | | | + | Begins | + | initialization | + | | | + | /|\ | + | _________ __/ | \__________ | + | /DHCPREQU EST | DHCPREQUEST\ | + |/ | \| + | | | + Locates | Locates + configuration | configuration + | | | + |\ | /| + | \ | ___________/ | + | \ | / DHCPACK | + | \ _______ |/ | + | DHCPACK\ | | + | Initialization | + | complete | + | \| | + | | | + | (Subsequent | + | DHCPACKS | + | ignored) | + | | | + | | | + v v v + + Figure 4: Timeline diagram of messages exchanged between DHCP + client and servers when reusing a previously allocated + network address + + + +Droms Standards Track [Page 18] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + If the client's request is invalid (e.g., the client has moved + to a new subnet), servers SHOULD respond with a DHCPNAK message to + the client. Servers SHOULD NOT respond if their information is not + guaranteed to be accurate. For example, a server that identifies a + request for an expired binding that is owned by another server SHOULD + NOT respond with a DHCPNAK unless the servers are using an explicit + mechanism to maintain coherency among the servers. + + If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on + the same subnet as the server. The server MUST + broadcast the DHCPNAK message to the 0xffffffff broadcast address + because the client may not have a correct network address or subnet + mask, and the client may not be answering ARP requests. + Otherwise, the server MUST send the DHCPNAK message to the IP + address of the BOOTP relay agent, as recorded in 'giaddr'. The + relay agent will, in turn, forward the message directly to the + client's hardware address, so that the DHCPNAK can be delivered even + if the client has moved to a new network. + + 3. The client receives the DHCPACK message with configuration + parameters. The client performs a final check on the parameters + (as in section 3.1), and notes the duration of the lease specified + in the DHCPACK message. The specific lease is implicitly identified + by the 'client identifier' or 'chaddr' and the network address. At + this point, the client is configured. + + If the client detects that the IP address in the DHCPACK message + is already in use, the client MUST send a DHCPDECLINE message to the + server and restarts the configuration process by requesting a + new network address. This action corresponds to the client + moving to the INIT state in the DHCP state diagram, which is + described in section 4.4. + + If the client receives a DHCPNAK message, it cannot reuse its + remembered network address. It must instead request a new + address by restarting the configuration process, this time + using the (non-abbreviated) procedure described in section + 3.1. This action also corresponds to the client moving to + the INIT state in the DHCP state diagram. + + The client times out and retransmits the DHCPREQUEST message if + the client receives neither a DHCPACK nor a DHCPNAK message. The + client retransmits the DHCPREQUEST according to the retransmission + algorithm in section 4.1. The client should choose to retransmit + the DHCPREQUEST enough times to give adequate probability of + contacting the server without causing the client (and the user of + that client) to wait overly long before giving up; e.g., a client + retransmitting as described in section 4.1 might retransmit the + + + +Droms Standards Track [Page 19] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + DHCPREQUEST message four times, for a total delay of 60 seconds, + before restarting the initialization procedure. If the client + receives neither a DHCPACK or a DHCPNAK message after employing + the retransmission algorithm, the client MAY choose to use the + previously allocated network address and configuration parameters + for the remainder of the unexpired lease. This corresponds to + moving to BOUND state in the client state transition diagram shown + in figure 5. + + 4. The client may choose to relinquish its lease on a network + address by sending a DHCPRELEASE message to the server. The + client identifies the lease to be released with its + 'client identifier', or 'chaddr' and network address in the + DHCPRELEASE message. + + Note that in this case, where the client retains its network + address locally, the client will not normally relinquish its + lease during a graceful shutdown. Only in the case where the + client explicitly needs to relinquish its lease, e.g., the client + is about to be moved to a different subnet, will the client send + a DHCPRELEASE message. + +3.3 Interpretation and representation of time values + + A client acquires a lease for a network address for a fixed period of + time (which may be infinite). Throughout the protocol, times are to + be represented in units of seconds. The time value of 0xffffffff is + reserved to represent "infinity". + + As clients and servers may not have synchronized clocks, times are + represented in DHCP messages as relative times, to be interpreted + with respect to the client's local clock. Representing relative + times in units of seconds in an unsigned 32 bit word gives a range of + relative times from 0 to approximately 100 years, which is sufficient + for the relative times to be measured using DHCP. + + The algorithm for lease duration interpretation given in the previous + paragraph assumes that client and server clocks are stable relative + to each other. If there is drift between the two clocks, the server + may consider the lease expired before the client does. To + compensate, the server may return a shorter lease duration to the + client than the server commits to its local database of client + information. + +3.4 Obtaining parameters with externally configured network address + + If a client has obtained a network address through some other means + (e.g., manual configuration), it may use a DHCPINFORM request message + + + +Droms Standards Track [Page 20] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + to obtain other local configuration parameters. Servers receiving a + DHCPINFORM message construct a DHCPACK message with any local + configuration parameters appropriate for the client without: + allocating a new address, checking for an existing binding, filling + in 'yiaddr' or including lease time parameters. The servers SHOULD + unicast the DHCPACK reply to the address given in the 'ciaddr' field + of the DHCPINFORM message. + + The server SHOULD check the network address in a DHCPINFORM message + for consistency, but MUST NOT check for an existing lease. The + server forms a DHCPACK message containing the configuration + parameters for the requesting client and sends the DHCPACK message + directly to the client. + +3.5 Client parameters in DHCP + + Not all clients require initialization of all parameters listed in + Appendix A. Two techniques are used to reduce the number of + parameters transmitted from the server to the client. First, most of + the parameters have defaults defined in the Host Requirements RFCs; + if the client receives no parameters from the server that override + the defaults, a client uses those default values. Second, in its + initial DHCPDISCOVER or DHCPREQUEST message, a client may provide the + server with a list of specific parameters the client is interested + in. If the client includes a list of parameters in a DHCPDISCOVER + message, it MUST include that list in any subsequent DHCPREQUEST + messages. + + The client SHOULD include the 'maximum DHCP message size' option to + let the server know how large the server may make its DHCP messages. + The parameters returned to a client may still exceed the space + allocated to options in a DHCP message. In this case, two additional + options flags (which must appear in the 'options' field of the + message) indicate that the 'file' and 'sname' fields are to be used + for options. + + The client can inform the server which configuration parameters the + client is interested in by including the 'parameter request list' + option. The data portion of this option explicitly lists the options + requested by tag number. + + In addition, the client may suggest values for the network address + and lease time in the DHCPDISCOVER message. The client may include + the 'requested IP address' option to suggest that a particular IP + address be assigned, and may include the 'IP address lease time' + option to suggest the lease time it would like. Other options + representing "hints" at configuration parameters are allowed in a + DHCPDISCOVER or DHCPREQUEST message. However, additional options may + + + +Droms Standards Track [Page 21] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + be ignored by servers, and multiple servers may, therefore, not + return identical values for some options. The 'requested IP address' + option is to be filled in only in a DHCPREQUEST message when the + client is verifying network parameters obtained previously. The + client fills in the 'ciaddr' field only when correctly configured + with an IP address in BOUND, RENEWING or REBINDING state. + + If a server receives a DHCPREQUEST message with an invalid 'requested + IP address', the server SHOULD respond to the client with a DHCPNAK + message and may choose to report the problem to the system + administrator. The server may include an error message in the + 'message' option. + +3.6 Use of DHCP in clients with multiple interfaces + + A client with multiple network interfaces must use DHCP through each + interface independently to obtain configuration information + parameters for those separate interfaces. + +3.7 When clients should use DHCP + + A client SHOULD use DHCP to reacquire or verify its IP address and + network parameters whenever the local network parameters may have + changed; e.g., at system boot time or after a disconnection from the + local network, as the local network configuration may change without + the client's or user's knowledge. + + If a client has knowledge of a previous network address and is unable + to contact a local DHCP server, the client may continue to use the + previous network address until the lease for that address expires. + If the lease expires before the client can contact a DHCP server, the + client must immediately discontinue use of the previous network + address and may inform local users of the problem. + +4. Specification of the DHCP client-server protocol + + In this section, we assume that a DHCP server has a block of network + addresses from which it can satisfy requests for new addresses. Each + server also maintains a database of allocated addresses and leases in + local permanent storage. + +4.1 Constructing and sending DHCP messages + + DHCP clients and servers both construct DHCP messages by filling in + fields in the fixed format section of the message and appending + tagged data items in the variable length option area. The options + area includes first a four-octet 'magic cookie' (which was described + in section 3), followed by the options. The last option must always + + + +Droms Standards Track [Page 22] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + be the 'end' option. + + DHCP uses UDP as its transport protocol. DHCP messages from a client + to a server are sent to the 'DHCP server' port (67), and DHCP + messages from a server to a client are sent to the 'DHCP client' port + (68). A server with multiple network address (e.g., a multi-homed + host) MAY use any of its network addresses in outgoing DHCP messages. + + The 'server identifier' field is used both to identify a DHCP server + in a DHCP message and as a destination address from clients to + servers. A server with multiple network addresses MUST be prepared + to to accept any of its network addresses as identifying that server + in a DHCP message. To accommodate potentially incomplete network + connectivity, a server MUST choose an address as a 'server + identifier' that, to the best of the server's knowledge, is reachable + from the client. For example, if the DHCP server and the DHCP client + are connected to the same subnet (i.e., the 'giaddr' field in the + message from the client is zero), the server SHOULD select the IP + address the server is using for communication on that subnet as the + 'server identifier'. If the server is using multiple IP addresses on + that subnet, any such address may be used. If the server has + received a message through a DHCP relay agent, the server SHOULD + choose an address from the interface on which the message was + recieved as the 'server identifier' (unless the server has other, + better information on which to make its choice). DHCP clients MUST + use the IP address provided in the 'server identifier' option for any + unicast requests to the DHCP server. + + DHCP messages broadcast by a client prior to that client obtaining + its IP address must have the source address field in the IP header + set to 0. + + If the 'giaddr' field in a DHCP message from a client is non-zero, + the server sends any return messages to the 'DHCP server' port on the + BOOTP relay agent whose address appears in 'giaddr'. If the 'giaddr' + field is zero and the 'ciaddr' field is nonzero, then the server + unicasts DHCPOFFER and DHCPACK messages to the address in 'ciaddr'. + If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is + set, then the server broadcasts DHCPOFFER and DHCPACK messages to + 0xffffffff. If the broadcast bit is not set and 'giaddr' is zero and + 'ciaddr' is zero, then the server unicasts DHCPOFFER and DHCPACK + messages to the client's hardware address and 'yiaddr' address. In + all cases, when 'giaddr' is zero, the server broadcasts any DHCPNAK + messages to 0xffffffff. + + If the options in a DHCP message extend into the 'sname' and 'file' + fields, the 'option overload' option MUST appear in the 'options' + field, with value 1, 2 or 3, as specified in RFC 1533. If the + + + +Droms Standards Track [Page 23] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + 'option overload' option is present in the 'options' field, the + options in the 'options' field MUST be terminated by an 'end' option, + and MAY contain one or more 'pad' options to fill the options field. + The options in the 'sname' and 'file' fields (if in use as indicated + by the 'options overload' option) MUST begin with the first octet of + the field, MUST be terminated by an 'end' option, and MUST be + followed by 'pad' options to fill the remainder of the field. Any + individual option in the 'options', 'sname' and 'file' fields MUST be + entirely contained in that field. The options in the 'options' field + MUST be interpreted first, so that any 'option overload' options may + be interpreted. The 'file' field MUST be interpreted next (if the + 'option overload' option indicates that the 'file' field contains + DHCP options), followed by the 'sname' field. + + The values to be passed in an 'option' tag may be too long to fit in + the 255 octets available to a single option (e.g., a list of routers + in a 'router' option [21]). Options may appear only once, unless + otherwise specified in the options document. The client concatenates + the values of multiple instances of the same option into a single + parameter list for configuration. + + DHCP clients are responsible for all message retransmission. The + client MUST adopt a retransmission strategy that incorporates a + randomized exponential backoff algorithm to determine the delay + between retransmissions. The delay between retransmissions SHOULD be + chosen to allow sufficient time for replies from the server to be + delivered based on the characteristics of the internetwork between + the client and the server. For example, in a 10Mb/sec Ethernet + internetwork, the delay before the first retransmission SHOULD be 4 + seconds randomized by the value of a uniform random number chosen + from the range -1 to +1. Clients with clocks that provide resolution + granularity of less than one second may choose a non-integer + randomization value. The delay before the next retransmission SHOULD + be 8 seconds randomized by the value of a uniform number chosen from + the range -1 to +1. The retransmission delay SHOULD be doubled with + subsequent retransmissions up to a maximum of 64 seconds. The client + MAY provide an indication of retransmission attempts to the user as + an indication of the progress of the configuration process. + + The 'xid' field is used by the client to match incoming DHCP messages + with pending requests. A DHCP client MUST choose 'xid's in such a + way as to minimize the chance of using an 'xid' identical to one used + by another client. For example, a client may choose a different, + random initial 'xid' each time the client is rebooted, and + subsequently use sequential 'xid's until the next reboot. Selecting + a new 'xid' for each retransmission is an implementation decision. A + client may choose to reuse the same 'xid' or select a new 'xid' for + each retransmitted message. + + + +Droms Standards Track [Page 24] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + Normally, DHCP servers and BOOTP relay agents attempt to deliver + DHCPOFFER, DHCPACK and DHCPNAK messages directly to the client using + uicast delivery. The IP destination address (in the IP header) is + set to the DHCP 'yiaddr' address and the link-layer destination + address is set to the DHCP 'chaddr' address. Unfortunately, some + client implementations are unable to receive such unicast IP + datagrams until the implementation has been configured with a valid + IP address (leading to a deadlock in which the client's IP address + cannot be delivered until the client has been configured with an IP + address). + + A client that cannot receive unicast IP datagrams until its protocol + software has been configured with an IP address SHOULD set the + BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or + DHCPREQUEST messages that client sends. The BROADCAST bit will + provide a hint to the DHCP server and BOOTP relay agent to broadcast + any messages to the client on the client's subnet. A client that can + receive unicast IP datagrams before its protocol software has been + configured SHOULD clear the BROADCAST bit to 0. The BOOTP + clarifications document discusses the ramifications of the use of the + BROADCAST bit [21]. + + A server or relay agent sending or relaying a DHCP message directly + to a DHCP client (i.e., not to a relay agent specified in the + 'giaddr' field) SHOULD examine the BROADCAST bit in the 'flags' + field. If this bit is set to 1, the DHCP message SHOULD be sent as + an IP broadcast using an IP broadcast address (preferably 0xffffffff) + as the IP destination address and the link-layer broadcast address as + the link-layer destination address. If the BROADCAST bit is cleared + to 0, the message SHOULD be sent as an IP unicast to the IP address + specified in the 'yiaddr' field and the link-layer address specified + in the 'chaddr' field. If unicasting is not possible, the message + MAY be sent as an IP broadcast using an IP broadcast address + (preferably 0xffffffff) as the IP destination address and the link- + layer broadcast address as the link-layer destination address. + +4.2 DHCP server administrative controls + + DHCP servers are not required to respond to every DHCPDISCOVER and + DHCPREQUEST message they receive. For example, a network + administrator, to retain stringent control over the clients attached + to the network, may choose to configure DHCP servers to respond only + to clients that have been previously registered through some external + mechanism. The DHCP specification describes only the interactions + between clients and servers when the clients and servers choose to + interact; it is beyond the scope of the DHCP specification to + describe all of the administrative controls that system + administrators might want to use. Specific DHCP server + + + +Droms Standards Track [Page 25] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + implementations may incorporate any controls or policies desired by a + network administrator. + + In some environments, a DHCP server will have to consider the values + of the vendor class options included in DHCPDISCOVER or DHCPREQUEST + messages when determining the correct parameters for a particular + client. + + A DHCP server needs to use some unique identifier to associate a + client with its lease. The client MAY choose to explicitly provide + the identifier through the 'client identifier' option. If the client + supplies a 'client identifier', the client MUST use the same 'client + identifier' in all subsequent messages, and the server MUST use that + identifier to identify the client. If the client does not provide a + 'client identifier' option, the server MUST use the contents of the + 'chaddr' field to identify the client. It is crucial for a DHCP + client to use an identifier unique within the subnet to which the + client is attached in the 'client identifier' option. Use of + 'chaddr' as the client's unique identifier may cause unexpected + results, as that identifier may be associated with a hardware + interface that could be moved to a new client. Some sites may choose + to use a manufacturer's serial number as the 'client identifier', to + avoid unexpected changes in a clients network address due to transfer + of hardware interfaces among computers. Sites may also choose to use + a DNS name as the 'client identifier', causing address leases to be + associated with the DNS name rather than a specific hardware box. + + DHCP clients are free to use any strategy in selecting a DHCP server + among those from which the client receives a DHCPOFFER message. The + client implementation of DHCP SHOULD provide a mechanism for the user + to select directly the 'vendor class identifier' values. + +4.3 DHCP server behavior + + A DHCP server processes incoming DHCP messages from a client based on + the current state of the binding for that client. A DHCP server can + receive the following messages from a client: + + o DHCPDISCOVER + + o DHCPREQUEST + + o DHCPDECLINE + + o DHCPRELEASE + + o DHCPINFORM + + + + +Droms Standards Track [Page 26] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + Table 3 gives the use of the fields and options in a DHCP message by + a server. The remainder of this section describes the action of the + DHCP server for each possible incoming message. + +4.3.1 DHCPDISCOVER message + + When a server receives a DHCPDISCOVER message from a client, the + server chooses a network address for the requesting client. If no + address is available, the server may choose to report the problem to + the system administrator. If an address is available, the new address + SHOULD be chosen as follows: + + o The client's current address as recorded in the client's current + binding, ELSE + + o The client's previous address as recorded in the client's (now + expired or released) binding, if that address is in the server's + pool of available addresses and not already allocated, ELSE + + o The address requested in the 'Requested IP Address' option, if that + address is valid and not already allocated, ELSE + + o A new address allocated from the server's pool of available + addresses; the address is selected based on the subnet from which + the message was received (if 'giaddr' is 0) or on the address of + the relay agent that forwarded the message ('giaddr' when not 0). + + As described in section 4.2, a server MAY, for administrative + reasons, assign an address other than the one requested, or may + refuse to allocate an address to a particular client even though free + addresses are available. + + Note that, in some network architectures (e.g., internets with more + than one IP subnet assigned to a physical network segment), it may be + the case that the DHCP client should be assigned an address from a + different subnet than the address recorded in 'giaddr'. Thus, DHCP + does not require that the client be assigned as address from the + subnet in 'giaddr'. A server is free to choose some other subnet, + and it is beyond the scope of the DHCP specification to describe ways + in which the assigned IP address might be chosen. + + While not required for correct operation of DHCP, the server SHOULD + NOT reuse the selected network address before the client responds to + the server's DHCPOFFER message. The server may choose to record the + address as offered to the client. + + The server must also choose an expiration time for the lease, as + follows: + + + +Droms Standards Track [Page 27] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + o IF the client has not requested a specific lease in the + DHCPDISCOVER message and the client already has an assigned network + address, the server returns the lease expiration time previously + assigned to that address (note that the client must explicitly + request a specific lease to extend the expiration time on a + previously assigned address), ELSE + + o IF the client has not requested a specific lease in the + DHCPDISCOVER message and the client does not have an assigned + network address, the server assigns a locally configured default + lease time, ELSE + + o IF the client has requested a specific lease in the DHCPDISCOVER + message (regardless of whether the client has an assigned network + address), the server may choose either to return the requested + lease (if the lease is acceptable to local policy) or select + another lease. + +Field DHCPOFFER DHCPACK DHCPNAK +----- --------- ------- ------- +'op' BOOTREPLY BOOTREPLY BOOTREPLY +'htype' (From "Assigned Numbers" RFC) +'hlen' (Hardware address length in octets) +'hops' 0 0 0 +'xid' 'xid' from client 'xid' from client 'xid' from client + DHCPDISCOVER DHCPREQUEST DHCPREQUEST + message message message +'secs' 0 0 0 +'ciaddr' 0 'ciaddr' from 0 + DHCPREQUEST or 0 +'yiaddr' IP address offered IP address 0 + to client assigned to client +'siaddr' IP address of next IP address of next 0 + bootstrap server bootstrap server +'flags' 'flags' from 'flags' from 'flags' from + client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST + message message message +'giaddr' 'giaddr' from 'giaddr' from 'giaddr' from + client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST + message message message +'chaddr' 'chaddr' from 'chaddr' from 'chaddr' from + client DHCPDISCOVER client DHCPREQUEST client DHCPREQUEST + message message message +'sname' Server host name Server host name (unused) + or options or options +'file' Client boot file Client boot file (unused) + name or options name or options +'options' options options + + + +Droms Standards Track [Page 28] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +Option DHCPOFFER DHCPACK DHCPNAK +------ --------- ------- ------- +Requested IP address MUST NOT MUST NOT MUST NOT +IP address lease time MUST MUST (DHCPREQUEST) MUST NOT + MUST NOT (DHCPINFORM) +Use 'file'/'sname' fields MAY MAY MUST NOT +DHCP message type DHCPOFFER DHCPACK DHCPNAK +Parameter request list MUST NOT MUST NOT MUST NOT +Message SHOULD SHOULD SHOULD +Client identifier MUST NOT MUST NOT MAY +Vendor class identifier MAY MAY MAY +Server identifier MUST MUST MUST +Maximum message size MUST NOT MUST NOT MUST NOT +All others MAY MAY MUST NOT + + Table 3: Fields and options used by DHCP servers + + Once the network address and lease have been determined, the server + constructs a DHCPOFFER message with the offered configuration + parameters. It is important for all DHCP servers to return the same + parameters (with the possible exception of a newly allocated network + address) to ensure predictable client behavior regardless of which + server the client selects. The configuration parameters MUST be + selected by applying the following rules in the order given below. + The network administrator is responsible for configuring multiple + DHCP servers to ensure uniform responses from those servers. The + server MUST return to the client: + + o The client's network address, as determined by the rules given + earlier in this section, + + o The expiration time for the client's lease, as determined by the + rules given earlier in this section, + + o Parameters requested by the client, according to the following + rules: + + -- IF the server has been explicitly configured with a default + value for the parameter, the server MUST include that value + in an appropriate option in the 'option' field, ELSE + + -- IF the server recognizes the parameter as a parameter + defined in the Host Requirements Document, the server MUST + include the default value for that parameter as given in the + Host Requirements Document in an appropriate option in the + 'option' field, ELSE + + -- The server MUST NOT return a value for that parameter, + + + +Droms Standards Track [Page 29] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + The server MUST supply as many of the requested parameters as + possible and MUST omit any parameters it cannot provide. The + server MUST include each requested parameter only once unless + explicitly allowed in the DHCP Options and BOOTP Vendor + Extensions document. + + o Any parameters from the existing binding that differ from the Host + Requirements Document defaults, + + o Any parameters specific to this client (as identified by + the contents of 'chaddr' or 'client identifier' in the DHCPDISCOVER + or DHCPREQUEST message), e.g., as configured by the network + administrator, + + o Any parameters specific to this client's class (as identified + by the contents of the 'vendor class identifier' + option in the DHCPDISCOVER or DHCPREQUEST message), + e.g., as configured by the network administrator; the parameters + MUST be identified by an exact match between the client's vendor + class identifiers and the client's classes identified in the + server, + + o Parameters with non-default values on the client's subnet. + + The server MAY choose to return the 'vendor class identifier' used to + determine the parameters in the DHCPOFFER message to assist the + client in selecting which DHCPOFFER to accept. The server inserts + the 'xid' field from the DHCPDISCOVER message into the 'xid' field of + the DHCPOFFER message and sends the DHCPOFFER message to the + requesting client. + +4.3.2 DHCPREQUEST message + + A DHCPREQUEST message may come from a client responding to a + DHCPOFFER message from a server, from a client verifying a previously + allocated IP address or from a client extending the lease on a + network address. If the DHCPREQUEST message contains a 'server + identifier' option, the message is in response to a DHCPOFFER + message. Otherwise, the message is a request to verify or extend an + existing lease. If the client uses a 'client identifier' in a + DHCPREQUEST message, it MUST use that same 'client identifier' in all + subsequent messages. If the client included a list of requested + parameters in a DHCPDISCOVER message, it MUST include that list in + all subsequent messages. + + + + + + + +Droms Standards Track [Page 30] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + Any configuration parameters in the DHCPACK message SHOULD NOT + conflict with those in the earlier DHCPOFFER message to which the + client is responding. The client SHOULD use the parameters in the + DHCPACK message for configuration. + + Clients send DHCPREQUEST messages as follows: + + o DHCPREQUEST generated during SELECTING state: + + Client inserts the address of the selected server in 'server + identifier', 'ciaddr' MUST be zero, 'requested IP address' MUST be + filled in with the yiaddr value from the chosen DHCPOFFER. + + Note that the client may choose to collect several DHCPOFFER + messages and select the "best" offer. The client indicates its + selection by identifying the offering server in the DHCPREQUEST + message. If the client receives no acceptable offers, the client + may choose to try another DHCPDISCOVER message. Therefore, the + servers may not receive a specific DHCPREQUEST from which they can + decide whether or not the client has accepted the offer. Because + the servers have not committed any network address assignments on + the basis of a DHCPOFFER, servers are free to reuse offered + network addresses in response to subsequent requests. As an + implementation detail, servers SHOULD NOT reuse offered addresses + and may use an implementation-specific timeout mechanism to decide + when to reuse an offered address. + + o DHCPREQUEST generated during INIT-REBOOT state: + + 'server identifier' MUST NOT be filled in, 'requested IP address' + option MUST be filled in with client's notion of its previously + assigned address. 'ciaddr' MUST be zero. The client is seeking to + verify a previously allocated, cached configuration. Server SHOULD + send a DHCPNAK message to the client if the 'requested IP address' + is incorrect, or is on the wrong network. + + Determining whether a client in the INIT-REBOOT state is on the + correct network is done by examining the contents of 'giaddr', the + 'requested IP address' option, and a database lookup. If the DHCP + server detects that the client is on the wrong net (i.e., the + result of applying the local subnet mask or remote subnet mask (if + 'giaddr' is not zero) to 'requested IP address' option value + doesn't match reality), then the server SHOULD send a DHCPNAK + message to the client. + + + + + + + +Droms Standards Track [Page 31] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + If the network is correct, then the DHCP server should check if + the client's notion of its IP address is correct. If not, then the + server SHOULD send a DHCPNAK message to the client. If the DHCP + server has no record of this client, then it MUST remain silent, + and MAY output a warning to the network administrator. This + behavior is necessary for peaceful coexistence of non- + communicating DHCP servers on the same wire. + + If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on + the same subnet as the server. The server MUST broadcast the + DHCPNAK message to the 0xffffffff broadcast address because the + client may not have a correct network address or subnet mask, and + the client may not be answering ARP requests. + + If 'giaddr' is set in the DHCPREQUEST message, the client is on a + different subnet. The server MUST set the broadcast bit in the + DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the + client, because the client may not have a correct network address + or subnet mask, and the client may not be answering ARP requests. + + o DHCPREQUEST generated during RENEWING state: + + 'server identifier' MUST NOT be filled in, 'requested IP address' + option MUST NOT be filled in, 'ciaddr' MUST be filled in with + client's IP address. In this situation, the client is completely + configured, and is trying to extend its lease. This message will + be unicast, so no relay agents will be involved in its + transmission. Because 'giaddr' is therefore not filled in, the + DHCP server will trust the value in 'ciaddr', and use it when + replying to the client. + + A client MAY choose to renew or extend its lease prior to T1. The + server may choose not to extend the lease (as a policy decision by + the network administrator), but should return a DHCPACK message + regardless. + + o DHCPREQUEST generated during REBINDING state: + + 'server identifier' MUST NOT be filled in, 'requested IP address' + option MUST NOT be filled in, 'ciaddr' MUST be filled in with + client's IP address. In this situation, the client is completely + configured, and is trying to extend its lease. This message MUST + be broadcast to the 0xffffffff IP broadcast address. The DHCP + server SHOULD check 'ciaddr' for correctness before replying to + the DHCPREQUEST. + + + + + + +Droms Standards Track [Page 32] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + The DHCPREQUEST from a REBINDING client is intended to accommodate + sites that have multiple DHCP servers and a mechanism for + maintaining consistency among leases managed by multiple servers. + A DHCP server MAY extend a client's lease only if it has local + administrative authority to do so. + +4.3.3 DHCPDECLINE message + + If the server receives a DHCPDECLINE message, the client has + discovered through some other means that the suggested network + address is already in use. The server MUST mark the network address + as not available and SHOULD notify the local system administrator of + a possible configuration problem. + +4.3.4 DHCPRELEASE message + + Upon receipt of a DHCPRELEASE message, the server marks the network + address as not allocated. The server SHOULD retain a record of the + client's initialization parameters for possible reuse in response to + subsequent requests from the client. + +4.3.5 DHCPINFORM message + + The server responds to a DHCPINFORM message by sending a DHCPACK + message directly to the address given in the 'ciaddr' field of the + DHCPINFORM message. The server MUST NOT send a lease expiration time + to the client and SHOULD NOT fill in 'yiaddr'. The server includes + other parameters in the DHCPACK message as defined in section 4.3.1. + +4.3.6 Client messages + + Table 4 details the differences between messages from clients in + various states. + + --------------------------------------------------------------------- + | |INIT-REBOOT |SELECTING |RENEWING |REBINDING | + --------------------------------------------------------------------- + |broad/unicast |broadcast |broadcast |unicast |broadcast | + |server-ip |MUST NOT |MUST |MUST NOT |MUST NOT | + |requested-ip |MUST |MUST |MUST NOT |MUST NOT | + |ciaddr |zero |zero |IP address |IP address| + --------------------------------------------------------------------- + + Table 4: Client messages from different states + + + + + + + +Droms Standards Track [Page 33] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +4.4 DHCP client behavior + + Figure 5 gives a state-transition diagram for a DHCP client. A + client can receive the following messages from a server: + + o DHCPOFFER + + o DHCPACK + + o DHCPNAK + + The DHCPINFORM message is not shown in figure 5. A client simply + sends the DHCPINFORM and waits for DHCPACK messages. Once the client + has selected its parameters, it has completed the configuration + process. + + Table 5 gives the use of the fields and options in a DHCP message by + a client. The remainder of this section describes the action of the + DHCP client for each possible incoming message. The description in + the following section corresponds to the full configuration procedure + previously described in section 3.1, and the text in the subsequent + section corresponds to the abbreviated configuration procedure + described in section 3.2. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Droms Standards Track [Page 34] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + -------- ------- +| | +-------------------------->| |<-------------------+ +| INIT- | | +-------------------->| INIT | | +| REBOOT |DHCPNAK/ +---------->| |<---+ | +| |Restart| | ------- | | + -------- | DHCPNAK/ | | | + | Discard offer | -/Send DHCPDISCOVER | +-/Send DHCPREQUEST | | | + | | | DHCPACK v | | + ----------- | (not accept.)/ ----------- | | +| | | Send DHCPDECLINE | | | +| REBOOTING | | | | SELECTING |<----+ | +| | | / | | |DHCPOFFER/ | + ----------- | / ----------- | |Collect | + | | / | | | replies | +DHCPACK/ | / +----------------+ +-------+ | +Record lease, set| | v Select offer/ | +timers T1, T2 ------------ send DHCPREQUEST | | + | +----->| | DHCPNAK, Lease expired/ | + | | | REQUESTING | Halt network | + DHCPOFFER/ | | | | + Discard ------------ | | + | | | | ----------- | + | +--------+ DHCPACK/ | | | + | Record lease, set -----| REBINDING | | + | timers T1, T2 / | | | + | | DHCPACK/ ----------- | + | v Record lease, set ^ | + +----------------> ------- /timers T1,T2 | | + +----->| |<---+ | | + | | BOUND |<---+ | | + DHCPOFFER, DHCPACK, | | | T2 expires/ DHCPNAK/ + DHCPNAK/Discard ------- | Broadcast Halt network + | | | | DHCPREQUEST | + +-------+ | DHCPACK/ | | + T1 expires/ Record lease, set | | + Send DHCPREQUEST timers T1, T2 | | + to leasing server | | | + | ---------- | | + | | |------------+ | + +->| RENEWING | | + | |----------------------------+ + ---------- + Figure 5: State-transition diagram for DHCP clients + + + + + + + +Droms Standards Track [Page 35] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +4.4.1 Initialization and allocation of network address + + The client begins in INIT state and forms a DHCPDISCOVER message. + The client SHOULD wait a random time between one and ten seconds to + desynchronize the use of DHCP at startup. The client sets 'ciaddr' + to 0x00000000. The client MAY request specific parameters by + including the 'parameter request list' option. The client MAY + suggest a network address and/or lease time by including the + 'requested IP address' and 'IP address lease time' options. The + client MUST include its hardware address in the 'chaddr' field, if + necessary for delivery of DHCP reply messages. The client MAY + include a different unique identifier in the 'client identifier' + option, as discussed in section 4.2. If the client included a list + of requested parameters in a DHCPDISCOVER message, it MUST include + that list in all subsequent messages. + + The client generates and records a random transaction identifier and + inserts that identifier into the 'xid' field. The client records its + own local time for later use in computing the lease expiration. The + client then broadcasts the DHCPDISCOVER on the local hardware + broadcast address to the 0xffffffff IP broadcast address and 'DHCP + server' UDP port. + + If the 'xid' of an arriving DHCPOFFER message does not match the + 'xid' of the most recent DHCPDISCOVER message, the DHCPOFFER message + must be silently discarded. Any arriving DHCPACK messages must be + silently discarded. + + The client collects DHCPOFFER messages over a period of time, selects + one DHCPOFFER message from the (possibly many) incoming DHCPOFFER + messages (e.g., the first DHCPOFFER message or the DHCPOFFER message + from the previously used server) and extracts the server address from + the 'server identifier' option in the DHCPOFFER message. The time + over which the client collects messages and the mechanism used to + select one DHCPOFFER are implementation dependent. + + + + + + + + + + + + + + + + +Droms Standards Track [Page 36] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +Field DHCPDISCOVER DHCPREQUEST DHCPDECLINE, + DHCPINFORM DHCPRELEASE +----- ------------ ----------- ----------- +'op' BOOTREQUEST BOOTREQUEST BOOTREQUEST +'htype' (From "Assigned Numbers" RFC) +'hlen' (Hardware address length in octets) +'hops' 0 0 0 +'xid' selected by client 'xid' from server selected by + DHCPOFFER message client +'secs' 0 or seconds since 0 or seconds since 0 + DHCP process started DHCP process started +'flags' Set 'BROADCAST' Set 'BROADCAST' 0 + flag if client flag if client + requires broadcast requires broadcast + reply reply +'ciaddr' 0 (DHCPDISCOVER) 0 or client's 0 (DHCPDECLINE) + client's network address client's network + network address (BOUND/RENEW/REBIND) address + (DHCPINFORM) (DHCPRELEASE) +'yiaddr' 0 0 0 +'siaddr' 0 0 0 +'giaddr' 0 0 0 +'chaddr' client's hardware client's hardware client's hardware + address address address +'sname' options, if options, if (unused) + indicated in indicated in + 'sname/file' 'sname/file' + option; otherwise option; otherwise + unused unused +'file' options, if options, if (unused) + indicated in indicated in + 'sname/file' 'sname/file' + option; otherwise option; otherwise + unused unused +'options' options options (unused) + + + + + + + + + + + + + + + + +Droms Standards Track [Page 37] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +Option DHCPDISCOVER DHCPREQUEST DHCPDECLINE, + DHCPINFORM DHCPRELEASE +------ ------------ ----------- ----------- +Requested IP address MAY MUST (in MUST + (DISCOVER) SELECTING or (DHCPDECLINE), + MUST NOT INIT-REBOOT) MUST NOT + (INFORM) MUST NOT (in (DHCPRELEASE) + BOUND or + RENEWING) +IP address lease time MAY MAY MUST NOT + (DISCOVER) + MUST NOT + (INFORM) +Use 'file'/'sname' fields MAY MAY MAY +DHCP message type DHCPDISCOVER/ DHCPREQUEST DHCPDECLINE/ + DHCPINFORM DHCPRELEASE +Client identifier MAY MAY MAY +Vendor class identifier MAY MAY MUST NOT +Server identifier MUST NOT MUST (after MUST + SELECTING) + MUST NOT (after + INIT-REBOOT, + BOUND, RENEWING + or REBINDING) +Parameter request list MAY MAY MUST NOT +Maximum message size MAY MAY MUST NOT +Message SHOULD NOT SHOULD NOT SHOULD +Site-specific MAY MAY MUST NOT +All others MAY MAY MUST NOT + + Table 5: Fields and options used by DHCP clients + + If the parameters are acceptable, the client records the address of + the server that supplied the parameters from the 'server identifier' + field and sends that address in the 'server identifier' field of a + DHCPREQUEST broadcast message. Once the DHCPACK message from the + server arrives, the client is initialized and moves to BOUND state. + The DHCPREQUEST message contains the same 'xid' as the DHCPOFFER + message. The client records the lease expiration time as the sum of + the time at which the original request was sent and the duration of + the lease from the DHCPACK message. The client SHOULD perform a + check on the suggested address to ensure that the address is not + already in use. For example, if the client is on a network that + supports ARP, the client may issue an ARP request for the suggested + request. When broadcasting an ARP request for the suggested address, + the client must fill in its own hardware address as the sender's + hardware address, and 0 as the sender's IP address, to avoid + confusing ARP caches in other hosts on the same subnet. If the + + + +Droms Standards Track [Page 38] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + network address appears to be in use, the client MUST send a + DHCPDECLINE message to the server. The client SHOULD broadcast an ARP + reply to announce the client's new IP address and clear any outdated + ARP cache entries in hosts on the client's subnet. + +4.4.2 Initialization with known network address + + The client begins in INIT-REBOOT state and sends a DHCPREQUEST + message. The client MUST insert its known network address as a + 'requested IP address' option in the DHCPREQUEST message. The client + may request specific configuration parameters by including the + 'parameter request list' option. The client generates and records a + random transaction identifier and inserts that identifier into the + 'xid' field. The client records its own local time for later use in + computing the lease expiration. The client MUST NOT include a + 'server identifier' in the DHCPREQUEST message. The client then + broadcasts the DHCPREQUEST on the local hardware broadcast address to + the 'DHCP server' UDP port. + + Once a DHCPACK message with an 'xid' field matching that in the + client's DHCPREQUEST message arrives from any server, the client is + initialized and moves to BOUND state. The client records the lease + expiration time as the sum of the time at which the DHCPREQUEST + message was sent and the duration of the lease from the DHCPACK + message. + +4.4.3 Initialization with an externally assigned network address + + The client sends a DHCPINFORM message. The client may request + specific configuration parameters by including the 'parameter request + list' option. The client generates and records a random transaction + identifier and inserts that identifier into the 'xid' field. The + client places its own network address in the 'ciaddr' field. The + client SHOULD NOT request lease time parameters. + + The client then unicasts the DHCPINFORM to the DHCP server if it + knows the server's address, otherwise it broadcasts the message to + the limited (all 1s) broadcast address. DHCPINFORM messages MUST be + directed to the 'DHCP server' UDP port. + + Once a DHCPACK message with an 'xid' field matching that in the + client's DHCPINFORM message arrives from any server, the client is + initialized. + + If the client does not receive a DHCPACK within a reasonable period + of time (60 seconds or 4 tries if using timeout suggested in section + 4.1), then it SHOULD display a message informing the user of the + problem, and then SHOULD begin network processing using suitable + + + +Droms Standards Track [Page 39] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + defaults as per Appendix A. + +4.4.4 Use of broadcast and unicast + + The DHCP client broadcasts DHCPDISCOVER, DHCPREQUEST and DHCPINFORM + messages, unless the client knows the address of a DHCP server. The + client unicasts DHCPRELEASE messages to the server. Because the + client is declining the use of the IP address supplied by the server, + the client broadcasts DHCPDECLINE messages. + + When the DHCP client knows the address of a DHCP server, in either + INIT or REBOOTING state, the client may use that address in the + DHCPDISCOVER or DHCPREQUEST rather than the IP broadcast address. + The client may also use unicast to send DHCPINFORM messages to a + known DHCP server. If the client receives no response to DHCP + messages sent to the IP address of a known DHCP server, the DHCP + client reverts to using the IP broadcast address. + +4.4.5 Reacquisition and expiration + + The client maintains two times, T1 and T2, that specify the times at + which the client tries to extend its lease on its network address. + T1 is the time at which the client enters the RENEWING state and + attempts to contact the server that originally issued the client's + network address. T2 is the time at which the client enters the + REBINDING state and attempts to contact any server. T1 MUST be + earlier than T2, which, in turn, MUST be earlier than the time at + which the client's lease will expire. + + To avoid the need for synchronized clocks, T1 and T2 are expressed in + options as relative times [2]. + + At time T1 the client moves to RENEWING state and sends (via unicast) + a DHCPREQUEST message to the server to extend its lease. The client + sets the 'ciaddr' field in the DHCPREQUEST to its current network + address. The client records the local time at which the DHCPREQUEST + message is sent for computation of the lease expiration time. The + client MUST NOT include a 'server identifier' in the DHCPREQUEST + message. + + Any DHCPACK messages that arrive with an 'xid' that does not match + the 'xid' of the client's DHCPREQUEST message are silently discarded. + When the client receives a DHCPACK from the server, the client + computes the lease expiration time as the sum of the time at which + the client sent the DHCPREQUEST message and the duration of the lease + in the DHCPACK message. The client has successfully reacquired its + network address, returns to BOUND state and may continue network + processing. + + + +Droms Standards Track [Page 40] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + If no DHCPACK arrives before time T2, the client moves to REBINDING + state and sends (via broadcast) a DHCPREQUEST message to extend its + lease. The client sets the 'ciaddr' field in the DHCPREQUEST to its + current network address. The client MUST NOT include a 'server + identifier' in the DHCPREQUEST message. + + Times T1 and T2 are configurable by the server through options. T1 + defaults to (0.5 * duration_of_lease). T2 defaults to (0.875 * + duration_of_lease). Times T1 and T2 SHOULD be chosen with some + random "fuzz" around a fixed value, to avoid synchronization of + client reacquisition. + + A client MAY choose to renew or extend its lease prior to T1. The + server MAY choose to extend the client's lease according to policy + set by the network administrator. The server SHOULD return T1 and + T2, and their values SHOULD be adjusted from their original values to + take account of the time remaining on the lease. + + In both RENEWING and REBINDING states, if the client receives no + response to its DHCPREQUEST message, the client SHOULD wait one-half + of the remaining time until T2 (in RENEWING state) and one-half of + the remaining lease time (in REBINDING state), down to a minimum of + 60 seconds, before retransmitting the DHCPREQUEST message. + + If the lease expires before the client receives a DHCPACK, the client + moves to INIT state, MUST immediately stop any other network + processing and requests network initialization parameters as if the + client were uninitialized. If the client then receives a DHCPACK + allocating that client its previous network address, the client + SHOULD continue network processing. If the client is given a new + network address, it MUST NOT continue using the previous network + address and SHOULD notify the local users of the problem. + +4.4.6 DHCPRELEASE + + If the client no longer requires use of its assigned network address + (e.g., the client is gracefully shut down), the client sends a + DHCPRELEASE message to the server. Note that the correct operation + of DHCP does not depend on the transmission of DHCPRELEASE messages. + + + + + + + + + + + + +Droms Standards Track [Page 41] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +5. Acknowledgments + + The author thanks the many (and too numerous to mention!) members of + the DHC WG for their tireless and ongoing efforts in the development + of DHCP and this document. + + The efforts of J Allard, Mike Carney, Dave Lapp, Fred Lien and John + Mendonca in organizing DHCP interoperability testing sessions are + gratefully acknowledged. + + The development of this document was supported in part by grants from + the Corporation for National Research Initiatives (CNRI), Bucknell + University and Sun Microsystems. + +6. References + + [1] Acetta, M., "Resource Location Protocol", RFC 887, CMU, December + 1983. + + [2] Alexander, S., and R. Droms, "DHCP Options and BOOTP Vendor + Extensions", RFC 1533, Lachman Technology, Inc., Bucknell + University, October 1993. + + [3] Braden, R., Editor, "Requirements for Internet Hosts -- + Communication Layers", STD 3, RFC 1122, USC/Information Sciences + Institute, October 1989. + + [4] Braden, R., Editor, "Requirements for Internet Hosts -- + Application and Support, STD 3, RFC 1123, USC/Information + Sciences Institute, October 1989. + + [5] Brownell, D, "Dynamic Reverse Address Resolution Protocol + (DRARP)", Work in Progress. + + [6] Comer, D., and R. Droms, "Uniform Access to Internet Directory + Services", Proc. of ACM SIGCOMM '90 (Special issue of Computer + Communications Review), 20(4):50--59, 1990. + + [7] Croft, B., and J. Gilmore, "Bootstrap Protocol (BOOTP)", RFC 951, + Stanford and SUN Microsystems, September 1985. + + [8] Deering, S., "ICMP Router Discovery Messages", RFC 1256, Xerox + PARC, September 1991. + + [9] Droms, D., "Interoperation between DHCP and BOOTP", RFC 1534, + Bucknell University, October 1993. + + + + + +Droms Standards Track [Page 42] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + [10] Finlayson, R., Mann, T., Mogul, J., and M. Theimer, "A Reverse + Address Resolution Protocol", RFC 903, Stanford, June 1984. + + [11] Gray C., and D. Cheriton, "Leases: An Efficient Fault-Tolerant + Mechanism for Distributed File Cache Consistency", In Proc. of + the Twelfth ACM Symposium on Operating Systems Design, 1989. + + [12] Mockapetris, P., "Domain Names -- Concepts and Facilities", STD + 13, RFC 1034, USC/Information Sciences Institute, November 1987. + + [13] Mockapetris, P., "Domain Names -- Implementation and + Specification", STD 13, RFC 1035, USC/Information Sciences + Institute, November 1987. + + [14] Mogul J., and S. Deering, "Path MTU Discovery", RFC 1191, + November 1990. + + [15] Morgan, R., "Dynamic IP Address Assignment for Ethernet Attached + Hosts", Work in Progress. + + [16] Postel, J., "Internet Control Message Protocol", STD 5, RFC 792, + USC/Information Sciences Institute, September 1981. + + [17] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497, + USC/Information Sciences Institute, August 1993. + + [18] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1700, + USC/Information Sciences Institute, October 1994. + + [19] Jeffrey Schiller and Mark Rosenstein. A Protocol for the Dynamic + Assignment of IP Addresses for use on an Ethernet. (Available + from the Athena Project, MIT), 1989. + + [20] Sollins, K., "The TFTP Protocol (Revision 2)", RFC 783, NIC, + June 1981. + + [21] Wimer, W., "Clarifications and Extensions for the Bootstrap + Protocol", RFC 1542, Carnegie Mellon University, October 1993. + +7. Security Considerations + + DHCP is built directly on UDP and IP which are as yet inherently + insecure. Furthermore, DHCP is generally intended to make + maintenance of remote and/or diskless hosts easier. While perhaps + not impossible, configuring such hosts with passwords or keys may be + difficult and inconvenient. Therefore, DHCP in its current form is + quite insecure. + + + + +Droms Standards Track [Page 43] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + + Unauthorized DHCP servers may be easily set up. Such servers can + then send false and potentially disruptive information to clients + such as incorrect or duplicate IP addresses, incorrect routing + information (including spoof routers, etc.), incorrect domain + nameserver addresses (such as spoof nameservers), and so on. + Clearly, once this seed information is in place, an attacker can + further compromise affected systems. + + Malicious DHCP clients could masquerade as legitimate clients and + retrieve information intended for those legitimate clients. Where + dynamic allocation of resources is used, a malicious client could + claim all resources for itself, thereby denying resources to + legitimate clients. + +8. Author's Address + + Ralph Droms + Computer Science Department + 323 Dana Engineering + Bucknell University + Lewisburg, PA 17837 + + Phone: (717) 524-1145 + EMail: droms@bucknell.edu + + + + + + + + + + + + + + + + + + + + + + + + + + + +Droms Standards Track [Page 44] + +RFC 2131 Dynamic Host Configuration Protocol March 1997 + + +A. Host Configuration Parameters + + IP-layer_parameters,_per_host:_ + + Be a router on/off HRC 3.1 + Non-local source routing on/off HRC 3.3.5 + Policy filters for + non-local source routing (list) HRC 3.3.5 + Maximum reassembly size integer HRC 3.3.2 + Default TTL integer HRC 3.2.1.7 + PMTU aging timeout integer MTU 6.6 + MTU plateau table (list) MTU 7 + IP-layer_parameters,_per_interface:_ + IP address (address) HRC 3.3.1.6 + Subnet mask (address mask) HRC 3.3.1.6 + MTU integer HRC 3.3.3 + All-subnets-MTU on/off HRC 3.3.3 + Broadcast address flavor 0x00000000/0xffffffff HRC 3.3.6 + Perform mask discovery on/off HRC 3.2.2.9 + Be a mask supplier on/off HRC 3.2.2.9 + Perform router discovery on/off RD 5.1 + Router solicitation address (address) RD 5.1 + Default routers, list of: + router address (address) HRC 3.3.1.6 + preference level integer HRC 3.3.1.6 + Static routes, list of: + destination (host/subnet/net) HRC 3.3.1.2 + destination mask (address mask) HRC 3.3.1.2 + type-of-service integer HRC 3.3.1.2 + first-hop router (address) HRC 3.3.1.2 + ignore redirects on/off HRC 3.3.1.2 + PMTU integer MTU 6.6 + perform PMTU discovery on/off MTU 6.6 + + Link-layer_parameters,_per_interface:_ + Trailers on/off HRC 2.3.1 + ARP cache timeout integer HRC 2.3.2.1 + Ethernet encapsulation (RFC 894/RFC 1042) HRC 2.3.3 + + TCP_parameters,_per_host:_ + TTL integer HRC 4.2.2.19 + Keep-alive interval integer HRC 4.2.3.6 + Keep-alive data size 0/1 HRC 4.2.3.6 + +Key: + + MTU = Path MTU Discovery (RFC 1191, Proposed Standard) + RD = Router Discovery (RFC 1256, Proposed Standard) + + + +Droms Standards Track [Page 45] + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b74f4d3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + eu.fraho + jdhcpd + jar + 0.11-SNAPSHOT + jdhcpd + + + 1.8 + UTF-8 + 2.5.1 + 2.7 + 2.10 + 2.2.1 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-eclipse-plugin + ${maven-eclipse-plugin.version} + + true + false + + + + org.apache.maven.plugins + maven-idea-plugin + ${maven-idea-plugin.version} + + true + true + + + + + diff --git a/src/main/java/edu/bucknell/net/JDHCP/DHCPMessage.java b/src/main/java/edu/bucknell/net/JDHCP/DHCPMessage.java new file mode 100644 index 0000000..f6f535a --- /dev/null +++ b/src/main/java/edu/bucknell/net/JDHCP/DHCPMessage.java @@ -0,0 +1,876 @@ +package edu.bucknell.net.JDHCP; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * This class represents a DHCP Message. + * + * @author Jason Goldschmidt, Nick Stone and Simon Frankenberger + */ +public class DHCPMessage { + // ----------------------------------------------------------- + // Constants + // ----------------------------------------------------------- + /** + * Operation for a request + */ + public static final byte OP_REQUEST = 1; + + /** + * Operation for a reply + */ + public static final byte OP_REPLY = 2; + + /** + * Message Code representing a DHCPDISCOVER message + */ + public static final byte DHCPDISCOVER = 1; + + /** + * Message Code representing a DHCPOFFER message + */ + public static final byte DHCPOFFER = 2; + + /** + * Message Code representing a DHCPREQUEST message + */ + public static final byte DHCPREQUEST = 3; + + /** + * Message Code representing a DHCPDECLINE message + */ + public static final byte DHCPDECLINE = 4; + + /** + * Message Code representing a DHCPACK message + */ + public static final byte DHCPACK = 5; + + /** + * Message Code representing a DHCPNAK message + */ + public static final byte DHCPNAK = 6; + + /** + * Message Code representing a DHCPRELEASE message + */ + public static final byte DHCPRELEASE = 7; + + /** + * Message Code representing a DHCPINFORM message + */ + public static final byte DHCPINFORM = 8; + + /** + * Default DHCP client port + */ + public static final int CLIENT_PORT = 68; // client port (by default) + + /** + * Default DHCP server port + */ + public static final int SERVER_PORT = 67; // server port (by default) + + /** + * Broadcast Adress to send packets to + */ + public static InetAddress BROADCAST_ADDR = null; + + + // ----------------------------------------------------------- + // Fields defining a dhcp message + // ----------------------------------------------------------- + /** + * Operation Code.
+ *
+ * Can either be {@link #OP_REQUEST} or {@link #OP_REPLY}. + */ + private byte op; + + /** + * Networktype as defined by + * RFC1340 page 54. + */ + private byte htype; + + /** + * Hardware address length (e.g. '6' for ethernet). + */ + private byte hlen; + + /** + * Client sets to zero, optionally used by relay-agents + * when booting via a relay-agent. + */ + private byte hops; + + /** + * Transaction ID, a random number chosen by the + * client, used by the client and server to associate + * messages and responses between a client and a + * server. + */ + private int xid; + + /** + * Filled in by client, seconds elapsed since client + * started trying to boot. + */ + private short secs; + + /** + * Flags for this message.
+ * The leftmost bit is defined as the BROADCAST (B) flag. + */ + private short flags; + + /** + * Client IP address; filled in by client in + * DHCPREQUEST if verifying previously allocated + * configuration parameters. + */ + private byte ciaddr[] = new byte[4]; + + /** + * 'your' (client) IP address. + */ + private byte yiaddr[] = new byte[4]; + + /** + * IP address of next server to use in bootstrap; + * returned in DHCPOFFER, DHCPACK and DHCPNAK by + * server. + */ + private byte siaddr[] = new byte[4]; + + /** + * Relay agent IP address, used in booting via a + * relay-agent. + */ + private byte giaddr[] = new byte[4]; + + /** + * Client hardware address. + */ + private byte chaddr[] = new byte[16]; + + /** + * Optional server host name, null terminated string. + */ + private byte sname[] = new byte[64]; + + /** + * Boot file name, null terminated string; "generic" + * name or null in DHCPDISCOVER, fully qualified + * directory-path name in DHCPOFFER. + */ + private byte file[] = new byte[128]; + + /** + * Internal representation of the given DHCP options. + */ + private DHCPOptions optionsList = null; + + /** + * global port variable for this message + */ + private int gPort; + + /** + * The destination IP-Adress of this message + */ + private InetAddress destination_IP; + + static { + try { + BROADCAST_ADDR = InetAddress.getByName("255.255.255.255"); + // broadcast address(by default) + } + catch (UnknownHostException e) { + } + } + + // ----------------------------------------------------------- + // Constructors + // ----------------------------------------------------------- + + /** + * Creates empty DHCPMessage object, + * initializes the object, sets the host to the broadcast address, + * the local subnet, binds to the default server port. + */ + public DHCPMessage() { + initialize(); + + destination_IP = BROADCAST_ADDR; + gPort = SERVER_PORT; + } + + /** + * Copy constructor + * creates DHCPMessage from inMessage + * + * @param inMessage The message to be copied + */ + public DHCPMessage(DHCPMessage inMessage) { + initialize(); + + destination_IP = BROADCAST_ADDR; + gPort = SERVER_PORT; + op = inMessage.getOp(); + htype = inMessage.getHtype(); + hlen = inMessage.getHlen(); + hops = inMessage.getHops(); + xid = inMessage.getXid(); + secs = inMessage.getSecs(); + flags = inMessage.getFlags(); + ciaddr = inMessage.getCiaddr(); + yiaddr = inMessage.getYiaddr(); + siaddr = inMessage.getSiaddr(); + giaddr = inMessage.getGiaddr(); + chaddr = inMessage.getChaddr(); + sname = inMessage.getSname(); + file = inMessage.getFile(); + optionsList.internalize(inMessage.getOptions()); + } + + /** + * Copy constructor + * creates DHCPMessage from inMessage and sets server and port. + * + * @param inMessage The message to be copied + * @param inServername The host name + * @param inPort The port number + */ + public DHCPMessage(DHCPMessage inMessage, InetAddress inServername, int inPort) { + initialize(); + + this.destination_IP = inServername; + this.gPort = inPort; + + op = inMessage.getOp(); + htype = inMessage.getHtype(); + hlen = inMessage.getHlen(); + hops = inMessage.getHops(); + xid = inMessage.getXid(); + secs = inMessage.getSecs(); + flags = inMessage.getFlags(); + ciaddr = inMessage.getCiaddr(); + yiaddr = inMessage.getYiaddr(); + siaddr = inMessage.getSiaddr(); + giaddr = inMessage.getGiaddr(); + chaddr = inMessage.getChaddr(); + sname = inMessage.getSname(); + file = inMessage.getFile(); + optionsList.internalize(inMessage.getOptions()); + } + + /** + * Copy constructor + * creates DHCPMessage from inMessage and sets server name. + * + * @param inMessage The message to be copied + * @param inServername The host name + */ + public DHCPMessage(DHCPMessage inMessage, InetAddress inServername) { + initialize(); + + this.destination_IP = inServername; + this.gPort = SERVER_PORT; + + op = inMessage.getOp(); + htype = inMessage.getHtype(); + hlen = inMessage.getHlen(); + hops = inMessage.getHops(); + xid = inMessage.getXid(); + secs = inMessage.getSecs(); + flags = inMessage.getFlags(); + ciaddr = inMessage.getCiaddr(); + yiaddr = inMessage.getYiaddr(); + siaddr = inMessage.getSiaddr(); + giaddr = inMessage.getGiaddr(); + chaddr = inMessage.getChaddr(); + sname = inMessage.getSname(); + file = inMessage.getFile(); + optionsList.internalize(inMessage.getOptions()); + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object, sets the host to a specified host name, + * and binds to a specified port. + * + * @param inServername The host name + * @param inPort The port number + */ + public DHCPMessage(InetAddress inServername, int inPort) { + initialize(); + + destination_IP = inServername; + gPort = inPort; + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object, sets the host to a specified host name, + * and binds to the default port. + * + * @param inServername The host name + */ + public DHCPMessage(InetAddress inServername) { + initialize(); + + destination_IP = inServername; + gPort = SERVER_PORT; + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object, sets the host to the broadcast address, + * and binds to a specified port. + * + * @param inPort The port number + */ + public DHCPMessage(int inPort) { + initialize(); + + destination_IP = BROADCAST_ADDR; + gPort = inPort; + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object with a specified byte array containing + * DHCP message information, sets the host to default host name, the + * local subnet, and bind to the default server port. + * + * @param ibuf The byte array to initialize DHCPMessage object + */ + public DHCPMessage(byte[] ibuf) { + initialize(); + internalize(ibuf); + + destination_IP = BROADCAST_ADDR; + gPort = SERVER_PORT; + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object with a specified byte array containing + * DHCP message information, sets the host to specified host name, + * and binds to the specified port. + * + * @param ibuf The byte array to initialize DHCPMessage object + * @param inServername The hostname + * @param inPort The port number + */ + public DHCPMessage(byte[] ibuf, InetAddress inServername, int inPort) { + initialize(); + internalize(ibuf); + + destination_IP = inServername; + gPort = inPort; + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object with a specified byte array containing + * DHCP message information, sets the host to broadcast address, + * and binds to the specified port. + * + * @param ibuf The byte array to initialize DHCPMessage object + * @param inPort The port number + */ + public DHCPMessage(byte ibuf[], int inPort) { + initialize(); + internalize(ibuf); + + destination_IP = BROADCAST_ADDR; + gPort = inPort; + } + + /** + * Creates an empty DHCPMessage object, + * initializes the object with a specified byte array containing + * DHCP message information, sets the host to specified host name, + * and binds to the specified port. + * + * @param ibuf The byte array to initialize DHCPMessage object + * @param inServername The hostname + */ + public DHCPMessage(byte[] ibuf, InetAddress inServername) { + initialize(); + internalize(ibuf); + + destination_IP = inServername; + gPort = SERVER_PORT; + } + + /** + * Creates a new DHCPMessage object from the giben DataInputStream. + * + * @param inStream The stream to read from + */ + public DHCPMessage(DataInputStream inStream) { + initialize(); + + try { + op = inStream.readByte(); + htype = inStream.readByte(); + hlen = inStream.readByte(); + hops = inStream.readByte(); + xid = inStream.readInt(); + secs = inStream.readShort(); + flags = inStream.readShort(); + inStream.readFully(ciaddr, 0, 4); + inStream.readFully(yiaddr, 0, 4); + inStream.readFully(siaddr, 0, 4); + inStream.readFully(giaddr, 0, 4); + inStream.readFully(chaddr, 0, 16); + inStream.readFully(sname, 0, 64); + inStream.readFully(file, 0, 128); + byte[] options = new byte[312]; + inStream.readFully(options, 0, 312); + optionsList.internalize(options); + } + catch (IOException e) { + System.err.println(e); + } + } + + // ----------------------------------------------------------- + // Methods + // ----------------------------------------------------------- + /** + * Initializes datamembers in the constructors + * every empty DHCPMessage object will by default contain these params. + * Initializes options array from linked list form. + */ + private void initialize() { + optionsList = new DHCPOptions(); + } + + /** + * Converts a DHCPMessage object to a byte array. + * + * @return A byte array with information from DHCPMessage object, + * ready to send. + */ + public synchronized byte[] externalize() { + ByteArrayOutputStream outBStream = new ByteArrayOutputStream(); + DataOutputStream outStream = new DataOutputStream(outBStream); + + try { + outStream.writeByte(op); + outStream.writeByte(htype); + outStream.writeByte(hlen); + outStream.writeByte(hops); + outStream.writeInt(xid); + outStream.writeShort(secs); + outStream.writeShort(flags); + outStream.write(ciaddr, 0, 4); + outStream.write(yiaddr, 0, 4); + outStream.write(siaddr, 0, 4); + outStream.write(giaddr, 0, 4); + outStream.write(chaddr, 0, 16); + outStream.write(sname, 0, 64); + outStream.write(file, 0, 128); + + byte[] options = new byte[312]; + if (optionsList == null) { + initialize(); + } + + options = optionsList.externalize(); + outStream.write(options, 0, 312); + } catch (IOException e) { + System.err.println(e); + } + + // extract the byte array from the Stream + byte data[] = outBStream.toByteArray(); + + return data; + } + + /** + * Convert a specified byte array containing a DHCP message into a + * DHCPMessage object. + * + * @param ibuff Byte array to convert to a DHCPMessage object + * @return A DHCPMessage object with information from byte array. + */ + + public synchronized DHCPMessage internalize(byte[] ibuff) { + ByteArrayInputStream inBStream = + new ByteArrayInputStream(ibuff, 0, ibuff.length); + DataInputStream inStream = new DataInputStream(inBStream); + + try { + op = inStream.readByte(); + htype = inStream.readByte(); + hlen = inStream.readByte(); + hops = inStream.readByte(); + xid = inStream.readInt(); + secs = inStream.readShort(); + flags = inStream.readShort(); + inStream.readFully(ciaddr, 0, 4); + inStream.readFully(yiaddr, 0, 4); + inStream.readFully(siaddr, 0, 4); + inStream.readFully(giaddr, 0, 4); + inStream.readFully(chaddr, 0, 16); + inStream.readFully(sname, 0, 64); + inStream.readFully(file, 0, 128); + + byte[] options = new byte[312]; + inStream.readFully(options, 0, 312); + if (optionsList == null) { + initialize(); + } + + optionsList.internalize(options); + } + catch (IOException e) { + System.err.println(e); + } // end catch + + return this; + } + + /** + * Set message Op code / message type. + * + * @param inOp message Op code / message type + */ + public void setOp(byte inOp) { + op = inOp; + } + + /** + * Set hardware address type. + * + * @param inHtype hardware address type + */ + public void setHtype(byte inHtype) { + htype = inHtype; + } + + /** + * Set hardware address length. + * + * @param inHlen hardware address length + */ + public void setHlen(byte inHlen) { + hlen = inHlen; + } + + /** + * Set hops field. + * + * @param inHops hops field + */ + public void setHops(byte inHops) { + hops = inHops; + } + + /** + * Set transaction ID. + * + * @param inXid transactionID + */ + public void setXid(int inXid) { + xid = inXid; + } + + /** + * Set seconds elapsed since client began address acquisition or + * renewal process. + * + * @param inSecs Seconds elapsed since client began address acquisition + * or renewal process + */ + public void setSecs(short inSecs) { + secs = inSecs; + } + + /** + * Set flags field. + * + * @param inFlags flags field + */ + public void setFlags(short inFlags) { + flags = inFlags; + } + + /** + * Set client IP address. + * + * @param inCiaddr client IP address + */ + public void setCiaddr(byte[] inCiaddr) { + ciaddr = inCiaddr; + } + + /** + * Set 'your' (client) IP address. + * + * @param inYiaddr 'your' (client) IP address + */ + public void setYiaddr(byte[] inYiaddr) { + yiaddr = inYiaddr; + } + + /** + * Set address of next server to use in bootstrap. + * + * @param inSiaddr address of next server to use in bootstrap + */ + public void setSiaddr(byte[] inSiaddr) { + siaddr = inSiaddr; + } + + /** + * Set relay agent IP address. + * + * @param inGiaddr relay agent IP address + */ + public void setGiaddr(byte[] inGiaddr) { + giaddr = inGiaddr; + } + + /** + * Set client harware address. + * + * @param inChaddr client hardware address + */ + public void setChaddr(byte[] inChaddr) { + chaddr = inChaddr; + } + + /** + * Set optional server host name. + * + * @param inSname server host name + */ + public void setSname(byte[] inSname) { + sname = inSname; + } + + /** + * Set boot file name. + * + * @param inFile boot file name + */ + public void setFile(byte[] inFile) { + file = inFile; + } + + /** + * Set message destination port. + * + * @param inPortNum port on message destination host + */ + public void setPort(int inPortNum) { + gPort = inPortNum; + } + + /** + * Set message destination IP + * @param inHost string representation of message destination IP or + * hostname + */ + public void setDestinationHost(String inHost) { + try { + destination_IP = InetAddress.getByName(inHost); + } + catch (Exception e) { + System.err.println(e); + } + } + + /** + * @return message Op code / message type. + */ + public byte getOp() { + return op; + } + + /** + * @return hardware address type. + */ + public byte getHtype() { + return htype; + } + + /** + * @return hardware address length. + */ + public byte getHlen() { + return hlen; + } + + /** + * @return hops field. + */ + public byte getHops() { + return hops; + } + + /** + * @return transaction ID. + */ + public int getXid() { + return xid; + } + + /** + * @return seconds elapsed since client began address + * acquisition or renewal process. + */ + public short getSecs() { + return secs; + } + + /** + * @return flags field. + */ + public short getFlags() { + return flags; + } + + /** + * @return client IP address. + */ + public byte[] getCiaddr() { + return ciaddr; + } + + /** + * @return 'your' (client) IP address. + */ + public byte[] getYiaddr() { + return yiaddr; + } + + /** + * @return address of next server to use in bootstrap. + */ + public byte[] getSiaddr() { + return siaddr; + } + + /** + * @return relay agent IP address. + */ + public byte[] getGiaddr() { + return giaddr; + } + + /** + * @return client harware address. + */ + public byte[] getChaddr() { + return chaddr; + } + + /** + * @return optional server host name. + */ + public byte[] getSname() { + return sname; + } + + /** + * @return boot file name. + */ + public byte[] getFile() { + return file; + } + + /** + * @return a byte array containing options + */ + public byte[] getOptions() { + if (optionsList == null) { + initialize(); + } + return optionsList.externalize(); + } + + /** + * @return An interger representation of the message + * destination port + */ + public int getPort() { + return gPort; + } + + /** + * Get message destination hostname + * + * @return A string representing the hostname of the + * message destination server + */ + public String getDestinationAddress() { + return destination_IP.getHostAddress(); + } + + /** + * Sets DHCP options in DHCPMessage. If option already exists + * then remove old option and insert a new one. + * + * @param inOptNum option number + * @param inOptionData option data + */ + public void setOption(int inOptNum, byte[] inOptionData) { + optionsList.setOption((byte) inOptNum, inOptionData); + } + + /** + * Returns specified DHCP option that matches the input code. Null is + * returned if option is not set. + * + * @param inOptNum option number + * + * @return the option matching input code + */ + public byte[] getOption(int inOptNum) { + if (optionsList == null) { + initialize(); + } + return optionsList.getOption((byte) inOptNum); + } + + /** + * Removes the specified DHCP option that matches the input code. + * + * @param inOptNum option number + */ + public void removeOption(int inOptNum) { + if (optionsList == null) { + initialize(); + } + optionsList.removeOption((byte) inOptNum); + } + + /** + * Report whether or not the input option is set. + * + * @param inOptNum option number + * + * @return is the given option set? + */ + public boolean IsOptSet(int inOptNum) { + if (optionsList == null) { + initialize(); + } + + return optionsList.contains((byte) inOptNum); + } +} diff --git a/src/main/java/edu/bucknell/net/JDHCP/DHCPOptions.java b/src/main/java/edu/bucknell/net/JDHCP/DHCPOptions.java new file mode 100644 index 0000000..9434653 --- /dev/null +++ b/src/main/java/edu/bucknell/net/JDHCP/DHCPOptions.java @@ -0,0 +1,232 @@ +package edu.bucknell.net.JDHCP; + +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * This class represents a linked list of options for a DHCP message. + * Its purpose is to ease option handling such as add, remove or change. + * + * @author Jason Goldschmidt and Simon Frankenberger + */ +public class DHCPOptions { + public static final int OPTION_PAD = 0; + public static final int OPTION_NETMASK = 1; + public static final int OPTION_TIME_OFFSET = 2; + public static final int OPTION_ROUTERS = 3; + public static final int OPTION_TIME_SERVERS = 4; + public static final int OPTION_NAME_SERVERS = 5; + public static final int OPTION_DNS_SERVERS = 6; + public static final int OPTION_LOG_SERVERS = 7; + public static final int OPTION_COOKIE_SERVERS = 8; + public static final int OPTION_LPR_SERVERS = 9; + public static final int OPTION_IMPRESS_SERVERS = 10; + public static final int OPTION_RESSOURCE_LOCATION_SERVERS = 11; + public static final int OPTION_HOSTNAME = 12; + public static final int OPTION_BOOT_FILESIZE = 13; + public static final int OPTION_MERIT_DUMPFILE = 14; + public static final int OPTION_DOMAIN_NAME = 15; + public static final int OPTION_SWAP_SERVER = 16; + public static final int OPTION_ROOT_PATH = 17; + public static final int OPTION_EXTENSIONS_PATH = 18; + public static final int OPTION_END = 255; + + public static final int OPTION_IP_HOST_FORWARDING_ENABLE = 19; + public static final int OPTION_IP_HOST_NON_LOCAL_SOURCE_ROUTING_ENABLE = 20; + public static final int OPTION_IP_HOST_POLICY_FILTERS = 21; + public static final int OPTION_IP_HOST_MAXIMUM_DATAGRAM_REASSEMBLY_SIZE = 22; + public static final int OPTION_IP_HOST_DEFAULT_TTL = 23; + public static final int OPTION_IP_HOST_MTU_AGEING_TIMEOUT = 24; + public static final int OPTION_IP_HOST_MTU_PLATEAU_TABLE = 25; + + public static final int OPTION_IP_INTERFACE_MTU = 26; + public static final int OPTION_IP_INTERFACE_ALL_SUBNETS_LOCAL_ENABLE = 27; + public static final int OPTION_IP_INTERFACE_BROADCAST_ADDRESS = 28; + public static final int OPTION_IP_INTERFACE_PERFORM_MASK_DISCOVERY_ENABLE = 29; + public static final int OPTION_IP_INTERFACE_MASK_SUPPLIER_ENABLE = 30; + public static final int OPTION_IP_INTERFACE_PERFORM_ROUTER_DISCOVERY_ENABLE = 31; + public static final int OPTION_IP_INTERFACE_ROUTER_SOLICITATION_ADDRESS = 32; + public static final int OPTION_IP_INTERFACE_STATIC_ROUTES = 33; + + public static final int OPTION_LINK_TRAILER_ENCAPSULATION_ENABLE = 34; + public static final int OPTION_LINK_ARP_CACHE_TIMEOUT = 35; + public static final int OPTION_LINK_ETHERNET_ENCAPSULATION_ENABLE = 36; + + public static final int OPTION_TCP_DEFAULT_TTL = 37; + public static final int OPTION_TCP_KEEP_ALIVE_INTERVAL = 38; + public static final int OPTION_TCP_KEEP_ALIVE_GERBAGE_ENABLE = 39; + + public static final int OPTION_NIS_DOMAIN = 40; + public static final int OPTION_NIS_SERVERS = 41; + public static final int OPTION_NTP_SERVERS = 42; + + public static final int OPTION_SERVICE_VENDOR_SPECIFIC_INFORMATIONS = 43; + public static final int OPTION_SERVICE_NETBOIS_NAME_SERVERS = 44; + public static final int OPTION_SERVICE_NETBOIS_DATAGRAM_DISTRIBUTION_SERVERS = 45; + public static final int OPTION_SERVICE_NETBOIS_NODE_TYPE = 46; + public static final int OPTION_SERVICE_NETBOIS_SCOPE_TYPE = 47; + public static final int OPTION_SERVICE_X_FONT_SERVERS = 48; + public static final int OPTION_SERVICE_X_DISPLAY_MANAGERS = 49; + + public static final int OPTION_DHCP_IP_ADRESS_REQUESTED = 50; + public static final int OPTION_DHCP_IP_LEASE_TIME = 51; + public static final int OPTION_DHCP_OVERLOAD = 52; + public static final int OPTION_DHCP_MESSAGE_TYPE = 53; + public static final int OPTION_DHCP_SERVER_IDENTIFIER = 54; + public static final int OPTION_DHCP_PARAMETER_REQUEST_LIST = 55; + public static final int OPTION_DHCP_MESSAGE = 56; + public static final int OPTION_DHCP_MAXIMUM_MESSAGE_SIZE = 57; + public static final int OPTION_DHCP_RENEWAL_TIME = 58; + public static final int OPTION_DHCP_REBIND_TIME = 59; + public static final int OPTION_DHCP_CLASS_IDENTIFIER = 60; + public static final int OPTION_DHCP_CLIENT_IDENTIFIER = 61; + + /** + *This inner class represent an entry in the Option Table + */ + + class DHCPOptionsEntry { + protected byte code; + protected byte length; + protected byte content[]; + + public DHCPOptionsEntry(byte entryCode, byte entryLength, + byte entryContent[]) { + code = entryCode; + length = entryLength; + content = entryContent; + } + + public String toString() { + return "Code: " + code + "\nContent: " + new String(content); + } + } + + private Hashtable optionsTable = null; + + public DHCPOptions() { + optionsTable = new Hashtable(); + } + + /** + * Removes option with specified bytecode + * @param entryCode The code of option to be removed + */ + + public void removeOption(byte entryCode) { + optionsTable.remove(new Byte(entryCode)); + } + + /** + * Returns true if option code is set in list; false otherwise + * @param entryCode The node's option code + * @return true if option is set, otherwise false + */ + public boolean contains(byte entryCode) { + return optionsTable.containsKey(new Byte(entryCode)); + } + + /** + * Determines if list is empty + * @return true if there are no options set, otherwise false + */ + public boolean isEmpty() { + return optionsTable.isEmpty(); + } + + /** + * Fetches value of option by its option code + * @param entryCode The node's option code + * @return byte array containing the value of option entryCode. + * null is returned if option is not set. + */ + public byte[] getOption(byte entryCode) { + if (this.contains(entryCode)) { + DHCPOptionsEntry ent = optionsTable.get(new Byte(entryCode)); + return ent.content; + } + else { + return null; + } + } + + /** + * Changes an existing option to new value + * @param entryCode The node's option code + * @param value Content of node option + */ + public void setOption(byte entryCode, byte value[]) { + DHCPOptionsEntry opt = new DHCPOptionsEntry(entryCode, (byte) value.length, value); + optionsTable.put(new Byte(entryCode), opt); + } + + /** + * Returns the option value of a specified option code in a byte array + * @param length Length of option content + * @param position Location in array of option node + * @param options The byte array of options + * @return byte array containing the value for the option + */ + private byte[] getArrayOption(int length, int position, byte options[]) { + byte value[] = new byte[(int) length]; + for (int i = 0; i < (int) length; i++) + value[i] = options[position + i]; + return value; + } + + /** + * Converts an options byte array to a linked list + * @param optionsArray The byte array representation of the options list + */ + public void internalize(byte[] optionsArray) { + + /* Assume options valid and correct */ + int pos = 4; // ignore vendor magic cookie + byte code, length; + byte value[]; + + while (optionsArray[pos] != (byte) 255) { // until end option + code = optionsArray[pos++]; + length = optionsArray[pos++]; + value = getArrayOption(length, pos, optionsArray); + setOption(code, value); + pos += length; // increment position pointer + } + } + + /** + * Converts a linked options list to a byte array + * @return array representation of optionsTable + */ + // todo provide overflow return + public byte[] externalize() { + byte[] options = new byte[312]; + + options[0] = (byte) 99; // insert vendor magic cookie + options[1] = (byte) 130; + options[2] = (byte) 83; + options[3] = (byte) 99; + + int position = 4; + Enumeration e = optionsTable.elements(); + + while (e.hasMoreElements()) { + DHCPOptionsEntry entry = e.nextElement(); + options[position++] = entry.code; + options[position++] = entry.length; + for (int i = 0; i < entry.length; ++i) { + options[position++] = entry.content[i]; + } + } + + options[position] = (byte) 255; // insert end option + return options; + } + + /** + * Prints the options linked list: For testing only. + */ + public void printList() { + System.out.println(optionsTable.toString()); + } +} diff --git a/src/main/java/edu/bucknell/net/JDHCP/DHCPSocket.java b/src/main/java/edu/bucknell/net/JDHCP/DHCPSocket.java new file mode 100644 index 0000000..2d1dde8 --- /dev/null +++ b/src/main/java/edu/bucknell/net/JDHCP/DHCPSocket.java @@ -0,0 +1,106 @@ +package edu.bucknell.net.JDHCP; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketException; +import java.net.UnknownHostException; + +/** + * This class represents a Socket for sending DHCP Messages + * + * @author Jason Goldschmidt and Simon Frankenberger + * + * @see java.net.DatagramSocket + */ + +public class DHCPSocket extends DatagramSocket { + /** + * Default socket timeout (1 second) + */ + private int SOCKET_TIMEOUT = 1000; + + /** + * Default MTU (Maximum Transmission Unit) for ethernet (in bytes) + */ + private int mtu = 1500; + + /** + * Constructor for creating DHCPSocket on a specific port on the local + * machine. + * + * @param inPort The port for the application to bind. + * + * @throws SocketException As thrown by the {@link Socket} constructor + */ + public DHCPSocket(int inPort) throws SocketException { + super(inPort); + setSoTimeout(SOCKET_TIMEOUT); + } + + /** + * Sets the Maximum Transfer Unit for the UDP DHCP Packets to be set. + * + * @param inSize Integer representing desired MTU + */ + public void setMTU(int inSize) { + mtu = inSize; + } + + /** + * Returns the set MTU for this socket + * + * @return The Maximum Transfer Unit set for this socket + */ + public int getMTU() { + return mtu; + } + + /** + * Sends a DHCPMessage object to a predifined host. + * + * @param inMessage Well-formed DHCPMessage to be sent to a server + * + * @throws IOException If the message could not be sent. + */ + public synchronized void send(DHCPMessage inMessage) throws IOException { + byte data[] = new byte[mtu]; + data = inMessage.externalize(); + InetAddress dest = null; + try { + dest = InetAddress.getByName(inMessage.getDestinationAddress()); + } + catch (UnknownHostException e) { + } + + DatagramPacket outgoing = new DatagramPacket(data, data.length, dest, + inMessage.getPort()); + + send(outgoing); // send outgoing message + } + + /** + * Receives a datagram packet containing a DHCP Message into + * a DHCPMessage object. + * + * @return true if message is received, + * false if timeout occurs. + * @param outMessage DHCPMessage object to receive new message into + */ + public synchronized boolean receive(DHCPMessage outMessage) { + try { + DatagramPacket incoming = new DatagramPacket(new byte[mtu], + mtu); + //gSocket. + receive(incoming); // block on receive for SOCKET_TIMEOUT + + outMessage.internalize(incoming.getData()); + } + catch (java.io.IOException e) { + return false; + } // end catch + return true; + } +} diff --git a/src/main/java/eu/fraho/jdhcpd/Application.java b/src/main/java/eu/fraho/jdhcpd/Application.java new file mode 100644 index 0000000..616a165 --- /dev/null +++ b/src/main/java/eu/fraho/jdhcpd/Application.java @@ -0,0 +1,642 @@ +package eu.fraho.jdhcpd; + +/* +JDHCP is a simple to configure and to use DHCP Server. +Copyright (C) 2010 Simon Frankenberger + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Observable; +import java.util.Observer; + +/** + * Main class of the server. Starts a new server and reads user input from + * the console. + * + * @author Simon Frankenberger + */ +public class Application implements Observer { + /** + * Version number + */ + public static final String VERSION = "0.10"; + + /** + * Program name + */ + public static final String NAME = "JDHCPD"; + + /** + * Configuration file + */ + public static final File CONFIG = new File("config.ini"); + + /** + * The netmask to announce + */ + protected static byte[] netmask; + + /** + * The IP-adress of the DHCP-server + */ + protected static byte[] server_ip; + + /** + * The first IP to offer + */ + protected static byte[] first_ip; + + /** + * The las IP to offer + */ + protected static byte[] last_ip; + + /** + * The lease time to announce + */ + protected static byte[] lease_time; + + /** + * The renewal time to announce + */ + protected static byte[] renewal_time; + + /** + * The DNS-Servers to announce + */ + protected static byte[] dns_servers; + + /** + * Parser for the configuration file + */ + protected static IniParser settings = null; + + /** + * An instance of this application for the singleton pattern. + */ + private static Application instance = null; + + /** + * Private static field to tell the server wether it should exit. + */ + private static boolean doExit = false; + + + static { + try { + settings = new IniParser(Application.CONFIG); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Returns the instance of this class, implementation of the singleton + * pattern. + * + * @return instance + */ + public static Application getInstance() { + if(instance == null) instance = new Application(); + + return instance; + } + + /** + * @return first ip adress to offer + */ + public static byte[] getFirstIp() { + return first_ip; + } + + /** + * @return the last ip adress to offer + */ + public static byte[] getLastIp() { + return last_ip; + } + + /** + * @return the time how long this lease is valid + */ + public static byte[] getLeaseTime() { + return lease_time; + } + + /** + * @return the configured netmask to use + */ + public static byte[] getNetmask() { + return netmask; + } + + /** + * @return the time after which the client should renew its lease + */ + public static byte[] getRenewalTime() { + return renewal_time; + } + + /** + * @return the static ip adress of this server + */ + public static byte[] getServerIp() { + return server_ip; + } + + /** + * @return the dns servers to announce + */ + public static byte[] getDNSServers() { + return dns_servers; + } + + /** + * Main method used to instantiate the program. + * + * @param args Arguments, currently only --nogui is implemented. + */ + public static void main(String[] args) { + getInstance(); + + if (args.length > 0 && args[0].equals("--nogui")) { + instance.readConsole(); + instance.close(); + } + else { + gui = new Gui(instance); + } + + + s = new Server(); + s.addObserver(getInstance()); + + s.start(); + } + + /** + * The server object + */ + private static Server s = null; + + /** + * A reference to the gui (if used) + */ + private static Gui gui = null; + + /** + * Creates a new instance of this program and starts the server + */ + public Application() { + System.out.println("JDHCPD Copyright (C) 2010 Simon Frankenberger"); + System.out.println("This program comes with ABSOLUTELY NO WARRANTY."); + System.out.println("This is free software, and you are welcome to redistribute"); + System.out.println("it under certain conditions; read 'LICENCE' for details."); + } + + /** + * Stops the server and exits the application + */ + protected void close() { + s.abort(); + s.waitTillDone(1000); + + System.exit(0); + } + + protected boolean doExit() { + return doExit; + } + + /** + * Retrieves and prints an option on the console. + * + * @param setting The setting to retrieve + * @param new_val Was a new value set? + * + * @return the value which was print + */ + private String get(String setting, boolean new_val) { + String prefix = ""; + + if(new_val) prefix = "new "; + + try { + if (setting.equals("netmask")) { + String val = Tools.byteToIp(netmask); + update(null, prefix + "netmask=" + val); + return val; + } + + if (setting.equals("first_ip")) { + String val = Tools.byteToIp(first_ip); + update(null, prefix + "first_ip=" + val); + return val; + } + + if (setting.equals("last_ip")) { + String val = Tools.byteToIp(last_ip); + update(null, prefix + "last_ip=" + val); + return val; + } + + if (setting.equals("lease_time")) { + String val = String.valueOf(Tools.byteToInt(lease_time)); + update(null, prefix + "lease_time=" + val); + return val; + } + + if (setting.equals("renewal_time")) { + String val = String.valueOf(Tools.byteToInt(renewal_time)); + update(null, prefix + "renewal_time=" + val); + return val; + } + + if (setting.equals("dns_servers")) { + StringBuilder tmp = new StringBuilder(); + + for(int i=0; i 0) tmp.append(" "); + + byte[] akt = new byte[4]; + System.arraycopy(dns_servers, i, akt, 0, 4); + + tmp.append(Tools.byteToIp(akt)); + } + + update(null, prefix + "dns_servers=" + tmp.toString()); + return tmp.toString(); + } + + update(null, "Variable not found."); + } + catch (Exception e) { + update(null, e); + } + + return null; + } + + /** + * Prints the help on the console + */ + private void printHelp() { + StringBuilder hlp = new StringBuilder(); + + hlp.append(NAME + " v" + VERSION + "\n"); + hlp.append("=======================\n"); + hlp.append("help | ?:\n"); + hlp.append("-> Display this help message.\n"); + hlp.append("\n"); + hlp.append("list:\n"); + hlp.append("-> Print table of MAC-Adresses and their leases.\n"); + hlp.append("\n"); + hlp.append("nextip:\n"); + hlp.append("-> Display the next ip adress to offer.\n"); + hlp.append("\n"); + hlp.append("save [FILENAME]:\n"); + hlp.append("-> Save the leases in the given file.\n"); + hlp.append("\n"); + hlp.append("saveconfig:\n"); + hlp.append("-> Save the current configuration.\n"); + hlp.append("\n"); + hlp.append("load [FILENAME]:\n"); + hlp.append("-> Load the leases from the given file.\n"); + hlp.append("\n"); + hlp.append("set [SETTING] [VALUE]:\n"); + hlp.append("-> Set a setting to the given value. Valid settings:\n"); + hlp.append("-> netmask, first_ip, last_ip, lease_time, renewal_time, dns_servers\n"); + hlp.append("\n"); + hlp.append("get [SETTING]:\n"); + hlp.append("-> Display the value of the given setting. Valid settings:\n"); + hlp.append("-> netmask, first_ip, last_ip, lease_time, renewal_time, dns_servers\n"); + hlp.append("\n"); + hlp.append("add [MAC] [IP]:\n"); + hlp.append("-> Add an entry into the table of leases.\n"); + hlp.append("\n"); + hlp.append("remove [IP | MAC]:\n"); + hlp.append("-> Remove an entry from the table of leases.\n"); + hlp.append("\n"); + hlp.append("clear:\n"); + hlp.append("-> Remove all entries from the table of leases.\n"); + hlp.append("\n"); + hlp.append("cls:\n"); + hlp.append("-> Only with GUI: Clears the displayed log entries.\n"); + hlp.append("\n"); + hlp.append("quit | q:\n"); + hlp.append("-> Close the server and exit.\n"); + hlp.append("======================="); + + synchronized (System.out) { + System.out.println(hlp.toString()); + } + + if(gui != null) { + gui.writeMessage(hlp.toString()); + } + } + + /** + * Method to read from the console and interpret user commands. + */ + private void readConsole() { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String line = null; + + try { + while (br != null && (line = br.readLine()) != null && !doExit) { + handleCommand(line); + } + } + catch (IOException e) { + update(null, e); + } + finally { + Tools.close(br); + } + } + + protected void handleCommand(String line) { + line = line.toLowerCase().trim(); + if (line.length() == 0) + return; + + if (line.equals("quit") || line.equals("q")) { + doExit = true; + return; + } + + if (line.equals("help") || line.equals("?")) { + printHelp(); + + return; + } + + if (line.equals("cls")) { + if(gui != null) { + gui.clearLog(); + } + } + + if (line.equals("list")) { + HashMap liste = s.getTable(); + + update(null, "Known MAC-Adresses and IPs:"); + for (String mac : liste.keySet()) { + update(null, mac + " => " + liste.get(mac)); + } + + if (liste.size() == 0) { + update(null, "No entries in table yet."); + } + + update(null, "< ================= >"); + + return; + } + + if (line.equals("saveconfig")) { + try { + settings.save(CONFIG); + } + catch (IOException e) { + update(null, e); + } + } + + if (line.startsWith("remove")) { + String[] parts = line.split(" "); + + if (parts.length == 2) + s.removeClient(parts[1]); + else + update(null, "Argument(s) missing: 'remove [IP | MAC]'"); + + return; + } + + if (line.startsWith("add")) { + String[] parts = line.split(" "); + + if (parts.length == 3) + s.addClient(parts[1], parts[2]); + else + update(null, "Argument(s) missing: 'add [MAC] [IP]'"); + + return; + } + + if (line.equals("nextip")) { + update(null, "Next IP to offer: " + s.getNextIP()); + + return; + } + + if (line.equals("clear")) { + s.removeAll(); + + return; + } + + if (line.startsWith("delete")) { + String[] parts = line.split(" "); + if (parts.length == 2) + new File(parts[1]).delete(); + else + update(null, "Argument(s) missing: 'delete [FILENAME]'"); + + return; + } + + if (line.startsWith("save")) { + String[] parts = line.split(" "); + + try { + if (parts.length == 2) { + s.saveLeases(new File(parts[1])); + update(null, "Leases successfully saved in " + parts[1]); + } + else + update(null, "Argument(s) missing: 'save [FILENAME]'"); + } + catch (IOException e) { + update(null, "Error while accessing file: " + + e.getLocalizedMessage()); + } + + return; + } + + if (line.startsWith("load")) { + String[] parts = line.split(" "); + + try { + if (parts.length == 2) { + s.loadLeases(new File(parts[1])); + update(null, "Leases successfully loaded from " + parts[1]); + } + else + update(null, "Argument(s) missing: 'load [FILENAME]'"); + } + catch (IOException e) { + update(null, "Error while accessing file: " + + e.getLocalizedMessage()); + } + + return; + } + + if (line.startsWith("set")) { + String[] parts = line.split(" ", 3); + + if (parts.length == 3) + set(parts[1], parts[2]); + else + update(null, "Argument(s) missing: 'set [SETTING] [VALUE]'"); + + return; + } + + if (line.startsWith("get")) { + String[] parts = line.split(" "); + + if (parts.length == 2) + get(parts[1], false); + else + update(null, "Argument(s) missing: 'get [SETTING]'"); + + return; + } + + update(null, new Exception("Unknown command: " + line.split(" ")[0])); + } + /** + * Sets an option to the given value and prints it on the console. + * + * @param setting The setting to set + * @param value The value to use + */ + private void set(String setting, String value) { + try { + if (setting.equals("netmask")) { + byte[] data = Tools.ipToByte(value); + if (Tools.checkNetmask(data)) { + netmask = data; + settings.set("global", "netmask", Tools.byteToIp(netmask)); + } + else { + update(null, "Invalid netmask: " + value); + return; + } + } + + if (setting.equals("first_ip")) { + byte[] data = Tools.ipToByte(value); + if (Tools.checkIp(data)) { + first_ip = data; + settings.set("global", "first_ip", Tools.byteToIp(first_ip)); + } + else { + update(null, "Invalid ip: " + value); + return; + } + } + + if (setting.equals("last_ip")) { + byte[] data = Tools.ipToByte(value); + if (Tools.checkIp(data)) { + last_ip = data; + settings.set("global", "last_ip", Tools.byteToIp(last_ip)); + } + else { + update(null, "Invalid ip: " + value); + return; + } + } + + if (setting.equals("lease_time")) { + lease_time = Tools.intToByte(Integer.valueOf(value)); + settings.set("global", "lease_time", Tools.byteToIp(lease_time)); + } + + if (setting.equals("renewal_time")) { + renewal_time = Tools.intToByte(Integer.valueOf(value)); + settings.set("global", "lease_time", Tools.byteToIp(renewal_time)); + } + + if (setting.equals("dns_servers")) { + String[] dns_servers = value.split(" "); + int count = dns_servers.length; + for(int i=0; i 0) { + byte[] akt = Tools.ipToByte(ip); + + System.arraycopy(akt, 0, Application.dns_servers, aktPos*4, 4); + aktPos++; + } + } + + settings.set("global", "dns_servers", get(setting, true)); + settings.save(CONFIG); + + return; + } + + get(setting, true); + settings.save(CONFIG); + } + catch (Exception e) { + update(null, e); + } + } + + @Override + public void update(Observable o, Object arg) { + synchronized (System.out) { + if (arg instanceof Throwable) { + System.out.println("[" + Tools.currentDateTime() + "] " + + ((Throwable) arg).getLocalizedMessage()); + } + else { + System.out.println("[" + Tools.currentDateTime() + "] " + + arg.toString()); + } + } + + if (gui != null) { + gui.writeMessage("[" + Tools.currentDateTime() + "] " + + arg.toString()); + } + } +} diff --git a/src/main/java/eu/fraho/jdhcpd/Gui.java b/src/main/java/eu/fraho/jdhcpd/Gui.java new file mode 100644 index 0000000..58647c9 --- /dev/null +++ b/src/main/java/eu/fraho/jdhcpd/Gui.java @@ -0,0 +1,168 @@ +package eu.fraho.jdhcpd; + +/* +JDHCP is a simple to configure and to use DHCP Server. +Copyright (C) 2010 Simon Frankenberger + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.JTextPane; + +/** + * Class to represent the grafical user interface. + * + * @author Simon Frankenberger + */ +public class Gui implements WindowListener, ActionListener, + KeyListener { + private JFrame window = new JFrame(); + + private JTextPane gui_log = new JTextPane(); + private JTextField gui_cmd = new JTextField(); + private JPanel pnl_bottom = new JPanel(new BorderLayout()); + + private JButton btn_cmd = new JButton("Execute"); + private Application parent = null; + + public Gui(Application parent) { + // Store reference to parent + this.parent = parent; + + // Add the several listeners + window.addWindowListener(this); + btn_cmd.addActionListener(this); + gui_cmd.addKeyListener(this); + + // Configure the frame + window.setSize(600, 400); + window.setTitle(Application.NAME + " v" + Application.VERSION); + window.setLayout(new BorderLayout()); + + // Set up the textpane with the log + gui_log.setText("[" + Tools.currentDateTime() + "] Interface started."); + gui_log.setEditable(false); + gui_log.setFocusable(false); + + // Add the elements to a wrapper panel + pnl_bottom.add(new JLabel("Command: "), BorderLayout.WEST); + pnl_bottom.add(gui_cmd); + pnl_bottom.add(btn_cmd, BorderLayout.EAST); + + // Add all elements to the frame + window.add(new JScrollPane(gui_log), BorderLayout.CENTER); + window.add(pnl_bottom, BorderLayout.SOUTH); + + centerWindow(); + window.setVisible(true); + gui_cmd.requestFocus(); + } + + private void centerWindow() { + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + Point p = new Point(); + + p.x = (d.width - window.getSize().width) / 2; + p.y = (d.height - window.getSize().height) / 2; + + window.setLocation(p); + } + + @Override + public void windowClosing(WindowEvent e) { + window.setVisible(false); + parent.close(); + } + + @Override + public void actionPerformed(ActionEvent e) { + parent.handleCommand(gui_cmd.getText()); + gui_cmd.setText(""); + + if(parent.doExit()) { + window.setVisible(false); + parent.close(); + } + } + + @Override + public void keyReleased(KeyEvent e) { + if(e.getKeyCode() == KeyEvent.VK_ENTER) { + btn_cmd.doClick(); + } + } + + protected void writeMessage(String msg) { + synchronized (gui_log) { + String newText = gui_log.getText() + "\n" + msg; + gui_log.setText(newText); + gui_log.setCaretPosition(newText.length()); + } + } + + protected void clearLog() { + synchronized (gui_log) { + gui_log.setText(""); + } + } + + @Override + public void windowActivated(WindowEvent e) { + } // unused + + @Override + public void windowClosed(WindowEvent e) { + } // unused + + @Override + public void windowDeactivated(WindowEvent e) { + } // unused + + @Override + public void windowDeiconified(WindowEvent e) { + } // unused + + @Override + public void windowIconified(WindowEvent e) { + } // unused + + @Override + public void windowOpened(WindowEvent e) { + } // unused + + @Override + public void keyTyped(KeyEvent e) { + } // unused + + @Override + public void keyPressed(KeyEvent e) { + } // unused +} diff --git a/src/main/java/eu/fraho/jdhcpd/IniParser.java b/src/main/java/eu/fraho/jdhcpd/IniParser.java new file mode 100644 index 0000000..0b016d7 --- /dev/null +++ b/src/main/java/eu/fraho/jdhcpd/IniParser.java @@ -0,0 +1,357 @@ +package eu.fraho.jdhcpd; + +/* +This file is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This file is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file. If not, see . +*/ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; + +/** + * Simple class to read and write ini-files.
+ * These are pretty simple textfiles which can store informations. + * + * @author sfrankenberger + */ +public class IniParser { + /** + * Inner class representing a section inside an ini file. + */ + private class IniSector { + /** + * name of this sector + */ + private String name = ""; + + /** + * the fields which this sector contains + */ + private HashMap fields = null; + + /** + * Creates a new sector with the given name. If name is + * null, the name is set to {@link IniParser#UNDEFINED_SECTION}. + * + * @param name the name of this sector + */ + public IniSector(String name) { + if (name == null || name.equals("")) { + this.name = UNDEFINED_SECTION; + } + else { + this.name = name; + } + + fields = new HashMap(); + } + + @Override + protected void finalize() throws Throwable { + fields.clear(); + fields = null; + } + + /** + * @param name the setting to get + * @return the value of the given setting. Returns null + * if the setting is not set. + */ + public String get(String name) { + if (name == null || name.equals("")) { + return null; + } + + if (ignore_case) { + name = name.toLowerCase(); + } + + return fields.get(name); + } + + /** + * Sets the given setting to a specific value. + * + * @param name the setting to set + * @param value the value to use + */ + public void set(String name, Object value) { + if (name == null || name.equals("")) { + return; + } + if (value == null) { + value = ""; + } + + if (ignore_case) { + name = name.toLowerCase(); + } + + synchronized (this) { + fields.put(name, value.toString()); + } + } + + @Override + public String toString() { + synchronized (this) { + StringBuilder back = new StringBuilder(); + + back.append("[" + name + "]"); + for (String k : fields.keySet()) { + back.append("\n" + k + "=" + fields.get(k)); + } + back.append("\n\n"); + + return back.toString(); + } + } + } + + /** + * The name of an undefined section. Should not be used. + */ + public static final String UNDEFINED_SECTION = "Undefined"; + + /** + * The sectors of this ini file containing the + * field <-> value pairs.
+ * First parameter defines the unique name of this section, + * the second the sector itself. + */ + private HashMap sectors = null; + + /** + * Should the sector names be case insensitive? + */ + private boolean ignore_case = true; + + /** + * was anything changed since last write? + */ + private boolean dirty = false; + + /** + * Creates an empty parser which is case insensitive. + */ + public IniParser() { + this(true); + } + + /** + * Creates an empty ini parse with the given case + * sensitivity. + * + * @param ignore_case should the spelling be ignored? + */ + public IniParser(boolean ignore_case) { + sectors = new HashMap(); + this.ignore_case = ignore_case; + } + + /** + * Parses the given file and initializes this object. + * + * @param f the file to parse + * @throws IOException if anything goes wrong while reading + * the file. + */ + public IniParser(File f) throws IOException { + this(f, true); + } + + /** + * Parses the given file and initializes this object. + * + * @param f the file to parse + * @param ignore_case should the spelling be ignored? + * @throws IOException if anything goes wrong while reading + * the file. + */ + public IniParser(File f, boolean ignore_case) throws IOException { + this(ignore_case); + if (!f.exists()) { + f.createNewFile(); + } + + parse(Tools.readTextFile(f)); + } + + /** + * Returns the value of the field identified by the section name + * and the fieldname as an integer. Returns null if the field + * doesnt exist or is not a valid integer. + * + * @param section the section to use + * @param name the field to get + * @return an integer representing the field or null + * if the field is not set or is not an integer. + */ + public Integer getInt(String section, String name) { + try { + String n = getString(section, name); + + if (n != null) { + return Integer.parseInt(n); + } + } + catch (NumberFormatException e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Returns the value of the field identified by the section name + * and the fieldname as an integer. If the field doesnt exist or is an + * invalid integer, the field is set to the given value. + * + * @param section the section to use + * @param name the field to get + * @param default_value the value to set if not set or invalid + * @return an integer representing the field + */ + public Integer getInt(String section, String name, int default_value) { + Integer n = getInt(section, name); + + if (n == null) { + set(section, name, String.valueOf(default_value)); + return default_value; + } + + return n; + } + + public String getString(String section, String name) { + if (section == null || section == "") { + section = UNDEFINED_SECTION; + } + + if (ignore_case) { + section = section.toLowerCase(); + } + + IniSector s = sectors.get(section); + + if (s == null) { + return null; + } + + return s.get(name); + } + + public String getString(String section, String name, String default_value) { + String s = getString(section, name); + + if (s == null) { + set(section, name, default_value); + return default_value; + } + + return s; + } + + private void parse(String text) { + String[] lines = text.split("\r\n|\r|\n"); + String aktSektion = null; + + for (String line : lines) { + if (line.startsWith("#") || line.length() < 3) { + continue; + } + + if (line.startsWith("[") && line.endsWith("]")) { + aktSektion = line.substring(1, line.length() - 1); + + continue; + } + + if (line.indexOf("=") == -1) { + continue; + } + + if (aktSektion != null) { + String[] parts = line.split("=", 2); + set(aktSektion, parts[0], parts[1]); + } + } + + dirty = false; + return; + } + + public void save(File f) throws IOException { + if (!dirty) + return; + + PrintWriter pw = null; + IOException ex = null; + try { + pw = new PrintWriter(new FileOutputStream(f)); + + pw.print(toString()); + pw.flush(); + pw.close(); + } + catch (IOException e) { + ex = e; + } + finally { + Tools.close(pw); + } + + if (ex != null) { + throw ex; + } + } + + public void set(String section, String name, String value) { + dirty = true; + + if (section == null || section.equals("")) { + section = UNDEFINED_SECTION; + } + + if (ignore_case) { + section = section.toLowerCase(); + } + + IniSector akt = sectors.get(section); + + if (akt != null) { + akt.set(name, value); + } + else { + akt = new IniSector(section); + akt.set(name, value); + sectors.put(section, akt); + } + } + + @Override + public String toString() { + StringBuilder back = new StringBuilder(); + + synchronized (sectors) { + for (IniSector s : sectors.values()) { + back.append(s.toString()); + } + } + + return back.toString(); + } +} diff --git a/src/main/java/eu/fraho/jdhcpd/MyThread.java b/src/main/java/eu/fraho/jdhcpd/MyThread.java new file mode 100644 index 0000000..8e0e60f --- /dev/null +++ b/src/main/java/eu/fraho/jdhcpd/MyThread.java @@ -0,0 +1,122 @@ +package eu.fraho.jdhcpd; + +/* +This file is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This file is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file. If not, see . +*/ + +import java.util.Observable; +import java.util.Observer; + +/** + * Abstract class which is an alternative to Thread, providing the ability + * to notify an observer and an easy way to pause and stop the thread. + * + * @author sfrankenberger + */ +public abstract class MyThread extends Observable implements Runnable { + protected Thread thread = null; + private Object lock = null; + + private boolean aborted = false; + + private boolean paused = false; + + public MyThread() { + lock = new Object(); + } + + public MyThread(Observer o) { + this(); + addObserver(o); + } + + public void abort() { + aborted = true; + } + + protected boolean doContinueWork() { + while (paused) { + try { + Thread.sleep(50); + } + catch (InterruptedException e) { + setChanged(); + notifyObservers(e); + } + } + + if (aborted) { + return false; + } + + return true; + } + + public boolean isAborted() { + return aborted; + } + + public boolean isPaused() { + return paused; + } + + public boolean isRunnning() { + return thread != null && thread.isAlive(); + } + + public void pause(boolean p) { + paused = p; + } + + @Override + public abstract void run(); + + public void setName(String n) { + if (n != null && isRunnning()) + thread.setName(n); + } + + public void start() { + if (isRunnning()) { + return; + } + + synchronized (lock) { + thread = new Thread(this); + thread.start(); + } + } + + public void waitTillDone() { + waitTillDone(-1); + } + + public void waitTillDone(int max) { + int zeit = 0; + + if (max == 0) + zeit = -1; + + while (isRunnning() && zeit < max) { + try { + Thread.sleep(100); + } + catch (InterruptedException e) { + setChanged(); + notifyObservers(e); + } + ; + } + } +} diff --git a/src/main/java/eu/fraho/jdhcpd/Server.java b/src/main/java/eu/fraho/jdhcpd/Server.java new file mode 100644 index 0000000..b9e15bf --- /dev/null +++ b/src/main/java/eu/fraho/jdhcpd/Server.java @@ -0,0 +1,825 @@ +package eu.fraho.jdhcpd; + +/* +JDHCP is a simple to configure and to use DHCP Server. +Copyright (C) 2010 Simon Frankenberger + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashMap; + +import edu.bucknell.net.JDHCP.DHCPMessage; +import edu.bucknell.net.JDHCP.DHCPOptions; +import edu.bucknell.net.JDHCP.DHCPSocket; + +/** + * Class which represents the server. Implemented as a thread which + * listens on all interfaces for incoming DHCP-requests.
+ * Handles all requests and offers ip-adresses which are in the + * given range. + * + * @author sfrankenberger + */ +public class Server extends MyThread { + /** + * Private class which defines IP-Adress ranges and provides the ability + * to check wheter a given IP is in the given range. + * + * @author sfrankenberger + */ + private static class IPRange { + /** + * The first ip adress in this range + */ + private int[] i_from; + + /** + * The last ip adress in this range + */ + private int[] i_till; + + /** + * Creates a new ip adress range between the given adresses. (including) + * + * @param from the first ip in this range + * @param till the last ip in this range + */ + public IPRange(byte[] from, byte[] till) { + i_from = Tools.byteAToIntA(from); + i_till = Tools.byteAToIntA(till); + } + + /** + * Checks whether the given ip adress is in this range. + * + * @param ip the ip adress to check + * @return is the given ip adress in this range? + */ + public boolean inRange(byte[] ip) { + int[] i_ip = Tools.byteAToIntA(ip); + + for (int i = 0; i < 4; i++) { + if (i_ip[i] < i_from[i] || i_ip[i] > i_till[i]) + return false; + } + + return true; + } + + /** + * Returns the next ip adress in this range, starting from the given + * ip adress. + * + * @param ip the ip adress to start from. + * @return the next ip adress in this range. + */ + public byte[] nextIp(byte[] ip) { + int[] akt = { + 0xFF & ip[0], 0xFF & ip[1], + 0xFF & ip[2], 0xFF & ip[3] + }; + akt[3]++; + + if (akt[3] > i_till[3]) { + akt[3] = 1; + akt[2]++; + } + + if (akt[2] > i_till[2]) { + akt[2] = 0; + akt[1]++; + } + + if (akt[1] > i_till[1]) { + akt[1] = 0; + akt[0]++; + } + + byte[] back = { + (byte) akt[0], (byte) akt[1], + (byte) akt[2], (byte) akt[3] + }; + + if (inRange(back)) + return back; + else + return new byte[] { + 0, 0, 0, 0 + }; + } + } + + /** + * Private class to represent a lease. Stores the ip-adress and the time the + * lease was granted. + * + * @author sfrankenberger + */ + private static class Lease { + /** + * The time how long a lease should be valid. + */ + private int lease_time = Tools.byteToInt(Application.getLeaseTime()) * 1000; + + /** + * The ip adress assigned to this lease. + */ + private byte[] ip_byte; + + /** + * A string representation of {@link #ip_byte} + */ + private String ip_string; + + /** + * When was this lease given / renewed? + */ + private long leased; + + /** + * Creates a new lease for the given ip adress. + * @param ip the ip adress to lease + */ + public Lease(byte[] ip) { + ip_byte = ip.clone(); + leased = System.currentTimeMillis() + 600000; + + ip_string = Tools.byteToIp(ip_byte); + } + + /** + * Creates a new lease with a custom leased timestamp. + * + * @param ip the ip adress to lease + * @param leased_timestamp the timestamp when this lease was granted. + */ + public Lease(String ip, String leased_timestamp) { + this(Tools.ipToByte(ip)); + + leased = Long.valueOf(leased_timestamp); + } + + /** + * @return the ip adress of this lease. + */ + public byte[] getIp() { + return ip_byte; + } + + /** + * @return the string representation of the leased ip adress + */ + public String getIpString() { + return ip_string; + } + + /** + * @return when was this lease granted? + */ + public long getLeasedTimestamp() { + return leased; + } + + /** + * @return is this lease still valid? + */ + public boolean isValid() { + return (leased + lease_time >= System.currentTimeMillis()); + } + + /** + * Refreshes a lease (renew it) + */ + public void refreshLease() { + leased = System.currentTimeMillis() + 1000; + } + + public String toString() { + return getIpString() + ", leased until: " + + Tools.dateTime(leased + lease_time); + } + } + + /** + * Private class which checks the leases and deletes expired leases. + * + * @author sfrankenberger + */ + private class LeaseTimer extends MyThread { + /** + * Constructor which initialises the timer. + */ + public LeaseTimer() { + setName("Lease_Timer"); + } + + /** + * Private method to check the leases from {@link Server#adresses} and + * deletes expired ones. + */ + private void check() { + ArrayList toRemove = new ArrayList(); + + synchronized (adresses) { + for (String mac : adresses.keySet()) { + if (!adresses.get(mac).isValid()) { + toRemove.add(mac); + } + } + + for (String mac : toRemove) { + message("Lease for " + adresses.get(mac).getIpString() + " expired."); + adresses.remove(mac); + } + } + } + + /** + * Periodically checks the leases. + */ + public void run() { + while (doContinueWork()) { + check(); + + try { + Thread.sleep(1000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + /** + * A hashmap stiring the mac adresses and leases. + */ + private HashMap adresses; + + /** + * Socket to send / receive dhcp messages. + */ + private DHCPSocket socket; + + /** + * The adress range we should offer + */ + private IPRange iprange; + + /** + * An timer which deletes expired leases. + */ + private LeaseTimer lease_timer; + + /** + * Creates a new instance of this server + */ + public Server() { + loadSettings(); + adresses = new HashMap(); + socket = null; + iprange = new IPRange(Application.getFirstIp(), Application.getLastIp()); + + lease_timer = new LeaseTimer(); + + setName("JDHCPD_Server"); + } + + private void loadSettings() { + try { + IniParser settings = Application.settings; + + Application.first_ip = Tools.ipToByte(settings.getString("global", "first_ip", + "192.168.0.20")); + Application.last_ip = Tools.ipToByte(settings.getString("global", "last_ip", + "192.168.0.254")); + Application.netmask = Tools.ipToByte(settings.getString("global", "netmask", + "255.255.255.0")); + Application.server_ip = Tools.ipToByte(settings.getString("global", "server_ip", + "192.168.0.1")); + Application.lease_time = Tools.intToByte(settings.getInt("global", "lease_time", + Integer.MAX_VALUE)); + Application.renewal_time = Tools.intToByte(settings.getInt("global", "renewal_time", + (int) (Integer.MAX_VALUE * 0.75))); + + String[] dns_servers = settings.getString("global", "dns_servers", + "").split(" |\t"); + + + int count = dns_servers.length; + for(int i=0; i 0) { + byte[] akt = Tools.ipToByte(ip); + + System.arraycopy(akt, 0, Application.dns_servers, aktPos*4, 4); + aktPos++; + } + } + + settings.save(Application.CONFIG); + } + catch (IOException e) { + e.printStackTrace(); + + System.exit(1); + } + } + + @Override + public void abort() { + lease_timer.abort(); + super.abort(); + } + + /** + * Manually adds a mac adress with a new lease. + * + * @param mac the mac adress to use + * @param ip the ip adress to assign + */ + public void addClient(String mac, String ip) { + synchronized (adresses) { + adresses.put(mac, new Lease(Tools.ipToByte(ip))); + } + } + + /** + * Private method which answers a DHCPREQUEST message + * + * @param m the request received from the client + */ + private void answerRequest(DHCPMessage m) { + String mac = Tools.byteToMac(m.getChaddr()); + + if (adresses.containsKey(mac)) { + sendAck(m, adresses.get(mac).getIp(), false); + adresses.get(mac).refreshLease(); + return; + } + + byte[] ip = m.getOption(DHCPOptions.OPTION_DHCP_IP_ADRESS_REQUESTED); + + if (ip == null || !isIpFree(Tools.byteToIp(ip))) { + ip = new byte[4]; + + sendNAck(m, ip); + } + else { + sendAck(m, ip, false); + + synchronized (adresses) { + adresses.put(Tools.byteToMac(m.getChaddr()), new Lease(ip)); + } + } + + return; + } + + /** + * Helper method to get the ip adress of the given mac, or + * if unknown the next free ip in our range. + * + * @param mac the mac adress to look up + * @return a new ip adress or an empty byte[] if no more ip adresses + * are left. + */ + private synchronized byte[] getNextFreeIp(String mac) { + synchronized (adresses) { + if (adresses.containsKey(mac)) + return adresses.get(mac).getIp(); + } + + byte[] back = Application.getFirstIp().clone(); + String ip = Tools.byteToIp(back); + + while (!isIpFree(ip)) { + back = iprange.nextIp(back); + ip = Tools.byteToIp(back); + } + + if (iprange.inRange(back)) + return back; + else + return new byte[] { + 0, 0, 0, 0 + }; + } + + /** + * @return The next free ip adress which will be offered to new clients. + */ + public String getNextIP() { + return Tools.byteToIp(getNextFreeIp(null)); + } + + /** + * @return a copy of our hashmap with the mac adresses and + * leases. Can be used to display the table in the console. + */ + public HashMap getTable() { + HashMap back = new HashMap(); + + synchronized (adresses) { + for (String mac : adresses.keySet()) { + back.put(mac, adresses.get(mac)); + } + } + + return back; + } + + /** + * Private method which handles an incoming dhcp request from a client. + * + * @param m the message to interprete + */ + private void handleRequest(DHCPMessage m) { + byte message_type = m.getOption(DHCPOptions.OPTION_DHCP_MESSAGE_TYPE)[0]; + String mac = Tools.byteToMac(m.getChaddr()); + String hostname = new String(m.getOption(DHCPOptions.OPTION_HOSTNAME)); + + String ident = mac; + + if(hostname != null && hostname.length() > 0) + ident += " (" + hostname + ")"; + + switch (message_type) { + case DHCPMessage.DHCPDISCOVER: + message("DHCPDISCOVER from " + ident); + sendDiscover(m); + break; + case DHCPMessage.DHCPREQUEST: + message("DHCPREQUEST from " + ident); + answerRequest(m); + break; + case DHCPMessage.DHCPDECLINE: + message("DHCPDECLINE from " + ident); + adresses.put(String.valueOf(System.currentTimeMillis()), + new Lease(Tools.ipToByte(Tools.byteToIp(m.getCiaddr())))); + adresses.remove(Tools.byteToMac(m.getChaddr())); + break; + case DHCPMessage.DHCPRELEASE: + message("DHCPRELEASE from " + ident); + adresses.remove(Tools.byteToMac(m.getChaddr())); + break; + case DHCPMessage.DHCPINFORM: + sendAck(m, new byte[4], true); + break; + default: + message("Received packet is an unhandled case. Message Type: " + + (int) message_type); + break; + } + } + + /** + * Checks wheter the given ip adress is not in use. Does a lookup + * in our HashTable {@link #adresses}. + * + * @param ip the ip adress to check + * @return is the given ip free? + */ + private boolean isIpFree(String ip) { + if (ip == null || ip.equals("0.0.0.0")) + return false; + + for (Lease akt : adresses.values()) { + if (akt.getIpString().equals(ip) && akt.isValid()) { + return false; + } + } + + return true; + } + + /** + * Loads the leases from the given file. + * + * @param f the file to lead the leases from + * @throws IOException If anything fails while reading the file. + */ + public void loadLeases(File f) throws IOException { + lease_timer.pause(true); + synchronized (adresses) { + adresses.clear(); + + BufferedReader br = new BufferedReader(new FileReader(f)); + String line = null; + + while ((line = br.readLine()) != null) { + if (line.startsWith("#") || line.trim().length() == 0) + continue; + + String[] parts = line.trim().split(" |\t"); + + adresses.put(parts[0], new Lease(parts[1], parts[2])); + } + } + lease_timer.pause(false); + } + + /** + * Helper method. Sends a message to the observer. + * @param m the message to send + */ + public void message(String m) { + setChanged(); + notifyObservers(m); + } + + /** + * Deletes all leases and removes the clients. + */ + public void removeAll() { + synchronized (adresses) { + adresses.clear(); + } + } + + /** + * Removes a client from the HashTable and marks the allocated ip adress + * as to be free. + * + * @param c the ip oder mac adress to remove + */ + public void removeClient(String c) { + synchronized (adresses) { + if (c.contains(":")) { // MAC + Lease lease = adresses.get(c); + + if (lease != null) { + adresses.remove(c); + message("Client " + c + " (" + lease.getIpString() + ") removed."); + } + } + else { // IP + String toDelete = null; + for (String mac : adresses.keySet()) { + Lease lease = adresses.get(mac); + + if (lease.getIpString().equals(c)) { + toDelete = mac; + } + } + + if (toDelete != null) { + adresses.remove(toDelete); + message("Client " + toDelete + " (" + c + ") removed."); + } + } + } + } + + @Override + public void run() { + message("Server started on " + Tools.byteToIp(Application.getServerIp())); + + try { + socket = new DHCPSocket(DHCPMessage.SERVER_PORT); + adresses.clear(); + } + catch (SocketException e) { + setChanged(); + notifyObservers(e); + + message("Server aborted on " + Tools.byteToIp(Application.getServerIp())); + return; + } + + lease_timer.start(); + while (doContinueWork()) { + DHCPMessage anfrage = new DHCPMessage(); + + if (socket.receive(anfrage)) + handleRequest(anfrage); + } + lease_timer.abort(); + + socket.close(); + socket = null; + adresses.clear(); + adresses = null; + iprange = null; + + message("Server closed on " + Tools.byteToIp(Application.getServerIp())); + } + + /** + * Saves the leases in the given file. + * + * @param f the file to save the leases to. + * @throws IOException If anything fails while writing the file. + */ + public void saveLeases(File f) throws IOException { + lease_timer.pause(true); + synchronized (adresses) { + PrintWriter pw = new PrintWriter(f); + + pw.println("# Saved leases"); + pw.println(); + pw.println("# Format:"); + pw.println("# MAC IP leased_timestamp"); + for (String mac : adresses.keySet()) { + Lease l = adresses.get(mac); + pw.println(mac + "\t" + l.getIpString() + "\t" + + l.getLeasedTimestamp()); + } + + pw.flush(); + pw.close(); + } + lease_timer.pause(false); + } + + /** + * Sends a DHCPACK message with the given ip adress. if unicast is not + * set, the options LEASETIME and RENEWAL_TIME + * are set in the answer. + * + * @param m the message to answer + * @param ip the ip adress of the new client + * @param unicast should the message be sent via the given ip adress? + * If false the message is sent via broadcast + * to all clients. + */ + private void sendAck(DHCPMessage m, byte[] ip, boolean unicast) { + DHCPMessage back = new DHCPMessage(); + + back.setOp(DHCPMessage.OP_REPLY); + back.setHtype(m.getHtype()); + back.setHlen(m.getHlen()); + back.setHops((byte) 0); + back.setXid(m.getXid()); + back.setFlags(m.getFlags()); + back.setYiaddr(ip); + back.setChaddr(m.getChaddr()); + back.setOption(DHCPOptions.OPTION_NETMASK, Application.getNetmask()); + if (!unicast) { + back.setOption(DHCPOptions.OPTION_DHCP_IP_LEASE_TIME, Application.getLeaseTime()); + back.setOption(DHCPOptions.OPTION_DHCP_RENEWAL_TIME, Application.getRenewalTime()); + } + back.setOption(DHCPOptions.OPTION_DHCP_MESSAGE_TYPE, new byte[] { + DHCPMessage.DHCPACK + }); + + if(Application.getDNSServers().length > 4) { + back.setOption(DHCPOptions.OPTION_DNS_SERVERS, Application.getDNSServers()); + } + + try { + byte[] data = back.externalize(); + + if (!unicast) { + socket.send(new DatagramPacket(data, data.length, + DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT)); + } + else { + InetAddress unicast_addr = null; + + try { + unicast_addr = InetAddress.getByAddress(ip); + } + catch (UnknownHostException e) { + setChanged(); + notifyObservers(e); + } + + socket.send(new DatagramPacket(data, data.length, + unicast_addr, DHCPMessage.CLIENT_PORT)); + } + } + catch (IOException e) { + setChanged(); + notifyObservers(e); + + return; + } + + message("DHCPACK to " + Tools.byteToMac(m.getChaddr()) + " for IP " + + Tools.byteToIp(ip)); + } + + /** + * Answers a DHCPDISCOVER message and offers a new ip adress to the client + * + * @param m the message to answer. + */ + private void sendDiscover(DHCPMessage m) { + DHCPMessage back = new DHCPMessage(); + + back.setOp(DHCPMessage.OP_REPLY); + back.setHtype(m.getHtype()); + back.setHlen(m.getHlen()); + back.setHops((byte) 0); + back.setXid(m.getXid()); + back.setFlags(m.getFlags()); + back.setYiaddr(getNextFreeIp(Tools.byteToMac(m.getChaddr()))); + back.setChaddr(m.getChaddr()); + back.setOption(DHCPOptions.OPTION_NETMASK, Application.getNetmask()); + back.setOption(DHCPOptions.OPTION_DHCP_MESSAGE_TYPE, new byte[] { + DHCPMessage.DHCPOFFER + }); + + if(Application.getDNSServers().length > 4) { + back.setOption(DHCPOptions.OPTION_DNS_SERVERS, Application.getDNSServers()); + } + + if (back.getYiaddr()[0] == (byte) 0) { + message("No more IPs left to serve client " + + Tools.byteToMac(m.getChaddr())); + return; + } + + try { + byte[] data = back.externalize(); + socket.send(new DatagramPacket(data, data.length, + DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT)); + } + catch (IOException e) { + setChanged(); + notifyObservers(e); + + return; + } + + synchronized (adresses) { + adresses.put(Tools.byteToMac(m.getChaddr()), new Lease(back.getYiaddr())); + } + + message("DHCPOFFER to " + Tools.byteToMac(m.getChaddr()) + " for IP " + + Tools.byteToIp(back.getYiaddr())); + + return; + } + + /** + * Sends a DHCHNACK message to the given client. + * + * @param m the message to answer + * @param ip the ip adress to send the message to + */ + private void sendNAck(DHCPMessage m, byte[] ip) { + DHCPMessage back = new DHCPMessage(); + + back.setOp(DHCPMessage.OP_REPLY); + back.setHtype(m.getHtype()); + back.setHlen(m.getHlen()); + back.setHops((byte) 0); + back.setXid(m.getXid()); + back.setFlags(m.getFlags()); + back.setYiaddr(ip); + back.setChaddr(m.getChaddr()); + back.setOption(DHCPOptions.OPTION_DHCP_MESSAGE_TYPE, new byte[] { + DHCPMessage.DHCPNAK + }); + + try { + byte[] data = back.externalize(); + socket.send(new DatagramPacket(data, data.length, + DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT)); + } + catch (IOException e) { + setChanged(); + notifyObservers(e); + + return; + } + + message("DHCPNACK to " + Tools.byteToMac(m.getChaddr())); + } +} diff --git a/src/main/java/eu/fraho/jdhcpd/Tools.java b/src/main/java/eu/fraho/jdhcpd/Tools.java new file mode 100644 index 0000000..f5978ce --- /dev/null +++ b/src/main/java/eu/fraho/jdhcpd/Tools.java @@ -0,0 +1,344 @@ +package eu.fraho.jdhcpd; + +/* +This file is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This file is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file. If not, see . +*/ + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Abstract class with only static methods. These methods are pretty generic + * and are used in different locations in the program. + * + * @author sfrankenberger + */ +public abstract class Tools { + /** + * Defines the format how dates are formated + */ + private static final String FORMAT_DATE = "yyyy-MM-dd"; + + /** + * Defines the format how times are formated + */ + private static final String FORMAT_TIME = "HH:mm:ss"; + + /** + * Object which formats dates + */ + private static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat( + FORMAT_DATE); + + /** + * Object which formats times + */ + private static final SimpleDateFormat TIME_FORMATER = new SimpleDateFormat( + FORMAT_TIME); + + /** + * Helper methods to convert 4 bytes into one integer. + * + * @param buffer the bytes to convert + * @return an integer representing the 4 bytes + * + * @see #intToByte(int) + */ + public static int byteToInt(byte[] buffer) { + if (buffer.length != 4) { + throw new IllegalArgumentException("buffer length must be 4 bytes!"); + } + + int value = (0xFF & buffer[0]) << 24; + value |= (0xFF & buffer[1]) << 16; + value |= (0xFF & buffer[2]) << 8; + value |= (0xFF & buffer[3]); + + return value; + } + + /** + * Method to convert 4 bytes to a textual ip adress representation. + * + * @param b the bytes to convert + * @return the bytes as an ip adress + */ + public static String byteToIp(byte[] b) { + StringBuilder back = new StringBuilder(); + + for (int i = 0; i < 4; i++) { + if (i > 0) + back.append("."); + String neu = String.valueOf(0xFF & b[i]); + + back.append(neu); + } + + return back.toString(); + } + + /** + * Helper method to convert 6 bytes to a textual mac adress representation. + * + * @param b the bytes to convert + * @return the bytes as a mac adress + */ + public static String byteToMac(byte[] b) { + StringBuilder back = new StringBuilder(); + + for (int i = 0; i < 6; i++) { + if (i > 0) + back.append(":"); + String neu = Integer.toHexString(0xFF & b[i]); + if (neu.length() == 1) + neu = "0" + neu; + + back.append(neu); + } + + return back.toString(); + } + + /** + * Closes the given Object and catches the exceptions. + * + * @param c the object to close + */ + public static void close(Closeable c) { + if (c == null) { + return; + } + + try { + c.close(); + } + catch (IOException e) { + Application.getInstance().update(null, e); + } + } + + /** + * @return current formatted date + * @see #DATE_FORMATER + */ + public static String currentDate() { + return DATE_FORMATER.format(new Date()); + } + + /** + * @return current formatted date and time, separated by a blank character + */ + public static String currentDateTime() { + return currentDate() + " " + currentTime(); + } + + /** + * @return current formatted time + * @see #TIME_FORMATER + */ + public static String currentTime() { + return TIME_FORMATER.format(new Date()); + } + + /** + * @param s the timestamp to format + * @return The formatted date and time of the timestamp + */ + public static String dateTime(long s) { + Date d = new Date(s); + return DATE_FORMATER.format(d) + " " + TIME_FORMATER.format(d); + } + + /** + * Splits the given int into 4 bytes + * + * @param val the int to convert + * @return a byte array containing 4 elements + * + * @see #byteToInt(byte[]) + */ + public static byte[] intToByte(int val) { + byte[] buffer = new byte[4]; + + buffer[0] = (byte) (val >>> 24); + buffer[1] = (byte) (val >>> 16); + buffer[2] = (byte) (val >>> 8); + buffer[3] = (byte) val; + + return buffer; + } + + /** + * Converts the given ip adress into 4 bytes + * + * @param ip te ip adress to convert + * @return a byte array containing 4 elements + */ + public static byte[] ipToByte(String ip) { + String[] parts = ip.split("\\."); + byte[] back = new byte[4]; + + if (parts.length != 4) + return back; + + for (int i = 0; i < 4; i++) { + int val = Integer.valueOf(parts[i]); + if(val < 0 || val > 255) + return new byte[4]; + + val -= 256; + back[i] = (byte) val; + } + + return back; + } + + /** + * Reads the given file and returns the content + * + * @param f the file to read + * @return an byte array with the files contents + * + * @throws FileNotFoundException if anything goes wrong while reading + * the file. + */ + public static byte[] readFile(File f) throws FileNotFoundException { + if (!f.exists()) { + throw new FileNotFoundException(); + } + + BufferedInputStream in = null; + ByteArrayOutputStream bs = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream(new FileInputStream(f)); + bs = new ByteArrayOutputStream(); + out = new BufferedOutputStream(bs); + + byte[] ioBuf = new byte[8192]; + int bytesRead; + + while ((bytesRead = in.read(ioBuf)) != -1) { + out.write(ioBuf, 0, bytesRead); + } + } + catch (IOException e) { + e.printStackTrace(); + } + finally { + close(in); + close(out); + close(bs); + } + + return bs.toByteArray(); + } + + /** + * Reads the given file and returns a string with the content + * + * @param f the file to read + * @return a string with the files contents + * + * @throws FileNotFoundException if anything goes wrong while reading + * the file. + */ + public static String readTextFile(File f) throws FileNotFoundException { + return new String(readFile(f)); + } + + /** + * Checks whether the given byte[] represents a valid netmask. + * + * @param nm the netmask to check + * @return is the byte[] a netmask? + */ + public static boolean checkNetmask(byte[] nm) { + boolean firstFalse = false; + + for (int i = 0; i < 4; i++) { + boolean[] akt = convertToBits(nm[i]); + for (int b = 0; b < 8; b++) { + if (firstFalse && akt[b]) + return false; + + if (!akt[b]) + firstFalse = true; + } + } + + return true; + } + + /** + * Method to convert a byte into 8 bits. + * + * @param b the byte to convert + * @return 8 booleans as an array + */ + private static boolean[] convertToBits(byte b) { + boolean[] bits = new boolean[8]; + + for (int i = 0; i < 8; i++) { + bits[7 - i] = ((b & (1 << i)) != 0); + } + + return bits; + } + + /** + * Checks wheter the given byte[] represents a valid ip adress which + * can propably announced to a client?
+ * Valid adresses range from 1 to 254 (0 is the net itself, + * 255 is the broadcast adress).
+ *
+ * Note that byte is signed, so the following 2 values are + * interesting for the comparison:
+ *
+	 *   byte    int
+	 *   -----------
+	 *   -1   =  255
+	 *    0   =  0
+	 * 
+ * + * @param ip the ip adress to check + * @return is the byte[] an ip adress? + */ + public static boolean checkIp(byte[] ip) { + return ip.length == 4 && ip[3] != -1 && ip[3] != 0; + } + + /** + * Helper method to convert a byte[] into an int[]. + * + * @param data The byte[] to convert + * @return an int[] representing the given byte[] + */ + public static int[] byteAToIntA(byte[] data) { + int[] back = new int[data.length]; + + for(int i=0; i