From d0c93c365e33f6970a0417dff7009a4a4fe2a3b1 Mon Sep 17 00:00:00 2001 From: Michael Prokop Date: Sat, 2 Dec 2006 10:46:11 +0100 Subject: [PATCH] * Build udhcpc binary from source. --- Makefile | 9 +- debian/TODO | 2 - debian/changelog | 7 +- udhcp/AUTHORS | 13 ++ udhcp/COPYING | 339 ++++++++++++++++++++++++++++++ udhcp/ChangeLog | 260 +++++++++++++++++++++++ udhcp/Makefile | 103 ++++++++++ udhcp/README | 53 +++++ udhcp/README.dumpleases | 17 ++ udhcp/README.udhcpc | 142 +++++++++++++ udhcp/README.udhcpd | 59 ++++++ udhcp/TODO | 16 ++ udhcp/arpping.c | 108 ++++++++++ udhcp/arpping.h | 35 ++++ udhcp/clientpacket.c | 249 ++++++++++++++++++++++ udhcp/clientpacket.h | 14 ++ udhcp/clientsocket.c | 62 ++++++ udhcp/clientsocket.h | 7 + udhcp/common.c | 162 +++++++++++++++ udhcp/common.h | 56 +++++ udhcp/dhcpc.c | 537 ++++++++++++++++++++++++++++++++++++++++++++++++ udhcp/dhcpc.h | 38 ++++ udhcp/dhcpd.c | 275 +++++++++++++++++++++++++ udhcp/dhcpd.h | 141 +++++++++++++ udhcp/dumpleases.1 | 30 +++ udhcp/dumpleases.c | 110 ++++++++++ udhcp/files.c | 346 +++++++++++++++++++++++++++++++ udhcp/files.h | 17 ++ udhcp/frontend.c | 16 ++ udhcp/leases.c | 158 ++++++++++++++ udhcp/leases.h | 23 +++ udhcp/libbb_udhcp.h | 54 +++++ udhcp/options.c | 234 +++++++++++++++++++++ udhcp/options.h | 40 ++++ udhcp/packet.c | 211 +++++++++++++++++++ udhcp/packet.h | 41 ++++ udhcp/pidfile.c | 75 +++++++ udhcp/pidfile.h | 25 +++ udhcp/script.c | 233 +++++++++++++++++++++ udhcp/script.h | 6 + udhcp/serverpacket.c | 275 +++++++++++++++++++++++++ udhcp/serverpacket.h | 12 ++ udhcp/signalpipe.c | 78 +++++++ udhcp/signalpipe.h | 22 ++ udhcp/socket.c | 137 ++++++++++++ udhcp/socket.h | 8 + udhcp/static_leases.c | 119 +++++++++++ udhcp/static_leases.h | 25 +++ udhcp/udhcpc.8 | 208 +++++++++++++++++++ udhcp/udhcpd.8 | 17 ++ udhcp/udhcpd.conf.5 | 166 +++++++++++++++ udhcp/version.h | 6 + udhcpc | Bin 451312 -> 0 bytes 53 files changed, 5391 insertions(+), 5 deletions(-) create mode 100644 udhcp/AUTHORS create mode 100644 udhcp/COPYING create mode 100644 udhcp/ChangeLog create mode 100644 udhcp/Makefile create mode 100644 udhcp/README create mode 100644 udhcp/README.dumpleases create mode 100644 udhcp/README.udhcpc create mode 100644 udhcp/README.udhcpd create mode 100644 udhcp/TODO create mode 100644 udhcp/arpping.c create mode 100644 udhcp/arpping.h create mode 100644 udhcp/clientpacket.c create mode 100644 udhcp/clientpacket.h create mode 100644 udhcp/clientsocket.c create mode 100644 udhcp/clientsocket.h create mode 100644 udhcp/common.c create mode 100644 udhcp/common.h create mode 100644 udhcp/dhcpc.c create mode 100644 udhcp/dhcpc.h create mode 100644 udhcp/dhcpd.c create mode 100644 udhcp/dhcpd.h create mode 100644 udhcp/dumpleases.1 create mode 100644 udhcp/dumpleases.c create mode 100644 udhcp/files.c create mode 100644 udhcp/files.h create mode 100644 udhcp/frontend.c create mode 100644 udhcp/leases.c create mode 100644 udhcp/leases.h create mode 100644 udhcp/libbb_udhcp.h create mode 100644 udhcp/options.c create mode 100644 udhcp/options.h create mode 100644 udhcp/packet.c create mode 100644 udhcp/packet.h create mode 100644 udhcp/pidfile.c create mode 100644 udhcp/pidfile.h create mode 100644 udhcp/script.c create mode 100644 udhcp/script.h create mode 100644 udhcp/serverpacket.c create mode 100644 udhcp/serverpacket.h create mode 100644 udhcp/signalpipe.c create mode 100644 udhcp/signalpipe.h create mode 100644 udhcp/socket.c create mode 100644 udhcp/socket.h create mode 100644 udhcp/static_leases.c create mode 100644 udhcp/static_leases.h create mode 100644 udhcp/udhcpc.8 create mode 100644 udhcp/udhcpd.8 create mode 100644 udhcp/udhcpd.conf.5 create mode 100644 udhcp/version.h delete mode 100755 udhcpc diff --git a/Makefile b/Makefile index ce2f508..9d2651e 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,14 @@ usrbin = $(usr)/bin usrsbin = $(usr)/sbin usrshare = $(usr)/share/$(name) -bin: timeout +bin: timeout udhcpc timeout: timeout.c diet gcc $(CFLAGS) $^ -o $@ + strip --strip-unneeded $@ + +udhcpc: udhcp + cd udhcp ; LDFLAGS='-static' make install: bin $(install_) -d -m 755 $(etc) @@ -33,6 +37,7 @@ install: bin $(install_) -m 755 rdir $(usrshare) $(install_) -m 755 cdir $(usrshare) $(install_) -m 755 timeout $(usrshare) + $(install_) -m 755 udhcp/udhcpc $(usrshare) $(install_) -m 755 discover-nic $(usrshare) cp -r templates $(usrshare) @@ -41,4 +46,4 @@ install: bin $(install_) -m 755 grml-terminalserver-config $(usrsbin) clean: - rm -f timeout + rm -f timeout ; cd udhcp && make clean && cd .. diff --git a/debian/TODO b/debian/TODO index fa3f0b6..e0ab1cd 100644 --- a/debian/TODO +++ b/debian/TODO @@ -1,8 +1,6 @@ TODOs for grml-terminalserver ----------------------------- - * resolv.conf should be copied from the initrd * DON'T delete /var/lib/tftpdboot on a !grml-system * config vars to use external services (dhcp, tftp, nfs) * make pxelinux configurable (to use another pxe-boot-manager) (MAYBE) - * build binaries (timeout, udhcpc,...) from source diff --git a/debian/changelog b/debian/changelog index 9e1cd3f..eaa3951 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,16 @@ grml-terminalserver (0.79) unstable; urgency=low + [mika] * Applied patch from Wolfgang Karall which: - improve display of iptables message - fix the /etc/resolv.conf issue (Closes: issue21) - support for SNAT - Thanks a lot, Wolfgang! + * Build udhcpc binary from source. + + [gebi] + * Added dietlibc-dev to build dependencies + * Slimmed down timeout.c and cleanly compile it from source -- Michael Prokop Sat, 2 Dec 2006 10:29:20 +0100 diff --git a/udhcp/AUTHORS b/udhcp/AUTHORS new file mode 100644 index 0000000..f3f4336 --- /dev/null +++ b/udhcp/AUTHORS @@ -0,0 +1,13 @@ +udhcp server/client package +----------------------- + +Russ Dill +Matthew Ramsay +Chris Trew + +Other Credits: +-------------- +Moreton Bay (http://www.moretonbay.com/) +Vladimir Oleynik Size optimizations + + diff --git a/udhcp/COPYING b/udhcp/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/udhcp/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/udhcp/ChangeLog b/udhcp/ChangeLog new file mode 100644 index 0000000..bf2982f --- /dev/null +++ b/udhcp/ChangeLog @@ -0,0 +1,260 @@ +0.9.9 (pending) ++ Various other size optimizations (Vladimir) ++ Change strerror(errno) to %m (Vladimir N. Oleynik ) ++ Fixed a little endian problem in mton (Bastian Blank ) ++ Fixed a arpping alignment problem (Rui He ) ++ Added sanity check for max_leases (udhcp bug #1285) (me) ++ Finally got rid of the trailing space in enviromental vars (me) ++ added an new enviromental variable: $mask. It contains the number + of subnet bits for tools like ip route that require it. + (Bastian Blank , me) + +0.9.8 (021031) ++ split up README files (me) ++ use /dev/urandom to seed xid's (instead of time(0)) (me) ++ fixed renew behavior (me) ++ udhcp now fits nicely into busybox + (Glenn McGrath as well as myself) ++ updated client manpage (me) ++ both client and server now use sockets for signal handling, + hopefully, this will be the last needed change in signal + handling, I'm fairly certain all the possible races are now + closed. (me) ++ The server now restarts the auto_time timer when it receives + a SIGUSR1 (write out config file). (me) ++ Improve signal handling (David Poole) ++ Fix to config file parsing (Matt Kraai) ++ Fix load lease logic (me) ++ Fix clear_lease logic (me) ++ -h is now an alias for -H (udhcp bug #1253) ++ Shorter timeout on not receiving offers (me) ++ Improved signal behavior by client (me) ++ Would never assign end address (Keith Smith ) ++ Was improperly reporting yiaddr as siaddr (ben-udhcp@bdlow.net) + udhcp bug#1256 ++ Fixed reading of client id (David Poole ) ++ change sys_errlist[] to strerror() as it aparently doesn't exist + (Erik Andersen ) ++ fixed get_raw_packet so it returns -2 on non fatal errors + (Ted Lemon ) ++ Improved (hopefully) NAKing behavior (me) ++ Added -b option (Jouni Malinen) ++ Compute checksums correctly on big endian hosts + (Jouni Malinen ) + +0.9.7 (020526) ++ Use add_lease in read_leases, sanitizes leases more, and clears out exprired + ones if there is no more room (me) ++ Moved udhcpd.leases to /var/lib/misc/udhcpd.leases (Debian bug #147747) ++ Change (obsolete) AF_INET in arping.c to PF_PACKET (Debian bug #127049) ++ Added script hook for DHCPNAK (nak), as well as providing the message option + (me) ++ Generate the paramaters request list by seeing what options in options.c are + ored with OPTION_REQ in options.c ++ Fix dhcp renew forgetfullness on client (bug #1230) ++ Fix dhcp release bug on client (bug #1231) ++ Set option request list for DHCP renew (bug #1233) ++ Set BOOTREQUEST/REPLY properly ++ Change client-identifier field to popularly expected behavior (me) ++ Only reopen port on errors (me) ++ Change fork/close/setsid structures to daemon() (me) ++ Allow user to specify udhcpd config file at run time (Steven, me) ++ Write pidfile after changing it (Steven CTR Carr ) ++ Added env var docs to udhcpc man page (Matt) ++ Standardized lowercase udhcp in documentation (me) ++ Accept packets without a UDP checksum (me) ++ Accept packets with extra garbage (me) ++ Better error handling in files.c (me) ++ Combined read_interface function to reduce COMBINED_BINARY size (me) ++ Drop calc_length(), some servers choke on smaller packets (me) ++ Try to clean some fat out (me) + +0.9.6 (011001) ++ Added bootp paramaters to server (me) ++ Added bootp paramaters to client (me) ++ Added vendor id to client (me) ++ Better pidfile handling in client and server (me) ++ Added man pages (Matt Kraai ) + +0.9.5 (010914) ++ Fixed $HOME and $PATH env passing (me) ++ Fixed client to only listen for raw packets on correct interface (me) ++ added --quit,-q option to quit after a lease is obtained (me) ++ Fixed 100% CPU utilization by client when interface is down (me) + +0.9.4 (010827) ++ Force broadcast to broken clients that request unicast (ie, MSFT 98) ++ Make install rules (Adam J. Richter ) ++ One scripts, instead of many (Adam) ++ Removed script paramater info files (env vars only) (Adam) ++ Controlling of forking behavior in client (Adam) ++ General script.c/dhcpc.c cleanups (Adam) + +0.9.3 (010820) ++ Increased debugging verbosity (me) ++ Cut trailing whitespace when reading config file (me) ++ added hostname option to client (me) ++ fixed a strncpy bug in script.c (me) ++ fixed a leaky socket in dhcpc.c (me) ++ fixed a leaky socket in dhcpd.c (me) + +0.9.2 (010810) ++ Added raw sockets to client (me) ++ alignment fixes (Mark Huang) ++ compiler warning fixes (Mark Huang) ++ client now sends parameter list (Mark Huang/me) ++ added ipttl option ++ Does now not request broadcast packets + +0.9.1 (010806) ++ Added udhcpc client ++ reorganized functions/files ++ listening socket now only binds to one interface + +0.9.0 (010720) Major rewrite, current changes, goals: ++ should not segfault on bogus packets. ++ Options can be read from sname and file fields. ++ supports all DHCP messages (release, decline, inform). ++ IP block is now specified by a range of IP's. ++ Leases file now contains lease time (relative, or absolute). ++ Just about any DHCP option is now supported. ++ DNS entries are no longer read from resolv.conf ++ Lease file can be written periodically when the process receives a SIGUSR1 ++ arpping should be supported on all arches. ++ support for DHCP relays. ++ DHCP messages can be unicast if the client requests it. ++ many, many, many other things. + +0.8.29 (000323) ++ stable(?) release + + +0.8.28 (000323) ++ removed alarm as it was causing server to go down ++ removed debugging ++ break down dhcpd.c into manageable files + + +0.8.27 (000221) ++ OFFER also sends gateway/subnet (for picky dhcp clients) ++ multiple DNS now handled from resolv.conf if available ++ multiple WINS (from dhcpd.conf) + +0.8.25 (000120) ++ now compiles *and* runs on a generic linux system + tested with a windows 98 client and the sample config + files in the samples directory. + +0.8.24 (000117) ++ makeiplist tool has basic functionality in place ++ new sample config files ++ route add -host 255.255.255.255 dev eth0 added for generic linux + +0.8.23 (000117) ++ NETtel specific fix for ignoring dhcp requests on 2nd interface + +0.8.22 (000113) ++ minor changes to compile under a generic linux system ++ minor config file location changes for a generic linux system ++ makeiplist fixes.. still incomplete.. but etting closer + +0.8.21 (000113) ++ now sends the correct server ip instead of hardcoded value ++ minor debugging fixes for critical messages + +0.8.20 (000106) ++ cut out dhcp server checking.. this was causing dialout ppp + sessions with idle time set to never time out. ++ also removed the 10 second pause before launching.. as this + was originally to stop it replying to a dhcp client + on a NETtel which was really a bad way to do it in the + first place :-) + +0.8.19 (000104) ++ fixes for route add -host on a machine that needs to run both + a DHCP client and server (dual eth box) + +0.8.18 (991220) + ++ Race conditions fixed by disabling alarm whilst the server is busy ++ Fixed continous clearing of the offered array so that it is only cleared + when it is dirty - (could change the position of when dirty is set) + +0.8.17 (991212) + +- has problems clearing out the offered array + +0.8.16 (991203) ++ Non blocking error is changes to informational as it is not really + an error + +0.8.15 (991129) ++ Servs the dns field 3 times (Nettel only) so that windows servers + dont time out whilst nettel is booting + +0.8.14 (991126) ++ added owner check for the offered array so clean out time may be + increased ++ added new func to print out chadder/MAC + +0.8.13 (991125) ++ added win95 support (w95 changed xid halfway through conversation) ++ had to change the offered array to use hardware addresses instead of xid ++ fixed re offered bug ++ added more debugging + +0.8.12 (991111) ++ debugging was real bad.. cleaned up a bit.. needs overhaul + + +0.8.11 (991110) ++ fixed up offeredAddr array to actually be used now!! offeredAddr is + used to see if another simultaneous connecting client was offered + an address that we are about to offer another client (multiple + client bug) ++ removed re_offered variable as it breaks multiple client support ++ added lease time to ACK -- doesn't work if in OFFER ++ decreased internal array clear delay to 60 seconds ++ minor findAddr bug (returning -1 instead of 0) ++ if clients xid already in offeredAddr offer the same addr and don't add a + new addr to offered (caused by a client issuing multiple DISCOVERs) + +0.8.10 (991105) ++ \n bug in arpping ++ minor debugging changes (removed printfs etc) ++ started browseiplist (not finished) + +0.8.9 (19991105) ++ fixed options array size bug (options were cut off) + +0.8.8 (19991105) ++ ignores requests from dhcpcd on the same machine + +0.8.7 (19991104) ++ don't die if we can't bind to search for existing DHCP server ++ slightly more verbose syslogging + +0.8.6 (19991103) ++ added makeiplist (not finished -- core dumps) ++ minor debug changes + +0.8.5 (19991029) ++ exits if another DHCP server is already on the network ++ added Linux Makefile + +0.8.4 (19991026) ++ minor bug fix in findaddr preventing an addr being found + +0.8.3 (19991025) ++ fixed up debugging ++ minor hwaddr issues + +0.8.2 (19991022) ++ free leases (new arpping code from dhcpcd) ++ fixed bug where crashes if no leases/iplist file ++ syslogging and debugging switch ++ serve DNS from resolv.conf ++ fixed bug where new lease added if same mac offered ++ now checks the ip is free b4 offering ++ now supports wins server + diff --git a/udhcp/Makefile b/udhcp/Makefile new file mode 100644 index 0000000..52d0ec9 --- /dev/null +++ b/udhcp/Makefile @@ -0,0 +1,103 @@ +# udhcp makefile + +DESTDIR = +prefix = /usr +SBINDIR = /sbin +USRSBINDIR = $(DESTDIR)${prefix}/sbin +USRBINDIR = $(DESTDIR)${prefix}/bin +USRSHAREDIR = $(DESTDIR)${prefix}/share + +# Uncomment this to get a shared binary. Call as udhcpd for the server, +# and udhcpc for the client +#COMBINED_BINARY=1 + +# Uncomment this for extra output and to compile with debugging symbols +#UDHCP_DEBUG=1 + +# Uncomment this to output messages to syslog, otherwise, messages go to stdout +CFLAGS += -DUDHCP_SYSLOG + +#CROSS_COMPILE=arm-uclibc- +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +INSTALL = install + +OBJS_SHARED = common.o options.o packet.o pidfile.o signalpipe.o socket.o +DHCPD_OBJS = dhcpd.o arpping.o files.o leases.o serverpacket.o static_leases.o +DHCPC_OBJS = dhcpc.o clientpacket.o clientsocket.o script.o + +ifdef COMBINED_BINARY +EXEC1 = udhcpd +OBJS1 = $(DHCPD_OBJS) $(DHCPC_OBJS) $(OBJS_SHARED) frontend.o +CFLAGS += -DCOMBINED_BINARY +else +EXEC1 = udhcpd +OBJS1 = $(DHCPD_OBJS) $(OBJS_SHARED) + +EXEC2 = udhcpc +OBJS2 = $(DHCPC_OBJS) $(OBJS_SHARED) +endif + +EXEC3 = dumpleases +OBJS3 = dumpleases.o + +BOOT_PROGRAM = udhcpc +DAEMON = udhcpd +COMMAND = dumpleases + +ifdef UDHCP_SYSLOG +CFLAGS += -DUDHCP_SYSLOG +endif + +CFLAGS += -W -Wall -Wstrict-prototypes -D_GNU_SOURCE + +ifdef UDHCP_DEBUG +CFLAGS += -g -DUDHCP_DEBUG +STRIP=true +else +CFLAGS += -Os -fomit-frame-pointer +STRIP=$(CROSS_COMPILE)strip +endif + +all: $(EXEC1) $(EXEC2) $(EXEC3) + $(STRIP) --remove-section=.note --remove-section=.comment $(EXEC1) $(EXEC2) $(EXEC3) + +$(OBJS1) $(OBJS2) $(OBJS3): *.h Makefile +$(EXEC1) $(EXEC2) $(EXEC3): Makefile + +.c.o: + $(CC) -c $(CFLAGS) $< + +$(EXEC1): $(OBJS1) + $(LD) $(LDFLAGS) $(OBJS1) -o $(EXEC1) + +$(EXEC2): $(OBJS2) + $(LD) $(LDFLAGS) $(OBJS2) -o $(EXEC2) + +$(EXEC3): $(OBJS3) + $(LD) $(LDFLAGS) $(OBJS3) -o $(EXEC3) + + +install: all + mkdir -p $(USRSBINDIR) $(USRBINDIR) + $(INSTALL) -m 755 $(DAEMON) $(USRSBINDIR) + $(INSTALL) -m 755 $(COMMAND) $(USRBINDIR) +ifdef COMBINED_BINARY + ln -sf $(DAEMON) $(USRSBINDIR)/$(BOOT_PROGRAM) +else + $(INSTALL) -m 755 $(BOOT_PROGRAM) $(USRSBINDIR) +endif + mkdir -p $(USRSHAREDIR)/udhcpc + for name in bound deconfig nak renew script ; do \ + $(INSTALL) -m 755 samples/sample.$$name \ + $(USRSHAREDIR)/udhcpc/default.$$name ; \ + done + mkdir -p $(USRSHAREDIR)/man/man1 + $(INSTALL) -m 644 dumpleases.1 $(USRSHAREDIR)/man/man1 + mkdir -p $(USRSHAREDIR)/man/man5 + $(INSTALL) -m 644 udhcpd.conf.5 $(USRSHAREDIR)/man/man5 + mkdir -p $(USRSHAREDIR)/man/man8 + $(INSTALL) -m 644 udhcpc.8 udhcpd.8 $(USRSHAREDIR)/man/man8 + +clean: + -rm -f udhcpd udhcpc dumpleases *.o core diff --git a/udhcp/README b/udhcp/README new file mode 100644 index 0000000..dd99294 --- /dev/null +++ b/udhcp/README @@ -0,0 +1,53 @@ +udhcp server/client package readme +------------------------- + +The udhcp server/client package is primarily geared towards embedded +systems. It does however, strive to be fully functional, and RFC +compliant. + + +compile time options +------------------- + +The Makefile contains three of the compile time options: + + UDHCP_DEBUG: If UDHCP_DEBUG is defined, udhcpd will output extra + debugging output, compile with -g, and not fork to the background when + run. + UDHCP_SYSLOG: If UDHCP_SYSLOG is defined, udhcpd will log all its + messages syslog, otherwise, it will attempt to log them to stdout. + + COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd, + is created. If called as udhcpd, the dhcp server will be started. + If called as udhcpc, the dhcp client will be started. + +dhcpd.h contains the other three compile time options: + + LEASE_TIME: The default lease time if not specified in the config + file. + + LEASES_FILE: The default file for storing leases. + + DHCPD_CONFIG_FILE: The defualt config file to use. + +options.c contains a set of dhcp options for the client: + + name[10]: The name of the option as it will appear in scripts + + flags: The type of option, as well as if it will be requested + by the client (OPTION_REQ) + + code: The DHCP code for this option + + +busybox drop-in +-------------- +udhcp is now a drop-in component for busybox (http://busybox.net). +To update busybox to the latest revision, simply do a: + +cp *.[ch] README AUTHORS COPYING ChangeLog TODO \ + /networking/udhcp + +The only two files udhcp does not provide are config.in and +Makefile.in, so these may need to be updated from time to time. + diff --git a/udhcp/README.dumpleases b/udhcp/README.dumpleases new file mode 100644 index 0000000..6367710 --- /dev/null +++ b/udhcp/README.dumpleases @@ -0,0 +1,17 @@ +udhcp lease dump (dumpleases) +---------------------------- + +dumpleases displays the leases written out by the udhcpd server. Lease +times are stored in the file by time remaining in lease (for systems +without clock that works when there is no power), or by the absolute +time that it expires in seconds from epoch. dumpleases accepts the +following command line options: + +-a, --absolute Interpret lease times as expiration time. +-r, --remaining Interpret lease times as remaining time. +-f, --file=FILE Read lease information from FILE. +-h, --help Display help. + +Note that if udhcpd has not written a leases file recently, the output +of may not be up to date. + diff --git a/udhcp/README.udhcpc b/udhcp/README.udhcpc new file mode 100644 index 0000000..61741d1 --- /dev/null +++ b/udhcp/README.udhcpc @@ -0,0 +1,142 @@ +udhcp client (udhcpc) +-------------------- + +The udhcp client negotiates a lease with the DHCP server and notifies +a set of scripts when a leases is obtained or lost. + + +command line options +------------------- + +The command line options for the udhcp client are: + +-c, --clientid=CLIENTID Client identifier +-H, --hostname=HOSTNAME Client hostname +-h, Alias for -H +-F, --fqdn=FQDN Client fully qualified domain name +-f, --foreground Do not fork after getting lease +-b, --background Fork to background if lease cannot be + immediately negotiated. +-i, --interface=INTERFACE Interface to use (default: eth0) +-n, --now Exit with failure if lease cannot be + immediately negotiated. +-p, --pidfile=file Store process ID of daemon in file +-q, --quit Quit after obtaining lease +-r, --request=IP IP address to request (default: none) +-s, --script=file Run file at dhcp events (default: + /etc/udhcpc/default.script) +-v, --version Display version + + +If the requested IP address cannot be obtained, the client accepts the +address that the server offers. + + +udhcp client scripts +------------------- + +When an event occurs, udhcpc calls the action script. udhcpc never does +any configuration of the network interface itself, but instead relies on +a set of scripts. The script by default is +/etc/udhcpc/default.script but this can be changed via the command +line arguments. The three possible arguments to the script are: + + deconfig: This argument is used when udhcpc starts, and + when a leases is lost. The script must put the interface in an + up, but deconfigured state, ie: ifconfig $interface 0.0.0.0. + + bound: This argument is used when udhcpc moves from an + unbound, to a bound state. All of the paramaters are set in + enviromental variables, The script should configure the interface, + and set any other relavent parameters (default gateway, dns server, + etc). + + renew: This argument is used when a DHCP lease is renewed. All of + the paramaters are set in enviromental variables. This argument is + used when the interface is already configured, so the IP address, + will not change, however, the other DHCP paramaters, such as the + default gateway, subnet mask, and dns server may change. + + nak: This argument is used with udhcpc receives a NAK message. + The script with the deconfig argument will be called directly + afterwards, so no changes to the network interface are neccessary. + This hook is provided for purely informational purposes (the + message option may contain a reason for the NAK). + +The paramaters for enviromental variables are as follows: + + $HOME - The set $HOME env or "/" + $PATH - the set $PATH env or "/bin:/usr/bin:/sbin:/usr/sbin" + $1 - What action the script should perform + interface - The interface this was obtained on + ip - The obtained IP + mask - The number of bits in the netmask (ie: 24) + siaddr - The bootp next server option + sname - The bootp server name option + boot_file - The bootp boot file option + subnet - The assigend subnet mask + timezone - Offset in seconds from UTC + router - A list of routers + timesvr - A list of time servers + namesvr - A list of IEN 116 name servers + dns - A list of DNS server + logsvr - A list of MIT-LCS UDP log servers + cookiesvr - A list of RFC 865 cookie servers + lprsvr - A list of LPR servers + hostname - The assigned hostname + bootsize - The length in 512 octect blocks of the bootfile + domain - The domain name of the network + swapsvr - The IP address of the client's swap server + rootpath - The path name of the client's root disk + ipttl - The TTL to use for this network + mtu - The MTU to use for this network + broadcast - The broadcast address for this network + ntpsrv - A list of NTP servers + wins - A list of WINS servers + lease - The lease time, in seconds + dhcptype - DHCP message type (safely ignored) + serverid - The IP of the server + message - Reason for a DHCPNAK + tftp - The TFTP server name + bootfile - The bootfile name + +additional options are easily added in options.c. + + +note on udhcpc's random seed +--------------------------- + +udhcpc will seed its random number generator (used for generating xid's) +by reading /dev/urandom. If you have a lot of embedded systems on the same +network, with no entropy, you can either seed /dev/urandom by a method of +your own, or doing the following on startup: + +ifconfig eth0 > /dev/urandom + +in order to seed /dev/urandom with some data (mac address) unique to your +system. If reading /dev/urandom fails, udhcpc will fall back to its old +behavior of seeding with time(0). + + +signals accepted by udhcpc +------------------------- + +udhcpc also responds to SIGUSR1 and SIGUSR2. SIGUSR1 will force a renew state, +and SIGUSR2 will force a release of the current lease, and cause udhcpc to +go into an inactive state (until it is killed, or receives a SIGUSR1). You do +not need to sleep between sending signals, as signals received are processed +sequencially in the order they are received. + + +compile time options +------------------- + +options.c contains a set of dhcp options for the client: + + name[10]: The name of the option as it will appear in scripts + + flags: The type of option, as well as if it will be requested + by the client (OPTION_REQ) + + code: The DHCP code for this option + diff --git a/udhcp/README.udhcpd b/udhcp/README.udhcpd new file mode 100644 index 0000000..169de78 --- /dev/null +++ b/udhcp/README.udhcpd @@ -0,0 +1,59 @@ +udhcp server (udhcpd) +-------------------- + +The only command line argument to udhcpd is an optional specifed +config file. If no config file is specified, udhcpd uses the default +config file, /etc/udhcpd.conf. Ex: + +udhcpd /etc/udhcpd.eth1.conf + +The udhcp server employs a number of simple config files: + +udhcpd.leases +------------ + +The udhcpd.leases behavior is designed for an embedded system. The +file is written either every auto_time seconds, or when a SIGUSR1 +is received (the auto_time timer restarts if a SIGUSR1 is received). +If you send a SIGTERM to udhcpd directly after a SIGUSR1, udhcpd will +finish writing the leases file and wait for the aftermentioned script +to be executed and finish before quiting, so you do not need to sleep +between sending signals. When the file is written, a script can be +optionally called to commit the file to flash. Lease times are stored +in the file by time remaining in lease (for systems without clock +that works when there is no power), or by the absolute time that it +expires in seconds from epoch. In the remaining format, expired leases +are stored as zero. The file is of the format: + +16 byte MAC +4 byte ip address +u32 expire time +16 byte MAC +4 byte ip address +u32 expire time +. +etc. + +example: hexdump udhcpd.leases + +0000000 1000 c95a 27d9 0000 0000 0000 0000 0000 +0000010 a8c0 150a 0d00 2d29 5000 23fc 8566 0000 +0000020 0000 0000 0000 0000 a8c0 140a 0d00 4e29 +0000030 + + +udhcpd.conf +---------- + +The format is fairly simple, there is a sample file with all the +available options and comments describing them in samples/udhcpd.conf + +compile time options +------------------- + +dhcpd.h contains the other two compile time options: + + LEASE_TIME: The default lease time if not specified in the config + file. + + DHCPD_CONFIG_FILE: The defualt config file to use. diff --git a/udhcp/TODO b/udhcp/TODO new file mode 100644 index 0000000..6febe5a --- /dev/null +++ b/udhcp/TODO @@ -0,0 +1,16 @@ +TODO +---- ++ Check for valid IP, netmask, hostname, paths, strings, etc ++ Integrade README.*'s with manpages ++ using time(0) breaks if the system clock changes, find a portable solution ++ make failure of reading functions revert to previous value, not the default ++ sanity code for option[OPT_LEN] ++ fix aliasing (ie: eth0:0) ++ better standard linux distro support ++ make sure packet generation works on a wide varitey of arches ++ Interoperability testing ++ Hooks within the DHCP server + * Server notification when a lease is added/removed ++ Additional bootp support in client/server ++ Make serverid option in server configurable ++ Possibly add failure message to DHCP NAK diff --git a/udhcp/arpping.c b/udhcp/arpping.c new file mode 100644 index 0000000..6662d0b --- /dev/null +++ b/udhcp/arpping.c @@ -0,0 +1,108 @@ +/* + * arpping.c + * + * Mostly stolen from: dhcpcd - DHCP client daemon + * by Yoichi Hariguchi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcpd.h" +#include "arpping.h" +#include "common.h" + +/* args: yiaddr - what IP to ping + * ip - our ip + * mac - our arp address + * interface - interface to use + * retn: 1 addr free + * 0 addr used + * -1 error + */ + +/* FIXME: match response against chaddr */ +int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface) +{ + + int timeout = 2; + int optval = 1; + int s; /* socket */ + int rv = 1; /* return value */ + struct sockaddr addr; /* for interface name */ + struct arpMsg arp; + fd_set fdset; + struct timeval tm; + time_t prevTime; + + + if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) { +#ifdef IN_BUSYBOX + LOG(LOG_ERR, bb_msg_can_not_create_raw_socket); +#else + LOG(LOG_ERR, "Could not open raw socket"); +#endif + return -1; + } + + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) == -1) { + LOG(LOG_ERR, "Could not setsocketopt on raw socket"); + close(s); + return -1; + } + + /* send arp request */ + memset(&arp, 0, sizeof(arp)); + memcpy(arp.h_dest, MAC_BCAST_ADDR, 6); /* MAC DA */ + memcpy(arp.h_source, mac, 6); /* MAC SA */ + arp.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */ + arp.htype = htons(ARPHRD_ETHER); /* hardware type */ + arp.ptype = htons(ETH_P_IP); /* protocol type (ARP message) */ + arp.hlen = 6; /* hardware address length */ + arp.plen = 4; /* protocol address length */ + arp.operation = htons(ARPOP_REQUEST); /* ARP op code */ + memcpy(arp.sInaddr, &ip, sizeof(ip)); /* source IP address */ + memcpy(arp.sHaddr, mac, 6); /* source hardware address */ + memcpy(arp.tInaddr, &yiaddr, sizeof(yiaddr)); /* target IP address */ + + memset(&addr, 0, sizeof(addr)); + //closes http://bugs.debian.org/283582 + //strcpy(addr.sa_data, interface); + strncpy(addr.sa_data, interface, sizeof(addr.sa_data)-1); + if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) + rv = 0; + + /* wait arp reply, and check it */ + tm.tv_usec = 0; + prevTime = uptime(); + while (timeout > 0) { + FD_ZERO(&fdset); + FD_SET(s, &fdset); + tm.tv_sec = timeout; + if (select(s + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) < 0) { + DEBUG(LOG_ERR, "Error on ARPING request: %m"); + if (errno != EINTR) rv = 0; + } else if (FD_ISSET(s, &fdset)) { + if (recv(s, &arp, sizeof(arp), 0) < 0 ) rv = 0; + if (arp.operation == htons(ARPOP_REPLY) && + bcmp(arp.tHaddr, mac, 6) == 0 && + *((uint32_t *) arp.sInaddr) == yiaddr) { + DEBUG(LOG_INFO, "Valid arp reply receved for this address"); + rv = 0; + break; + } + } + timeout -= uptime() - prevTime; + prevTime = uptime(); + } + close(s); + DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V"); + return rv; +} diff --git a/udhcp/arpping.h b/udhcp/arpping.h new file mode 100644 index 0000000..6f27d9f --- /dev/null +++ b/udhcp/arpping.h @@ -0,0 +1,35 @@ +/* + * arpping .h + */ + +#ifndef ARPPING_H +#define ARPPING_H + +#include +#include +#include +#include + +struct arpMsg { + /* Ethernet header */ + u_char h_dest[6]; /* destination ether addr */ + u_char h_source[6]; /* source ether addr */ + u_short h_proto; /* packet type ID field */ + + /* ARP packet */ + uint16_t htype; /* hardware type (must be ARPHRD_ETHER) */ + uint16_t ptype; /* protocol type (must be ETH_P_IP) */ + uint8_t hlen; /* hardware address length (must be 6) */ + uint8_t plen; /* protocol address length (must be 4) */ + uint16_t operation; /* ARP opcode */ + uint8_t sHaddr[6]; /* sender's hardware address */ + uint8_t sInaddr[4]; /* sender's IP address */ + uint8_t tHaddr[6]; /* target's hardware address */ + uint8_t tInaddr[4]; /* target's IP address */ + uint8_t pad[18]; /* pad for min. Ethernet payload (60 bytes) */ +} __attribute__ ((packed)); + +/* function prototypes */ +int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface); + +#endif diff --git a/udhcp/clientpacket.c b/udhcp/clientpacket.c new file mode 100644 index 0000000..c5e1c21 --- /dev/null +++ b/udhcp/clientpacket.c @@ -0,0 +1,249 @@ +/* clientpacket.c + * + * Packet generation and dispatching functions for the DHCP client. + * + * Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 +#include +#include +#else +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include + + +#include "dhcpd.h" +#include "clientpacket.h" +#include "options.h" +#include "dhcpc.h" +#include "common.h" + + +/* Create a random xid */ +unsigned long random_xid(void) +{ + static int initialized; + if (!initialized) { + int fd; + unsigned long seed; + + fd = open("/dev/urandom", 0); + if (fd < 0 || read(fd, &seed, sizeof(seed)) < 0) { + LOG(LOG_WARNING, "Could not load seed from /dev/urandom: %m"); + seed = time(0); + } + if (fd >= 0) close(fd); + srand(seed); + initialized++; + } + return rand(); +} + + +/* initialize a packet with the proper defaults */ +static void init_packet(struct dhcpMessage *packet, char type) +{ + struct vendor { + char vendor, length; + char str[sizeof("udhcp "VERSION)]; + } vendor_id = { DHCP_VENDOR, sizeof("udhcp "VERSION) - 1, "udhcp "VERSION}; + + init_header(packet, type); + memcpy(packet->chaddr, client_config.arp, 6); + add_option_string(packet->options, client_config.clientid); + if (client_config.hostname) add_option_string(packet->options, client_config.hostname); + if (client_config.fqdn) add_option_string(packet->options, client_config.fqdn); + add_option_string(packet->options, (uint8_t *) &vendor_id); +} + + +/* Add a parameter request list for stubborn DHCP servers. Pull the data + * from the struct in options.c. Don't do bounds checking here because it + * goes towards the head of the packet. */ +static void add_requests(struct dhcpMessage *packet) +{ + int end = end_option(packet->options); + int i, len = 0; + + packet->options[end + OPT_CODE] = DHCP_PARAM_REQ; + for (i = 0; dhcp_options[i].code; i++) + if (dhcp_options[i].flags & OPTION_REQ) + packet->options[end + OPT_DATA + len++] = dhcp_options[i].code; + packet->options[end + OPT_LEN] = len; + packet->options[end + OPT_DATA + len] = DHCP_END; + +} + + +/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ +int send_discover(unsigned long xid, unsigned long requested) +{ + struct dhcpMessage packet; + + init_packet(&packet, DHCPDISCOVER); + packet.xid = xid; + if (requested) + add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); + + add_requests(&packet); + LOG(LOG_DEBUG, "Sending discover..."); + return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, + SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); +} + + +/* Broadcasts a DHCP request message */ +int send_selecting(unsigned long xid, unsigned long server, unsigned long requested) +{ + struct dhcpMessage packet; + struct in_addr addr; + + init_packet(&packet, DHCPREQUEST); + packet.xid = xid; + + add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); + add_simple_option(packet.options, DHCP_SERVER_ID, server); + + add_requests(&packet); + addr.s_addr = requested; + LOG(LOG_DEBUG, "Sending select for %s...", inet_ntoa(addr)); + return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, + SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); +} + + +/* Unicasts or broadcasts a DHCP renew message */ +int send_renew(unsigned long xid, unsigned long server, unsigned long ciaddr) +{ + struct dhcpMessage packet; + int ret = 0; + + init_packet(&packet, DHCPREQUEST); + packet.xid = xid; + packet.ciaddr = ciaddr; + + add_requests(&packet); + LOG(LOG_DEBUG, "Sending renew..."); + if (server) + ret = kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); + else ret = raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, + SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); + return ret; +} + + +/* Unicasts a DHCP release message */ +int send_release(unsigned long server, unsigned long ciaddr) +{ + struct dhcpMessage packet; + + init_packet(&packet, DHCPRELEASE); + packet.xid = random_xid(); + packet.ciaddr = ciaddr; + + add_simple_option(packet.options, DHCP_REQUESTED_IP, ciaddr); + add_simple_option(packet.options, DHCP_SERVER_ID, server); + + LOG(LOG_DEBUG, "Sending release..."); + return kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); +} + + +/* return -1 on errors that are fatal for the socket, -2 for those that aren't */ +int get_raw_packet(struct dhcpMessage *payload, int fd) +{ + int bytes; + struct udp_dhcp_packet packet; + uint32_t source, dest; + uint16_t check; + + memset(&packet, 0, sizeof(struct udp_dhcp_packet)); + bytes = read(fd, &packet, sizeof(struct udp_dhcp_packet)); + if (bytes < 0) { + DEBUG(LOG_INFO, "couldn't read on raw listening socket -- ignoring"); + usleep(500000); /* possible down interface, looping condition */ + return -1; + } + + if (bytes < (int) (sizeof(struct iphdr) + sizeof(struct udphdr))) { + DEBUG(LOG_INFO, "message too short, ignoring"); + return -2; + } + + if (bytes < ntohs(packet.ip.tot_len)) { + DEBUG(LOG_INFO, "Truncated packet"); + return -2; + } + + /* ignore any extra garbage bytes */ + bytes = ntohs(packet.ip.tot_len); + + /* Make sure its the right packet for us, and that it passes sanity checks */ + if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION || + packet.ip.ihl != sizeof(packet.ip) >> 2 || packet.udp.dest != htons(CLIENT_PORT) || + bytes > (int) sizeof(struct udp_dhcp_packet) || + ntohs(packet.udp.len) != (uint16_t) (bytes - sizeof(packet.ip))) { + DEBUG(LOG_INFO, "unrelated/bogus packet"); + return -2; + } + + /* check IP checksum */ + check = packet.ip.check; + packet.ip.check = 0; + if (check != checksum(&(packet.ip), sizeof(packet.ip))) { + DEBUG(LOG_INFO, "bad IP header checksum, ignoring"); + return -1; + } + + /* verify the UDP checksum by replacing the header with a psuedo header */ + source = packet.ip.saddr; + dest = packet.ip.daddr; + check = packet.udp.check; + packet.udp.check = 0; + memset(&packet.ip, 0, sizeof(packet.ip)); + + packet.ip.protocol = IPPROTO_UDP; + packet.ip.saddr = source; + packet.ip.daddr = dest; + packet.ip.tot_len = packet.udp.len; /* cheat on the psuedo-header */ + if (check && check != checksum(&packet, bytes)) { + DEBUG(LOG_ERR, "packet with bad UDP checksum received, ignoring"); + return -2; + } + + memcpy(payload, &(packet.data), bytes - (sizeof(packet.ip) + sizeof(packet.udp))); + + if (ntohl(payload->cookie) != DHCP_MAGIC) { + LOG(LOG_ERR, "received bogus message (bad magic) -- ignoring"); + return -2; + } + DEBUG(LOG_INFO, "oooooh!!! got some!"); + return bytes - (sizeof(packet.ip) + sizeof(packet.udp)); + +} diff --git a/udhcp/clientpacket.h b/udhcp/clientpacket.h new file mode 100644 index 0000000..8e5441b --- /dev/null +++ b/udhcp/clientpacket.h @@ -0,0 +1,14 @@ +#ifndef _CLIENTPACKET_H +#define _CLIENTPACKET_H + +#include "packet.h" + +unsigned long random_xid(void); +int send_discover(unsigned long xid, unsigned long requested); +int send_selecting(unsigned long xid, unsigned long server, unsigned long requested); +int send_renew(unsigned long xid, unsigned long server, unsigned long ciaddr); +int send_renew(unsigned long xid, unsigned long server, unsigned long ciaddr); +int send_release(unsigned long server, unsigned long ciaddr); +int get_raw_packet(struct dhcpMessage *payload, int fd); + +#endif diff --git a/udhcp/clientsocket.c b/udhcp/clientsocket.c new file mode 100644 index 0000000..7c1b6e8 --- /dev/null +++ b/udhcp/clientsocket.c @@ -0,0 +1,62 @@ +/* + * clientsocket.c -- DHCP client socket creation + * + * udhcp client + * + * Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 +#include +#include +#else +#include +#include +#include +#endif + +#include "clientsocket.h" +#include "common.h" + + +int raw_socket(int ifindex) +{ + int fd; + struct sockaddr_ll sock; + + DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex); + if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { + DEBUG(LOG_ERR, "socket call failed: %m"); + return -1; + } + + sock.sll_family = AF_PACKET; + sock.sll_protocol = htons(ETH_P_IP); + sock.sll_ifindex = ifindex; + if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) { + DEBUG(LOG_ERR, "bind call failed: %m"); + close(fd); + return -1; + } + + return fd; +} diff --git a/udhcp/clientsocket.h b/udhcp/clientsocket.h new file mode 100644 index 0000000..17a55c1 --- /dev/null +++ b/udhcp/clientsocket.h @@ -0,0 +1,7 @@ +/* clientsocket.h */ +#ifndef _CLIENTSOCKET_H +#define _CLIENTSOCKET_H + +int raw_socket(int ifindex); + +#endif diff --git a/udhcp/common.c b/udhcp/common.c new file mode 100644 index 0000000..bf2ac44 --- /dev/null +++ b/udhcp/common.c @@ -0,0 +1,162 @@ +/* common.c + * + * Functions for debugging and logging as well as some other + * simple helper functions. + * + * Russ Dill 2001-2003 + * Rewritten by Vladimir Oleynik (C) 2003 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "pidfile.h" + + +static int daemonized; + +long uptime(void) +{ + struct sysinfo info; + sysinfo(&info); + return info.uptime; +} + + +/* + * This function makes sure our first socket calls + * aren't going to fd 1 (printf badness...) and are + * not later closed by daemon() + */ +static inline void sanitize_fds(void) +{ + int zero; + if ((zero = open(_PATH_DEVNULL, O_RDWR, 0)) < 0) return; + while (zero < 3) zero = dup(zero); + close(zero); +} + + +void background(const char *pidfile) +{ +#ifdef __uClinux__ + LOG(LOG_ERR, "Cannot background in uclinux (yet)"); +#else /* __uClinux__ */ + int pid_fd; + + /* hold lock during fork. */ + pid_fd = pidfile_acquire(pidfile); + if (daemon(0, 0) == -1) { + perror("fork"); + exit(1); + } + daemonized++; + pidfile_write_release(pid_fd); +#endif /* __uClinux__ */ +} + + +#ifdef UDHCP_SYSLOG +void udhcp_logging(int level, const char *fmt, ...) +{ + va_list p; + va_list p2; + + va_start(p, fmt); + __va_copy(p2, p); + if(!daemonized) { + vprintf(fmt, p); + putchar('\n'); + } + vsyslog(level, fmt, p2); + va_end(p); +} + + +void start_log_and_pid(const char *client_server, const char *pidfile) +{ + int pid_fd; + + /* Make sure our syslog fd isn't overwritten */ + sanitize_fds(); + + /* do some other misc startup stuff while we are here to save bytes */ + pid_fd = pidfile_acquire(pidfile); + pidfile_write_release(pid_fd); + + /* equivelent of doing a fflush after every \n */ + setlinebuf(stdout); + + openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0); + udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION); +} + + +#else + + +static char *syslog_level_msg[] = { + [LOG_EMERG] = "EMERGENCY!", + [LOG_ALERT] = "ALERT!", + [LOG_CRIT] = "critical!", + [LOG_WARNING] = "warning", + [LOG_ERR] = "error", + [LOG_INFO] = "info", + [LOG_DEBUG] = "debug" +}; + + +void udhcp_logging(int level, const char *fmt, ...) +{ + va_list p; + + va_start(p, fmt); + if(!daemonized) { + printf("%s, ", syslog_level_msg[level]); + vprintf(fmt, p); + putchar('\n'); + } + va_end(p); +} + + +void start_log_and_pid(const char *client_server, const char *pidfile) +{ + int pid_fd; + + /* Make sure our syslog fd isn't overwritten */ + sanitize_fds(); + + /* do some other misc startup stuff while we are here to save bytes */ + pid_fd = pidfile_acquire(pidfile); + pidfile_write_release(pid_fd); + + /* equivelent of doing a fflush after every \n */ + setlinebuf(stdout); + + udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION); +} +#endif + diff --git a/udhcp/common.h b/udhcp/common.h new file mode 100644 index 0000000..ca19a24 --- /dev/null +++ b/udhcp/common.h @@ -0,0 +1,56 @@ +/* common.h + * + * Russ Dill September 2001 + * Rewritten by Vladimir Oleynik (C) 2003 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _COMMON_H +#define _COMMON_H + +#include "version.h" +#include "libbb_udhcp.h" + + +#ifndef UDHCP_SYSLOG +enum syslog_levels { + LOG_EMERG = 0, + LOG_ALERT, + LOG_CRIT, + LOG_WARNING, + LOG_ERR, + LOG_INFO, + LOG_DEBUG +}; +#else +#include +#endif + +long uptime(void); +void background(const char *pidfile); +void start_log_and_pid(const char *client_server, const char *pidfile); +void background(const char *pidfile); +void udhcp_logging(int level, const char *fmt, ...); + +#define LOG(level, str, args...) udhcp_logging(level, str, ## args) + +#ifdef UDHCP_DEBUG +# define DEBUG(level, str, args...) LOG(level, str, ## args) +#else +# define DEBUG(level, str, args...) do {;} while(0) +#endif + +#endif diff --git a/udhcp/dhcpc.c b/udhcp/dhcpc.c new file mode 100644 index 0000000..95fa815 --- /dev/null +++ b/udhcp/dhcpc.c @@ -0,0 +1,537 @@ +/* dhcpc.c + * + * udhcp DHCP client + * + * Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcpd.h" +#include "dhcpc.h" +#include "options.h" +#include "clientpacket.h" +#include "clientsocket.h" +#include "script.h" +#include "socket.h" +#include "common.h" +#include "signalpipe.h" + +static int state; +static unsigned long requested_ip; /* = 0 */ +static unsigned long server_addr; +static unsigned long timeout; +static int packet_num; /* = 0 */ +static int fd = -1; + +#define LISTEN_NONE 0 +#define LISTEN_KERNEL 1 +#define LISTEN_RAW 2 +static int listen_mode; + +struct client_config_t client_config = { + /* Default options. */ + abort_if_no_lease: 0, + foreground: 0, + quit_after_lease: 0, + background_if_no_lease: 0, + interface: "eth0", + pidfile: NULL, + script: DEFAULT_SCRIPT, + clientid: NULL, + hostname: NULL, + fqdn: NULL, + ifindex: 0, + arp: "\0\0\0\0\0\0", /* appease gcc-3.0 */ +}; + +#ifndef IN_BUSYBOX +static void __attribute__ ((noreturn)) show_usage(void) +{ + printf( +"Usage: udhcpc [OPTIONS]\n\n" +" -c, --clientid=CLIENTID Client identifier\n" +" -H, --hostname=HOSTNAME Client hostname\n" +" -h Alias for -H\n" +" -F, --fqdn=FQDN Client fully qualified domain name\n" +" -f, --foreground Do not fork after getting lease\n" +" -b, --background Fork to background if lease cannot be\n" +" immediately negotiated.\n" +" -i, --interface=INTERFACE Interface to use (default: eth0)\n" +" -n, --now Exit with failure if lease cannot be\n" +" immediately negotiated.\n" +" -p, --pidfile=file Store process ID of daemon in file\n" +" -q, --quit Quit after obtaining lease\n" +" -r, --request=IP IP address to request (default: none)\n" +" -s, --script=file Run file at dhcp events (default:\n" +" " DEFAULT_SCRIPT ")\n" +" -v, --version Display version\n" + ); + exit(0); +} +#else +#define show_usage bb_show_usage +extern void show_usage(void) __attribute__ ((noreturn)); +#endif + + +/* just a little helper */ +static void change_mode(int new_mode) +{ + DEBUG(LOG_INFO, "entering %s listen mode", + new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none"); + if (fd >= 0) close(fd); + fd = -1; + listen_mode = new_mode; +} + + +/* perform a renew */ +static void perform_renew(void) +{ + LOG(LOG_INFO, "Performing a DHCP renew"); + switch (state) { + case BOUND: + change_mode(LISTEN_KERNEL); + case RENEWING: + case REBINDING: + state = RENEW_REQUESTED; + break; + case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ + run_script(NULL, "deconfig"); + case REQUESTING: + case RELEASED: + change_mode(LISTEN_RAW); + state = INIT_SELECTING; + break; + case INIT_SELECTING: + break; + } + + /* start things over */ + packet_num = 0; + + /* Kill any timeouts because the user wants this to hurry along */ + timeout = 0; +} + + +/* perform a release */ +static void perform_release(void) +{ + char buffer[16]; + struct in_addr temp_addr; + + /* send release packet */ + if (state == BOUND || state == RENEWING || state == REBINDING) { + temp_addr.s_addr = server_addr; + sprintf(buffer, "%s", inet_ntoa(temp_addr)); + temp_addr.s_addr = requested_ip; + LOG(LOG_INFO, "Unicasting a release of %s to %s", + inet_ntoa(temp_addr), buffer); + send_release(server_addr, requested_ip); /* unicast */ + run_script(NULL, "deconfig"); + } + LOG(LOG_INFO, "Entering released state"); + + change_mode(LISTEN_NONE); + state = RELEASED; + timeout = 0x7fffffff; +} + + +static void client_background(void) +{ + background(client_config.pidfile); + client_config.foreground = 1; /* Do not fork again. */ + client_config.background_if_no_lease = 0; +} + + +#ifdef COMBINED_BINARY +int udhcpc_main(int argc, char *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + uint8_t *temp, *message; + unsigned long t1 = 0, t2 = 0, xid = 0; + unsigned long start = 0, lease; + fd_set rfds; + int retval; + struct timeval tv; + int c, len; + struct dhcpMessage packet; + struct in_addr temp_addr; + long now; + int max_fd; + int sig; + + static const struct option arg_options[] = { + {"clientid", required_argument, 0, 'c'}, + {"foreground", no_argument, 0, 'f'}, + {"background", no_argument, 0, 'b'}, + {"hostname", required_argument, 0, 'H'}, + {"hostname", required_argument, 0, 'h'}, + {"fqdn", required_argument, 0, 'F'}, + {"interface", required_argument, 0, 'i'}, + {"now", no_argument, 0, 'n'}, + {"pidfile", required_argument, 0, 'p'}, + {"quit", no_argument, 0, 'q'}, + {"request", required_argument, 0, 'r'}, + {"script", required_argument, 0, 's'}, + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + + /* get options */ + while (1) { + int option_index = 0; + c = getopt_long(argc, argv, "c:fbH:h:F:i:np:qr:s:v", arg_options, &option_index); + if (c == -1) break; + + switch (c) { + case 'c': + len = strlen(optarg) > 255 ? 255 : strlen(optarg); + if (client_config.clientid) free(client_config.clientid); + client_config.clientid = xmalloc(len + 2); + client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID; + client_config.clientid[OPT_LEN] = len; + client_config.clientid[OPT_DATA] = '\0'; + strncpy(client_config.clientid + OPT_DATA, optarg, len); + break; + case 'f': + client_config.foreground = 1; + break; + case 'b': + client_config.background_if_no_lease = 1; + break; + case 'h': + case 'H': + len = strlen(optarg) > 255 ? 255 : strlen(optarg); + if (client_config.hostname) free(client_config.hostname); + client_config.hostname = xmalloc(len + 2); + client_config.hostname[OPT_CODE] = DHCP_HOST_NAME; + client_config.hostname[OPT_LEN] = len; + strncpy(client_config.hostname + 2, optarg, len); + break; + case 'F': + len = strlen(optarg) > 255 ? 255 : strlen(optarg); + if (client_config.fqdn) free(client_config.fqdn); + client_config.fqdn = xmalloc(len + 5); + client_config.fqdn[OPT_CODE] = DHCP_FQDN; + client_config.fqdn[OPT_LEN] = len + 3; + /* Flags: 0000NEOS + S: 1 => Client requests Server to update A RR in DNS as well as PTR + O: 1 => Server indicates to client that DNS has been updated regardless + E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com" + N: 1 => Client requests Server to not update DNS + */ + client_config.fqdn[OPT_LEN + 1] = 0x1; + client_config.fqdn[OPT_LEN + 2] = 0; + client_config.fqdn[OPT_LEN + 3] = 0; + strncpy(client_config.fqdn + 5, optarg, len); + break; + case 'i': + client_config.interface = optarg; + break; + case 'n': + client_config.abort_if_no_lease = 1; + break; + case 'p': + client_config.pidfile = optarg; + break; + case 'q': + client_config.quit_after_lease = 1; + break; + case 'r': + requested_ip = inet_addr(optarg); + break; + case 's': + client_config.script = optarg; + break; + case 'v': + printf("udhcpcd, version %s\n\n", VERSION); + return 0; + break; + default: + show_usage(); + } + } + + /* Start the log, sanitize fd's, and write a pid file */ + start_log_and_pid("udhcpc", client_config.pidfile); + + if (read_interface(client_config.interface, &client_config.ifindex, + NULL, client_config.arp) < 0) + return 1; + + if (!client_config.clientid) { + client_config.clientid = xmalloc(6 + 3); + client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID; + client_config.clientid[OPT_LEN] = 7; + client_config.clientid[OPT_DATA] = 1; + memcpy(client_config.clientid + 3, client_config.arp, 6); + } + + /* setup the signal pipe */ + udhcp_sp_setup(); + + state = INIT_SELECTING; + run_script(NULL, "deconfig"); + change_mode(LISTEN_RAW); + + for (;;) { + + tv.tv_sec = timeout - uptime(); + tv.tv_usec = 0; + + if (listen_mode != LISTEN_NONE && fd < 0) { + if (listen_mode == LISTEN_KERNEL) + fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface); + else + fd = raw_socket(client_config.ifindex); + if (fd < 0) { + LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m"); + return 0; + } + } + max_fd = udhcp_sp_fd_set(&rfds, fd); + + if (tv.tv_sec > 0) { + DEBUG(LOG_INFO, "Waiting on select..."); + retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); + } else retval = 0; /* If we already timed out, fall through */ + + now = uptime(); + if (retval == 0) { + /* timeout dropped to zero */ + switch (state) { + case INIT_SELECTING: + if (packet_num < 3) { + if (packet_num == 0) + xid = random_xid(); + + /* send discover packet */ + send_discover(xid, requested_ip); /* broadcast */ + + timeout = now + ((packet_num == 2) ? 4 : 2); + packet_num++; + } else { + run_script(NULL, "leasefail"); + if (client_config.background_if_no_lease) { + LOG(LOG_INFO, "No lease, forking to background."); + client_background(); + } else if (client_config.abort_if_no_lease) { + LOG(LOG_INFO, "No lease, failing."); + return 1; + } + /* wait to try again */ + packet_num = 0; + timeout = now + 60; + } + break; + case RENEW_REQUESTED: + case REQUESTING: + if (packet_num < 3) { + /* send request packet */ + if (state == RENEW_REQUESTED) + send_renew(xid, server_addr, requested_ip); /* unicast */ + else send_selecting(xid, server_addr, requested_ip); /* broadcast */ + + timeout = now + ((packet_num == 2) ? 10 : 2); + packet_num++; + } else { + /* timed out, go back to init state */ + if (state == RENEW_REQUESTED) run_script(NULL, "deconfig"); + state = INIT_SELECTING; + timeout = now; + packet_num = 0; + change_mode(LISTEN_RAW); + } + break; + case BOUND: + /* Lease is starting to run out, time to enter renewing state */ + state = RENEWING; + change_mode(LISTEN_KERNEL); + DEBUG(LOG_INFO, "Entering renew state"); + /* fall right through */ + case RENEWING: + /* Either set a new T1, or enter REBINDING state */ + if ((t2 - t1) <= (lease / 14400 + 1)) { + /* timed out, enter rebinding state */ + state = REBINDING; + timeout = now + (t2 - t1); + DEBUG(LOG_INFO, "Entering rebinding state"); + } else { + /* send a request packet */ + send_renew(xid, server_addr, requested_ip); /* unicast */ + + t1 = (t2 - t1) / 2 + t1; + timeout = t1 + start; + } + break; + case REBINDING: + /* Either set a new T2, or enter INIT state */ + if ((lease - t2) <= (lease / 14400 + 1)) { + /* timed out, enter init state */ + state = INIT_SELECTING; + LOG(LOG_INFO, "Lease lost, entering init state"); + run_script(NULL, "deconfig"); + timeout = now; + packet_num = 0; + change_mode(LISTEN_RAW); + } else { + /* send a request packet */ + send_renew(xid, 0, requested_ip); /* broadcast */ + + t2 = (lease - t2) / 2 + t2; + timeout = t2 + start; + } + break; + case RELEASED: + /* yah, I know, *you* say it would never happen */ + timeout = 0x7fffffff; + break; + } + } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) { + /* a packet is ready, read it */ + + if (listen_mode == LISTEN_KERNEL) + len = get_packet(&packet, fd); + else len = get_raw_packet(&packet, fd); + + if (len == -1 && errno != EINTR) { + DEBUG(LOG_INFO, "error on read, %m, reopening socket"); + change_mode(listen_mode); /* just close and reopen */ + } + if (len < 0) continue; + + if (packet.xid != xid) { + DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)", + (unsigned long) packet.xid, xid); + continue; + } + + if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { + DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring"); + continue; + } + + switch (state) { + case INIT_SELECTING: + /* Must be a DHCPOFFER to one of our xid's */ + if (*message == DHCPOFFER) { + if ((temp = get_option(&packet, DHCP_SERVER_ID))) { + memcpy(&server_addr, temp, 4); + xid = packet.xid; + requested_ip = packet.yiaddr; + + /* enter requesting state */ + state = REQUESTING; + timeout = now; + packet_num = 0; + } else { + DEBUG(LOG_ERR, "No server ID in message"); + } + } + break; + case RENEW_REQUESTED: + case REQUESTING: + case RENEWING: + case REBINDING: + if (*message == DHCPACK) { + if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) { + LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease"); + lease = 60 * 60; + } else { + memcpy(&lease, temp, 4); + lease = ntohl(lease); + } + + /* enter bound state */ + t1 = lease / 2; + + /* little fixed point for n * .875 */ + t2 = (lease * 0x7) >> 3; + temp_addr.s_addr = packet.yiaddr; + LOG(LOG_INFO, "Lease of %s obtained, lease time %ld", + inet_ntoa(temp_addr), lease); + start = now; + timeout = t1 + start; + requested_ip = packet.yiaddr; + run_script(&packet, + ((state == RENEWING || state == REBINDING) ? "renew" : "bound")); + + state = BOUND; + change_mode(LISTEN_NONE); + if (client_config.quit_after_lease) + return 0; + if (!client_config.foreground) + client_background(); + + } else if (*message == DHCPNAK) { + /* return to init state */ + LOG(LOG_INFO, "Received DHCP NAK"); + run_script(&packet, "nak"); + if (state != REQUESTING) + run_script(NULL, "deconfig"); + state = INIT_SELECTING; + timeout = now; + requested_ip = 0; + packet_num = 0; + change_mode(LISTEN_RAW); + sleep(3); /* avoid excessive network traffic */ + } + break; + /* case BOUND, RELEASED: - ignore all packets */ + } + } else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) { + switch (sig) { + case SIGUSR1: + perform_renew(); + break; + case SIGUSR2: + perform_release(); + break; + case SIGTERM: + LOG(LOG_INFO, "Received SIGTERM"); + return 0; + } + } else if (retval == -1 && errno == EINTR) { + /* a signal was caught */ + } else { + /* An error occured */ + DEBUG(LOG_ERR, "Error on select"); + } + + } + return 0; +} diff --git a/udhcp/dhcpc.h b/udhcp/dhcpc.h new file mode 100644 index 0000000..edba6a1 --- /dev/null +++ b/udhcp/dhcpc.h @@ -0,0 +1,38 @@ +/* dhcpc.h */ +#ifndef _DHCPC_H +#define _DHCPC_H + +#define DEFAULT_SCRIPT "/etc/udhcpc/default.script" + +/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */ +#include "libbb_udhcp.h" + +#define INIT_SELECTING 0 +#define REQUESTING 1 +#define BOUND 2 +#define RENEWING 3 +#define REBINDING 4 +#define INIT_REBOOT 5 +#define RENEW_REQUESTED 6 +#define RELEASED 7 + + +struct client_config_t { + char foreground; /* Do not fork */ + char quit_after_lease; /* Quit after obtaining lease */ + char abort_if_no_lease; /* Abort if no lease */ + char background_if_no_lease; /* Fork to background if no lease */ + char *interface; /* The name of the interface to use */ + char *pidfile; /* Optionally store the process ID */ + char *script; /* User script to run at dhcp events */ + uint8_t *clientid; /* Optional client id to use */ + uint8_t *hostname; /* Optional hostname to use */ + uint8_t *fqdn; /* Optional fully qualified domain name to use */ + int ifindex; /* Index number of the interface to use */ + uint8_t arp[6]; /* Our arp address */ +}; + +extern struct client_config_t client_config; + + +#endif diff --git a/udhcp/dhcpd.c b/udhcp/dhcpd.c new file mode 100644 index 0000000..767f9b0 --- /dev/null +++ b/udhcp/dhcpd.c @@ -0,0 +1,275 @@ +/* dhcpd.c + * + * udhcp Server + * Copyright (C) 1999 Matthew Ramsay + * Chris Trew + * + * Rewrite by Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcpd.h" +#include "arpping.h" +#include "socket.h" +#include "options.h" +#include "files.h" +#include "serverpacket.h" +#include "common.h" +#include "signalpipe.h" +#include "static_leases.h" + + +/* globals */ +struct dhcpOfferedAddr *leases; +struct server_config_t server_config; + + +#ifdef COMBINED_BINARY +int udhcpd_main(int argc, char *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + fd_set rfds; + struct timeval tv; + int server_socket = -1; + int bytes, retval; + struct dhcpMessage packet; + uint8_t *state; + uint8_t *server_id, *requested; + uint32_t server_id_align, requested_align; + unsigned long timeout_end; + struct option_set *option; + struct dhcpOfferedAddr *lease; + struct dhcpOfferedAddr static_lease; + int max_sock; + unsigned long num_ips; + + uint32_t static_lease_ip; + + memset(&server_config, 0, sizeof(struct server_config_t)); + read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]); + + /* Start the log, sanitize fd's, and write a pid file */ + start_log_and_pid("udhcpd", server_config.pidfile); + + if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) { + memcpy(&server_config.lease, option->data + 2, 4); + server_config.lease = ntohl(server_config.lease); + } + else server_config.lease = LEASE_TIME; + + /* Sanity check */ + // Let's try to fix http://bugs.debian.org/341139 (ericvb@debian.org - 16/12/05) + //num_ips = ntohl(server_config.end) - ntohl(server_config.start); + num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1; + if (server_config.max_leases > num_ips) { + LOG(LOG_ERR, "max_leases value (%lu) not sane, " + "setting to %lu instead", + server_config.max_leases, num_ips); + server_config.max_leases = num_ips; + } + + leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr)); + read_leases(server_config.lease_file); + + if (read_interface(server_config.interface, &server_config.ifindex, + &server_config.server, server_config.arp) < 0) + return 1; + +#ifndef UDHCP_DEBUG + background(server_config.pidfile); /* hold lock during fork. */ +#endif + + /* Setup the signal pipe */ + udhcp_sp_setup(); + + timeout_end = time(0) + server_config.auto_time; + while(1) { /* loop until universe collapses */ + + if (server_socket < 0) + if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) { + LOG(LOG_ERR, "FATAL: couldn't create server socket, %m"); + return 2; + } + + max_sock = udhcp_sp_fd_set(&rfds, server_socket); + if (server_config.auto_time) { + tv.tv_sec = timeout_end - time(0); + tv.tv_usec = 0; + } + if (!server_config.auto_time || tv.tv_sec > 0) { + retval = select(max_sock + 1, &rfds, NULL, NULL, + server_config.auto_time ? &tv : NULL); + } else retval = 0; /* If we already timed out, fall through */ + + if (retval == 0) { + write_leases(); + timeout_end = time(0) + server_config.auto_time; + continue; + } else if (retval < 0 && errno != EINTR) { + DEBUG(LOG_INFO, "error on select"); + continue; + } + + switch (udhcp_sp_read(&rfds)) { + case SIGUSR1: + LOG(LOG_INFO, "Received a SIGUSR1"); + write_leases(); + /* why not just reset the timeout, eh */ + timeout_end = time(0) + server_config.auto_time; + continue; + case SIGTERM: + LOG(LOG_INFO, "Received a SIGTERM"); + return 0; + case 0: break; /* no signal */ + default: continue; /* signal or error (probably EINTR) */ + } + + if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */ + if (bytes == -1 && errno != EINTR) { + DEBUG(LOG_INFO, "error on read, %m, reopening socket"); + close(server_socket); + server_socket = -1; + } + continue; + } + + if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { + DEBUG(LOG_ERR, "couldn't get option from packet, ignoring"); + continue; + } + + /* Look for a static lease */ + static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr); + + if(static_lease_ip) + { + printf("Found static lease: %x\n", static_lease_ip); + + memcpy(&static_lease.chaddr, &packet.chaddr, 16); + static_lease.yiaddr = static_lease_ip; + static_lease.expires = 0; + + lease = &static_lease; + + } + else + { + lease = find_lease_by_chaddr(packet.chaddr); + } + + switch (state[0]) { + case DHCPDISCOVER: + DEBUG(LOG_INFO,"received DISCOVER"); + + if (sendOffer(&packet) < 0) { + LOG(LOG_ERR, "send OFFER failed"); + } + break; + case DHCPREQUEST: + DEBUG(LOG_INFO, "received REQUEST"); + + requested = get_option(&packet, DHCP_REQUESTED_IP); + server_id = get_option(&packet, DHCP_SERVER_ID); + + if (requested) memcpy(&requested_align, requested, 4); + if (server_id) memcpy(&server_id_align, server_id, 4); + + if (lease) { + if (server_id) { + /* SELECTING State */ + DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align)); + if (server_id_align == server_config.server && requested && + requested_align == lease->yiaddr) { + sendACK(&packet, lease->yiaddr); + } + } else { + if (requested) { + /* INIT-REBOOT State */ + if (lease->yiaddr == requested_align) + sendACK(&packet, lease->yiaddr); + else sendNAK(&packet); + } else { + /* RENEWING or REBINDING State */ + if (lease->yiaddr == packet.ciaddr) + sendACK(&packet, lease->yiaddr); + else { + /* don't know what to do!!!! */ + sendNAK(&packet); + } + } + } + + /* what to do if we have no record of the client */ + } else if (server_id) { + /* SELECTING State */ + + } else if (requested) { + /* INIT-REBOOT State */ + if ((lease = find_lease_by_yiaddr(requested_align))) { + if (lease_expired(lease)) { + /* probably best if we drop this lease */ + memset(lease->chaddr, 0, 16); + /* make some contention for this address */ + } else sendNAK(&packet); + } else if (requested_align < server_config.start || + requested_align > server_config.end) { + sendNAK(&packet); + } /* else remain silent */ + + } else { + /* RENEWING or REBINDING State */ + } + break; + case DHCPDECLINE: + DEBUG(LOG_INFO,"received DECLINE"); + if (lease) { + memset(lease->chaddr, 0, 16); + lease->expires = time(0) + server_config.decline_time; + } + break; + case DHCPRELEASE: + DEBUG(LOG_INFO,"received RELEASE"); + if (lease) lease->expires = time(0); + break; + case DHCPINFORM: + DEBUG(LOG_INFO,"received INFORM"); + send_inform(&packet); + break; + default: + LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]); + } + } + + return 0; +} + diff --git a/udhcp/dhcpd.h b/udhcp/dhcpd.h new file mode 100644 index 0000000..65c8348 --- /dev/null +++ b/udhcp/dhcpd.h @@ -0,0 +1,141 @@ +/* dhcpd.h */ +#ifndef _DHCPD_H +#define _DHCPD_H + +#include +#include + +#include "libbb_udhcp.h" +#include "leases.h" +#include "version.h" + +/************************************/ +/* Defaults _you_ may want to tweak */ +/************************************/ + +/* the period of time the client is allowed to use that address */ +#define LEASE_TIME (60*60*24*10) /* 10 days of seconds */ +#define LEASES_FILE "/var/lib/misc/udhcpd.leases" + +/* where to find the DHCP server configuration file */ +#define DHCPD_CONF_FILE "/etc/udhcpd.conf" + +/*****************************************************************/ +/* Do not modify below here unless you know what you are doing!! */ +/*****************************************************************/ + +/* DHCP protocol -- see RFC 2131 */ +#define SERVER_PORT 67 +#define CLIENT_PORT 68 + +#define DHCP_MAGIC 0x63825363 + +/* DHCP option codes (partial list) */ +#define DHCP_PADDING 0x00 +#define DHCP_SUBNET 0x01 +#define DHCP_TIME_OFFSET 0x02 +#define DHCP_ROUTER 0x03 +#define DHCP_TIME_SERVER 0x04 +#define DHCP_NAME_SERVER 0x05 +#define DHCP_DNS_SERVER 0x06 +#define DHCP_LOG_SERVER 0x07 +#define DHCP_COOKIE_SERVER 0x08 +#define DHCP_LPR_SERVER 0x09 +#define DHCP_HOST_NAME 0x0c +#define DHCP_BOOT_SIZE 0x0d +#define DHCP_DOMAIN_NAME 0x0f +#define DHCP_SWAP_SERVER 0x10 +#define DHCP_ROOT_PATH 0x11 +#define DHCP_IP_TTL 0x17 +#define DHCP_MTU 0x1a +#define DHCP_BROADCAST 0x1c +#define DHCP_NTP_SERVER 0x2a +#define DHCP_WINS_SERVER 0x2c +#define DHCP_REQUESTED_IP 0x32 +#define DHCP_LEASE_TIME 0x33 +#define DHCP_OPTION_OVER 0x34 +#define DHCP_MESSAGE_TYPE 0x35 +#define DHCP_SERVER_ID 0x36 +#define DHCP_PARAM_REQ 0x37 +#define DHCP_MESSAGE 0x38 +#define DHCP_MAX_SIZE 0x39 +#define DHCP_T1 0x3a +#define DHCP_T2 0x3b +#define DHCP_VENDOR 0x3c +#define DHCP_CLIENT_ID 0x3d +#define DHCP_FQDN 0x51 + +#define DHCP_END 0xFF + + +#define BOOTREQUEST 1 +#define BOOTREPLY 2 + +#define ETH_10MB 1 +#define ETH_10MB_LEN 6 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 +#define DHCPINFORM 8 + +#define BROADCAST_FLAG 0x8000 + +#define OPTION_FIELD 0 +#define FILE_FIELD 1 +#define SNAME_FIELD 2 + +/* miscellaneous defines */ +#define MAC_BCAST_ADDR (uint8_t *) "\xff\xff\xff\xff\xff\xff" +#define OPT_CODE 0 +#define OPT_LEN 1 +#define OPT_DATA 2 + +struct option_set { + uint8_t *data; + struct option_set *next; +}; + +struct static_lease { + uint8_t *mac; + uint32_t *ip; + struct static_lease *next; +}; + +struct server_config_t { + uint32_t server; /* Our IP, in network order */ + uint32_t start; /* Start address of leases, network order */ + uint32_t end; /* End of leases, network order */ + struct option_set *options; /* List of DHCP options loaded from the config file */ + char *interface; /* The name of the interface to use */ + int ifindex; /* Index number of the interface to use */ + uint8_t arp[6]; /* Our arp address */ + unsigned long lease; /* lease time in seconds (host order) */ + unsigned long max_leases; /* maximum number of leases (including reserved address) */ + char remaining; /* should the lease file be interpreted as lease time remaining, or + * as the time the lease expires */ + unsigned long auto_time; /* how long should udhcpd wait before writing a config file. + * if this is zero, it will only write one on SIGUSR1 */ + unsigned long decline_time; /* how long an address is reserved if a client returns a + * decline message */ + unsigned long conflict_time; /* how long an arp conflict offender is leased for */ + unsigned long offer_time; /* how long an offered address is reserved */ + unsigned long min_lease; /* minimum lease a client can request*/ + char *lease_file; + char *pidfile; + char *notify_file; /* What to run whenever leases are written */ + uint32_t siaddr; /* next server bootp option */ + char *sname; /* bootp server name */ + char *boot_file; /* bootp boot file option */ + struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */ +}; + +extern struct server_config_t server_config; +extern struct dhcpOfferedAddr *leases; + + +#endif diff --git a/udhcp/dumpleases.1 b/udhcp/dumpleases.1 new file mode 100644 index 0000000..04a04da --- /dev/null +++ b/udhcp/dumpleases.1 @@ -0,0 +1,30 @@ +.TH DUMPLEASES 1 2001-09-27 GNU/Linux "GNU/Linux Administrator's Manual" +.SH NAME +dumpleases \- display leases granted by udhcp server +.SH SYNOPSIS +.B dumpleases +.RI [ OPTION ]... +.SH DESCRIPTION +Display the DHCP leases granted by +.BR udhcpd (8). +.SH OPTIONS +.TP +.BR \-a ,\ \-\-absolute +Interpret lease times as expiration time. +.TP +.BI \-f\ FILE,\ \-\-file= FILE +Read lease information from +.IR FILE . +.TP +.BR \-h ,\ \-\-help +Display help. +.TP +.BR \-r ,\ \-\-remaining +Interpret lease times as remaining time. +.SH FILES +.TP +.I /var/lib/misc/udhcpd.leases +Lease information file. +.SH SEE ALSO +.BR udhcpd (8), +.BR udhcpd.conf (5). diff --git a/udhcp/dumpleases.c b/udhcp/dumpleases.c new file mode 100644 index 0000000..a9036df --- /dev/null +++ b/udhcp/dumpleases.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcpd.h" +#include "leases.h" +#include "libbb_udhcp.h" + +#define REMAINING 0 +#define ABSOLUTE 1 + + +#ifndef IN_BUSYBOX +static void __attribute__ ((noreturn)) show_usage(void) +{ + printf( +"Usage: dumpleases -f -[r|a]\n\n" +" -f, --file=FILENAME Leases file to load\n" +" -r, --remaining Interepret lease times as time remaing\n" +" -a, --absolute Interepret lease times as expire time\n"); + exit(0); +} +#else +#define show_usage bb_show_usage +#endif + + +#ifdef IN_BUSYBOX +int dumpleases_main(int argc, char *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + FILE *fp; + int i, c, mode = REMAINING; + long expires; + const char *file = LEASES_FILE; + struct dhcpOfferedAddr lease; + struct in_addr addr; + + static const struct option options[] = { + {"absolute", 0, 0, 'a'}, + {"remaining", 0, 0, 'r'}, + {"file", 1, 0, 'f'}, + {0, 0, 0, 0} + }; + + while (1) { + int option_index = 0; + c = getopt_long(argc, argv, "arf:", options, &option_index); + if (c == -1) break; + + switch (c) { + case 'a': mode = ABSOLUTE; break; + case 'r': mode = REMAINING; break; + case 'f': + file = optarg; + break; + default: + show_usage(); + } + } + + fp = xfopen(file, "r"); + + printf("Mac Address IP-Address Expires %s\n", mode == REMAINING ? "in" : "at"); + /* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */ + while (fread(&lease, sizeof(lease), 1, fp)) { + + for (i = 0; i < 6; i++) { + printf("%02x", lease.chaddr[i]); + if (i != 5) printf(":"); + } + addr.s_addr = lease.yiaddr; + printf(" %-15s", inet_ntoa(addr)); + expires = ntohl(lease.expires); + printf(" "); + if (mode == REMAINING) { + if (!expires) printf("expired\n"); + else { + if (expires > 60*60*24) { + printf("%ld days, ", expires / (60*60*24)); + expires %= 60*60*24; + } + if (expires > 60*60) { + printf("%ld hours, ", expires / (60*60)); + expires %= 60*60; + } + if (expires > 60) { + printf("%ld minutes, ", expires / 60); + expires %= 60; + } + printf("%ld seconds\n", expires); + } + } else printf("%s", ctime(&expires)); + } + fclose(fp); + + return 0; +} diff --git a/udhcp/files.c b/udhcp/files.c new file mode 100644 index 0000000..73a3bbc --- /dev/null +++ b/udhcp/files.c @@ -0,0 +1,346 @@ +/* + * files.c -- DHCP server file manipulation * + * Rewrite by Russ Dill July 2001 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "static_leases.h" + +#include "dhcpd.h" +#include "files.h" +#include "options.h" +#include "common.h" + +/* + * Domain names may have 254 chars, and string options can be 254 + * chars long. However, 80 bytes will be enough for most, and won't + * hog up memory. If you have a special application, change it + */ +#define READ_CONFIG_BUF_SIZE 80 + +/* on these functions, make sure you datatype matches */ +static int read_ip(const char *line, void *arg) +{ + struct in_addr *addr = arg; + struct hostent *host; + int retval = 1; + + if (!inet_aton(line, addr)) { + if ((host = gethostbyname(line))) + addr->s_addr = *((unsigned long *) host->h_addr_list[0]); + else retval = 0; + } + return retval; +} + +static int read_mac(const char *line, void *arg) +{ + uint8_t *mac_bytes = arg; + struct ether_addr *temp_ether_addr; + int retval = 1; + + temp_ether_addr = ether_aton(line); + + if(temp_ether_addr == NULL) + retval = 0; + else + memcpy(mac_bytes, temp_ether_addr, 6); + + return retval; +} + + +static int read_str(const char *line, void *arg) +{ + char **dest = arg; + + if (*dest) free(*dest); + *dest = strdup(line); + + return 1; +} + + +static int read_u32(const char *line, void *arg) +{ + uint32_t *dest = arg; + char *endptr; + *dest = strtoul(line, &endptr, 0); + return endptr[0] == '\0'; +} + + +static int read_yn(const char *line, void *arg) +{ + char *dest = arg; + int retval = 1; + + if (!strcasecmp("yes", line)) + *dest = 1; + else if (!strcasecmp("no", line)) + *dest = 0; + else retval = 0; + + return retval; +} + + +/* read a dhcp option and add it to opt_list */ +static int read_opt(const char *const_line, void *arg) +{ + struct option_set **opt_list = arg; + char *opt, *val, *endptr; + struct dhcp_option *option; + int retval = 0, length; + char buffer[8]; + char *line; + uint16_t *result_u16 = (uint16_t *) buffer; + uint32_t *result_u32 = (uint32_t *) buffer; + + /* Cheat, the only const line we'll actually get is "" */ + line = (char *) const_line; + if (!(opt = strtok(line, " \t="))) return 0; + + for (option = dhcp_options; option->code; option++) + if (!strcasecmp(option->name, opt)) + break; + + if (!option->code) return 0; + + do { + if (!(val = strtok(NULL, ", \t"))) break; + length = option_lengths[option->flags & TYPE_MASK]; + retval = 0; + opt = buffer; /* new meaning for variable opt */ + switch (option->flags & TYPE_MASK) { + case OPTION_IP: + retval = read_ip(val, buffer); + break; + case OPTION_IP_PAIR: + retval = read_ip(val, buffer); + if (!(val = strtok(NULL, ", \t/-"))) retval = 0; + if (retval) retval = read_ip(val, buffer + 4); + break; + case OPTION_STRING: + length = strlen(val); + if (length > 0) { + if (length > 254) length = 254; + opt = val; + retval = 1; + } + break; + case OPTION_BOOLEAN: + retval = read_yn(val, buffer); + break; + case OPTION_U8: + buffer[0] = strtoul(val, &endptr, 0); + retval = (endptr[0] == '\0'); + break; + case OPTION_U16: + *result_u16 = htons(strtoul(val, &endptr, 0)); + retval = (endptr[0] == '\0'); + break; + case OPTION_S16: + *result_u16 = htons(strtol(val, &endptr, 0)); + retval = (endptr[0] == '\0'); + break; + case OPTION_U32: + *result_u32 = htonl(strtoul(val, &endptr, 0)); + retval = (endptr[0] == '\0'); + break; + case OPTION_S32: + *result_u32 = htonl(strtol(val, &endptr, 0)); + retval = (endptr[0] == '\0'); + break; + default: + break; + } + if (retval) + attach_option(opt_list, option, opt, length); + } while (retval && option->flags & OPTION_LIST); + return retval; +} + +static int read_staticlease(const char *const_line, void *arg) +{ + + char *line; + char *mac_string; + char *ip_string; + uint8_t *mac_bytes; + uint32_t *ip; + + + /* Allocate memory for addresses */ + mac_bytes = xmalloc(sizeof(unsigned char) * 8); + ip = xmalloc(sizeof(uint32_t)); + + /* Read mac */ + line = (char *) const_line; + mac_string = strtok(line, " \t"); + read_mac(mac_string, mac_bytes); + + /* Read ip */ + ip_string = strtok(NULL, " \t"); + read_ip(ip_string, ip); + + addStaticLease(arg, mac_bytes, ip); + +#ifdef UDHCP_DEBUG + printStaticLeases(arg); +#endif + + return 1; + +} + + +static const struct config_keyword keywords[] = { + /* keyword handler variable address default */ + {"start", read_ip, &(server_config.start), "192.168.0.20"}, + {"end", read_ip, &(server_config.end), "192.168.0.254"}, + {"interface", read_str, &(server_config.interface), "eth0"}, + {"option", read_opt, &(server_config.options), ""}, + {"opt", read_opt, &(server_config.options), ""}, + {"max_leases", read_u32, &(server_config.max_leases), "254"}, + {"remaining", read_yn, &(server_config.remaining), "yes"}, + {"auto_time", read_u32, &(server_config.auto_time), "7200"}, + {"decline_time",read_u32, &(server_config.decline_time),"3600"}, + {"conflict_time",read_u32,&(server_config.conflict_time),"3600"}, + {"offer_time", read_u32, &(server_config.offer_time), "60"}, + {"min_lease", read_u32, &(server_config.min_lease), "60"}, + {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, + {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, + {"notify_file", read_str, &(server_config.notify_file), ""}, + {"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"}, + {"sname", read_str, &(server_config.sname), ""}, + {"boot_file", read_str, &(server_config.boot_file), ""}, + {"static_lease",read_staticlease, &(server_config.static_leases), ""}, + /*ADDME: static lease */ + {"", NULL, NULL, ""} +}; + + +int read_config(const char *file) +{ + FILE *in; + char buffer[READ_CONFIG_BUF_SIZE], *token, *line; +#ifdef UDHCP_DEBUG + char orig[READ_CONFIG_BUF_SIZE]; +#endif + int i, lm = 0; + + for (i = 0; keywords[i].keyword[0]; i++) + if (keywords[i].def[0]) + keywords[i].handler(keywords[i].def, keywords[i].var); + + if (!(in = fopen(file, "r"))) { + LOG(LOG_ERR, "unable to open config file: %s", file); + return 0; + } + + while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) { + lm++; + if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0'; +#ifdef UDHCP_DEBUG + strcpy(orig, buffer); +#endif + if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0'; + + if (!(token = strtok(buffer, " \t"))) continue; + if (!(line = strtok(NULL, ""))) continue; + + /* eat leading whitespace */ + line = line + strspn(line, " \t="); + /* eat trailing whitespace */ + for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--); + line[i] = '\0'; + + for (i = 0; keywords[i].keyword[0]; i++) + if (!strcasecmp(token, keywords[i].keyword)) + if (!keywords[i].handler(line, keywords[i].var)) { + LOG(LOG_ERR, "Failure parsing line %d of %s", lm, file); + DEBUG(LOG_ERR, "unable to parse '%s'", orig); + /* reset back to the default value */ + keywords[i].handler(keywords[i].def, keywords[i].var); + } + } + fclose(in); + return 1; +} + + +void write_leases(void) +{ + FILE *fp; + unsigned int i; + char buf[255]; + time_t curr = time(0); + unsigned long tmp_time; + + if (!(fp = fopen(server_config.lease_file, "w"))) { + LOG(LOG_ERR, "Unable to open %s for writing", server_config.lease_file); + return; + } + + for (i = 0; i < server_config.max_leases; i++) { + if (leases[i].yiaddr != 0) { + + /* screw with the time in the struct, for easier writing */ + tmp_time = leases[i].expires; + + if (server_config.remaining) { + if (lease_expired(&(leases[i]))) + leases[i].expires = 0; + else leases[i].expires -= curr; + } /* else stick with the time we got */ + leases[i].expires = htonl(leases[i].expires); + fwrite(&leases[i], sizeof(struct dhcpOfferedAddr), 1, fp); + + /* Then restore it when done. */ + leases[i].expires = tmp_time; + } + } + fclose(fp); + + if (server_config.notify_file) { + sprintf(buf, "%s %s", server_config.notify_file, server_config.lease_file); + system(buf); + } +} + + +void read_leases(const char *file) +{ + FILE *fp; + unsigned int i = 0; + struct dhcpOfferedAddr lease; + + if (!(fp = fopen(file, "r"))) { + LOG(LOG_ERR, "Unable to open %s for reading", file); + return; + } + + while (i < server_config.max_leases && (fread(&lease, sizeof lease, 1, fp) == 1)) { + /* ADDME: is it a static lease */ + if (lease.yiaddr >= server_config.start && lease.yiaddr <= server_config.end) { + lease.expires = ntohl(lease.expires); + if (!server_config.remaining) lease.expires -= time(0); + if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) { + LOG(LOG_WARNING, "Too many leases while loading %s\n", file); + break; + } + i++; + } + } + DEBUG(LOG_INFO, "Read %d leases", i); + fclose(fp); +} diff --git a/udhcp/files.h b/udhcp/files.h new file mode 100644 index 0000000..279738a --- /dev/null +++ b/udhcp/files.h @@ -0,0 +1,17 @@ +/* files.h */ +#ifndef _FILES_H +#define _FILES_H + +struct config_keyword { + const char *keyword; + int (* const handler)(const char *line, void *var); + void *var; + const char *def; +}; + + +int read_config(const char *file); +void write_leases(void); +void read_leases(const char *file); + +#endif diff --git a/udhcp/frontend.c b/udhcp/frontend.c new file mode 100644 index 0000000..fa77ab9 --- /dev/null +++ b/udhcp/frontend.c @@ -0,0 +1,16 @@ +#include + +extern int udhcpd_main(int argc, char *argv[]); +extern int udhcpc_main(int argc, char *argv[]); + +int main(int argc, char *argv[]) +{ + int ret = 0; + char *base = strrchr(argv[0], '/'); + + if (strstr(base ? (base + 1) : argv[0], "dhcpd")) + ret = udhcpd_main(argc, argv); + else ret = udhcpc_main(argc, argv); + + return ret; +} diff --git a/udhcp/leases.c b/udhcp/leases.c new file mode 100644 index 0000000..4da21a2 --- /dev/null +++ b/udhcp/leases.c @@ -0,0 +1,158 @@ +/* + * leases.c -- tools to manage DHCP leases + * Russ Dill July 2001 + */ + +#include +#include +#include +#include +#include + +#include "dhcpd.h" +#include "files.h" +#include "options.h" +#include "leases.h" +#include "arpping.h" +#include "common.h" + +#include "static_leases.h" + + +uint8_t blank_chaddr[] = {[0 ... 15] = 0}; + +/* clear every lease out that chaddr OR yiaddr matches and is nonzero */ +void clear_lease(uint8_t *chaddr, uint32_t yiaddr) +{ + unsigned int i, j; + + for (j = 0; j < 16 && !chaddr[j]; j++); + + for (i = 0; i < server_config.max_leases; i++) + if ((j != 16 && !memcmp(leases[i].chaddr, chaddr, 16)) || + (yiaddr && leases[i].yiaddr == yiaddr)) { + memset(&(leases[i]), 0, sizeof(struct dhcpOfferedAddr)); + } +} + + +/* add a lease into the table, clearing out any old ones */ +struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) +{ + struct dhcpOfferedAddr *oldest; + + /* clean out any old ones */ + clear_lease(chaddr, yiaddr); + + oldest = oldest_expired_lease(); + + if (oldest) { + memcpy(oldest->chaddr, chaddr, 16); + oldest->yiaddr = yiaddr; + oldest->expires = time(0) + lease; + } + + return oldest; +} + + +/* true if a lease has expired */ +int lease_expired(struct dhcpOfferedAddr *lease) +{ + return (lease->expires < (unsigned long) time(0)); +} + + +/* Find the oldest expired lease, NULL if there are no expired leases */ +struct dhcpOfferedAddr *oldest_expired_lease(void) +{ + struct dhcpOfferedAddr *oldest = NULL; + unsigned long oldest_lease = time(0); + unsigned int i; + + + for (i = 0; i < server_config.max_leases; i++) + if (oldest_lease > leases[i].expires) { + oldest_lease = leases[i].expires; + oldest = &(leases[i]); + } + return oldest; + +} + + +/* Find the first lease that matches chaddr, NULL if no match */ +struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr) +{ + unsigned int i; + + for (i = 0; i < server_config.max_leases; i++) + if (!memcmp(leases[i].chaddr, chaddr, 16)) return &(leases[i]); + + return NULL; +} + + +/* Find the first lease that matches yiaddr, NULL is no match */ +struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) +{ + unsigned int i; + + for (i = 0; i < server_config.max_leases; i++) + if (leases[i].yiaddr == yiaddr) return &(leases[i]); + + return NULL; +} + + +/* check is an IP is taken, if it is, add it to the lease table */ +static int check_ip(uint32_t addr) +{ + struct in_addr temp; + + if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) { + temp.s_addr = addr; + LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds", + inet_ntoa(temp), server_config.conflict_time); + add_lease(blank_chaddr, addr, server_config.conflict_time); + return 1; + } else return 0; +} + + +/* find an assignable address, it check_expired is true, we check all the expired leases as well. + * Maybe this should try expired leases by age... */ +uint32_t find_address(int check_expired) +{ + uint32_t addr, ret; + struct dhcpOfferedAddr *lease = NULL; + + addr = ntohl(server_config.start); /* addr is in host order here */ + for (;addr <= ntohl(server_config.end); addr++) { + + /* ie, 192.168.55.0 */ + if (!(addr & 0xFF)) continue; + + /* ie, 192.168.55.255 */ + if ((addr & 0xFF) == 0xFF) continue; + + /* Only do if it isn't an assigned as a static lease */ + if(!reservedIp(server_config.static_leases, htonl(addr))) + { + + /* lease is not taken */ + ret = htonl(addr); + if ((!(lease = find_lease_by_yiaddr(ret)) || + + /* or it expired and we are checking for expired leases */ + (check_expired && lease_expired(lease))) && + + /* and it isn't on the network */ + !check_ip(ret)) { + return ret; + break; + } + } + } + return 0; +} diff --git a/udhcp/leases.h b/udhcp/leases.h new file mode 100644 index 0000000..b13fa72 --- /dev/null +++ b/udhcp/leases.h @@ -0,0 +1,23 @@ +/* leases.h */ +#ifndef _LEASES_H +#define _LEASES_H + + +struct dhcpOfferedAddr { + uint8_t chaddr[16]; + uint32_t yiaddr; /* network order */ + uint32_t expires; /* host order */ +}; + +extern uint8_t blank_chaddr[]; + +void clear_lease(uint8_t *chaddr, uint32_t yiaddr); +struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease); +int lease_expired(struct dhcpOfferedAddr *lease); +struct dhcpOfferedAddr *oldest_expired_lease(void); +struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr); +struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr); +uint32_t find_address(int check_expired); + + +#endif diff --git a/udhcp/libbb_udhcp.h b/udhcp/libbb_udhcp.h new file mode 100644 index 0000000..51e1571 --- /dev/null +++ b/udhcp/libbb_udhcp.h @@ -0,0 +1,54 @@ +/* libbb_udhcp.h - busybox compatability wrapper */ + +/* bit of a hack, do this no matter what the order of the includes. + * (for busybox) */ + +#ifdef CONFIG_INSTALL_NO_USR +#undef DEFAULT_SCRIPT +#define DEFAULT_SCRIPT "/share/udhcpc/default.script" +#endif + +#ifndef _LIBBB_UDHCP_H +#define _LIBBB_UDHCP_H + +#ifdef IN_BUSYBOX +#include "busybox.h" + +#ifdef CONFIG_FEATURE_UDHCP_SYSLOG +#define UDHCP_SYSLOG +#endif + +#ifdef CONFIG_FEATURE_UDHCP_DEBUG +#define UDHCP_DEBUG +#endif + +#define COMBINED_BINARY +#include "version.h" + +#define xfopen bb_xfopen + +#else /* ! BB_VER */ + +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +#define xmalloc malloc +#define xcalloc calloc + +static inline FILE *xfopen(const char *file, const char *mode) +{ + FILE *fp; + if (!(fp = fopen(file, mode))) { + perror("could not open input file"); + exit(0); + } + return fp; +} + +#endif /* BB_VER */ + +#endif /* _LIBBB_UDHCP_H */ diff --git a/udhcp/options.c b/udhcp/options.c new file mode 100644 index 0000000..d9c32a8 --- /dev/null +++ b/udhcp/options.c @@ -0,0 +1,234 @@ +/* + * options.c -- DHCP server option packet tools + * Rewrite by Russ Dill July 2001 + */ + +#include +#include + +#include "dhcpd.h" +#include "files.h" +#include "options.h" +#include "common.h" + + +/* supported options are easily added here */ +struct dhcp_option dhcp_options[] = { + /* name[10] flags code */ + {"subnet", OPTION_IP | OPTION_REQ, 0x01}, + {"timezone", OPTION_S32, 0x02}, + {"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03}, + {"timesvr", OPTION_IP | OPTION_LIST, 0x04}, + {"namesvr", OPTION_IP | OPTION_LIST, 0x05}, + {"dns", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x06}, + {"logsvr", OPTION_IP | OPTION_LIST, 0x07}, + {"cookiesvr", OPTION_IP | OPTION_LIST, 0x08}, + {"lprsvr", OPTION_IP | OPTION_LIST, 0x09}, + {"hostname", OPTION_STRING | OPTION_REQ, 0x0c}, + {"bootsize", OPTION_U16, 0x0d}, + {"domain", OPTION_STRING | OPTION_REQ, 0x0f}, + {"swapsvr", OPTION_IP, 0x10}, + //We had the possibility for the client to ask for a rootpath + //closes http://bugs.debian.org/279110 (ericvb@debian.org) + //{"rootpath", OPTION_STRING, 0x11}, + {"rootpath", OPTION_STRING | OPTION_REQ, 0x11}, + {"ipttl", OPTION_U8, 0x17}, + {"mtu", OPTION_U16, 0x1a}, + {"broadcast", OPTION_IP | OPTION_REQ, 0x1c}, + {"nisdomain", OPTION_STRING | OPTION_REQ, 0x28}, + {"nissrv", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x29}, + {"ntpsrv", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a}, + {"wins", OPTION_IP | OPTION_LIST, 0x2c}, + {"requestip", OPTION_IP, 0x32}, + {"lease", OPTION_U32, 0x33}, + {"dhcptype", OPTION_U8, 0x35}, + {"serverid", OPTION_IP, 0x36}, + {"message", OPTION_STRING, 0x38}, + {"tftp", OPTION_STRING, 0x42}, + {"bootfile", OPTION_STRING, 0x43}, + {"wpad", OPTION_STRING, 0xfc}, + {"", 0x00, 0x00} +}; + +/* Lengths of the different option types */ +int option_lengths[] = { + [OPTION_IP] = 4, + [OPTION_IP_PAIR] = 8, + [OPTION_BOOLEAN] = 1, + [OPTION_STRING] = 1, + [OPTION_U8] = 1, + [OPTION_U16] = 2, + [OPTION_S16] = 2, + [OPTION_U32] = 4, + [OPTION_S32] = 4 +}; + + +/* get an option with bounds checking (warning, not aligned). */ +uint8_t *get_option(struct dhcpMessage *packet, int code) +{ + int i, length; + uint8_t *optionptr; + int over = 0, done = 0, curr = OPTION_FIELD; + + optionptr = packet->options; + i = 0; + length = 308; + while (!done) { + if (i >= length) { + LOG(LOG_WARNING, "bogus packet, option fields too long."); + return NULL; + } + if (optionptr[i + OPT_CODE] == code) { + if (i + 1 + optionptr[i + OPT_LEN] >= length) { + LOG(LOG_WARNING, "bogus packet, option fields too long."); + return NULL; + } + return optionptr + i + 2; + } + switch (optionptr[i + OPT_CODE]) { + case DHCP_PADDING: + i++; + break; + case DHCP_OPTION_OVER: + if (i + 1 + optionptr[i + OPT_LEN] >= length) { + LOG(LOG_WARNING, "bogus packet, option fields too long."); + return NULL; + } + over = optionptr[i + 3]; + i += optionptr[OPT_LEN] + 2; + break; + case DHCP_END: + if (curr == OPTION_FIELD && over & FILE_FIELD) { + optionptr = packet->file; + i = 0; + length = 128; + curr = FILE_FIELD; + } else if (curr == FILE_FIELD && over & SNAME_FIELD) { + optionptr = packet->sname; + i = 0; + length = 64; + curr = SNAME_FIELD; + } else done = 1; + break; + default: + i += optionptr[OPT_LEN + i] + 2; + } + } + return NULL; +} + + +/* return the position of the 'end' option (no bounds checking) */ +int end_option(uint8_t *optionptr) +{ + int i = 0; + + while (optionptr[i] != DHCP_END) { + if (optionptr[i] == DHCP_PADDING) i++; + else i += optionptr[i + OPT_LEN] + 2; + } + return i; +} + + +/* add an option string to the options (an option string contains an option code, + * length, then data) */ +int add_option_string(uint8_t *optionptr, uint8_t *string) +{ + int end = end_option(optionptr); + + /* end position + string length + option code/length + end option */ + if (end + string[OPT_LEN] + 2 + 1 >= 308) { + LOG(LOG_ERR, "Option 0x%02x did not fit into the packet!", string[OPT_CODE]); + return 0; + } + DEBUG(LOG_INFO, "adding option 0x%02x", string[OPT_CODE]); + memcpy(optionptr + end, string, string[OPT_LEN] + 2); + optionptr[end + string[OPT_LEN] + 2] = DHCP_END; + return string[OPT_LEN] + 2; +} + + +/* add a one to four byte option to a packet */ +int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) +{ + char length = 0; + int i; + uint8_t option[2 + 4]; + uint8_t *u8; + uint16_t *u16; + uint32_t *u32; + uint32_t aligned; + u8 = (uint8_t *) &aligned; + u16 = (uint16_t *) &aligned; + u32 = &aligned; + + for (i = 0; dhcp_options[i].code; i++) + if (dhcp_options[i].code == code) { + length = option_lengths[dhcp_options[i].flags & TYPE_MASK]; + } + + if (!length) { + DEBUG(LOG_ERR, "Could not add option 0x%02x", code); + return 0; + } + + option[OPT_CODE] = code; + option[OPT_LEN] = length; + + switch (length) { + case 1: *u8 = data; break; + case 2: *u16 = data; break; + case 4: *u32 = data; break; + } + memcpy(option + 2, &aligned, length); + return add_option_string(optionptr, option); +} + + +/* find option 'code' in opt_list */ +struct option_set *find_option(struct option_set *opt_list, char code) +{ + while (opt_list && opt_list->data[OPT_CODE] < code) + opt_list = opt_list->next; + + if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list; + else return NULL; +} + + +/* add an option to the opt_list */ +void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length) +{ + struct option_set *existing, *new, **curr; + + /* add it to an existing option */ + if ((existing = find_option(*opt_list, option->code))) { + DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name); + if (option->flags & OPTION_LIST) { + if (existing->data[OPT_LEN] + length <= 255) { + existing->data = realloc(existing->data, + existing->data[OPT_LEN] + length + 2); + memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length); + existing->data[OPT_LEN] += length; + } /* else, ignore the data, we could put this in a second option in the future */ + } /* else, ignore the new data */ + } else { + DEBUG(LOG_INFO, "Attaching option %s to list", option->name); + + /* make a new option */ + new = xmalloc(sizeof(struct option_set)); + new->data = xmalloc(length + 2); + new->data[OPT_CODE] = option->code; + new->data[OPT_LEN] = length; + memcpy(new->data + 2, buffer, length); + + curr = opt_list; + while (*curr && (*curr)->data[OPT_CODE] < option->code) + curr = &(*curr)->next; + + new->next = *curr; + *curr = new; + } +} diff --git a/udhcp/options.h b/udhcp/options.h new file mode 100644 index 0000000..fbe54c8 --- /dev/null +++ b/udhcp/options.h @@ -0,0 +1,40 @@ +/* options.h */ +#ifndef _OPTIONS_H +#define _OPTIONS_H + +#include "packet.h" + +#define TYPE_MASK 0x0F + +enum { + OPTION_IP=1, + OPTION_IP_PAIR, + OPTION_STRING, + OPTION_BOOLEAN, + OPTION_U8, + OPTION_U16, + OPTION_S16, + OPTION_U32, + OPTION_S32 +}; + +#define OPTION_REQ 0x10 /* have the client request this option */ +#define OPTION_LIST 0x20 /* There can be a list of 1 or more of these */ + +struct dhcp_option { + char name[10]; + char flags; + uint8_t code; +}; + +extern struct dhcp_option dhcp_options[]; +extern int option_lengths[]; + +uint8_t *get_option(struct dhcpMessage *packet, int code); +int end_option(uint8_t *optionptr); +int add_option_string(uint8_t *optionptr, uint8_t *string); +int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data); +struct option_set *find_option(struct option_set *opt_list, char code); +void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length); + +#endif diff --git a/udhcp/packet.c b/udhcp/packet.c new file mode 100644 index 0000000..7774291 --- /dev/null +++ b/udhcp/packet.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include +#include +#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 +#include +#include +#else +#include +#include +#include +#endif +#include + +#include "packet.h" +#include "dhcpd.h" +#include "options.h" +#include "common.h" + + +void init_header(struct dhcpMessage *packet, char type) +{ + memset(packet, 0, sizeof(struct dhcpMessage)); + switch (type) { + case DHCPDISCOVER: + case DHCPREQUEST: + case DHCPRELEASE: + case DHCPINFORM: + packet->op = BOOTREQUEST; + break; + case DHCPOFFER: + case DHCPACK: + case DHCPNAK: + packet->op = BOOTREPLY; + } + packet->htype = ETH_10MB; + packet->hlen = ETH_10MB_LEN; + packet->cookie = htonl(DHCP_MAGIC); + packet->options[0] = DHCP_END; + add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type); +} + + +/* read a packet from socket fd, return -1 on read error, -2 on packet error */ +int get_packet(struct dhcpMessage *packet, int fd) +{ + int bytes; + int i; + const char broken_vendors[][8] = { + "MSFT 98", + "" + }; + char unsigned *vendor; + + memset(packet, 0, sizeof(struct dhcpMessage)); + bytes = read(fd, packet, sizeof(struct dhcpMessage)); + if (bytes < 0) { + DEBUG(LOG_INFO, "couldn't read on listening socket, ignoring"); + return -1; + } + + if (ntohl(packet->cookie) != DHCP_MAGIC) { + LOG(LOG_ERR, "received bogus message, ignoring"); + return -2; + } + DEBUG(LOG_INFO, "Received a packet"); + + if (packet->op == BOOTREQUEST && (vendor = get_option(packet, DHCP_VENDOR))) { + for (i = 0; broken_vendors[i][0]; i++) { + if (vendor[OPT_LEN - 2] == (uint8_t) strlen(broken_vendors[i]) && + !strncmp(vendor, broken_vendors[i], vendor[OPT_LEN - 2])) { + DEBUG(LOG_INFO, "broken client (%s), forcing broadcast", + broken_vendors[i]); + packet->flags |= htons(BROADCAST_FLAG); + } + } + } + + + return bytes; +} + + +uint16_t checksum(void *addr, int count) +{ + /* Compute Internet Checksum for "count" bytes + * beginning at location "addr". + */ + register int32_t sum = 0; + uint16_t *source = (uint16_t *) addr; + + while (count > 1) { + /* This is the inner loop */ + sum += *source++; + count -= 2; + } + + /* Add left-over byte, if any */ + if (count > 0) { + /* Make sure that the left-over byte is added correctly both + * with little and big endian hosts */ + uint16_t tmp = 0; + *(uint8_t *) (&tmp) = * (uint8_t *) source; + sum += tmp; + } + /* Fold 32-bit sum to 16 bits */ + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + + return ~sum; +} + + +/* Construct a ip/udp header for a packet, and specify the source and dest hardware address */ +int raw_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_port, + uint32_t dest_ip, int dest_port, uint8_t *dest_arp, int ifindex) +{ + int fd; + int result; + struct sockaddr_ll dest; + struct udp_dhcp_packet packet; + + if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { + DEBUG(LOG_ERR, "socket call failed: %m"); + return -1; + } + + memset(&dest, 0, sizeof(dest)); + memset(&packet, 0, sizeof(packet)); + + dest.sll_family = AF_PACKET; + dest.sll_protocol = htons(ETH_P_IP); + dest.sll_ifindex = ifindex; + dest.sll_halen = 6; + memcpy(dest.sll_addr, dest_arp, 6); + if (bind(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_ll)) < 0) { + DEBUG(LOG_ERR, "bind call failed: %m"); + close(fd); + return -1; + } + + packet.ip.protocol = IPPROTO_UDP; + packet.ip.saddr = source_ip; + packet.ip.daddr = dest_ip; + packet.udp.source = htons(source_port); + packet.udp.dest = htons(dest_port); + packet.udp.len = htons(sizeof(packet.udp) + sizeof(struct dhcpMessage)); /* cheat on the psuedo-header */ + packet.ip.tot_len = packet.udp.len; + memcpy(&(packet.data), payload, sizeof(struct dhcpMessage)); + packet.udp.check = checksum(&packet, sizeof(struct udp_dhcp_packet)); + + packet.ip.tot_len = htons(sizeof(struct udp_dhcp_packet)); + packet.ip.ihl = sizeof(packet.ip) >> 2; + packet.ip.version = IPVERSION; + packet.ip.ttl = IPDEFTTL; + packet.ip.check = checksum(&(packet.ip), sizeof(packet.ip)); + + result = sendto(fd, &packet, sizeof(struct udp_dhcp_packet), 0, (struct sockaddr *) &dest, sizeof(dest)); + if (result <= 0) { + DEBUG(LOG_ERR, "write on socket failed: %m"); + } + close(fd); + return result; +} + + +/* Let the kernel do all the work for packet generation */ +int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_port, + uint32_t dest_ip, int dest_port) +{ + int n = 1; + int fd, result; + struct sockaddr_in client; + + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return -1; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) + { + close(fd); + return -1; + } + + memset(&client, 0, sizeof(client)); + client.sin_family = AF_INET; + client.sin_port = htons(source_port); + client.sin_addr.s_addr = source_ip; + + if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) + { + close(fd); + return -1; + } + + memset(&client, 0, sizeof(client)); + client.sin_family = AF_INET; + client.sin_port = htons(dest_port); + client.sin_addr.s_addr = dest_ip; + + if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) + { + close(fd); + return -1; + } + + result = write(fd, payload, sizeof(struct dhcpMessage)); + close(fd); + return result; +} diff --git a/udhcp/packet.h b/udhcp/packet.h new file mode 100644 index 0000000..f5859e8 --- /dev/null +++ b/udhcp/packet.h @@ -0,0 +1,41 @@ +#ifndef _PACKET_H +#define _PACKET_H + +#include +#include + +struct dhcpMessage { + uint8_t op; + uint8_t htype; + uint8_t hlen; + uint8_t hops; + uint32_t xid; + uint16_t secs; + uint16_t flags; + uint32_t ciaddr; + uint32_t yiaddr; + uint32_t siaddr; + uint32_t giaddr; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + uint32_t cookie; + uint8_t options[308]; /* 312 - cookie */ +}; + +struct udp_dhcp_packet { + struct iphdr ip; + struct udphdr udp; + struct dhcpMessage data; +}; + +void init_header(struct dhcpMessage *packet, char type); +int get_packet(struct dhcpMessage *packet, int fd); +uint16_t checksum(void *addr, int count); +int raw_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_port, + uint32_t dest_ip, int dest_port, uint8_t *dest_arp, int ifindex); +int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_port, + uint32_t dest_ip, int dest_port); + + +#endif diff --git a/udhcp/pidfile.c b/udhcp/pidfile.c new file mode 100644 index 0000000..2e0c753 --- /dev/null +++ b/udhcp/pidfile.c @@ -0,0 +1,75 @@ +/* pidfile.c + * + * Functions to assist in the writing and removing of pidfiles. + * + * Russ Dill September 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "pidfile.h" +#include "common.h" + +static char *saved_pidfile; + +static void pidfile_delete(void) +{ + if (saved_pidfile) unlink(saved_pidfile); +} + + +int pidfile_acquire(const char *pidfile) +{ + int pid_fd; + if (!pidfile) return -1; + + pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644); + if (pid_fd < 0) { + LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile); + } else { + lockf(pid_fd, F_LOCK, 0); + if (!saved_pidfile) + atexit(pidfile_delete); + saved_pidfile = (char *) pidfile; + } + + return pid_fd; +} + + +void pidfile_write_release(int pid_fd) +{ + FILE *out; + + if (pid_fd < 0) return; + + if ((out = fdopen(pid_fd, "w")) != NULL) { + fprintf(out, "%d\n", getpid()); + fclose(out); + } + lockf(pid_fd, F_UNLCK, 0); + close(pid_fd); +} + + + + diff --git a/udhcp/pidfile.h b/udhcp/pidfile.h new file mode 100644 index 0000000..ea97d1d --- /dev/null +++ b/udhcp/pidfile.h @@ -0,0 +1,25 @@ +/* pidfile.h + * + * Functions to assist in the writing and removing of pidfiles. + * + * Russ Dill September 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +int pidfile_acquire(const char *pidfile); +void pidfile_write_release(int pid_fd); + diff --git a/udhcp/script.c b/udhcp/script.c new file mode 100644 index 0000000..820fbb0 --- /dev/null +++ b/udhcp/script.c @@ -0,0 +1,233 @@ +/* script.c + * + * Functions to call the DHCP client notification scripts + * + * Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "options.h" +#include "dhcpd.h" +#include "dhcpc.h" +#include "common.h" + +/* get a rough idea of how long an option will be (rounding up...) */ +static const int max_option_length[] = { + [OPTION_IP] = sizeof("255.255.255.255 "), + [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, + [OPTION_STRING] = 1, + [OPTION_BOOLEAN] = sizeof("yes "), + [OPTION_U8] = sizeof("255 "), + [OPTION_U16] = sizeof("65535 "), + [OPTION_S16] = sizeof("-32768 "), + [OPTION_U32] = sizeof("4294967295 "), + [OPTION_S32] = sizeof("-2147483684 "), +}; + + +static inline int upper_length(int length, int opt_index) +{ + return max_option_length[opt_index] * + (length / option_lengths[opt_index]); +} + + +static int sprintip(char *dest, char *pre, uint8_t *ip) +{ + return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]); +} + + +/* really simple implementation, just count the bits */ +static int mton(struct in_addr *mask) +{ + int i; + unsigned long bits = ntohl(mask->s_addr); + /* too bad one can't check the carry bit, etc in c bit + * shifting */ + for (i = 0; i < 32 && !((bits >> i) & 1); i++); + return 32 - i; +} + + +/* Fill dest with the text of option 'option'. */ +static void fill_options(char *dest, uint8_t *option, struct dhcp_option *type_p) +{ + int type, optlen; + uint16_t val_u16; + int16_t val_s16; + uint32_t val_u32; + int32_t val_s32; + int len = option[OPT_LEN - 2]; + + dest += sprintf(dest, "%s=", type_p->name); + + type = type_p->flags & TYPE_MASK; + optlen = option_lengths[type]; + for(;;) { + switch (type) { + case OPTION_IP_PAIR: + dest += sprintip(dest, "", option); + *(dest++) = '/'; + option += 4; + optlen = 4; + case OPTION_IP: /* Works regardless of host byte order. */ + dest += sprintip(dest, "", option); + break; + case OPTION_BOOLEAN: + dest += sprintf(dest, *option ? "yes" : "no"); + break; + case OPTION_U8: + dest += sprintf(dest, "%u", *option); + break; + case OPTION_U16: + memcpy(&val_u16, option, 2); + dest += sprintf(dest, "%u", ntohs(val_u16)); + break; + case OPTION_S16: + memcpy(&val_s16, option, 2); + dest += sprintf(dest, "%d", ntohs(val_s16)); + break; + case OPTION_U32: + memcpy(&val_u32, option, 4); + dest += sprintf(dest, "%lu", (unsigned long) ntohl(val_u32)); + break; + case OPTION_S32: + memcpy(&val_s32, option, 4); + dest += sprintf(dest, "%ld", (long) ntohl(val_s32)); + break; + case OPTION_STRING: + memcpy(dest, option, len); + dest[len] = '\0'; + return; /* Short circuit this case */ + } + option += optlen; + len -= optlen; + if (len <= 0) break; + dest += sprintf(dest, " "); + } +} + + +/* put all the parameters into an environment */ +static char **fill_envp(struct dhcpMessage *packet) +{ + int num_options = 0; + int i, j; + char **envp; + uint8_t *temp; + struct in_addr subnet; + char over = 0; + + if (packet == NULL) + num_options = 0; + else { + for (i = 0; dhcp_options[i].code; i++) + if (get_option(packet, dhcp_options[i].code)) { + num_options++; + if (dhcp_options[i].code == DHCP_SUBNET) + num_options++; /* for mton */ + } + if (packet->siaddr) num_options++; + if ((temp = get_option(packet, DHCP_OPTION_OVER))) + over = *temp; + if (!(over & FILE_FIELD) && packet->file[0]) num_options++; + if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++; + } + + envp = xcalloc(sizeof(char *), num_options + 5); + j = 0; + asprintf(&envp[j++], "interface=%s", client_config.interface); + asprintf(&envp[j++], "%s=%s", "PATH", + getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin"); + asprintf(&envp[j++], "%s=%s", "HOME", getenv("HOME") ? : "/"); + + if (packet == NULL) return envp; + + envp[j] = xmalloc(sizeof("ip=255.255.255.255")); + sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); + + + for (i = 0; dhcp_options[i].code; i++) { + if (!(temp = get_option(packet, dhcp_options[i].code))) + continue; + envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], + dhcp_options[i].flags & TYPE_MASK) + strlen(dhcp_options[i].name) + 2); + fill_options(envp[j++], temp, &dhcp_options[i]); + + /* Fill in a subnet bits option for things like /24 */ + if (dhcp_options[i].code == DHCP_SUBNET) { + memcpy(&subnet, temp, 4); + asprintf(&envp[j++], "mask=%d", mton(&subnet)); + } + } + if (packet->siaddr) { + envp[j] = xmalloc(sizeof("siaddr=255.255.255.255")); + sprintip(envp[j++], "siaddr=", (uint8_t *) &packet->siaddr); + } + if (!(over & FILE_FIELD) && packet->file[0]) { + /* watch out for invalid packets */ + packet->file[sizeof(packet->file) - 1] = '\0'; + asprintf(&envp[j++], "boot_file=%s", packet->file); + } + if (!(over & SNAME_FIELD) && packet->sname[0]) { + /* watch out for invalid packets */ + packet->sname[sizeof(packet->sname) - 1] = '\0'; + asprintf(&envp[j++], "sname=%s", packet->sname); + } + return envp; +} + + +/* Call a script with a par file and env vars */ +void run_script(struct dhcpMessage *packet, const char *name) +{ + int pid; + char **envp, **curr; + + if (client_config.script == NULL) + return; + + DEBUG(LOG_INFO, "vforking and execle'ing %s", client_config.script); + + envp = fill_envp(packet); + /* call script */ + pid = vfork(); + if (pid) { + waitpid(pid, NULL, 0); + for (curr = envp; *curr; curr++) free(*curr); + free(envp); + return; + } else if (pid == 0) { + /* close fd's? */ + + /* exec script */ + execle(client_config.script, client_config.script, + name, NULL, envp); + LOG(LOG_ERR, "script %s failed: %m", client_config.script); + exit(1); + } +} diff --git a/udhcp/script.h b/udhcp/script.h new file mode 100644 index 0000000..87a20cc --- /dev/null +++ b/udhcp/script.h @@ -0,0 +1,6 @@ +#ifndef _SCRIPT_H +#define _SCRIPT_H + +void run_script(struct dhcpMessage *packet, const char *name); + +#endif diff --git a/udhcp/serverpacket.c b/udhcp/serverpacket.c new file mode 100644 index 0000000..75d55bd --- /dev/null +++ b/udhcp/serverpacket.c @@ -0,0 +1,275 @@ +/* serverpacket.c + * + * Construct and send DHCP server packets + * + * Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include "serverpacket.h" +#include "dhcpd.h" +#include "options.h" +#include "common.h" +#include "static_leases.h" + +/* send a packet to giaddr using the kernel ip stack */ +static int send_packet_to_relay(struct dhcpMessage *payload) +{ + DEBUG(LOG_INFO, "Forwarding packet to relay"); + + return kernel_packet(payload, server_config.server, SERVER_PORT, + payload->giaddr, SERVER_PORT); +} + + +/* send a packet to a specific arp address and ip address by creating our own ip packet */ +static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcast) +{ + uint8_t *chaddr; + uint32_t ciaddr; + + if (force_broadcast) { + DEBUG(LOG_INFO, "broadcasting packet to client (NAK)"); + ciaddr = INADDR_BROADCAST; + chaddr = MAC_BCAST_ADDR; + } else if (payload->ciaddr) { + DEBUG(LOG_INFO, "unicasting packet to client ciaddr"); + ciaddr = payload->ciaddr; + chaddr = payload->chaddr; + } else if (ntohs(payload->flags) & BROADCAST_FLAG) { + DEBUG(LOG_INFO, "broadcasting packet to client (requested)"); + ciaddr = INADDR_BROADCAST; + chaddr = MAC_BCAST_ADDR; + } else { + DEBUG(LOG_INFO, "unicasting packet to client yiaddr"); + ciaddr = payload->yiaddr; + chaddr = payload->chaddr; + } + return raw_packet(payload, server_config.server, SERVER_PORT, + ciaddr, CLIENT_PORT, chaddr, server_config.ifindex); +} + + +/* send a dhcp packet, if force broadcast is set, the packet will be broadcast to the client */ +static int send_packet(struct dhcpMessage *payload, int force_broadcast) +{ + int ret; + + if (payload->giaddr) + ret = send_packet_to_relay(payload); + else ret = send_packet_to_client(payload, force_broadcast); + return ret; +} + + +static void init_packet(struct dhcpMessage *packet, struct dhcpMessage *oldpacket, char type) +{ + init_header(packet, type); + packet->xid = oldpacket->xid; + memcpy(packet->chaddr, oldpacket->chaddr, 16); + packet->flags = oldpacket->flags; + packet->giaddr = oldpacket->giaddr; + packet->ciaddr = oldpacket->ciaddr; + add_simple_option(packet->options, DHCP_SERVER_ID, server_config.server); +} + + +/* add in the bootp options */ +static void add_bootp_options(struct dhcpMessage *packet) +{ + packet->siaddr = server_config.siaddr; + if (server_config.sname) + strncpy(packet->sname, server_config.sname, sizeof(packet->sname) - 1); + if (server_config.boot_file) + strncpy(packet->file, server_config.boot_file, sizeof(packet->file) - 1); +} + + +/* send a DHCP OFFER to a DHCP DISCOVER */ +int sendOffer(struct dhcpMessage *oldpacket) +{ + struct dhcpMessage packet; + struct dhcpOfferedAddr *lease = NULL; + uint32_t req_align, lease_time_align = server_config.lease; + uint8_t *req, *lease_time; + struct option_set *curr; + struct in_addr addr; + + uint32_t static_lease_ip; + + init_packet(&packet, oldpacket, DHCPOFFER); + + static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr); + + /* ADDME: if static, short circuit */ + if(!static_lease_ip) + { + /* the client is in our lease/offered table */ + if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { + if (!lease_expired(lease)) + lease_time_align = lease->expires - time(0); + packet.yiaddr = lease->yiaddr; + + /* Or the client has a requested ip */ + } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) && + + /* Don't look here (ugly hackish thing to do) */ + memcpy(&req_align, req, 4) && + + /* and the ip is in the lease range */ + ntohl(req_align) >= ntohl(server_config.start) && + ntohl(req_align) <= ntohl(server_config.end) && + + !static_lease_ip && /* Check that its not a static lease */ + /* and is not already taken/offered */ + ((!(lease = find_lease_by_yiaddr(req_align)) || + + /* or its taken, but expired */ /* ADDME: or maybe in here */ + lease_expired(lease)))) { + packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ + + /* otherwise, find a free IP */ + } else { + /* Is it a static lease? (No, because find_address skips static lease) */ + packet.yiaddr = find_address(0); + + /* try for an expired lease */ + if (!packet.yiaddr) packet.yiaddr = find_address(1); + } + + if(!packet.yiaddr) { + LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned"); + return -1; + } + + if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { + LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); + return -1; + } + + if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { + memcpy(&lease_time_align, lease_time, 4); + lease_time_align = ntohl(lease_time_align); + if (lease_time_align > server_config.lease) + lease_time_align = server_config.lease; + } + + /* Make sure we aren't just using the lease time from the previous offer */ + if (lease_time_align < server_config.min_lease) + lease_time_align = server_config.lease; + } + /* ADDME: end of short circuit */ + else + { + /* It is a static lease... use it */ + packet.yiaddr = static_lease_ip; + } + + add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); + + curr = server_config.options; + while (curr) { + if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) + add_option_string(packet.options, curr->data); + curr = curr->next; + } + + add_bootp_options(&packet); + + addr.s_addr = packet.yiaddr; + LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); + return send_packet(&packet, 0); +} + + +int sendNAK(struct dhcpMessage *oldpacket) +{ + struct dhcpMessage packet; + + init_packet(&packet, oldpacket, DHCPNAK); + + DEBUG(LOG_INFO, "sending NAK"); + return send_packet(&packet, 1); +} + + +int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr) +{ + struct dhcpMessage packet; + struct option_set *curr; + uint8_t *lease_time; + uint32_t lease_time_align = server_config.lease; + struct in_addr addr; + + init_packet(&packet, oldpacket, DHCPACK); + packet.yiaddr = yiaddr; + + if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { + memcpy(&lease_time_align, lease_time, 4); + lease_time_align = ntohl(lease_time_align); + if (lease_time_align > server_config.lease) + lease_time_align = server_config.lease; + else if (lease_time_align < server_config.min_lease) + lease_time_align = server_config.lease; + } + + add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); + + curr = server_config.options; + while (curr) { + if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) + add_option_string(packet.options, curr->data); + curr = curr->next; + } + + add_bootp_options(&packet); + + addr.s_addr = packet.yiaddr; + LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); + + if (send_packet(&packet, 0) < 0) + return -1; + + add_lease(packet.chaddr, packet.yiaddr, lease_time_align); + + return 0; +} + + +int send_inform(struct dhcpMessage *oldpacket) +{ + struct dhcpMessage packet; + struct option_set *curr; + + init_packet(&packet, oldpacket, DHCPACK); + + curr = server_config.options; + while (curr) { + if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) + add_option_string(packet.options, curr->data); + curr = curr->next; + } + + add_bootp_options(&packet); + + return send_packet(&packet, 0); +} diff --git a/udhcp/serverpacket.h b/udhcp/serverpacket.h new file mode 100644 index 0000000..9024928 --- /dev/null +++ b/udhcp/serverpacket.h @@ -0,0 +1,12 @@ +#ifndef _SERVERPACKET_H +#define _SERVERPACKET_H + +#include "packet.h" + +int sendOffer(struct dhcpMessage *oldpacket); +int sendNAK(struct dhcpMessage *oldpacket); +int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr); +int send_inform(struct dhcpMessage *oldpacket); + + +#endif diff --git a/udhcp/signalpipe.c b/udhcp/signalpipe.c new file mode 100644 index 0000000..074c8a6 --- /dev/null +++ b/udhcp/signalpipe.c @@ -0,0 +1,78 @@ +/* signalpipe.c + * + * Signal pipe infrastructure. A reliable way of delivering signals. + * + * Russ Dill December 2003 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + + +#include "signalpipe.h" +#include "common.h" + +static int signal_pipe[2]; + +static void signal_handler(int sig) +{ + if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) + DEBUG(LOG_ERR, "Could not send signal: %m"); +} + + +/* Call this before doing anything else. Sets up the socket pair + * and installs the signal handler */ +void udhcp_sp_setup(void) +{ + socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe); + signal(SIGUSR1, signal_handler); + signal(SIGUSR2, signal_handler); + signal(SIGTERM, signal_handler); +} + + +/* Quick little function to setup the rfds. Will return the + * max_fd for use with select. Limited in that you can only pass + * one extra fd */ +int udhcp_sp_fd_set(fd_set *rfds, int extra_fd) +{ + FD_ZERO(rfds); + FD_SET(signal_pipe[0], rfds); + if (extra_fd >= 0) FD_SET(extra_fd, rfds); + return signal_pipe[0] > extra_fd ? signal_pipe[0] : extra_fd; +} + + +/* Read a signal from the signal pipe. Returns 0 if there is + * no signal, -1 on error (and sets errno appropriately), and + * your signal on success */ +int udhcp_sp_read(fd_set *rfds) +{ + int sig; + + if (!FD_ISSET(signal_pipe[0], rfds)) + return 0; + + if (read(signal_pipe[0], &sig, sizeof(sig)) < 0) + return -1; + + return sig; +} diff --git a/udhcp/signalpipe.h b/udhcp/signalpipe.h new file mode 100644 index 0000000..70c1e57 --- /dev/null +++ b/udhcp/signalpipe.h @@ -0,0 +1,22 @@ +/* signalpipe.h + * + * Russ Dill December 2003 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +void udhcp_sp_setup(void); +int udhcp_sp_fd_set(fd_set *rfds, int extra_fd); +int udhcp_sp_read(fd_set *rfds); diff --git a/udhcp/socket.c b/udhcp/socket.c new file mode 100644 index 0000000..7529250 --- /dev/null +++ b/udhcp/socket.c @@ -0,0 +1,137 @@ +/* + * socket.c -- DHCP server client/server socket creation + * + * udhcp client/server + * Copyright (C) 1999 Matthew Ramsay + * Chris Trew + * + * Rewrite by Russ Dill July 2001 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 +#include +#include +#else +#include +#include +#include +#endif + +#include "socket.h" +#include "common.h" + +int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) +{ + int fd; + struct ifreq ifr; + struct sockaddr_in *our_ip; + + memset(&ifr, 0, sizeof(struct ifreq)); + if((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) { + ifr.ifr_addr.sa_family = AF_INET; + //closes http://bugs.debian.org/283582 + //strcpy(ifr.ifr_name, interface); + strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); + + if (addr) { + if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) { + our_ip = (struct sockaddr_in *) &ifr.ifr_addr; + *addr = our_ip->sin_addr.s_addr; + DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name, inet_ntoa(our_ip->sin_addr)); + } else { + LOG(LOG_ERR, "SIOCGIFADDR failed, is the interface up and configured?: %m"); + close(fd); + return -1; + } + } + + if (ioctl(fd, SIOCGIFINDEX, &ifr) == 0) { + DEBUG(LOG_INFO, "adapter index %d", ifr.ifr_ifindex); + *ifindex = ifr.ifr_ifindex; + } else { + LOG(LOG_ERR, "SIOCGIFINDEX failed!: %m"); + close(fd); + return -1; + } + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) { + memcpy(arp, ifr.ifr_hwaddr.sa_data, 6); + DEBUG(LOG_INFO, "adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x", + arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]); + } else { + LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %m"); + close(fd); + return -1; + } + } else { + LOG(LOG_ERR, "socket failed!: %m"); + return -1; + } + close(fd); + return 0; +} + + +int listen_socket(uint32_t ip, int port, char *inf) +{ + struct ifreq interface; + int fd; + struct sockaddr_in addr; + int n = 1; + + DEBUG(LOG_INFO, "Opening listen socket on 0x%08x:%d %s", ip, port, inf); + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + DEBUG(LOG_ERR, "socket call failed: %m"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = ip; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) { + close(fd); + return -1; + } + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) == -1) { + close(fd); + return -1; + } + + strncpy(interface.ifr_ifrn.ifrn_name, inf, IFNAMSIZ); + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,(char *)&interface, sizeof(interface)) < 0) { + close(fd); + return -1; + } + + if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) { + close(fd); + return -1; + } + + return fd; +} diff --git a/udhcp/socket.h b/udhcp/socket.h new file mode 100644 index 0000000..66179d4 --- /dev/null +++ b/udhcp/socket.h @@ -0,0 +1,8 @@ +/* socket.h */ +#ifndef _SOCKET_H +#define _SOCKET_H + +int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp); +int listen_socket(uint32_t ip, int port, char *inf); + +#endif diff --git a/udhcp/static_leases.c b/udhcp/static_leases.c new file mode 100644 index 0000000..1124d39 --- /dev/null +++ b/udhcp/static_leases.c @@ -0,0 +1,119 @@ +/* + * static_leases.c -- Couple of functions to assist with storing and + * retrieving data for static leases + * + * Wade Berrier September 2004 + * + */ + + +#include +#include +#include + +#include "static_leases.h" +#include "dhcpd.h" + +/* Takes the address of the pointer to the static_leases linked list, + * Address to a 6 byte mac address + * Address to a 4 byte ip address */ +int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip) +{ + + struct static_lease *cur; + struct static_lease *new_static_lease; + + /* Build new node */ + new_static_lease = xmalloc(sizeof(struct static_lease)); + new_static_lease->mac = mac; + new_static_lease->ip = ip; + new_static_lease->next = NULL; + + /* If it's the first node to be added... */ + if(*lease_struct == NULL) + { + *lease_struct = new_static_lease; + } + else + { + cur = *lease_struct; + while(cur->next != NULL) + { + cur = cur->next; + } + + cur->next = new_static_lease; + } + + return 1; + +} + +/* Check to see if a mac has an associated static lease */ +uint32_t getIpByMac(struct static_lease *lease_struct, void *arg) +{ + uint32_t return_ip; + struct static_lease *cur = lease_struct; + uint8_t *mac = arg; + + return_ip = 0; + + while(cur != NULL) + { + /* If the client has the correct mac */ + if(memcmp(cur->mac, mac, 6) == 0) + { + return_ip = *(cur->ip); + } + + cur = cur->next; + } + + return return_ip; + +} + +/* Check to see if an ip is reserved as a static ip */ +uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip) +{ + struct static_lease *cur = lease_struct; + + uint32_t return_val = 0; + + while(cur != NULL) + { + /* If the client has the correct ip */ + if(*cur->ip == ip) + return_val = 1; + + cur = cur->next; + } + + return return_val; + +} + +#ifdef UDHCP_DEBUG +/* Print out static leases just to check what's going on */ +/* Takes the address of the pointer to the static_leases linked list */ +void printStaticLeases(struct static_lease **arg) +{ + /* Get a pointer to the linked list */ + struct static_lease *cur = *arg; + + while(cur != NULL) + { + /* printf("PrintStaticLeases: Lease mac Address: %x\n", cur->mac); */ + printf("PrintStaticLeases: Lease mac Value: %x\n", *(cur->mac)); + /* printf("PrintStaticLeases: Lease ip Address: %x\n", cur->ip); */ + printf("PrintStaticLeases: Lease ip Value: %x\n", *(cur->ip)); + + cur = cur->next; + } + + +} +#endif + + + diff --git a/udhcp/static_leases.h b/udhcp/static_leases.h new file mode 100644 index 0000000..d06520b --- /dev/null +++ b/udhcp/static_leases.h @@ -0,0 +1,25 @@ +/* static_leases.h */ +#ifndef _STATIC_LEASES_H +#define _STATIC_LEASES_H + +#include "dhcpd.h" + +/* Config file will pass static lease info to this function which will add it + * to a data structure that can be searched later */ +int addStaticLease(struct static_lease **lease_struct, uint8_t *mac, uint32_t *ip); + +/* Check to see if a mac has an associated static lease */ +uint32_t getIpByMac(struct static_lease *lease_struct, void *arg); + +/* Check to see if an ip is reserved as a static ip */ +uint32_t reservedIp(struct static_lease *lease_struct, uint32_t ip); + +#ifdef UDHCP_DEBUG +/* Print out static leases just to check what's going on */ +void printStaticLeases(struct static_lease **lease_struct); +#endif + +#endif + + + diff --git a/udhcp/udhcpc.8 b/udhcp/udhcpc.8 new file mode 100644 index 0000000..61bc2db --- /dev/null +++ b/udhcp/udhcpc.8 @@ -0,0 +1,208 @@ +.TH UDHCPC 8 2001-09-26 GNU/Linux "GNU/Linux Administrator's Manual" +.SH NAME +udhcpc \- very small DHCP client +.SH SYNOPSIS +.B udhcpc +.RI [ OPTION ]... +.SH DESCRIPTION +The udhcp client negotiates a lease with the DHCP server and +executes a script when it is obtained or lost. +.SH OPTIONS +.TP +.BI \-c\ CLIENTID ,\ \-\-clientid= CLIENTID +Send the client identifier +.IR CLIENTID . +.TP +.BR -f ,\ \-\-foreground +Do not fork after obtaining a lease. +.TP +.BI \-H\ HOSTNAME ,\ \-\-hostname= HOSTNAME +Send the client hostname +.IR HOSTNAME . +.TP +.BI \-h\ HOSTNAME +Alias for -H +.IR HOSTNAME . +.TP +.BI \-i\ INTERFACE ,\ \-\-interface= INTERFACE +Configure +.IR INTERFACE . +.TP +.BR -n ,\ \-\-now +Exit with failure if a lease cannot be obtained. +.TP +.BI \-p\ FILE ,\ \-\-pidfile= FILE +Write the process ID of the daemon to +.IR FILE . +.TP +.BR -q ,\ \-\-quit +Exit after obtaining a lease. +.TP +.BI \-r\ ADDRESS ,\ \-\-request= ADDRESS +Request IP address +.IR ADDRESS . +.TP +.BI \-s\ FILE ,\ \-\-script= FILE +Use script +.IR FILE . +.TP +.BR -v ,\ \-\-version +Display version. +.SH USAGE +When an event occurs, +.B udhcpc +executes a script. There are four possible arguments to this +script: +.TP +.B deconfig +.B deconfig +is used when +.B udhcpc +starts, and when a lease is lost. The script should put the +interface in an up, but deconfigured, state. +.TP +.B bound +.B bound +is used when +.B udhcpc +moves from an unbound to a bound state. The script should +configure the interface and set any other relevant parameters +(e.g., default gateway, dns server, etc.). +.TP +.B renew +.B renew +is used when +.B udhcpc +when a lease is renewed. The interface is already +configured, so the IP address will not change. Other parameters +(e.g., default gateway, subnet mask, dns server) may. +.TP +.B nak +.B nak +is used when +.B udhcpc +receieves a NAK packet from the server. The +enviromental variable +.B $message +will contain the reason for the +NAK message if the server included one. Processing this message +is optional, as the script will also be called with deconfig if +need be. +.PP +Parameters are passed to the script via the following environment +variables: +.TP +.B HOME +The inherited HOME, or "/" if it is unset. +.TP +.B PATH +The inherited PATH, or "/bin:/usr/bin:/sbin:/usr/sbin" if it is +unset. +.TP +.B interface +The interface. +.TP +.B ip +The client IP address. +.TP +.B siaddr +The BOOTP next server option. +.TP +.B sname +The BOOTP server name option. +.TP +.B boot_file +The BOOTP boot file option. +.TP +.B subnet +The subnet mask. +.TP +.B timezone +The timezone offset from UTC in seconds. +.TP +.B router +The list of routers. +.TP +.B timesvr +The list of time servers. +.TP +.B namesvr +The list of IEN 116 name servers. +.TP +.B dns +The list of DNS servers. +.TP +.B logsvr +The list of MIT-LCS UDP log servers. +.TP +.B cookiesvr +The list of RFC 865 cookie servers. +.TP +.B lprsvr +The list of LPR servers. +.TP +.B hostname +The host name. +.TP +.B bootsize +The length in 512-octet blocks of the bootfile. +.TP +.B domain +The domain name of the network. +.TP +.B swapsvr +The client's swap server. +.TP +.B rootpath +The path of the client's root dist. +.TP +.B ipttl +The TTL. +.TP +.B mtu +The MTU. +.TP +.B broadcast +The broadcast address. +.TP +.B ntpsrv +The list of NTP servers. +.TP +.B wins +The list of WINS servers. +.TP +.B lease +The lease time in seconds. +.TP +.B dhcptype +The DHCP message type (safely ignored). +.TP +.B serverid +The server IP address. +.TP +.B message +Reason for a DHCPNAK. +.TP +.B tftp +The TFTP server name. +.TP +.B bootfile +The bootfile name. +.SH FILES +.TP +.I /etc/udhcpc/default.script +Script run when leases are obtained or lost. +.SH NOTES +.B udhcpc +responds to the following signals: +.TP +.B SIGUSR1 +This signal causes +.B udhcpc +to renew the current lease or, if it does not have one, obtain a +new lease. +.TP +.B SIGUSR2 +This signal caused +.B udhcpc +to release the current lease. diff --git a/udhcp/udhcpd.8 b/udhcp/udhcpd.8 new file mode 100644 index 0000000..be8fac8 --- /dev/null +++ b/udhcp/udhcpd.8 @@ -0,0 +1,17 @@ +.TH UDHCPD 8 2001-09-27 GNU/Linux "GNU/Linux Administrator's Manual" +.SH NAME +udhcpd \- very small DHCP server +.SH SYNOPSIS +.B udhcpd +.SH DESCRIPTION +The udhcp server negotiates leases with DHCP clients. +.SH FILES +.TP +.I /etc/udhcpd.conf +Configuration file. +.TP +.I /var/lib/misc/udhcpd.leases +Lease information file. +.SH SEE ALSO +.BR dumpleases (1), +.BR udhcpd.conf (8). diff --git a/udhcp/udhcpd.conf.5 b/udhcp/udhcpd.conf.5 new file mode 100644 index 0000000..99e66ca --- /dev/null +++ b/udhcp/udhcpd.conf.5 @@ -0,0 +1,166 @@ +.TH UDHCPD.CONF 5 2001-09-26 GNU/Linux "GNU/Linux Administrator's Manual" +.SH NAME +udhcpd.conf \- udhcp server configuration file +.SH DESCRIPTION +The file +.I /etc/udhcpd.conf +contains configuration information specific to the udhcp server. +It should contain one configuration keyword per line, followed by +appropriate configuration information. +.SH OPTIONS +.TP +.BI start\ ADDRESS +The starting address of the IP lease block is +.IR ADDRESS . +The default is +.BR 192.168.0.20 . +.TP +.BI end\ ADDRESS +The ending address of the IP lease block is +.IR ADDRESS . +The default is +.BR 192.168.0.254 . +.TP +.BI interface\ INTERFACE +The udhcp server should listen on +.IR INTERFACE . +The default is +.BR eth0 . +.TP +.BI max_leases\ LEASES +Offer at most +.I LEASES +leases (including those reserved by OFFERs, DECLINEs, and ARP +conflicts). The default is +.BR 254 . +.TP +.BI remaining\ REMAINING +If +.I REMAINING +is +.BR yes , +store the time remaining for each lease. If it is +.BR no , +store the expiration time for each lease. The default is +.BR yes . +.TP +.BI auto_time\ SECONDS +Write the lease information to a file every +.I SECONDS +seconds. The default is +.BR 7200 . +.TP +.BI decline_time\ SECONDS +Reserve an IP for +.I SECONDS +seconds if a DHCP decline message is received. The default is +.BR 3600 . +.TP +.BI conflict_time\ SECONDS +Reserve an IP for +.I SECONDS +seconds if an ARP conflict occurs. The default is +.BR 3600 . +.TP +.BI offer_time\ SECONDS +Reserve an IP for +.I SECONDS +seconds if it is offered. The default is +.BR 60 . +.TP +.BI min_lease\ SECONDS +Reserve an IP for the full lease time if the lease to be given is less than +.I SECONDS +seconds. The default is +.BR 60 . +.TP +.BI lease_file\ FILE +Write the lease information to +.IR FILE . +The default is +.BR /var/lib/misc/udhcpd.leases . +.TP +.BI pidfile\ FILE +Write the process ID to +.IR FILE . +The default is +.BR /var/run/udhcpd.pid . +.TP +.BI notify_file\ FILE +Execute +.I FILE +after the lease information is written. By default, no file is executed. +.TP +.BI siaddr\ ADDRESS +BOOTP specific option. The default is +.BR 0.0.0.0 . +.TP +.BI sname\ NAME +BOOTP specific option. There is no default. +.TP +.BI boot_file\ FILE +BOOTP specific option. There is no default. +.TP +.BI option\ OPTION +DHCP specific option. +.RS +.TP +.BI subnet\ ADDRESS +.TP +.BI timezone\ OFFSET +.TP +.BI router\ ADDRESS... +.TP +.BI timesvr\ ADDRESS... +.TP +.BI namesvr\ ADDRESS... +.TP +.BI dns\ ADDRESS... +.TP +.BI logsvr\ ADDRESS... +.TP +.BI cookiesvr\ ADDRESS... +.TP +.BI lprsvr\ ADDRESS... +.TP +.BI hostname\ HOSTNAME +.TP +.BI bootsize\ SIZE +.TP +.BI domain\ DOMAIN +.TP +.BI swapsvr\ ADDRESS +.TP +.BI rootpath\ PATH +.TP +.BI ipttl\ TTL +.TP +.BI mtu\ MTU +.TP +.BI broadcast\ ADDRESS +.TP +.BI ntpsrv\ ADDRESS... +.TP +.BI wins\ ADDRESS... +.TP +.BI requestip\ ADDRESS +.TP +.BI lease\ SECONDS +.TP +.BI dhcptype\ TYPE +.TP +.BI serverid\ ADDRESS +.TP +.BI tftp\ FILE +.TP +.BI wpad\ URL +.TP +.BI bootfile\ FILE +The default for +.B lease +is +.BR 864000 . +There are no defaults for the other options. +.RE +.SH SEE ALSO +.BR udhcpd (8). diff --git a/udhcp/version.h b/udhcp/version.h new file mode 100644 index 0000000..3862539 --- /dev/null +++ b/udhcp/version.h @@ -0,0 +1,6 @@ +#ifndef _UDHCP_VERSION_H +#define _UDHCP_VERSION_H + +#define VERSION "0.9.9-pre" + +#endif diff --git a/udhcpc b/udhcpc deleted file mode 100755 index fb25939ceaa03065a9668565f7715bb47b68f1fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 451312 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

4Ax_>n|j%HJ;vx21Mmvk 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

<(PMR0F2uhK8Ph%@9Y@`J-y0|!57WTO_a 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≥sfAhDoDs1*rb)~7y4oA> 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 -- 2.1.4