remove in place of external link
This commit was genuinely broken at the time (not related to our build system): scripts/config/mkconfigs.c (2005-08-01 - 2006-10-05 arasi) uretilen bbconfigopts.h icine .config satirlarini kacissiz, ham newline'larla gömüyordu - gecerli C degildi, busybox'un kendi bb_mkdep araci bile parse edemiyordu (7d219aab7 ile duzeltildi, mkconfigs shell scripte cevrildi)
No binary (build failed)
—
(log yok)
| @@ -1,13 +0,0 @@ | |
| - | udhcp server/client package |
| - | ----------------------- |
| - | |
| - | Russ Dill <[email protected]> |
| - | Matthew Ramsay <[email protected]> |
| - | Chris Trew <[email protected]> |
| - | |
| - | Other Credits: |
| - | -------------- |
| - | Moreton Bay (http://www.moretonbay.com/) |
| - | Vladimir Oleynik <[email protected]> Size optimizations |
| - | |
| - | |
| @@ -1,339 +0,0 @@ | |
| - | 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. |
| - | |
| - | <one line to give the program's name and a brief idea of what it does.> |
| - | Copyright (C) 19yy <name of author> |
| - | |
| - | 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. |
| - | |
| - | <signature of Ty Coon>, 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. |
| @@ -1,260 +0,0 @@ | |
| - | 0.9.9 (pending) |
| - | + Various other size optimizations (Vladimir) |
| - | + Change strerror(errno) to %m (Vladimir N. Oleynik <[email protected]>) |
| - | + Fixed a little endian problem in mton (Bastian Blank <[email protected]>) |
| - | + Fixed a arpping alignment problem (Rui He <[email protected]>) |
| - | + 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 <[email protected]>, 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 <[email protected]> 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 <[email protected]>) |
| - | + Was improperly reporting yiaddr as siaddr ([email protected]) |
| - | udhcp bug#1256 |
| - | + Fixed reading of client id (David Poole <[email protected]>) |
| - | + change sys_errlist[] to strerror() as it aparently doesn't exist |
| - | (Erik Andersen <[email protected]>) |
| - | + fixed get_raw_packet so it returns -2 on non fatal errors |
| - | (Ted Lemon <[email protected]>) |
| - | + Improved (hopefully) NAKing behavior (me) |
| - | + Added -b option (Jouni Malinen) |
| - | + Compute checksums correctly on big endian hosts |
| - | (Jouni Malinen <[email protected]>) |
| - | |
| - | 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 <[email protected]>) |
| - | + 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 <[email protected]>) |
| - | |
| - | 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 <[email protected]>) |
| - | + 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 |
| - | |
| @@ -1,62 +0,0 @@ | |
| - | # |
| - | # For a description of the syntax of this configuration file, |
| - | # see scripts/kbuild/config-language.txt. |
| - | # |
| - | |
| - | menu "udhcp Server/Client" |
| - | |
| - | config CONFIG_UDHCPD |
| - | bool "udhcp Server (udhcpd)" |
| - | default n |
| - | help |
| - | uDHCPd is a DHCP server geared primarily toward embedded systems, |
| - | while striving to be fully functional and RFC compliant. |
| - | |
| - | See http://udhcp.busybox.net for further details. |
| - | |
| - | config CONFIG_UDHCPC |
| - | bool "udhcp Client (udhcpc)" |
| - | default n |
| - | help |
| - | uDHCPc is a DHCP client geared primarily toward embedded systems, |
| - | while striving to be fully functional and RFC compliant. |
| - | |
| - | The udhcp client negotiates a lease with the DHCP server and |
| - | notifies a set of scripts when a lease is obtained or lost. |
| - | |
| - | See http://udhcp.busybox.net for further details. |
| - | |
| - | config CONFIG_DUMPLEASES |
| - | bool "Lease display utility (dumpleases)" |
| - | default n |
| - | depends on CONFIG_UDHCPD |
| - | help |
| - | dumpleases displays the leases written out by the udhcpd server. |
| - | Lease times are stored in the file by time remaining in lease, or |
| - | by the absolute time that it expires in seconds from epoch. |
| - | |
| - | See http://udhcp.busybox.net for further details. |
| - | |
| - | config CONFIG_FEATURE_UDHCP_SYSLOG |
| - | bool " Log udhcp messages to syslog (instead of stdout)" |
| - | default n |
| - | depends on CONFIG_UDHCPD || CONFIG_UDHCPC |
| - | help |
| - | If selected, udhcpd will log all its messages to syslog, otherwise, |
| - | it will attempt to log them to stdout. |
| - | |
| - | See http://udhcp.busybox.net for further details. |
| - | |
| - | config CONFIG_FEATURE_UDHCP_DEBUG |
| - | bool " Compile udhcp with noisy debugging messages" |
| - | default n |
| - | depends on CONFIG_UDHCPD || CONFIG_UDHCPC |
| - | help |
| - | If selected, udhcpd will output extra debugging output. If using |
| - | this option, compile uDHCP with "-g", and do not fork the daemon to |
| - | the background. |
| - | |
| - | See http://udhcp.busybox.net for further details. |
| - | |
| - | endmenu |
| - | |
| @@ -1,5 +0,0 @@ | |
| - | ifneq ($(wildcard ../../networking/Config.in),) |
| - | include Makefile.busybox |
| - | else |
| - | include Makefile.udhcp |
| - | endif |
| @@ -1,36 +0,0 @@ | |
| - | # Makefile for busybox |
| - | # |
| - | # Copyright (C) 1999-2004 by Erik Andersen <[email protected]> |
| - | # |
| - | # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| - | # |
| - | |
| - | ifndef top_srcdir |
| - | top_srcdir=../.. |
| - | endif |
| - | ifndef top_builddir |
| - | top_builddir=../.. |
| - | endif |
| - | srcdir=$(top_srcdir)/networking/udhcp |
| - | UDHCP_DIR:=./ |
| - | include $(top_builddir)/Rules.mak |
| - | include $(top_builddir)/.config |
| - | include Makefile.in |
| - | all: $(libraries-y) |
| - | -include $(top_builddir)/.depend |
| - | |
| - | clean: |
| - | rm -f *.o *.a $(AR_TARGET) |
| - | |
| @@ -1,53 +0,0 @@ | |
| - | # Makefile for busybox |
| - | # |
| - | # Copyright (C) 1999-2004 by Erik Andersen <[email protected]> |
| - | # |
| - | # Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
| - | # |
| - | |
| - | UDHCP_AR:=udhcp.a |
| - | ifndef $(UDHCP_DIR) |
| - | UDHCP_DIR:=$(top_builddir)/networking/udhcp/ |
| - | endif |
| - | srcdir=$(top_srcdir)/networking/udhcp |
| - | |
| - | #ok, so I forgot how to do an or, but this is a quick and dirty hack |
| - | ifeq ($(strip $(CONFIG_UDHCPC)),y) |
| - | CONFIG_UDHCP_SHARED=y |
| - | else |
| - | ifeq ($(strip $(CONFIG_UDHCPD)),y) |
| - | CONFIG_UDHCP_SHARED=y |
| - | else |
| - | CONFIG_UDHCP_SHARED=n |
| - | endif |
| - | endif |
| - | |
| - | UDHCP-y:= |
| - | UDHCP-$(CONFIG_UDHCP_SHARED) += common.c options.c packet.c pidfile.c \ |
| - | signalpipe.c socket.c |
| - | UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c clientsocket.c \ |
| - | script.c |
| - | UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c \ |
| - | serverpacket.c static_leases.c |
| - | UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c |
| - | UDHCP_OBJS:=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y)) |
| - | |
| - | ifneq ($(strip $(UDHCP-y)),) |
| - | libraries-y+=$(UDHCP_DIR)$(UDHCP_AR) |
| - | endif |
| - | |
| - | UDHCP-y:=$(patsubst %,$(srcdir)/%,$(UDHCP-y)) |
| - | UDHCP-a:=$(wildcard $(srcdir)/*.c) |
| - | APPLET_SRC-y+=$(UDHCP-y) |
| - | APPLET_SRC-a+=$(UDHCP-a) |
| - | |
| - | UDHCP_INCLUDES:=$(srcdir) |
| - | |
| - | APPLETS_DEFINE-y+=-DIN_BUSYBOX -I$(UDHCP_INCLUDES) |
| - | APPLETS_DEFINE-a+=-DIN_BUSYBOX -I$(UDHCP_INCLUDES) |
| - | |
| - | $(UDHCP_DIR)$(UDHCP_AR): $(UDHCP_OBJS) |
| - | $(do_ar) |
| - | |
| - | $(UDHCP_OBJS): $(UDHCP_DIR)%.o : $(srcdir)/%.c |
| - | $(compile.c) -DIN_BUSYBOX |
| @@ -1,53 +0,0 @@ | |
| - | 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 \ |
| - | <busybox_source>/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. |
| - | |
| @@ -1,17 +0,0 @@ | |
| - | 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. |
| - | |
| @@ -1,144 +0,0 @@ | |
| - | 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 Set client identifier. Type is first char. |
| - | -C, --clientid-none Suppress default client identifier |
| - | -V, --vendorclass=CLASSID Set vendor class 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: |
| - | /usr/share/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 |
| - | /usr/share/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 |
| - | |
| @@ -1,59 +0,0 @@ | |
| - | 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. |
| @@ -1,16 +0,0 @@ | |
| - | 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 |
| @@ -1,106 +0,0 @@ | |
| - | /* |
| - | * arpping.c |
| - | * |
| - | * Mostly stolen from: dhcpcd - DHCP client daemon |
| - | * by Yoichi Hariguchi <[email protected]> |
| - | */ |
| - | |
| - | #include <sys/time.h> |
| - | #include <time.h> |
| - | #include <sys/socket.h> |
| - | #include <netinet/if_ether.h> |
| - | #include <net/if_arp.h> |
| - | #include <netinet/in.h> |
| - | #include <string.h> |
| - | #include <unistd.h> |
| - | #include <errno.h> |
| - | |
| - | #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)); |
| - | strcpy(addr.sa_data, interface); |
| - | 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; |
| - | } |
| @@ -1,35 +0,0 @@ | |
| - | /* |
| - | * arpping .h |
| - | */ |
| - | |
| - | #ifndef ARPPING_H |
| - | #define ARPPING_H |
| - | |
| - | #include <netinet/if_ether.h> |
| - | #include <net/if_arp.h> |
| - | #include <net/if.h> |
| - | #include <netinet/in.h> |
| - | |
| - | 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 |
| @@ -1,245 +0,0 @@ | |
| - | /* clientpacket.c |
| - | * |
| - | * Packet generation and dispatching functions for the DHCP client. |
| - | * |
| - | * Russ Dill <[email protected]> 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 <string.h> |
| - | #include <sys/socket.h> |
| - | #include <features.h> |
| - | #if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 |
| - | #include <netpacket/packet.h> |
| - | #include <net/ethernet.h> |
| - | #else |
| - | #include <asm/types.h> |
| - | #include <linux/if_packet.h> |
| - | #include <linux/if_ether.h> |
| - | #endif |
| - | #include <stdlib.h> |
| - | #include <time.h> |
| - | #include <unistd.h> |
| - | #include <netinet/in.h> |
| - | #include <arpa/inet.h> |
| - | #include <fcntl.h> |
| - | |
| - | |
| - | #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) |
| - | { |
| - | init_header(packet, type); |
| - | memcpy(packet->chaddr, client_config.arp, 6); |
| - | if (client_config.clientid) |
| - | 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, client_config.vendorclass); |
| - | } |
| - | |
| - | |
| - | /* 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)); |
| - | |
| - | } |
| @@ -1,14 +0,0 @@ | |
| - | #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 |
| @@ -1,62 +0,0 @@ | |
| - | /* |
| - | * clientsocket.c -- DHCP client socket creation |
| - | * |
| - | * udhcp client |
| - | * |
| - | * Russ Dill <[email protected]> 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 <sys/types.h> |
| - | #include <sys/socket.h> |
| - | #include <unistd.h> |
| - | #include <netinet/in.h> |
| - | #include <features.h> |
| - | #if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 |
| - | #include <netpacket/packet.h> |
| - | #include <net/ethernet.h> |
| - | #else |
| - | #include <asm/types.h> |
| - | #include <linux/if_packet.h> |
| - | #include <linux/if_ether.h> |
| - | #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; |
| - | } |
| @@ -1,7 +0,0 @@ | |
| - | /* clientsocket.h */ |
| - | #ifndef _CLIENTSOCKET_H |
| - | #define _CLIENTSOCKET_H |
| - | |
| - | int raw_socket(int ifindex); |
| - | |
| - | #endif |
| @@ -1,162 +0,0 @@ | |
| - | /* common.c |
| - | * |
| - | * Functions for debugging and logging as well as some other |
| - | * simple helper functions. |
| - | * |
| - | * Russ Dill <[email protected]> 2001-2003 |
| - | * Rewritten by Vladimir Oleynik <[email protected]> (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 <fcntl.h> |
| - | #include <unistd.h> |
| - | #include <errno.h> |
| - | #include <string.h> |
| - | #include <stdlib.h> |
| - | #include <signal.h> |
| - | #include <paths.h> |
| - | #include <sys/socket.h> |
| - | #include <stdarg.h> |
| - | |
| - | #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 |
| - | |
| @@ -1,55 +0,0 @@ | |
| - | /* common.h |
| - | * |
| - | * Russ Dill <[email protected]> September 2001 |
| - | * Rewritten by Vladimir Oleynik <[email protected]> (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 <syslog.h> |
| - | #endif |
| - | |
| - | long uptime(void); |
| - | void background(const char *pidfile); |
| - | void start_log_and_pid(const char *client_server, 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 |
| @@ -1,573 +0,0 @@ | |
| - | /* dhcpc.c |
| - | * |
| - | * udhcp DHCP client |
| - | * |
| - | * Russ Dill <[email protected]> July 2001 |
| - | * |
| - | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
| - | */ |
| - | |
| - | #include <sys/time.h> |
| - | #include <sys/file.h> |
| - | #include <unistd.h> |
| - | #include <getopt.h> |
| - | #include <stdlib.h> |
| - | #include <sys/socket.h> |
| - | #include <netinet/in.h> |
| - | #include <arpa/inet.h> |
| - | #include <signal.h> |
| - | #include <time.h> |
| - | #include <string.h> |
| - | #include <sys/ioctl.h> |
| - | #include <net/if.h> |
| - | #include <errno.h> |
| - | |
| - | #include "common.h" |
| - | #include "dhcpd.h" |
| - | #include "dhcpc.h" |
| - | #include "options.h" |
| - | #include "clientpacket.h" |
| - | #include "clientsocket.h" |
| - | #include "script.h" |
| - | #include "socket.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, |
| - | .vendorclass = NULL, |
| - | .hostname = NULL, |
| - | .fqdn = NULL, |
| - | .ifindex = 0, |
| - | .retries = 3, |
| - | .timeout = 3, |
| - | .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 Set client identifier - type is first char\n" |
| - | " -C, --clientid-none Suppress default client identifier\n" |
| - | " -V, --vendorclass=CLASSID Set vendor class 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" |
| - | " -T, --timeout=seconds Try to get the lease for the amount of\n" |
| - | " seconds (default: 3)\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; |
| - | int no_clientid = 0; |
| - | |
| - | static const struct option arg_options[] = { |
| - | {"clientid", required_argument, 0, 'c'}, |
| - | {"clientid-none", no_argument, 0, 'C'}, |
| - | {"vendorclass", required_argument, 0, 'V'}, |
| - | {"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'}, |
| - | {"timeout", required_argument, 0, 'T'}, |
| - | {"version", no_argument, 0, 'v'}, |
| - | {"retries", required_argument, 0, 't'}, |
| - | {0, 0, 0, 0} |
| - | }; |
| - | |
| - | /* get options */ |
| - | while (1) { |
| - | int option_index = 0; |
| - | c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:T:t:v", arg_options, &option_index); |
| - | if (c == -1) break; |
| - | |
| - | switch (c) { |
| - | case 'c': |
| - | if (no_clientid) show_usage(); |
| - | len = strlen(optarg) > 255 ? 255 : strlen(optarg); |
| - | 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((char*)client_config.clientid + OPT_DATA, optarg, len); |
| - | break; |
| - | case 'C': |
| - | if (client_config.clientid) show_usage(); |
| - | no_clientid = 1; |
| - | break; |
| - | case 'V': |
| - | len = strlen(optarg) > 255 ? 255 : strlen(optarg); |
| - | free(client_config.vendorclass); |
| - | client_config.vendorclass = xmalloc(len + 2); |
| - | client_config.vendorclass[OPT_CODE] = DHCP_VENDOR; |
| - | client_config.vendorclass[OPT_LEN] = len; |
| - | strncpy((char*)client_config.vendorclass + 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); |
| - | 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((char*)client_config.hostname + 2, optarg, len); |
| - | break; |
| - | case 'F': |
| - | len = strlen(optarg) > 255 ? 255 : strlen(optarg); |
| - | 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((char*)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 'T': |
| - | client_config.timeout = atoi(optarg); |
| - | break; |
| - | case 't': |
| - | client_config.retries = atoi(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 not set, and not suppressed, setup the default client ID */ |
| - | if (!client_config.clientid && !no_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); |
| - | } |
| - | |
| - | if (!client_config.vendorclass) { |
| - | client_config.vendorclass = xmalloc(sizeof("udhcp "VERSION) + 2); |
| - | client_config.vendorclass[OPT_CODE] = DHCP_VENDOR; |
| - | client_config.vendorclass[OPT_LEN] = sizeof("udhcp "VERSION) - 1; |
| - | client_config.vendorclass[OPT_DATA] = 1; |
| - | memcpy(&client_config.vendorclass[OPT_DATA], |
| - | "udhcp "VERSION, sizeof("udhcp "VERSION) - 1); |
| - | } |
| - | |
| - | |
| - | /* 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 < client_config.retries) { |
| - | if (packet_num == 0) |
| - | xid = random_xid(); |
| - | |
| - | /* send discover packet */ |
| - | send_discover(xid, requested_ip); /* broadcast */ |
| - | |
| - | timeout = now + client_config.timeout; |
| - | 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 < client_config.retries) { |
| - | /* 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; |
| - | } |
| - | |
| - | /* Ignore packets that aren't for us */ |
| - | if (memcmp(packet.chaddr, client_config.arp, 6)) { |
| - | DEBUG(LOG_INFO, "packet does not have our chaddr -- ignoring"); |
| - | 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; |
| - | } |
| @@ -1,39 +0,0 @@ | |
| - | /* dhcpc.h */ |
| - | #ifndef _DHCPC_H |
| - | #define _DHCPC_H |
| - | |
| - | /* grab define 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 *vendorclass; /* Optional vendor class-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 */ |
| - | int retries; /* Max number of request packets */ |
| - | int timeout; /* Number of seconds to try to get a lease */ |
| - | uint8_t arp[6]; /* Our arp address */ |
| - | }; |
| - | |
| - | extern struct client_config_t client_config; |
| - | |
| - | |
| - | #endif |
| @@ -1,273 +0,0 @@ | |
| - | /* dhcpd.c |
| - | * |
| - | * udhcp Server |
| - | * Copyright (C) 1999 Matthew Ramsay <[email protected]> |
| - | * Chris Trew <[email protected]> |
| - | * |
| - | * Rewrite by Russ Dill <[email protected]> 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 <fcntl.h> |
| - | #include <string.h> |
| - | #include <stdlib.h> |
| - | #include <sys/wait.h> |
| - | #include <arpa/inet.h> |
| - | #include <netdb.h> |
| - | #include <netinet/in.h> |
| - | #include <sys/socket.h> |
| - | #include <unistd.h> |
| - | #include <signal.h> |
| - | #include <errno.h> |
| - | #include <sys/ioctl.h> |
| - | #include <time.h> |
| - | #include <sys/time.h> |
| - | |
| - | #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 */ |
| - | 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; |
| - | } |
| - | |
| @@ -1,141 +0,0 @@ | |
| - | /* dhcpd.h */ |
| - | #ifndef _DHCPD_H |
| - | #define _DHCPD_H |
| - | |
| - | #include <netinet/ip.h> |
| - | #include <netinet/udp.h> |
| - | |
| - | #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 |
| @@ -1,114 +0,0 @@ | |
| - | /* vi: set sw=4 ts=4: */ |
| - | /* |
| - | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
| - | */ |
| - | #include <fcntl.h> |
| - | #include <string.h> |
| - | #include <stdlib.h> |
| - | #include <stdio.h> |
| - | #include <sys/wait.h> |
| - | #include <arpa/inet.h> |
| - | #include <netdb.h> |
| - | #include <netinet/in.h> |
| - | #include <stdio.h> |
| - | #include <sys/socket.h> |
| - | #include <unistd.h> |
| - | #include <getopt.h> |
| - | #include <time.h> |
| - | |
| - | #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 <file> -[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; |
| - | } |
| @@ -1,393 +0,0 @@ | |
| - | /* |
| - | * files.c -- DHCP server file manipulation * |
| - | * Rewrite by Russ Dill <[email protected]> July 2001 |
| - | */ |
| - | |
| - | #include <sys/socket.h> |
| - | #include <arpa/inet.h> |
| - | #include <string.h> |
| - | #include <stdlib.h> |
| - | #include <time.h> |
| - | #include <ctype.h> |
| - | #include <netdb.h> |
| - | |
| - | #include <netinet/ether.h> |
| - | #include "static_leases.h" |
| - | |
| - | #include "dhcpd.h" |
| - | #include "options.h" |
| - | #include "files.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; |
| - | |
| - | 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; |
| - | } |
| - | |
| - | |
| - | /* 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 */ |
| - | static 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; |
| - | } |
| - | } |
| - | |
| - | |
| - | /* 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); |
| - | } |
| @@ -1,19 +0,0 @@ | |
| - | /* 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); |
| - | |
| - | struct option_set *find_option(struct option_set *opt_list, char code); |
| - | |
| - | #endif |
| @@ -1,16 +0,0 @@ | |
| - | #include <string.h> |
| - | |
| - | 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; |
| - | } |
| @@ -1,158 +0,0 @@ | |
| - | /* |
| - | * leases.c -- tools to manage DHCP leases |
| - | * Russ Dill <[email protected]> July 2001 |
| - | */ |
| - | |
| - | #include <time.h> |
| - | #include <string.h> |
| - | #include <sys/socket.h> |
| - | #include <netinet/in.h> |
| - | #include <arpa/inet.h> |
| - | |
| - | #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; |
| - | } |
| @@ -1,23 +0,0 @@ | |
| - | /* 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 |
| @@ -1,92 +0,0 @@ | |
| - | /* libbb_udhcp.h - busybox compatability wrapper */ |
| - | |
| - | /* bit of a hack, do this no matter what the order of the includes. |
| - | * (for busybox) */ |
| - | |
| - | #ifndef _LIBBB_UDHCP_H |
| - | #define _LIBBB_UDHCP_H |
| - | |
| - | #ifdef CONFIG_INSTALL_NO_USR |
| - | # define DEFAULT_SCRIPT "/share/udhcpc/default.script" |
| - | #else |
| - | # define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" |
| - | #endif |
| - | |
| - | #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 |
| - | |
| - | /* make safe the exported namespace */ |
| - | /* from common.h */ |
| - | #define background udhcp_background |
| - | #define start_log_and_pid udhcp_start_log_and_pid |
| - | /* from script.h */ |
| - | #define run_script udhcp_run_script |
| - | /* from packet.h */ |
| - | #define init_header udhcp_init_header |
| - | #define get_packet udhcp_get_packet |
| - | #define checksum udhcp_checksum |
| - | #define raw_packet udhcp_raw_packet |
| - | #define kernel_packet udhcp_kernel_packet |
| - | /* from pidfile.h */ |
| - | #define pidfile_acquire udhcp_pidfile_acquire |
| - | #define pidfile_write_release udhcp_pidfile_write_release |
| - | /* from options.h */ |
| - | #define get_option udhcp_get_option |
| - | #define end_option udhcp_end_option |
| - | #define add_option_string udhcp_add_option_string |
| - | #define add_simple_option udhcp_add_simple_option |
| - | #define option_lengths udhcp_option_lengths |
| - | /* from socket.h */ |
| - | #define listen_socket udhcp_listen_socket |
| - | #define read_interface udhcp_read_interface |
| - | /* from dhcpc.h */ |
| - | #define client_config udhcp_client_config |
| - | /* from dhcpd.h */ |
| - | #define server_config udhcp_server_config |
| - | |
| - | #else /* ! IN_BUSYBOX */ |
| - | |
| - | #include <stdlib.h> |
| - | #include <stdio.h> |
| - | #include <sys/sysinfo.h> |
| - | |
| - | #ifndef ATTRIBUTE_NORETURN |
| - | #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) |
| - | #endif /* ATTRIBUTE_NORETURN */ |
| - | |
| - | #ifndef ATTRIBUTE_PACKED |
| - | #define ATTRIBUTE_PACKED __attribute__ ((__packed__)) |
| - | #endif /* ATTRIBUTE_PACKED */ |
| - | |
| - | #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 /* IN_BUSYBOX */ |
| - | |
| - | #endif /* _LIBBB_UDHCP_H */ |
| @@ -1,172 +0,0 @@ | |
| - | /* |
| - | * options.c -- DHCP server option packet tools |
| - | * Rewrite by Russ Dill <[email protected]> July 2001 |
| - | */ |
| - | |
| - | #include <stdlib.h> |
| - | #include <string.h> |
| - | |
| - | #include "common.h" |
| - | #include "dhcpd.h" |
| - | #include "options.h" |
| - | #include "files.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}, |
| - | {"rootpath", OPTION_STRING, 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}, |
| - | {"", 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) |
| - | { |
| - | struct dhcp_option *dh; |
| - | |
| - | for (dh=dhcp_options; dh->code; dh++) { |
| - | if (dh->code == code) { |
| - | uint8_t option[6], len; |
| - | |
| - | option[OPT_CODE] = code; |
| - | len = option_lengths[dh->flags & TYPE_MASK]; |
| - | option[OPT_LEN] = len; |
| - | if (__BYTE_ORDER == __BIG_ENDIAN) |
| - | data <<= 8 * (4 - len); |
| - | /* This memcpy is for broken processors which can't |
| - | * handle a simple unaligned 32-bit assignment */ |
| - | memcpy(&option[OPT_DATA], &data, 4); |
| - | return add_option_string(optionptr, option); |
| - | } |
| - | } |
| - | |
| - | DEBUG(LOG_ERR, "Could not add option 0x%02x", code); |
| - | return 0; |
| - | } |
| @@ -1,38 +0,0 @@ | |
| - | /* 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); |
| - | |
| - | #endif |
| @@ -1,207 +0,0 @@ | |
| - | #include <unistd.h> |
| - | #include <string.h> |
| - | #include <netinet/in.h> |
| - | #include <sys/types.h> |
| - | #include <sys/socket.h> |
| - | #include <features.h> |
| - | #if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 |
| - | #include <netpacket/packet.h> |
| - | #include <net/ethernet.h> |
| - | #else |
| - | #include <asm/types.h> |
| - | #include <linux/if_packet.h> |
| - | #include <linux/if_ether.h> |
| - | #endif |
| - | #include <errno.h> |
| - | |
| - | #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) |
| - | { |
| - | static const char broken_vendors[][8] = { |
| - | "MSFT 98", |
| - | "" |
| - | }; |
| - | int bytes; |
| - | int i; |
| - | 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((char*)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; |
| - | } |
| @@ -1,41 +0,0 @@ | |
| - | #ifndef _PACKET_H |
| - | #define _PACKET_H |
| - | |
| - | #include <netinet/udp.h> |
| - | #include <netinet/ip.h> |
| - | |
| - | 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 |
| @@ -1,75 +0,0 @@ | |
| - | /* pidfile.c |
| - | * |
| - | * Functions to assist in the writing and removing of pidfiles. |
| - | * |
| - | * Russ Dill <[email protected]> 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 <sys/types.h> |
| - | #include <sys/stat.h> |
| - | #include <fcntl.h> |
| - | #include <unistd.h> |
| - | #include <stdio.h> |
| - | #include <stdlib.h> |
| - | |
| - | #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); |
| - | } |
| - | |
| - | |
| - | |
| - | |
| @@ -1,25 +0,0 @@ | |
| - | /* pidfile.h |
| - | * |
| - | * Functions to assist in the writing and removing of pidfiles. |
| - | * |
| - | * Russ Dill <[email protected]> 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); |
| - | |
| @@ -1,234 +0,0 @@ | |
| - | /* script.c |
| - | * |
| - | * Functions to call the DHCP client notification scripts |
| - | * |
| - | * Russ Dill <[email protected]> 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 <string.h> |
| - | #include <unistd.h> |
| - | #include <stdio.h> |
| - | #include <stdlib.h> |
| - | #include <sys/socket.h> |
| - | #include <netinet/in.h> |
| - | #include <arpa/inet.h> |
| - | #include <sys/types.h> |
| - | #include <sys/wait.h> |
| - | |
| - | #include "common.h" |
| - | #include "options.h" |
| - | #include "dhcpd.h" |
| - | #include "dhcpc.h" |
| - | #include "script.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); |
| - | } |
| - | } |
| @@ -1,6 +0,0 @@ | |
| - | #ifndef _SCRIPT_H |
| - | #define _SCRIPT_H |
| - | |
| - | extern void run_script(struct dhcpMessage *packet, const char *name); |
| - | |
| - | #endif |
| @@ -1,275 +0,0 @@ | |
| - | /* serverpacket.c |
| - | * |
| - | * Construct and send DHCP server packets |
| - | * |
| - | * Russ Dill <[email protected]> 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 <sys/socket.h> |
| - | #include <netinet/in.h> |
| - | #include <arpa/inet.h> |
| - | #include <string.h> |
| - | #include <time.h> |
| - | |
| - | #include "common.h" |
| - | #include "serverpacket.h" |
| - | #include "dhcpd.h" |
| - | #include "options.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((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1); |
| - | if (server_config.boot_file) |
| - | strncpy((char*)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); |
| - | } |
| @@ -1,12 +0,0 @@ | |
| - | #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 |
| @@ -1,78 +0,0 @@ | |
| - | /* signalpipe.c |
| - | * |
| - | * Signal pipe infrastructure. A reliable way of delivering signals. |
| - | * |
| - | * Russ Dill <[email protected]> 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 <unistd.h> |
| - | #include <signal.h> |
| - | #include <sys/types.h> |
| - | #include <sys/socket.h> |
| - | #include <sys/select.h> |
| - | |
| - | |
| - | #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; |
| - | } |
| @@ -1,22 +0,0 @@ | |
| - | /* signalpipe.h |
| - | * |
| - | * Russ Dill <[email protected]> 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); |
| @@ -1,135 +0,0 @@ | |
| - | /* |
| - | * socket.c -- DHCP server client/server socket creation |
| - | * |
| - | * udhcp client/server |
| - | * Copyright (C) 1999 Matthew Ramsay <[email protected]> |
| - | * Chris Trew <[email protected]> |
| - | * |
| - | * Rewrite by Russ Dill <[email protected]> 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 <sys/types.h> |
| - | #include <sys/socket.h> |
| - | #include <sys/ioctl.h> |
| - | #include <netinet/in.h> |
| - | #include <unistd.h> |
| - | #include <string.h> |
| - | #include <arpa/inet.h> |
| - | #include <net/if.h> |
| - | #include <errno.h> |
| - | #include <features.h> |
| - | #if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 |
| - | #include <netpacket/packet.h> |
| - | #include <net/ethernet.h> |
| - | #else |
| - | #include <asm/types.h> |
| - | #include <linux/if_packet.h> |
| - | #include <linux/if_ether.h> |
| - | #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; |
| - | strcpy(ifr.ifr_name, interface); |
| - | |
| - | 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; |
| - | } |
| @@ -1,8 +0,0 @@ | |
| - | /* 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 |
| @@ -1,119 +0,0 @@ | |
| - | /* |
| - | * static_leases.c -- Couple of functions to assist with storing and |
| - | * retrieving data for static leases |
| - | * |
| - | * Wade Berrier <[email protected]> September 2004 |
| - | * |
| - | */ |
| - | |
| - | |
| - | #include <stdlib.h> |
| - | #include <stdio.h> |
| - | #include <string.h> |
| - | |
| - | #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 |
| - | |
| - | |
| - | |
| @@ -1,25 +0,0 @@ | |
| - | /* 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 |
| - | |
| - | |
| - | |
| @@ -1,6 +0,0 @@ | |
| - | #ifndef _UDHCP_VERSION_H |
| - | #define _UDHCP_VERSION_H |
| - | |
| - | #define VERSION "0.9.9-pre" |
| - | |
| - | #endif |