2004-11-15 Dan Williams <dcbw@redhat.com>

Major rework of link detection code.  We now use DHCP
	as part of the link detection which proves to be much more robust,
	and also supports Open System authentication for wireless networks.

	We no longer use external DHCP client programs.  Instead, we use
	our own DHCP client, based on substantially reworked bits of 'dhcpcd'
	which was written by:
		Yoichi Hariguchi <yoichi@fore.com>
		Sergei Viznyuk <sv@phystech.com>
		http://www.phystech.com/download/
	It resides in the "dhcpcd" directory and was refactored into a general
	purpose DHCP client library by me.

	Also misc fixes (CPPFLAGS->AM_CPPFLAGS, move some stuff around),
	move src/backends/NetworkManagerSystem.h -> src/NetworkManagerSystem.h


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@314 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2004-11-16 02:41:53 +00:00
parent b36e976315
commit 2ad25b238e
34 changed files with 5355 additions and 173 deletions

View File

@@ -1,3 +1,21 @@
2004-11-15 Dan Williams <dcbw@redhat.com>
Major rework of link detection code. We now use DHCP
as part of the link detection which proves to be much more robust,
and also supports Open System authentication for wireless networks.
We no longer use external DHCP client programs. Instead, we use
our own DHCP client, based on substantially reworked bits of 'dhcpcd'
which was written by:
Yoichi Hariguchi <yoichi@fore.com>
Sergei Viznyuk <sv@phystech.com>
http://www.phystech.com/download/
It resides in the "dhcpcd" directory and was refactored into a general
purpose DHCP client library by me.
Also misc fixes (CPPFLAGS->AM_CPPFLAGS, move some stuff around),
move src/backends/NetworkManagerSystem.h -> src/NetworkManagerSystem.h
2004-11-15 Dan Williams <dcbw@redhat.com> 2004-11-15 Dan Williams <dcbw@redhat.com>
Patch from Tom Parker <palfrey@tevp.net>: Patch from Tom Parker <palfrey@tevp.net>:

View File

@@ -1,4 +1,4 @@
SUBDIRS = src dispatcher-daemon $(notification_icon_dir) info-daemon initscript test po SUBDIRS = src dispatcher-daemon $(notification_icon_dir) info-daemon initscript test dhcpcd po
EXTRA_DIST = CONTRIBUTING NetworkManager.pc.in NetworkManager.h EXTRA_DIST = CONTRIBUTING NetworkManager.pc.in NetworkManager.h

View File

@@ -5,11 +5,34 @@ AM_INIT_AUTOMAKE([subdir-objects])
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
dnl
dnl Require programs
dnl
AC_PROG_CC AC_PROG_CC
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
dnl
dnl Required headers
dnl
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h paths.h sys/ioctl.h sys/time.h syslog.h unistd.h)
dnl
dnl Checks for typedefs, structures, and compiler characteristics.
dnl
AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_HEADER_TIME
dnl
dnl Checks for library functions.
dnl
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_CHECK_FUNCS(select socket uname)
GETTEXT_PACKAGE=NetworkManager GETTEXT_PACKAGE=NetworkManager
AC_SUBST(GETTEXT_PACKAGE) AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package]) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
@@ -170,6 +193,7 @@ dispatcher-daemon/Makefile
info-daemon/Makefile info-daemon/Makefile
panel-applet/Makefile panel-applet/Makefile
panel-applet/icons/Makefile panel-applet/icons/Makefile
dhcpcd/Makefile
test/Makefile test/Makefile
initscript/Makefile initscript/Makefile
initscript/RedHat/Makefile initscript/RedHat/Makefile

2
dhcpcd/AUTHORS Normal file
View File

@@ -0,0 +1,2 @@
Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>

340
dhcpcd/COPYING Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 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
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) <year> <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year 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.

794
dhcpcd/ChangeLog Normal file
View File

@@ -0,0 +1,794 @@
12/31/02 - v.1.3.22-pl4
Peter Poeml <poeml@suse.de> submitted patches to:
1. enable support for Token Ring.
2. disable second DHCP_DISCOVER message. S.V - added "-S" option to dhcpcd command
line to make second DHCP_DISCOVER message optional.
3. Make dhcpcd write to the console if syslogd is not running only with
"-d" DebugFlag.
Robert Whaley <rwhaley@applieddata.net> submitted patch to elimited potential
race condition between setting up the setjmp for dhcpReboot and the sigalarm handler.
Ian Sharpe <ian.sharpe@sharpe-practice.co.uk> submitted patch to handle situations
with DHCP server changing lease or T1,T2 times from renewal to renewal.
Jamey Hicks <jamey.hicks@hp.com> pointed out the setting of the netmask for
static route still doesn't always work correctly. Wrote "getgenmask" function
to try to deduce the netmask for static routes - S.V.
Per-Olof Pettersson <peope@peope.net> suggested "-G" option to prevent
dhcpcd from installing default routes. Expanded "-G" to include optional
[gateway] parameter for ip address of default router - S.V. The "-G" option
has also been added by Peter Poeml <poeml@suse.de> in one of the patches he sent.
S.V.- moved parts of the code from client.c into cache.c and dhcpconfig.c files.
09/30/02 - v.1.3.22-pl3
Duke Cho <duke@embeddedweb.co.kr> submitted patch for dhcpSendAndRecv() to scan
for begining of IP header in the received Ethernet frame rather than assume
it begins right after Ethernet header. It made dhcpcd work for ARM7TDMI cored SoC
boards.
Marc Beuchat <marc@siana.ch> submitted patch to open 0,1,2 file descriptors
at the start of dhcpcd if they are closed as in a case when dhcpcd starts from
pcmcia-cs network script.
09/21/02 - v.1.3.22-pl2
James Hicks <Jamey.Hicks@hp.com> submitted patch to set the netmask properly
for static routes provided by the DHCP server.
Michal Dobes <dobes@tesnet.cz> pointed out there could be situation with
many dhcpcd clients starting at the same time on different machines on the
same network in which case they will generate the DHCP messages with the
same XID and potentially configure the same IP addresses. Fixed by
including CLientHwAddr (MAC address) into the seed for srandom(). -S.V.
David Fallon <davef@d2.com> recomended changing sbindir to = ${exec_prefix}/sbin
rather than ${prefix} in Makefile.am. Also changed docdir=/usr/doc. -S.V.
Henning Spruth <henning.spruth@epost.de> suggested replacing
getuid() call with geteuid() in dhcpcd.c to enable setuid tools
to launch dhcpcd.
David Oleszkiewicz <davole@us.ibm.com> pointed out "logger" should
be used in dhcpcd.exe script instead of direct write to a log files.
Tobias Blomberg <tobias.blomberg@home.se> pointed out to a bug report at
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=65515
what appears to be dhcpcd cache overriding command line options -I and -i.
The related problem has been also reported by <20>yvind Bakksj<73>
<oyvind@bakksjo.no>. Fixed by calling clientIDsetup and classIDsetup
even after successfull cache read.
Kosbar, Kurt Louis <kosbar@umr.edu> submitted patch to fix a case of
dhcpcd client crash because of some DHCP server sending no dhcpMessageType
field in DHCP message.
Simon Kelley <simon@thekelleys.org.uk> pointed out at security bug in dhcpcd
related to *.info file. A malicios administrator of untrusted DHCP server
may execute any command with root privileges on DHCP client machine by
sending the command enclosed in shell metacharacters in one of DHCP server
provided options. Fixed by enclosing all strings in *.info file into single
quotes and replacing any single quotes found in DHCP option strings
with space. - S.V.
01/20/02 - v.1.3.22-pl1
S.V. - added support for virtual interfaces (eth0:1, eth1:2, etc)
inside dhcpcd itself. The "external" support (with external script
using *.info file) has been added in v.1.3.22-pl0.
01/19/02 - v.1.3.22-pl0
Scott Gifford <sgifford@tir.com> and Victor McSmith <vmcs@mail.ru>
suggested letting custom scripts instead of dhcpcd do all the
interface configuration work using DHCP info secured by dhcpcd
and stored in the *.info file.
Pramod Immaneni <pramod@aligo.com> suggested adding -L option to
dhcpcd to enable writing configuration information into a given *.info
file to be later used by other scripts. He also suggested modifying
-T option to save configuration information rather than just exiting after
DHCP negotiation sequence.
S.V. - the above proposals inspired the following changes to dhcpcd:
1. "-L <ConfigDir>" option has been added. Dhcpcd will store *.info,
*.cache files under <ConfigDir> rather than default /etc/dhcpc.
2. *.pid file has moved from under /var/run to under <ConfigDir>
(default /etc/dhcpc) subdirectory.
3. -T option behaviour has been modified to include writing
*.info, *.cache, *.pid files under <ConfigDir>, and executing
*.exe script in the same manner as without -T option.
Now with -T option dhcpcd will do everything except actually
configuring interface or changing any files under /etc.
Also now with -T option dhcpcd will not exit at the end of DHCP
negotiation sequence but will go into background and attempt
to renew the lease as usual.
-T option in conjunction with -L <ConfigDir> and -I <ClientID> will
enable users to negotiate/renew multiple IP addresses using the same
dummy interface.
It should also enable configuration of virtual interfaces.
4. <ConfigDir>/dhcpcd.exe script calling convention has changed. Now
dhcpcd will pass the path to *.info file as first argument and "up/down/new"
keyword as second argument. The third argument is optional
debugFlag "-d" passed from dhcpcd command line. See sample dhcpcd.exe
script supplied with distribution.
5. "-c <ExecFile>" option has been given second life and its behaviour
has slightly changed. Now <ExecFile> script will be executed instead of
default <ConfigDir>/dhcpcd.exe and in the same manner as
<ConfigDir>/dhcpcd.exe script (see Item 4 above).
6. The following lines has been added to *.info file written by
dhcpcd:
INTERFACE=<interface> (e.g. INTERFACE=eth1)
CLASSID=<class_id_string> (e.g. CLASSID="Linux 2.4.14 i686")
CLIENTID=<client_id_string> (e.g. CLIENT_ID=10:32:C3:37:25:14 or
CLIENT_ID="test1")
7. dhcpcd now will rename previous *.info file to *.info.old
Other changes:
Tim Wright <timw@polyserve.com> submitted patch to prevent dhcpcd
from altering network interface flags that it should not change.
Pavel Roskin <proski@gnu.org> submitted patch to dhcpcd.spec file
to fix the installation directories.
Tim Goodwin <tjg@star.le.ac.uk> suggested using full-qualified
host names rather than truncating them at first ".".
12/31/01 - v.1.3.21-pl2
D. Hugh Redelmeier <hugh@mimosa.com> pointed out a problem with
binding udpFooSocket in client.c to address 0.0.0.0 port 68 and
exiting with error status if binding fails as in a case of more
than one dhcpcd process. This effectively prevented dhcpcd from
running on more than one interface. Fixed for now by disabling
error exit in a case udpFooSocket binding fails. Perhaps a better
solution is needed.
Thomas Aeby <tomae@sfi.ch> pointed out nisDomainName should not
be used in /etc/resolv.conf file. Fixed.
Roger Maclean <rmaclean@marchnetworks.com> suggested to increase
"time since bootup" parameter in DHCP message to 10, otherwise
dhcpcd may not get an IP address from WinNT DHCP server.
Jani Averbach <jaa@cc.jyu.fi> suggested changes to Makefile.am to
make ./configure accept installation options.
Yaacov Akiba Slama <slamaya@yahoo.com> submitted a patch to make use
dhcp-spoof feature of adsl modems/routers. The patch sets netmask to
255.255.255.255 in a case the dhcpConfig routine fails to set it to
the netmask supplied by DHCP server.
10/13/01 - v.1.3.21-pl1
Pavel Roskin <proski@gnu.org> submitted patch for dhcpcd.spec.in
file to fix "rpm -ta dhcpcd-1.3.21-pl1.tar.gz" RPM package creation.
10/09/01 - v.1.3.21-pl0
Toralf Lund <toralf@kscanners.com> submitted patch to add
support for NIS and NTP server options in DHCP. -Y and -N
flags have been added to dhcpcd command line. Dhcpcd now creates
/etc/yp.conf and /etc/ntp.conf files unless -Y or -N
options are specified (see dhcpcd manual page). Among other things
in the patch: dhcpcd saves the hostname and domainname of the host
and restores it upon exit; dhcpcd now retries HWADDR_TRIES times
to retrieve NIC MAC address in dhcpStart().
Jarno Huuskonen <Jarno.Huuskonen@uku.fi> pointed out
dhcpcd sets mode of the pid file corresponding to the umask of
the calling process which may be a security risk if calling
process has umask 000 which happens when dhcpcd runs from APM
suspend/resume. Fixed by setting umask of dhcpcd process to 022 at
the very beginning in dhcpcd.c.
Olivier Baudron <Olivier.Baudron@ens.fr> suggested using just one
dhcpcd.exe script, which is to run every time interface is
configured or brought down. The interface name will be passed as
first parameter and configuration state as second parameter to the
script. So /etc/dhcpc/dhcpcd.exe script is invoked as
/etc/dhcpc/dhcpcd.exe <interface> <up|down|new> [ip_address] [-d]
Second parameter has value "up" when interface is brought up with
the same IP address as before, "new" when interface is brought up
with new IP address, and "down" when interface is brought down when
dhcpcd exits. This usage to the executable script was suggested by
Scott Gifford <sgifford@tir.com>.
**** This version requires rewrite of dhcpcd*.exe script(s) as it is
incompatible with previous versions of dhcpcd.
10/08/01 - v.1.3.20-pl2
Fabrizio Gennari <fabrizio.gennari@philips.com> reported
dhcpcd could not add a static route supplied by his DHCP server. He suggested
changing a line in client.c
rtent.rt_flags = RTF_UP|RTF_HOST;
to
rtent.rt_flags = RTF_UP|RTF_HOST|RTF_GATEWAY;
which fixed the problem for him. I will give it a shot .. with RoadRunner
no matter how much you screw dhcpcd, it always works ..
Simon Oliver <simon.oliver@umist.ac.uk> reported an interesting case
if DHCP server supplying dhcpAddrLeaseTime>0 and dhcpT1value=0 and
dhcpT2value=0 which made dhcpcd go mad about lease renewal. Fixed by
checking for dhcpT1value=0 and dhcpT2value=0 in client.c
10/01/01 - v.1.3.20-pl1
Matteo Frigo <athena@fftw.org> pointed out a bug in client.c:
in a case of class A network and DHCP server not supplying subnet mask
dhcpcd did not zero out second octet in subnet mask.
Elliot Lee <sopwith@redhat.com> submitted patches:
1. dhcpcd to accept IEEE 802 TokenRing interface (not sure if this one
will actually make dhcpcd work with TokenRing, since
dhcpcd builds messages on top of Ethernet frames)
2. make some globally defined variables to be local
3. use nis domain name along with dns domain name in search string of
/etc/resolv.conf file.
4. run a script when interface gets configured in addition to
/etc/dhcpc/dhcpcd-eth0.exe script which runs only when IP address
changes. S.V. - made the script name /etc/dhcpc/dhcpcd_up-eth0.exe
S.V - make dhcpcd run a script when interface goes down, the script is
/etc/dhcpc/dhcpcd_down-eth0.exe. This was also suggested by
Jason Bodnar <jbodnar@buzzard.kdi.com>
Craig Lawson <craig.lawson@symphony-systems.com> pointed out to a bug
in dhcpcd when it runs on multiple interfaces. When dhcpcd exits
it tries to restore resolv.conf.sv back to resolv.conf even if
dhcpcd did not rename it at first. Fixed.
Olivier Baudron <Olivier.Baudron@ens.fr> submitted patch to bind a
datagram socket to udp port 68 to prevent icmp error message from
the kernel. This problem has also been report by Robert Paluszak
<paluszak@nycap.rr.com>.
S.V.- cleaned up "configure" scripts to make sure ./configure will
create the Makefile with correct installation paths.
04/06/01 - v.1.3.20-pl0
S.V - removed 0x0 from ClientID and ClassID options
04/03/01 - v.1.3.19-pl9
Young, Jeremy <jeremy.young@cccnetsys.com> pointed out
to a bug introduced in v.1.3.19-pl6 which resulted in
7-byte long MAC address with 0x0 at the end. Fixed.
03/10/01 - v.1.3.19-pl8
Rune Torgersen <rune36@home.com> pointed out
at a bug introduced in v.1.3.19-pl7 with "rootPath"
option. The dhcpParamRequest had to be changed to 14.
The bug probably disabled "-h hostname" option to dhcpcd
in v.1.3.19-pl7.
02/22/01 - v.1.3.19-pl7
Chris Petro <petro@auctionwatch.com>
submitted patch to disable processing of
"routersOnSubnet" DHCP option if it is not
provided by DHCP server, as "routersOnSubnet" is
indeed optional.
Jason A. Pattie <pattieja@pcxperience.com>
submitted patch to include "rootPath" DHCP option.
Peter Poeml <poeml@suse.de> submitted patch
to work around a problem with dhcpcd setting
hostname when it is not provided by DHCP server if
there is no initial /etc/resolv.conf file to
be able to resolv hostname from obtained IP address.
01/14/01 - v.1.3.19-pl6
Simon Byrnand <sbyrnand@xtra.co.nz> reported the compilation
on older kernels broke again somewhere in pl3-pl5.
Pavel Roskin <proski@gnu.org> submitted patch to fix the
problem with compilation on older kernels.
S.V - added 0x0 to the end of ClientID and ClassID
options in the DHCP message.
12/21/00 - v.1.3.19-pl5
Pavel Roskin <proski@gnu.org> submitted patch:
README:
- Mention that MediaOne is now AT&T Broadband. dhcpcd works with it.
Makefile.am:
- Copy the binary dhcpcd to the distribution. Added a comment about
the dist-hook target.
configure.in:
- Remove AC_CANONICAL_TARGET - dhcpcd is not a compiler.
- Don't check Linux version - it can be determined at the compile time.
- Don't call uname directly - rely on the results of
AC_CANONICAL_HOST instead.
- Don't ever ignore predefined CFLAGS.
client.c:
- Include <linux/version.h>
- Define OLD_LINUX_VERSION for kernels older than 2.1.1.
The patch is also available here:
http://www.red-bean.com/~proski/dhcpcd/dhcpcd-pl4.diff
12/19/00 - v.1.3.19-pl4
Pavel Roskin <proski@gnu.org>
submitted patch to work around broken version of automake
which was used in generating v.1.3.19-pl3. Also
dhcpcd-1.3.19-pl4.tar.gz has been generated using
"make distcheck"
12/15/00 - v.1.3.19-pl3
Nico Baggus <nico_baggus@compuserve.com>
- added version checking to the cache file
- added support for specifying window size for the
gateway routes (default = 32768) (gives better throughput
when used for Cablenetworks...;-)
- modified defining the offsets in the ipudphdr & ipicmphdr
to get the stuff through gcc 2.96
Pavel Roskin <proski@gnu.org>
Makefile.am:
- Manuals and examples added to EXTRA_DIST
- dhcpcd.spec added to the distribution.
- dhcpcd.spec is now rebuilt by "make all".
- "make rpm" depends on "make distcheck" and uses the dhcpcd.conf
embedded into the tarball.
config.guess:
- Updated to the latest version. PA-Linux team will appreciate it.
config.sub:
- Likewise.
configure.in:
- Versioning simplified to ensure the right tarball name.
Removed dash from the patchlevel to accomodate rpm.
- Avoid square brackets or quote them properly.
dhcpcd.spec.in:
- Substitute "Source".
- "BuildRoot" should be under /var/tmp, not /usr/tmp.
- Don't use filelists - it breaks with rpm-3.0.5 that compresses
manuals.
- Include directory /etc/dhcpc.
- Exclude dhcpcd.spec.in from docs.
- Include any *.lsm file.
missing:
- Updated to avoid problems with future versions of automake.
10/11/00 - v.1.3.19-pl2
Nils Ohlmeier <nils.ohlmeier@innominate.de> and
Warren Jones <wjones@tc.fluke.com> rightfully pointed out
nisDomainName should not be used in resolv.conf file.
Fixed.
08/05/00 - v.1.3.19-pl1
Simon Byrnand <sbyrnand@xtra.co.nz> submitted patches to make
ioctl(dhcpSocket,SIOCSIFADDR,&ifr) call in dhcpStop() routine
applicable only to kernels versions > 2.0 and
to fix handling of SIGCHLD signal.
08/05/00 - v.1.3.19-pl0
Lenz Grimmer <grimmer@suse.de> submitted patch to prevent
"unaligned memory access" warnings to appear on IA64-based systems.
08/05/00 - v.1.3.18-pl9
uncommented ioctl(dhcpSocket,SIOCSIFADDR,&ifr) call in dhcpStop()
routine to prevent interface from having invalid IP address
during DHCP negotiation.
Simon Byrnand <sbyrnand@xtra.co.nz> submitted patch to take
care of the following:
o Make dhcpcd both libc5 and glibc compatible
o Rebind dhcpSocket after change in IP address to avoid
problem with 2.0 kernel losing socket binding to the interface
after resetting of the interface
o Problem with lost DhcpRelease message under 2.0 kernel
when interface gets shut down
Brian K. White <linut@squonk.net> submitted "Note 4." to the
README file.
05/10/00 - v.1.3.18-pl8
Konstantin Boldyshev <konst@linuxassembly.org> submitted patch
to make dhcpcd work with 2.0 kernels. Modified configure script
to pass -DOLD_LINUX_VERSION flag to compiler if the kernel version
is 2.0.xx, in which case socket(AF_INET,SOCK_PACKET,..) call is used
instead of socket(AF_PACKET,SOCK_PACKET,..) and the local route
is added. Local route is added automatically under more recent kernels.
Rolf Jentsch <RJentsch@electronicpartner.de> submitted patch to
add -T flag to the dhcpcd command line. With -T flag dhcpcd will
go through normal DHCP negotiation sequence but will not configure
the interface or otherwise change anything on the system. Useful for
testing DHCP servers.
05/06/00 - v.1.3.18-pl7
Simon Baatz <baatz@informatik.uni-bonn.de> submited patch to fix
possible problem in retransmitting DHCP requests, and make dhcpcd
adapt to possible change in DHCP server address in the middle of a
client's lease.
Habibie <habibie@MailandNews.com> submitted patch to include
GNU automake, autoconf, and RPM packaging features into dhcpcd
distribution. Now dhcpcd build follows usual GNU scheme:
./configure
make
In any case, the old Makefile is also included. ./configure overwrites
it with generated version.
Added "-n" flag to dhcpcd command line. Now "dhcpcd -n" will force
currently running dhcpcd to try to renew the lease. This behavior
is similar to "pump -R".
04/15/00 - v.1.3.18-pl6
Jarno Huuskonen <jhuuskon@messi.uku.fi> submited patch to set
dhcpcd's process umask to 022 before creating /etc/resolv.conf file.
Scott Bronson <bronson@trestle.com> sent some feedback on how RH "pump"
behaves vs. dhcpcd. Now dhcpcd will also send second DHCP_DISCOVER
message.
Performing checksum on received packets is now optional and can be
switched on with -C option on dhcpcd command line.
03/27/00 - v.1.3.18-pl5
Lenz Grimmer <grimmer@suse.de> sent a patch to make dhcpcd do
reverse hostname lookup in a case DHCP server did not provide
hostName option with -H flag or in a case DHCP server did not provide
domainName option with -D flag to dhcpcd.
A bit enhanced version of the patch moved into "production".
03/27/00 - v.1.3.18-pl4
Removed "-m586" from Makefile.
The static executable contained with the distribution has been compiled
against glibc-2.1.3 and 2.3.99-pre3 kernel.
10/27/99 - v.1.3.18-pl3
Mike Hartman <wild@klondike.com> pointed out to include
NULL byte at the end of the HostName string.
10/26/99 - v.1.3.18-pl2
Mike Hartman <wild@klondike.com> submited a patch to fix
a bug in handling "-h" flag. Hostname option flag has been broken
since v.1.3.18-pl0.
09/17/99 - v.1.3.18-pl1
Put back "1.3.17-pl10" patch with some tweaking to get rid
of error in recvfrom call. Some minor cleanup.
09/01/99 - v.1.3.18-pl0
Reversed 1.3.17-pl10 patch. Binding dhcpSocket to the
interface produced error in recvfrom() call.
Chris G. Demetriou <cgd@netbsd.org> sent a patch
to make dhcpcd code portable to ARM platform.
Added "-s [ipaddr]" command-line option which makes dhcpcd
send DHCP_INFORM message. Added "-B" command-line option
to make dhcpcd solicit broadcast response. Added LOG_CONS option to
openlog(3). Changed "domain xxx" entry in resolv.conf to point
by default to nisDomainName, added "search nisDomainName" and
"search domainName" entries to resolv.conf file.
dhcpcd-<interface>.info file has minor changes to the format.
Namely, DNS and GATEWAY entries now will provide a comma-separated
list of corresponding IP addresses, not just the first IP address in
the list. Added support for static route option.
07/23/99 - v.1.3.17-pl10.
Johan Verrept <Johan.Verrept@alcatel.be> suggested "bind"-ing
dhcpSocket to the interface so the socket does not
receive packets from other interfaces. Change made to dhcpStart
routine to include a call to the bind().
07/09/99 - v.1.3.17-pl9.
PETAZZONI <jpetazzo@ryu.univ-mlv.fr> reported a case of
DHCP server responding with IpAddrLeaseTime=0 which
drove dhcpcd-1.3 mad. Added check for IpAddrLeaseTime=0 so
when dhcpcd receives IpAddrLeasetime=0 it will assume
DEFAULT_LEASETIME, infinite by default.
Added '-V' flag to dhcpcd syntax. Dhcpcd will print
copyright/version banner when used with '-V' flag.
06/19/99 - v.1.3.17-pl8.
Olivier Baudron <Olivier.Baudron@ens.fr> pointed out
to a problem with in_cksum routine when compiling with
egcs or gcc-2.8.xx compilers and proposed a patch to
work around the compiler bug.
Changed in_cksum routine in udpipgen.c file to
get rid of problems with wrong checksums if compiled
with egcs or gcc-2.8.xx compilers.
06/10/99 - v.1.3.17-pl7.
Hans Andersson <Hans.XH.Andersson@trab.se> and some
other gentlemen pointed out at 64-bit uncleanless of
current dhcpcd code, and sent relevant patches.
This release is an attempt to make dhcpcd-1.3
64-bit safe. No new functionality has been added.
This is left for v.1.3.18.
05/10/99 - v.1.3.17-pl6.
Andrew S. Howell <andy@tibco.com> submitted a patch
eliminating unnecessary padOptions in buildmsg.c file.
It helped with his cable modem. Removed
"Your IP address=xxx.xxx.xxx.xxx" message on a screen
when dhcpcd configures the interface.
03/14/99 - v.1.3.17-pl5.
Mike Benoit <ipso@academyoflearning.ca> submitted
debugging info. Change made to "client.c" to allow
dhcpcd to get router IP address from DHCP_ACK message
if it didn't come with DHCP_OFFER.
03/10/99 - v.1.3.17-pl4.
Tim Auckland <tim.auckland@Corp.Sun.COM> submitted
patch to dhcpcd-1.3.17-pl3 to close all standard
file descriptors when dhcpcd forks into background.
It should help with pcmcia cards which use popen() call.
02/04/99 - v.1.3.17-pl3.
Sergei Viznyuk <sv@phystech.com>
Now if dhcpcd does not get DHCP_ACK for the same
IP address as before reboot, it will fall back
to dhcpInit and will send DHCP_DISCOVER message(s).
Dhcpcd will now write pid file before forking
into background not after. Updated manual page.
01/15/99 - v.1.3.17-pl2.
Sergei Viznyuk <sv@phystech.com>
Changed the dhcpcd exec-bin directory from /usr/sbin to /sbin.
Pavel Polischouk <pavelp@iil.intel.com> sent a tcpdump
which inspired me to make some changes to the code
to avoid potential race condition when there are multiple
DHCP servers on the network.
01/12/99 - v.1.3.17-pl1.
Marc ZYNGIER <Marc.Zyngier@wanadoo.fr> submitted another
patch to dhcpcd-1.3 to make it work on Linux Alpha
platforms.
01/10/99 - v.1.3.17
Sergei Viznyuk <sv@phystech.com>
Came across patch for dhcpcd-1.3.16
submitted to linux.debian.alpha
by Marc Zyngier Marc.Zyngier@bull.net.
Changed the default lease time requested
to infinite.
Removed "mlip" client 'cause of www.ml.org death.
Did some other minor changes to the code.
11/09/98 - v.1.3.16
Sergei Viznyuk <sv@phystech.com>
Thanks to a great help from Brion Vibber <brion@pobox.com>
another nasty bug has been found and hopefully
squashed. Also the problem with setting default
route on some of the systems has been finally
solved. Kernel refuses to accept a route for a gateway
if its IP address does not seem to be on the same
subnet as in a case with bridged subnets.
The work around suggested by Brion Vibber is
to add a local route to the gateway. I hope we've got
it right in v.1.3.16.
11/07/98 - v.1.3.15
Sergei Viznyuk <sv@phystech.com>
Fixed rather nasty bug in dhcpSendAndRecv routine
introduced in v.1.3.13 which might have prevented
quite of few users from receiving DHCP_OFFER message.
Added command-line options -D,-H,-R to dhcpcd.
Request and patch submitted by Aron Griffis <agriffis@css.tayloru.edu>
10/28/98 - v.1.3.14
Sergei Viznyuk <sv@phystech.com>
Removed setting a local route in addition to default one
in v.1.3.13. This did not help with the problem
one user experiences with setting a default route but
rather resulted in duplicate entries for the local
route in the routing table.
10/27/98 - v.1.3.13
Sergei Viznyuk <sv@phystech.com>
Fixed a minor bug in dhcpSendAndRecv routine
which caused quite a few bogus "DHCP server declined request: op=XX"
messages in /var/log/debug file.
Add (or rather put back) setting of local route.
Normally the local route is set automatically by
the kernel when default route entry is added, however
as it seems that doesn't always work for everybody.
10/25/98 - v.1.3.12
Sergei Viznyuk <sv@phystech.com>
Made a good faith attempt to squash a bug in UDP/IP
layer of dhcpcd which might have been a cause of
problems on PPC-based systems. Originally reported
by Martin Costabel <martin@wanadoo.fr>.
Rewrote quite a bit of UDP/IP code so if dhcpcd-1.3.12
doesn't work for you at all you may try v.1.3.11.
There seemed to be a problem with setting default
route on 2.1.125 kernel reported by Brion Vibber
<brion@pobox.com>. Changed "dhcpConfig" to not force
dhcpcd to die if it cannot set default route. At least
it would be easier to find the cause of problem...
Also did some changes to "client.c" code to move it
closer to the point when one can add support for Token Ring
and/or other link protocols.
10/15/98 - v.1.3.11
Sergei Viznyuk <sv@phystech.com>
Put back '-c filename' option for dhcpcd due to
a requests from some users of Mediaone cable modems
who were trying to use 'ipup' et similar bootup scripts.
Originally requested by Robert Shapiro <rshapiro@mediaone.com>
Some minor fixes.
10/13/98 - v.1.3.10
Sergei Viznyuk <sv@phystech.com>
Added a new feature: whenever the assigned IP address for the
interface changes dhcpcd will execute /etc/dhcpc/dhcpcd-interface.exe
program. The word <interface> is substituted by
the actual interface name like e.g. eth0.
Caution: do not use /etc/dhcpc/dhcpcd-interface.exe as a bootup
script. It will not be executed if the assigned IP address
is the same as it was before reboot.
The included sample /etc/dhcpc/dhcpcd-interface.exe will log
the time of IP change to /var/log/messages file.
The included mlip program changes the IP address
for your host at DNS servers provided by www.ml.org
in a case you happen to be a member of Monolith's DynDNS.
Edit mlip.h file to supply your hostname, username, and password at
Monolith. Do "make mlip" to compile it. Then copy the executable
to /etc/dhcpc/dhcpcd-interface.exe.
Added a compile time options '-DSETHOSTNAME' and '-DSETDOMAINNAME'
to Makefile. If used, dhcpcd will set hostname and/or domainname
of the host to the values it receives from DHCP server.
Rehashed the Changes file to reverse the time order of entries.
10/02/98 - v.1.3.9
Sergei Viznyuk <sv@phystech.com>
Reduced the timeouts for sending and receiving DHCP messages.
Commented out arpCheck() call. It didn't work anyway
because there won't be ARP_REPLY message unless the
sender's IP address is set which defeats the purpose
of doing ARP check. This is something for the authors
of RFC 2131 to fix.
09/04/98 - v.1.3.8
Sergei Viznyuk <sv@phystech.com>
Some user reported he couldn't get dhcpcd to configure
interface because it failed to set broadcast address.
Changed the order dhcpcd configures the interface so it does
1. sets IP address
2. sets netmask
3. sets broadcast address (redundant?)
Reduced the timeout for ARP check from 10secs to 3 secs, so
dhcpcd finishes faster.
08/01/98 -
Sergei Viznyuk <sv@phystech.com>
Changed the "time since bootup" parameter in DHCP_DISCOVER
message from zero to 5 secs to accomodate for WinNT DHCP server
wishes. General cleanup.
01/31/98 -
Sergei Viznyuk <sv@phystech.com> :
Changed dhcpcd to use socket(AF_PACKET,SOCK_PACKET,..)
instead of socket(AF_INET,SOCK_DGRAM,..) which did not
work with newer kernels.
Dropped 'dhcpcd -c filename' usage in favor of dhcpcd
returning valid exit status to the parent.
Added '-t timeout' option which specifies for how
long 'dhcpcd' will try to get an IP address before
forking into background.
Changed 'dhcpcd -d' option to be a debug flag.
======== before v.1.3 ============
08/28/97 1. added '-I' (client identifier) option.
0.70 2. added '-h' (hostname) option (Note 10).
04/24/97 changed the source UDP port from a random number to 68
0.65 because some servers respond to NOT port 68 but the source
UDP port in the received datagram (Note 9).
03/16/97 1. fixed the bug that DHCPDECLINE message was RFC1541
0.6 compliant. Now dhcpcd can send both Interned Draft
compliant DHCPDECLINE message and RFC1541 compliant
one (mkDhcpDeclineMsg).
2. fixed the bug that the broadcast address and the
subnetmask were set to the wrong value under the
following condition:
1. dhcpcd is in the REBOOTING state
2. received DHCP ACK msg does not include the
broadcast or subnetmask option.
(rebooting in client.c)
3. fixed the bug that dhcpcd does not send a DHCPDECLINE
msg when it detects the duplicate IP adddress
(arpCheck in arp.c)..
4. changed the way to make a DHCPREQUEST msg in the
SELECTING state (selecting, mkDhcpRequestMsg)
5. changed the pcmcia/network script to unmount the NFS
filesystems before invoking "dhcpcd -k" command when
the card service goes down.
6. added a new environment variable DHCP_DEVICE, which
contains the name of network interface to which
dhcpcd is attached.
03/07/97 1. fixed the bug that the renewal time and the rebind time
are messed up (becomes minus number :p) when dhcpcd gets
the lease time whose least significant byte is greater
than or equal to 0x80 (setDhcpInfo in client.c) (Note 7).
For example, if the lease time is 24 hours, dhcpcd does
not work.
2. added the hostname option to the parameter request list
(mkDhcpDiscoverMsg and mkDhcpRequestMsg in client.c)
3. fixed the bug that dhcpcd sends a DHCPREQUEST message
which does not have the server identifier option in the
SELECTING state (mkDhcpRequestMsg in client.c)
4. fixed the bug that dhcpcd uses the information from the
DHCPOFFER message for configuring the host (it must use
the information from the DHCPREQUEST message) (initHost
in client.c) (Note 8).
01/30/97 made version 0.5a2 into 0.5, and released it.
0.5
01/20/97 changed init, renewing, rebinding (client.c), and
0.5a2 rcvAndCheckDhcpMsg (socket-if.c) to fix the bug that dhcpcd
exited with holding the assigned IP address when it failed in
invoking sendto system call in the RENEWING state. This happened
when the server is down in the RENEWING state. It causes
hosts to use expired IP addresses (how dangerous!). Now
dhcpcd does not exit even when it gets an error from sendto
in the RENEWING state. It continues to use the assigned IP
address until the lease time is expired, then it
initializes the network interface and goes into the INIT
state (Note 6).
01/13/97 1. added IFF_MULTICAST in initHost (client.c) (Note 1).
0.5a 2. fixed the bug that dhcpcd core-dumped when it received a
datagram containig the DHCP message option (parseDhcpMsg
in options.c) (Note 2).
3. added -r option which makes dhcpcd RFC1541 compliant
(Note 3).
4. changed mkDhcpRequestMsg (client.c) to put the
parameter request list option into the DHCPREQUEST
message in order to support the CMU version of DHCP
server (Note 4). But I do not check whether it works
with the CMU version of DHCP server.
5. changed the argument to logOpen from LOG_CONS to LOG_PID
(Note 5).
6. add nextState initialization in rebinding (client.c).
7. changed the host information file name from "hostinfo"
to "hostinfo-ifname" (saveHostInfo in hostinfo.c)
(Note 5). Ifname is actually replaced with the network
interface name like "eth0". This is good when multiple
dhcpcd's attach to different network interfaces.
09/22/96 made dhcpcd compliant to the Internet Draft in order to
0.4 work with ISC version of DHCP server.
Changed client.c, options.c, socket-if.c
09/19/96 quick fix to make it work with ISC's dhcpd. I made BROACAST
0.33 flag available and added the NEED_BCAST_RESPONSE macro.
ISC's DHCP server is the Internet Draft compliant, but
dhcpcd is RFC1541 compliant. So this is a "workaround" version.
09/17/96 added the code checking option field to parseDhcpMsg (options.c)
0.32
09/16/96 fixed a typo in selecting (client.c)
0.31
09/13/96 1. enhanced NTP support. Now dhcpcd creates the file, ntp.conf
0.3 in the directory, /etc/dhcpc.
2. added the code verifying if router addresses are correct
09/12/96 added the following sample shell scripts:
0.3b 1. "network" for pcmcia-cs
2. "rc" scripts (rc.inet1, rc.inet2, rc.M)
3. "rc.dhcp", a command file which can be executed from dhcpcd
09/11/96 1. fixed a bug in setDefRoute (if.c). rt_flags was RT_UP.
0.3a It should be RT_GATEWAY.
2. fixed typos in openRecvSocket (socket-if.c)
3. changed the way to invoke a command file from using
signal to forking twice
4. removed unnecessary socket close/re-open
09/09/96 added support to the "router" option.
0.25a changed files: options.c, dhcp-options.h, dhcp.h, hostinfo.c,
if.c, client.c
08/09/96 added the code to make a copy of the DHCP options in the
0.2 DHCPOFFER message because Windows NT server does not put
DHCP options in the DHCPACK message except for netmask, T1
time, and T2time. Other DHCP options are only in the
DHCPOFFER message.
07/27/96 added '-i' option specifying the class identifier because
0.2a RFC1541 says "The client implementation of DHCP should
provide a mechanism for the user to select directly the
'class-identifier' value.".
07/23/96 1. moved ARP check from just after dhcpcd received a
0.2a DHCPOFFER message to just after dhcpcd received a
DHCPACK message.
2. added 'Parameter Request List' in the DHCPDISCOVER message.
3. added code to output the content of DHCP message option from
the server
Note 1: Koji Okamura suggested this.
Note 2: This fix was made by Dan Halbert.
Note 3: Dan Halbert found that dhcpcd-0.4 does not work with some
RFC1541 compliant DHCP servers, and made a patch for it.
Brandon Mitchell suggested -r option.
Note 4: N. Komazaki found that CMU's DHCP server (dhcpd-3.3.7
+patch) requires the parameter request option in the
DHCPREQUEST message.
Note 5: Ulrich Windl suggested this.
Note 6: Koji Okamura found this bug.
Note 7: Andrew Kieschnick found this bug.
Note 8: Tim Riker found this bug.
Note 9: I found this problem by using the tcpdump log which
Larry Hawkins sent me.
Note 10: I found some DHCP servers require this option by using the
tcpdump log which David Filiatrault sent me.

24
dhcpcd/Makefile.am Normal file
View File

@@ -0,0 +1,24 @@
INCLUDES = -I${top_srcdir} -I${top_srcdir}/src
AM_CPPFLAGS = \
$(NM_CFLAGS) \
-DBINDIR=\"$(bindir)\" \
-DDATADIR=\"$(datadir)\"
noinst_LIBRARIES = libdhcpc.a
libdhcpc_a_SOURCES= \
udpipgen.c \
udpipgen.h \
buildmsg.c \
buildmsg.h \
arp.c \
arp.h \
client.c \
client.h \
dhcpcd.c \
dhcpcd.h
bin_PROGRAMS = dhcp_test
dhcp_test_SOURCES = dhcp_test.c
dhcp_test_LDADD = libdhcpc.a

3
dhcpcd/NEWS Normal file
View File

@@ -0,0 +1,3 @@
Please refer to
http://www.phystech.com/download/

276
dhcpcd/README Normal file
View File

@@ -0,0 +1,276 @@
0. Introduction
This is an RFC2131,RFC2132, and RFC1541 compliant DHCP client daemon.
RFC1541 was obsoleted by RFC2131, but there are still some RFC1541 compliant
DHCP servers. dhcpcd gets an IP address and other information from a
corresponding DHCP server, configures the network interface
automatically, and tries to renew the lease time according to RFC2131
or RFC1541 depending on the command line option.
dhcpcd-1.3 has been reported to compile
on Intel,PPC, and Alpha-based Linux platforms
providing glibc-2.0.5 or later has been
installed. Please refer to the Notes below for details.
dhcpcd-1.3 has been reported as compatible with DHCP servers
used by the following network service providers:
1. Time Warner RoadRunner http://www.rr.com/
2. MediaOne (now AT&T Broadband) http://www.attbroadband.com/
3. Comcast.Net, formerly @Home Networks http://www.comcast.net/
4. France Telecom ADSL http://www.wanadoo.fr/
5. USWest.net DSL (now Qwest) http://www.uswest.com/
6. France CyberCable http://www.cybercable.fr/
7. BellSouth ADSL http://www.bellsouth.net/
8. BCtel Multimedia Gateway ADSL http://www.bctel.net/
9. Cogeco Cable Canada http://www.cogeco.ca/
10.Sympatico High Speed Edition ADSL http://www.hse.sympatico.ca/
11.Adelphia PowerLink http://powerlink.adelphia.net/
12.Videotron, Canada http://www.videotron.ca/
13.Access Cable, Nova Scotia, Canada http://www.accesscable.net/
14.A2000 Cable, Netherlands http://www.a2000.nl/
15.Tele-Communications, Inc http://www.tci.com/
16.Telenet, Belgium http://www.telenet.be/
17.Telekabel Wien, Austria http://www.telekabel.at/
18.RMCnet, France http://www.rmcnet.fr/
19.Retecal, Spain http://www.retecal.es/
20.TVD, Belgium http://www.tvd.net/
21.Optimum Online, NY http://www.optimumonline.com/
22.Knology Comm. http://www.knology.com/
23.Highpernet, Switzeland. http://www.highpernet.ch/
24.TeledisNet, Belgium. http://www.teledisnet.be/
25.Southwestern Bell DSL. http://www.swbell.net/
26.Brutele, Belgium. http://www.brutele.be/
27.Telus, Canada. http://www.telusplanet.net/
28.Chello, Netherlands. http://www.chello.nl/
29.RCN. http://www.rcn.com/
30.Pandora, Belgium. http://www.pandora.be/
31.Armstrong's Cable Services, PA. http://www.zbzoom.net/
32.21st Century, Chicago. http://www.21stcentury.net/
33.Supercable, Spain. http://www.supercable.es/
34.Primacom, Germany. http://www.primacom.net/
35.Click! Network, Tacoma, WA. http://www.click-network.com/
36.Telocity, Cupertino, CA. http://www.telocity.com/
37.Charter Communications. http://www.chartercom.com/
38.Tebenet, Netherlands. http://www.tebenet.nl/
39.ZoomTown, Cincinnati, OH. http://www.zoomtown.com/
40.Telecom New Zealand Jetstream ADSL. http://www.telecom.co.nz/
41.Belgacom Turboline ADSL. http://www.turboline.be/
42.ISP Channel. http://www.ispchannel.com/
43.Telia.Com Sweden. http://www.telia.com/
44.Netcabo Portugal. http://www.netcabo.pt/
45.CyberCity xDSL, Denmark. http://www.cybercity.dk/
46.Tokyo Metallic Comm. http://www.metallic.co.jp/
47.Telenor, Norway. http://www.telenor.no/
48.Telstra, Austria. http://www.telstra.com/
49.Look Wireless, Montreal. http://www.look.ca/
50.Virtua, Brazil. http://www.virtua.com.br/
51.Verizon DSL. http://www.verizon.com/dsl/
52.Sonera, Netherlands. http://www.soneraplaza.nl/
53.NTL, UK. http://www.ntl.co.uk/cablemodems/
54.Telewest, UK. http://www.telewest.co.uk/
55.VTR, Chile. http://www.vtr.net/
56.Millennium Digital Media. http://www.mdm.net/
57.Madritel, Spain. http://www.madritel.es/
58.Cistron Telecom, Netherlands. http://www.cistron.nl/
59.Cox Express, Las Vegas. http://www.cox.com/
60.Cablecom GMBH, Switzerland. http://www.hispeed.ch/
61.Elektro Ablasser Hausmannstaetten, Austria. http://www.catv4u.at/
62.Kiva Networking, Indiana. http://www.kiva.net/
63.Blueyonder, UK. http://www.blueyonder.co.uk/
64.Salzburg-Online, Austria. http://www.salzburg-online.at/
65.Cablenet, Colombia. http://www.cable.net.co/
66.i-Cable, Hong Kong. http://www.i-cable.com/
67.Shaw High Speed. http://www.shaw.ca/
68.Rogers Communications. http://www.rogers.com/
69.Chello, France. http://www.chello.fr/
70.Acesserapido, Brazil. http://www.acesserapido.com.br/
71.Wirefire. http://www.wirefire.com/
72.Ajato, Brazil. http://www.ajato.com.br/
73.TDC/TeleDanmark, Denmark. http://www.teledanmark.dk/
74.Telstra Bigpond Broadband ADSL, Australia. http://www.bigpond.com.au/
75.Eastern Connecticut Cable. http://www.myeastern.com/
76.ADSL Brazil Telecom. http://www.internetturbo.com.br/
77.InsightBB.com. http://www.insightbb.com/
78.S?derhamn Teknikpark AB, Sweden. http://www.teknikpark.se/
79.Tele 2, Sweden. http://www.tele2.se/
if you have been successfully using dhcpcd-1.3
on your network please report the fact along
with network provider's name/URL/whatever and dhcpcd version
to the author <sv@phystech.com>.
dhcpcd-1.3 primary web site is
http://www.phystech.com/download/
ftp://ftp.phystech.com/pub/
1. Install
Make sure your kernel is compiled with support for SOCK_PACKET
(CONFIG_PACKET option). Cd to source distribution directory. Do
./configure --prefix=/
Please note the GNU default installation --prefix=/usr/local
is not what most users want for dhcpcd installation.
Edit Makefile to customize compile time options.
Do 'make' followed by 'make install'.
To enable dhcpcd error logging add the following line to your
/etc/syslog.conf file:
local0.* /var/log/dhcpcd.log
and then refresh syslogd daemon:
kill -1 `cat /var/run/syslogd.pid`
Note 1.
to compile dhcpcd-1.3.X you have to install glibc-2.0.5 or later.
dhcpcd-1.3.X might not compile under libc.5.
If you don't have glibc installed you can use the precompiled
binary included with the distribution.
If you are trying to compile dhcpcd yourself and getting error
"cannot find net/ethernet.h file", you don't have glibc
installed.
Note 2.
some releases of GNU C compiler, notably
gcc-2.8.1 are buggy. The same goes for egcs as of 05/10/99.
If you have compiled dhcpcd with gcc-2.8.1 or egcs you may
get the following errors in dhcpcd.log file:
May 4 12:43:03 dhcpcd[423]: corrupted UDP msg with uh_ulen=319 in_cksum=-2 discarded
and dhcpcd won't work. The workaround is to compile dhcpcd without
-O2 in Makefile.
Note 3.
if you are trying to run dhcpcd and are getting the following error in
the log file:
dhcpcd[xx]: dhcpStart: socket(): Invalid argument
it means you kernel is compiled without support for SOCK_PACKET
(CONFIG_PACKET option).
Note 4.
if your dhcpcd binary compiles fine and runs OK with "--help" flag
only and otherwise immediately coredumps with "Segmentation Fault"
error then delete /etc/dhcpc/dhcpcd-<interface>.cache file and
try running dhcpcd again. There is a chance your dhcpcd cache file
is from old version of dhcpcd.
Note 5.
If you replace your network card or upgrade to a different version of
dhcpcd you might not be able to obtain the same old IP address from
DHCP server. This is because the DHCP server identifies clients by
ClientID DHCP option which by default is MAC address of the network
card. The work around is to use -I ClientID option with some
unique "ClientID" string.
Also, upgrading to a different version of dhcpcd invalidates *.cache
file where dhcpcd stores IP address which it tries to renew on restart.
2. How to Use It
Invoke the client by typing 'dhcpcd'. Note you should NOT
explicitly put it in the background with the '&' character -
background processing is automatic unless 'dhcpcd' was
compiled with -DDEBUG flag. Dhcpcd will fork into background
as soon as it configures the interface. By default, dhcpcd will
attach to 'eth0' unless you explicitly give an interface name on the
command line.
The example below demonstrates dhcpcd usage in a case where
linux box serves as a router/firewall for the local network 192.168.12.0.
if dhcpcd eth1; then
inetd
/usr/sbin/sendmail -bd
httpd
echo 1 > /proc/sys/net/ipv4/ip_forward
modprobe ip_tables
modprobe iptable_nat
modprobe iptable_filter
modprobe ipt_MASQUERADE
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
else
echo "**** Unable to configure eth0"
fi
The bootup process will wait until 'dhcpcd' configures
interface or until dhcpcd times out before proceeding further.
Any time dhcpcd configures or shuts down interface it will try to
execute <ConfigDir>/dhcpcd.exe script with appropriate
parameters passed. The exact pathname of the executable script can be
changed with "-c ExecFilePath" dhcpcd option. The <ConfigDir>
directory can be specified with "-L <ConfigDir>" option, otherwise
it defaults to /etc/dhcpc/. The dhcpcd.exe script invokation is:
<ConfigDir>/dhcpcd.exe <HostInfoFilePath> <up|down|new> [-d]
where <HostInfoFilePath> is actually <ConfigDir>/dhcpcd-<interface>.info
file; optional parameter [-d] is a debug flag passed if dhcpcd has
been invoked with -d flag. The second parameter to dhcpcd.exe script is
"up" if the interface has been configured with the same IP
address as before reboot, "down" if the interface has been shut
down, "new" if the interface has been configured with new IP address.
3. Supported DHCP Options
The current version of dhcpcd supports the following DHCP options:
o lease time
o renewal (T1) time
o rebind (T2) time
o netmask
o broadcast address
o router
o dns
o host name
o domain name
o nis domain name
o nis servers
o ntp servers
o static routes
5. Cache File
dhcpcd saves the assigned IP address into the file
<ConfigDir>/dhcpcd-<interface>.cache (the word <interface> is actually
replaced with the interface name like eth0, etc. to which dhcpcd is
attached) so that it can try to use that IP address when it is invoked
next time. Remove the file <ConfigDir>/dhcpcd-<interface>.cache before
you invoke dhcpcd unless you like using the previously assigned IP
address.
6. Information File
dhcpcd writes the configuration information into
<ConfigDir>/dhcpcd-<interface>.info file. The word <interface> is actually
replaced with the interface name like eth0, etc. to which dhcpcd is
attached. That file may be included into a Bourne or Korn shell script
to set an environment variables like e.g. HOSTNAME, DOMAIN, NETMASK, etc.
The supplied sample <ConfigDir>/dhcpcd.exe script demonstrates usage
of <ConfigDir>/dhcpcd-<interface>.info file.
7. Other Information
dhcpcd sends DHCP_RELEASE message to the DHCP server, deletes the
<ConfigDir>/dhcpcd-<interface>.cache file and brings the attached
network interface down when it gets SIGHUP signal. It will
not send DHCP_RELEASE message and will not delete
<ConfigDir>/dhcpcd-<interface>.cache file in a case it gets
SIGTERM as normally happens upon reboot.
dhcpcd may be used to obtain multiple IP addresses for the same
dummy interface providing one invokes dhcpcd with
-I ClientID -L ConfigDir -T -c ExecFilePath
options where ClientID and ConfigDir are unique to each of the requested
IP addresses. The same way it can be used to obtain IP addresses
for virtual interfaces, e.g. eth0:1
dhcpcd currently supports only Ethernet link protocol.
8. In case dhcpcd does not work:
Run 'dhcpcd -d' and mail me the relevant messages
from /var/log/dhcpcd.log file. Also run
tcpdump -evvn -i eth0
and mail me the results of that.
If the things are too bad for you,
uncomment -DDEBUG flag in Makefile
and recompile 'dhcpcd'. Run 'dhcpcd -d'
and mail me what you see.
Sergei Viznyuk <sv@phystech.com>

229
dhcpcd/arp.c Normal file
View File

@@ -0,0 +1,229 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 <net/if_arp.h>
#include <string.h>
#include <syslog.h>
#include "client.h"
#include "arp.h"
typedef struct arpMessage
{
struct packed_ether_header ethhdr;
u_short htype; /* hardware type (must be ARPHRD_ETHER) */
u_short ptype; /* protocol type (must be ETHERTYPE_IP) */
u_char hlen; /* hardware address length (must be 6) */
u_char plen; /* protocol address length (must be 4) */
u_short operation; /* ARP opcode */
u_char sHaddr[ETH_ALEN]; /* sender's hardware address */
u_char sInaddr[4]; /* sender's IP address */
u_char tHaddr[ETH_ALEN]; /* target's hardware address */
u_char tInaddr[4]; /* target's IP address */
u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */
} __attribute__((packed)) arpMessage;
#define BasicArpLen(A) (sizeof(A) - (sizeof(A.ethhdr) + sizeof(A.pad)))
extern int DebugFlag;
int eth2tr(struct packed_ether_header *frame, int datalen);
int tr2eth(struct packed_ether_header *frame);
/*****************************************************************************/
#ifdef ARPCHECK
int arpCheck(const dhcp_interface *iface)
{
arpMessage arp_msg_send;
arpMessage arp_msg_recv;
struct sockaddr addr;
int j,i=0,len=0;
memset (&arp_msg_send, 0, sizeof(arpMessage));
memcpy (arp_msg_send.ethhdr.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);
memcpy (arp_msg_send.ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
arp_msg_send.ethhdr.ether_type = htons(ETHERTYPE_ARP);
arp_msg_send.htype = (iface->bTokenRing) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
arp_msg_send.ptype = htons(ETHERTYPE_IP);
arp_msg_send.hlen = ETH_ALEN;
arp_msg_send.plen = 4;
arp_msg_send.operation = htons(ARPOP_REQUEST);
memcpy (arp_msg_send.sHaddr, iface->chaddr, ETH_ALEN);
memcpy (&arp_msg_send.tInaddr, &(iface->ciaddr), 4);
if ( DebugFlag )
{
syslog(LOG_DEBUG, "broadcasting ARPOP_REQUEST for %u.%u.%u.%u\n",
arp_msg_send.tInaddr[0],arp_msg_send.tInaddr[1],
arp_msg_send.tInaddr[2],arp_msg_send.tInaddr[3]);
}
do
{
do
{
if ( i++ > 4 )
return 0; /* 5 probes */
memset (&addr, 0, sizeof(struct sockaddr));
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
if ( iface->bTokenRing )
len = eth2tr (&arp_msg_send.ethhdr, BasicArpLen(ArpMsgSend));
else
len = sizeof (arpMessage);
if ( sendto(iface->sk, &arp_msg_send, len, 0, &addr, sizeof(struct sockaddr)) == -1 )
{
syslog(LOG_ERR,"arpCheck: sendto: %m\n");
return -1;
}
} while ( peekfd(iface->sk,50000) ); /* 50 msec timeout */
do
{
memset (&arp_msg_recv, 0, sizeof(arpMessage));
j = sizeof(struct sockaddr);
if ( recvfrom(iface->sk, &arp_msg_recv, sizeof(arpMessage), 0, (struct sockaddr *)&addr, &j) == -1 )
{
syslog(LOG_ERR,"arpCheck: recvfrom: %m\n");
return -1;
}
if ( iface->bTokenRing )
{
if ( tr2eth (&arp_msg_recv.ethhdr) )
continue;
}
if ( arp_msg_recv.ethhdr.ether_type != htons(ETHERTYPE_ARP) )
continue;
if ( arp_msg_recv.operation == htons(ARPOP_REPLY) )
{
if ( DebugFlag )
syslog(LOG_DEBUG, "ARPOP_REPLY received from %u.%u.%u.%u for %u.%u.%u.%u\n",
arp_msg_recv.sInaddr[0],arp_msg_recv.sInaddr[1],
arp_msg_recv.sInaddr[2],arp_msg_recv.sInaddr[3],
arp_msg_recv.tInaddr[0],arp_msg_recv.tInaddr[1],
arp_msg_recv.tInaddr[2],arp_msg_recv.tInaddr[3]);
}
else
continue;
if ( memcmp (arp_msg_recv.tHaddr, iface->chaddr, ETH_ALEN) )
{
if ( DebugFlag )
syslog(LOG_DEBUG,
"target hardware address mismatch: %02X.%02X.%02X.%02X.%02X.%02X received, %02X.%02X.%02X.%02X.%02X.%02X expected\n",
arp_msg_recv.tHaddr[0],arp_msg_recv.tHaddr[1],arp_msg_recv.tHaddr[2],
arp_msg_recv.tHaddr[3],arp_msg_recv.tHaddr[4],arp_msg_recv.tHaddr[5],
iface->chaddr[0],iface->chaddr[1],
iface->chaddr[2],iface->chaddr[3],
iface->chaddr[4],iface->chaddr[5]);
continue;
}
if (memcmp (&arp_msg_recv.sInaddr, &(iface->ciaddr), 4))
{
if ( DebugFlag )
syslog(LOG_DEBUG, "sender IP address mismatch: %u.%u.%u.%u received, %u.%u.%u.%u expected\n",
arp_msg_recv.sInaddr[0],arp_msg_recv.sInaddr[1],arp_msg_recv.sInaddr[2],arp_msg_recv.sInaddr[3],
((unsigned char *)&(iface->ciaddr))[0],
((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2],
((unsigned char *)&(iface->ciaddr))[3]);
continue;
}
return 1;
} while ( peekfd(iface->sk,50000) == 0 );
} while ( 1 );
return 0;
}
#endif
/*****************************************************************************/
int arpRelease(const dhcp_interface *iface) /* sends UNARP message, cf. RFC1868 */
{
arpMessage ArpMsgSend;
struct sockaddr addr;
int len;
const int inaddr_broadcast = INADDR_BROADCAST;
/* build Ethernet header */
memset (&ArpMsgSend,0,sizeof(arpMessage));
memcpy (ArpMsgSend.ethhdr.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);
memcpy (ArpMsgSend.ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP);
/* build UNARP message */
ArpMsgSend.htype = (iface->bTokenRing) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
ArpMsgSend.ptype = htons(ETHERTYPE_IP);
ArpMsgSend.plen = 4;
ArpMsgSend.operation= htons(ARPOP_REPLY);
memcpy (&ArpMsgSend.sInaddr, &(iface->ciaddr), 4);
memcpy (&ArpMsgSend.tInaddr, &inaddr_broadcast, 4);
memset(&addr,0,sizeof(struct sockaddr));
memcpy(addr.sa_data,iface->iface,strlen (iface->iface));
if ( iface->bTokenRing )
len = eth2tr (&ArpMsgSend.ethhdr, BasicArpLen(ArpMsgSend));
else
len = sizeof (arpMessage);
if ( sendto (iface->sk, &ArpMsgSend, len, 0, &addr, sizeof(struct sockaddr)) == -1 )
{
syslog (LOG_ERR,"arpRelease: sendto: %m\n");
return -1;
}
return 0;
}
/*****************************************************************************/
int arpInform(const dhcp_interface *iface)
{
arpMessage ArpMsgSend;
struct sockaddr addr;
int len;
const int inaddr_broadcast = INADDR_BROADCAST;
memset (&ArpMsgSend, 0, sizeof(arpMessage));
memcpy (ArpMsgSend.ethhdr.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);
memcpy (ArpMsgSend.ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP);
ArpMsgSend.htype = (iface->bTokenRing) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
ArpMsgSend.ptype = htons(ETHERTYPE_IP);
ArpMsgSend.hlen = ETH_ALEN;
ArpMsgSend.plen = 4;
ArpMsgSend.operation= htons(ARPOP_REPLY);
memcpy (ArpMsgSend.sHaddr, iface->chaddr, ETH_ALEN);
memcpy (ArpMsgSend.tHaddr, iface->shaddr, ETH_ALEN);
memcpy (ArpMsgSend.sInaddr, &(iface->ciaddr), 4);
memcpy (ArpMsgSend.tInaddr, &inaddr_broadcast, 4);
memset (&addr, 0, sizeof(struct sockaddr));
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
if ( iface->bTokenRing )
len = eth2tr(&ArpMsgSend.ethhdr,BasicArpLen(ArpMsgSend));
else
len = sizeof(arpMessage);
if ( sendto(iface->sk,&ArpMsgSend,len,0, &addr,sizeof(struct sockaddr)) == -1 )
{
syslog(LOG_ERR,"arpInform: sendto: %m\n");
return -1;
}
return 0;
}

32
dhcpcd/arp.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 ARP_H
#define ARP_H
#ifdef ARPCHECK
int arpCheck(const dhcp_interface *iface);
#endif
int arpRelease(const dhcp_interface *iface);
int arpInform(const dhcp_interface *iface);
#endif

329
dhcpcd/buildmsg.c Normal file
View File

@@ -0,0 +1,329 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 Softwarme
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <string.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include "client.h"
#include "buildmsg.h"
#include "udpipgen.h"
#include <stdio.h>
extern int DebugFlag;
/*****************************************************************************/
void fill_common_fields (dhcp_interface *iface, udpipMessage *msg, unsigned char dhost_addr[6], int bcast_rep)
{
dhcpMessage *dhcp_msg = (dhcpMessage *)&(msg->udpipmsg[sizeof(udpiphdr)]);
int magic_cookie = htonl (MAGIC_COOKIE);
/* build Ethernet header */
memcpy (msg->ethhdr.ether_dhost, dhost_addr, ETH_ALEN);
memcpy (msg->ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
msg->ethhdr.ether_type = htons (ETHERTYPE_IP);
dhcp_msg->op = DHCP_BOOTREQUEST;
dhcp_msg->htype = (iface->bTokenRing) ? ARPHRD_IEEE802_TR : ARPHRD_ETHER;
dhcp_msg->hlen = ETH_ALEN;
dhcp_msg->xid = iface->xid;
dhcp_msg->secs = htons(10);
if ( bcast_rep && iface->client_options->do_broadcast_response )
dhcp_msg->flags = htons (BROADCAST_FLAG);
memcpy (dhcp_msg->chaddr, iface->chaddr, ETH_ALEN);
memcpy (dhcp_msg->options, &magic_cookie, 4);
}
/*****************************************************************************/
unsigned char *fill_host_and_class_id (dhcp_interface *iface, unsigned char *p)
{
const char *host_name = iface->client_options->host_name;
int host_name_len = strlen (host_name);
if ( host_name_len )
{
*p++ = hostName;
*p++ = host_name_len;
memcpy (p, host_name, host_name_len);
p += host_name_len;
}
*p++ = dhcpClassIdentifier;
*p++ = iface->cls_id_len;
memcpy (p, iface->cls_id, iface->cls_id_len);
p += iface->cls_id_len;
memcpy (p, iface->cli_id, iface->cli_id_len);
p += iface->cli_id_len;
return p;
}
/*****************************************************************************/
unsigned char *fill_param_request (unsigned char *p)
{
*p++ = dhcpParamRequest;
*p++ = 14;
*p++ = subnetMask;
*p++ = routersOnSubnet;
*p++ = dns;
*p++ = hostName;
*p++ = domainName;
*p++ = rootPath;
*p++ = defaultIPTTL;
*p++ = broadcastAddr;
*p++ = performMaskDiscovery;
*p++ = performRouterDiscovery;
*p++ = staticRoute;
*p++ = nisDomainName;
*p++ = nisServers;
*p++ = ntpServers;
return p;
}
/*****************************************************************************/
unsigned char *fill_requested_ipaddr (dhcp_interface *iface, unsigned char *p)
{
*p++ = dhcpRequestedIPaddr;
*p++ = 4;
memcpy (p, &(iface->ciaddr), 4);
p += 4;
return p;
}
/*****************************************************************************/
unsigned char *fill_lease_time (unsigned int *lease_time, unsigned char *p)
{
*p++ = dhcpIPaddrLeaseTime;
*p++ = 4;
memcpy (p, lease_time, 4);
p += 4;
return p;
}
/*****************************************************************************/
unsigned char *fill_server_id (unsigned int *server_id, unsigned char *p)
{
*p++ = dhcpServerIdentifier;
*p++ = 4;
memcpy (p, server_id, 4);
p += 4;
return p;
}
/*****************************************************************************/
unsigned char *fill_message_type (unsigned char request, unsigned char *p)
{
const unsigned short dhcpMsgSize = htons(sizeof(dhcpMessage));
*p++ = dhcpMessageType;
*p++ = 1;
*p++ = request;
*p++ = dhcpMaxMsgSize;
*p++ = 2;
memcpy (p, &dhcpMsgSize, 2);
p += 2;
return p;
}
/*****************************************************************************/
udpipMessage *buildDhcpDiscover(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
unsigned int lease_time = htonl (iface->default_lease_time);
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
p = fill_message_type (DHCP_DISCOVER, p);
if ( iface->ciaddr )
{
if ( iface->client_options->do_rfc1541 )
dhcp_msg->ciaddr = iface->ciaddr;
else
p = fill_requested_ipaddr (iface, p);
}
p = fill_lease_time (&lease_time, p);
p = fill_param_request (p);
p = fill_host_and_class_id (iface, p);
*p = endOption;
/* build UDP/IP header */
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
return (udp_msg);
}
/*****************************************************************************/
udpipMessage *buildDhcpRequest(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
p = fill_message_type (DHCP_REQUEST, p);
p = fill_server_id (iface->dhcp_options.val[dhcpServerIdentifier], p);
if ( iface->client_options->do_rfc1541 )
dhcp_msg->ciaddr = iface->ciaddr;
else
p = fill_requested_ipaddr (iface, p);
if ( iface->dhcp_options.val[dhcpIPaddrLeaseTime] )
p = fill_lease_time (iface->dhcp_options.val[dhcpIPaddrLeaseTime], p);
p = fill_param_request (p);
p = fill_host_and_class_id (iface, p);
*p = endOption;
/* build UDP/IP header */
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
return udp_msg;
}
/*****************************************************************************/
udpipMessage *buildDhcpRenew(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
dhcp_msg->ciaddr = iface->ciaddr;
p = fill_message_type (DHCP_REQUEST, p);
#if 0
if ( iface->dhcp_options.val[dhcpIPaddrLeaseTime] )
p = fill_lease_time (iface->dhcp_options.val[dhcpIPaddrLeaseTime], p);
#endif
p = fill_param_request (p);
p = fill_host_and_class_id (iface, p);
*p = endOption;
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, iface->siaddr, &iface->ip_id);
return (udp_msg);
}
/*****************************************************************************/
udpipMessage *buildDhcpRebind(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
dhcp_msg->ciaddr = iface->ciaddr;
p = fill_message_type (DHCP_REQUEST, p);
if ( iface->dhcp_options.val[dhcpIPaddrLeaseTime] )
p = fill_lease_time (iface->dhcp_options.val[dhcpIPaddrLeaseTime], p);
p = fill_param_request (p);
p = fill_host_and_class_id (iface, p);
*p = endOption;
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, INADDR_BROADCAST, &iface->ip_id);
return udp_msg;
}
/*****************************************************************************/
udpipMessage *buildDhcpReboot(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
unsigned int lease_time = htonl (iface->default_lease_time);
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
p = fill_message_type (DHCP_REQUEST, p);
if ( iface->client_options->do_rfc1541 )
dhcp_msg->ciaddr = iface->ciaddr;
else
p = fill_requested_ipaddr (iface, p);
p = fill_lease_time (&lease_time, p);
p = fill_param_request (p);
p = fill_host_and_class_id (iface, p);
*p = endOption;
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
return (udp_msg);
}
/*****************************************************************************/
udpipMessage *buildDhcpRelease(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
dhcp_msg->ciaddr = iface->ciaddr;
*p++ = dhcpMessageType;
*p++ = 1;
*p++ = DHCP_RELEASE;
p = fill_server_id (iface->dhcp_options.val[dhcpServerIdentifier], p);
memcpy(p, iface->cli_id, iface->cli_id_len);
p += iface->cli_id_len;
*p = endOption;
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, iface->siaddr, &iface->ip_id);
return (udp_msg);
}
/*****************************************************************************/
#ifdef ARPCHECK
udpipMessage *buildDhcpDecline(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
*p++ = dhcpMessageType;
*p++ = 1;
*p++ = DHCP_DECLINE;
p = fill_server_id (iface->dhcp_options.val[dhcpServerIdentifier], p);
if ( iface->client_options->do_rfc1541 )
dhcp_msg->ciaddr = iface->ciaddr;
else
p = fill_requested_ipaddr (iface, p);
memcpy (p, iface->cli_id, iface->cli_id_len);
p += iface->cli_id_len;
*p = endOption;
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, iface->siaddr, &iface->ip_id);
return (udp_msg);
}
#endif
/*****************************************************************************/
udpipMessage *buildDhcpInform(dhcp_interface *iface)
{
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
register unsigned char *p = dhcp_msg->options + 4;
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
dhcp_msg->ciaddr = iface->ciaddr;
p = fill_message_type (DHCP_INFORM, p);
p = fill_param_request (p);
p = fill_host_and_class_id (iface, p);
*p = endOption;
udpipgen((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
return (udp_msg);
}

35
dhcpcd/buildmsg.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 BUILDMSG_H
#define BUILDMSG_H
udpipMessage *buildDhcpDiscover(dhcp_interface *iface);
udpipMessage *buildDhcpRequest(dhcp_interface *iface);
udpipMessage *buildDhcpRenew(dhcp_interface *iface);
udpipMessage *buildDhcpRebind(dhcp_interface *iface);
udpipMessage *buildDhcpReboot(dhcp_interface *iface);
udpipMessage *buildDhcpRelease(dhcp_interface *iface);
udpipMessage *buildDhcpDecline(dhcp_interface *iface);
udpipMessage *buildDhcpInform(dhcp_interface *iface);
#endif

1179
dhcpcd/client.c Normal file

File diff suppressed because it is too large Load Diff

286
dhcpcd/client.h Normal file
View File

@@ -0,0 +1,286 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 CLIENT_H
#define CLIENT_H
#include <net/ethernet.h>
#include <linux/types.h>
#include <linux/if_tr.h>
#include <netinet/in.h>
#include "dhcpcd.h"
#define IPPACKET_SIZE 1500
#define MAGIC_COOKIE 0x63825363
#define BROADCAST_FLAG 0x8000
#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff"
#ifndef AF_PACKET
#define AF_PACKET 17 /* should have been in socketbits.h */
#endif
#define HWADDR_TRIES 3
/* UDP port numbers for DHCP */
#define DHCP_SERVER_PORT 67 /* from client to server */
#define DHCP_CLIENT_PORT 68 /* from server to client */
/* DHCP message OP code */
#define DHCP_BOOTREQUEST 1
#define DHCP_BOOTREPLY 2
/* DHCP message type */
#define DHCP_DISCOVER 1
#define DHCP_OFFER 2
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_NAK 6
#define DHCP_RELEASE 7
#define DHCP_INFORM 8
/* DHCP RETRANSMISSION TIMEOUT (microseconds) */
#define DHCP_INITIAL_RTO (4*1000000)
#define DHCP_MAX_RTO (64*1000000)
/* DHCP option and value (cf. RFC1533) */
enum
{
padOption = 0,
subnetMask = 1,
timerOffset = 2,
routersOnSubnet = 3,
timeServer = 4,
nameServer = 5,
dns = 6,
logServer = 7,
cookieServer = 8,
lprServer = 9,
impressServer = 10,
resourceLocationServer = 11,
hostName = 12,
bootFileSize = 13,
meritDumpFile = 14,
domainName = 15,
swapServer = 16,
rootPath = 17,
extentionsPath = 18,
IPforwarding = 19,
nonLocalSourceRouting = 20,
policyFilter = 21,
maxDgramReasmSize = 22,
defaultIPTTL = 23,
pathMTUagingTimeout = 24,
pathMTUplateauTable = 25,
ifMTU = 26,
allSubnetsLocal = 27,
broadcastAddr = 28,
performMaskDiscovery = 29,
maskSupplier = 30,
performRouterDiscovery = 31,
routerSolicitationAddr = 32,
staticRoute = 33,
trailerEncapsulation = 34,
arpCacheTimeout = 35,
ethernetEncapsulation = 36,
tcpDefaultTTL = 37,
tcpKeepaliveInterval = 38,
tcpKeepaliveGarbage = 39,
nisDomainName = 40,
nisServers = 41,
ntpServers = 42,
vendorSpecificInfo = 43,
netBIOSnameServer = 44,
netBIOSdgramDistServer = 45,
netBIOSnodeType = 46,
netBIOSscope = 47,
xFontServer = 48,
xDisplayManager = 49,
dhcpRequestedIPaddr = 50,
dhcpIPaddrLeaseTime = 51,
dhcpOptionOverload = 52,
dhcpMessageType = 53,
dhcpServerIdentifier = 54,
dhcpParamRequest = 55,
dhcpMsg = 56,
dhcpMaxMsgSize = 57,
dhcpT1value = 58,
dhcpT2value = 59,
dhcpClassIdentifier = 60,
dhcpClientIdentifier = 61,
endOption = 255
};
typedef struct dhcpMessage
{
u_char op; /* message type */
u_char htype; /* hardware address type */
u_char hlen; /* hardware address length */
u_char hops; /* should be zero in client's message */
u_int xid; /* transaction id */
u_short secs; /* elapsed time in sec. from trying to boot */
u_short flags;
u_int ciaddr; /* (previously allocated) client IP address */
u_int yiaddr; /* 'your' client IP address */
u_int siaddr; /* should be zero in client's messages */
u_int giaddr; /* should be zero in client's messages */
u_char chaddr[16]; /* client's hardware address */
u_char sname[64]; /* server host name, null terminated string */
u_char file[128]; /* boot file name, null terminated string */
u_char options[312]; /* message options */
} __attribute__((packed)) dhcpMessage;
struct packed_ether_header
{
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
u_int16_t ether_type; /* packet type ID field */
} __attribute__((packed));
#define TOKEN_RING_HEADER_PAD sizeof(struct trh_hdr) + sizeof(struct trllc)
typedef struct udpipMessage
{
struct packed_ether_header ethhdr;
char udpipmsg[IPPACKET_SIZE];
char pad_for_tokenring_header[TOKEN_RING_HEADER_PAD];
} __attribute__((packed)) udpipMessage;
typedef struct dhcpOptions
{
u_char num;
u_char len[256];
void *val[256];
} __attribute__((packed)) dhcpOptions;
typedef struct dhcp_interface
{
char *iface;
int cease;
int running;
int sk;
int foo_sk;
short int saved_if_flags;
int bTokenRing;
unsigned int default_lease_time;
time_t req_sent_time;
struct in_addr default_router;
int ciaddr;
unsigned char chaddr[ETH_ALEN];
int siaddr;
unsigned char shaddr[ETH_ALEN];
unsigned int xid;
unsigned short ip_id;
unsigned char cls_id[DHCP_CLASS_ID_MAX_LEN];
int cls_id_len;
unsigned char cli_id[DHCP_CLIENT_ID_MAX_LEN];
int cli_id_len;
dhcpOptions dhcp_options;
dhcp_client_options *client_options;
} dhcp_interface;
typedef struct dhcp_option_table
{
const int option;
const char *name;
const int len;
} dhcp_option_table;
static dhcp_option_table dhcp_opt_table[] =
{
{ padOption, "padOption", 1 },
{ subnetMask, "subnetMask", 4 },
{ timerOffset, "timerOffset", -1 },
{ routersOnSubnet, "routersOnSubnet", 4 },
{ timeServer, "timeServer", 4 },
{ nameServer, "nameServer", 4 },
{ dns, "dns", 4 },
{ logServer, "logServer", 4 },
{ cookieServer, "cookieServer", 4 },
{ lprServer, "lprServer", 4 },
{ impressServer, "impressServer", 4 },
{ resourceLocationServer,"resourceLocationServer",4 },
{ hostName, "hostName", -1 },
{ bootFileSize, "bootFileSize", 4 },
{ meritDumpFile, "meritDumpFile", 4 },
{ domainName, "domainName", -1 },
{ swapServer, "swapServer", 4 },
{ rootPath, "rootPath", -1 },
{ extentionsPath, "extentionsPath", -1 },
{ IPforwarding, "IPforwarding", -1 },
{ nonLocalSourceRouting, "nonLocalSourceRouting", -1 },
{ policyFilter, "policyFilter", -1 },
{ maxDgramReasmSize, "maxDgramReasmSize", -1 },
{ defaultIPTTL, "defaultIPTTL", -1 },
{ pathMTUagingTimeout, "pathMTUagingTimeout", -1 },
{ pathMTUplateauTable, "pathMTUplateauTable", -1 },
{ ifMTU, "ifMTU", -1 },
{ allSubnetsLocal, "allSubnetsLocal", -1 },
{ broadcastAddr, "broadcastAddr", 4 },
{ performMaskDiscovery, "performMaskDiscovery", -1 },
{ routerSolicitationAddr,"routerSolicitationAddr",-1 },
{ staticRoute, "staticRoute", 4 },
{ trailerEncapsulation, "trailerEncapsulation", -1 },
{ arpCacheTimeout, "arpCacheTimeout", -1 },
{ ethernetEncapsulation, "ethernetEncapsulation", -1 },
{ tcpDefaultTTL, "tcpDefaultTTL", -1 },
{ tcpKeepaliveInterval, "tcpKeepaliveInterval", -1 },
{ tcpKeepaliveGarbage, "tcpKeepaliveGarbage", -1 },
{ nisDomainName, "nisDomainName", -1 },
{ nisServers, "nisServers", 4 },
{ ntpServers, "ntpServers", 4 },
{ vendorSpecificInfo, "vendorSpecificInfo", -1 },
{ netBIOSnameServer, "netBIOSnameServer", -1 },
{ netBIOSdgramDistServer,"netBIOSdgramDistServer",-1 },
{ netBIOSnodeType, "netBIOSnodeType", -1 },
{ netBIOSscope, "netBIOSscope", -1 },
{ xFontServer, "xFontServer", -1 },
{ xDisplayManager, "xDisplayManager", -1 },
{ dhcpRequestedIPaddr, "dhcpRequestedIPaddr", 4 },
{ dhcpIPaddrLeaseTime, "dhcpIPaddrLeaseTime", 4 },
{ dhcpOptionOverload, "dhcpOptionOverload", -1 },
{ dhcpMessageType, "dhcpMessageType", -1 },
{ dhcpServerIdentifier, "dhcpServerIdentifier", -1 },
{ dhcpParamRequest, "dhcpParamRequest", -1 },
{ dhcpMsg, "dhcpMsg", -1 },
{ dhcpMaxMsgSize, "dhcpMaxMsgSize", -1 },
{ dhcpT1value, "dhcpT1value", 4 },
{ dhcpT2value, "dhcpT2value", 4 },
{ dhcpClassIdentifier, "dhcpClassIdentifier", -1 },
{ dhcpClientIdentifier, "dhcpClientIdentifier", -1 },
{ -1, NULL, -1 }
};
typedef udpipMessage *(*dhcp_msg_build_proc)(dhcp_interface *);
int dhcp_reboot(dhcp_interface *iface);
int dhcp_init(dhcp_interface *iface);
int dhcp_request(dhcp_interface *iface, dhcp_msg_build_proc buildDhcpMsg);
int dhcp_renew(dhcp_interface *iface);
int dhcp_rebind(dhcp_interface *iface);
int dhcp_release(dhcp_interface *iface);
#ifdef ARPCHECK
int dhcp_decline(dhcp_interface *iface);
#endif
int dhcp_inform(dhcp_interface *iface);
#endif

30
dhcpcd/dhcp_test.c Normal file
View File

@@ -0,0 +1,30 @@
#include "dhcpcd.h"
#include "client.h"
#include <syslog.h>
#include <stdio.h>
int main (int argc, char **argv)
{
dhcp_client_options opts;
dhcp_interface *iface;
if (argc < 2 || argv[1] == NULL)
{
fprintf (stderr, "Need an interface\n");
exit (1);
}
memset (&opts, 0, sizeof (dhcp_client_options));
opts.base_timeout = 5;
openlog ("dhcp_test", LOG_CONS | LOG_PERROR, LOG_USER);
if (!(iface = dhcp_interface_init (argv[1], &opts)))
exit (1);
dhcp_init (iface);
dhcp_interface_free (iface);
exit (0);
}

221
dhcpcd/dhcpcd.c Normal file
View File

@@ -0,0 +1,221 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if_packet.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <ctype.h>
#include "dhcpcd.h"
#include "client.h"
/*
* DHCP Client Daemon v1.3.22-pl4
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
* Location: http://www.phystech.com/download/
*/
void classIDsetup(dhcp_interface *iface, const char *g_cls_id);
void clientIDsetup(dhcp_interface *iface, const char *g_cli_id);
void releaseDhcpOptions (dhcp_interface *iface);
/*****************************************************************************/
dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *in_opts)
{
int o = 1;
unsigned i = 0;
struct ifreq ifr;
struct sockaddr_pkt sap;
struct sockaddr_in clientAddr;
dhcp_interface *iface = NULL;
dhcp_client_options *opts = NULL;
if (!if_name || !in_opts)
return NULL;
if (!(iface = calloc (1, sizeof (dhcp_interface))))
return NULL;
iface->iface = strdup (if_name);
iface->default_lease_time = DHCP_DEFAULT_LEASETIME;
iface->xid = random ();
iface->sk = -1;
iface->foo_sk = -1;
if (!(opts = calloc (1, sizeof (dhcp_client_options))))
goto err_out;
memcpy (opts, in_opts, sizeof (dhcp_client_options));
iface->client_options = opts;
classIDsetup (iface, iface->client_options->class_id);
clientIDsetup (iface, iface->client_options->client_id);
memset (&ifr, 0, sizeof(struct ifreq));
memcpy (ifr.ifr_name, iface->iface, strlen (iface->iface));
iface->sk = socket (AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL));
if (iface->sk == -1)
{
syslog (LOG_ERR,"dhcp_interface_init: socket: %m\n");
goto err_out;
}
if ( ioctl (iface->sk, SIOCGIFHWADDR, &ifr) )
{
syslog(LOG_ERR,"dhcpStart: ioctl SIOCGIFHWADDR: %m\n");
goto err_out;
}
if (setsockopt (iface->sk, SOL_SOCKET, SO_BROADCAST, &o, sizeof(o)) == -1)
{
syslog (LOG_ERR,"dhcp_interface_init: setsockopt: %m\n");
goto err_out;
}
if (ioctl (iface->sk, SIOCGIFFLAGS, &ifr))
{
syslog (LOG_ERR, "dhcp_interface_init: ioctl SIOCGIFFLAGS: %m\n");
goto err_out;
}
iface->saved_if_flags = ifr.ifr_flags;
ifr.ifr_flags = iface->saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;
if (ioctl (iface->sk, SIOCSIFFLAGS, &ifr))
{
syslog (LOG_ERR,"dhcp_interface_init: ioctl SIOCSIFFLAGS: %m\n");
goto err_out;
}
memset (&sap, 0, sizeof(sap));
sap.spkt_protocol = htons (ETH_P_ALL);
memcpy (sap.spkt_device, iface->iface, strlen (iface->iface));
sap.spkt_family = AF_PACKET;
if ( bind (iface->sk, (void*)&sap, sizeof(struct sockaddr)) == -1 )
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
memcpy (iface->chaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
fprintf(stdout,"dhcpcd: MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n",
iface->chaddr[0], iface->chaddr[1], iface->chaddr[2],
iface->chaddr[3], iface->chaddr[4], iface->chaddr[5]);
i = time (NULL) + iface->chaddr[5] + 4*iface->chaddr[4] + 8*iface->chaddr[3] +
16*iface->chaddr[2] + 32*iface->chaddr[1] + 64*iface->chaddr[0];
srandom (i);
iface->ip_id = i & 0xffff;
iface->foo_sk = socket (AF_INET, SOCK_DGRAM, 0);
if ( iface->foo_sk == -1 )
{
syslog (LOG_ERR,"dhcp_interface_init: socket: %m\n");
goto err_out;
}
if (setsockopt (iface->foo_sk, SOL_SOCKET, SO_BROADCAST, &o, sizeof(o)))
syslog (LOG_ERR,"dhcp_interface_init: setsockopt: %m\n");
memset (&clientAddr.sin_addr, 0, sizeof (&clientAddr.sin_addr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons (DHCP_CLIENT_PORT);
if ( bind (iface->foo_sk, (struct sockaddr *)&clientAddr, sizeof(clientAddr)) )
{
if (errno != EADDRINUSE)
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
close (iface->foo_sk);
iface->foo_sk = -1;
}
else if (fcntl (iface->foo_sk, F_SETFL, O_NONBLOCK) == -1)
{
syslog (LOG_ERR,"dhcp_interface_init: fcntl: %m\n");
goto err_out;
}
return iface;
err_out:
dhcp_interface_free (iface);
return NULL;
}
/*****************************************************************************/
void dhcp_interface_free (dhcp_interface *iface)
{
struct ifreq ifr;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
releaseDhcpOptions (iface);
if (iface->foo_sk >= 0)
close (iface->foo_sk);
free (iface->iface);
free (iface->client_options);
free (iface);
}
/*****************************************************************************/
void dhcp_interface_cease (dhcp_interface *iface)
{
if (!iface)
return;
iface->cease = 1;
}
/*****************************************************************************/
int dhcp_interface_dhcp_field_exists (dhcp_interface *iface, int val)
{
if (!iface) return 0;
return (!!iface->dhcp_options.len[val]);
}
/*****************************************************************************/
void *dhcp_interface_get_dhcp_field (dhcp_interface *iface, int val)
{
if (!iface) return 0;
return (iface->dhcp_options.val[val]);
}
/*****************************************************************************/
int dhcp_interface_get_dhcp_field_len (dhcp_interface *iface, int val)
{
if (!iface) return 0;
return (iface->dhcp_options.len[val]);
}
/*****************************************************************************/
int dhcp_individual_value_len (int val)
{
if (val <= dhcpClientIdentifier)
return (dhcp_opt_table[val].len);
else
return -1;
}

67
dhcpcd/dhcpcd.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 DHCPCD_H
#define DHCPCD_H
#include <time.h>
#define DHCP_DEFAULT_TIMEOUT 60
#define DHCP_DEFAULT_LEASETIME 0xffffffff /* infinite lease time */
#define DHCP_CLASS_ID_MAX_LEN 48
#define DHCP_CLIENT_ID_MAX_LEN 48
#define DHCP_HOSTNAME_MAX_LEN 64
/* Return codes */
#define RET_DHCP_ERROR 0
#define RET_DHCP_ADDRESS_IN_USE 1
#define RET_DHCP_TIMEOUT 2
#define RET_DHCP_CEASED 3
#define RET_DHCP_NAK 4
#define RET_DHCP_SUCCESS 5
#define RET_DHCP_BOUND 6
typedef struct dhcp_client_options
{
unsigned char host_name[DHCP_HOSTNAME_MAX_LEN];
unsigned char class_id[DHCP_CLASS_ID_MAX_LEN];
unsigned char client_id[DHCP_CLIENT_ID_MAX_LEN];
int do_rfc1541;
int do_broadcast_response;
time_t base_timeout;
int do_checksum;
int send_second_discover;
int window;
} dhcp_client_options;
struct dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *in_opts);
void dhcp_interface_free (struct dhcp_interface *iface);
void dhcp_interface_cease (struct dhcp_interface *iface);
int dhcp_interface_dhcp_field_exists (struct dhcp_interface *iface, int val);
int dhcp_interface_get_dhcp_field_len (struct dhcp_interface *iface, int val);
void *dhcp_interface_get_dhcp_field (struct dhcp_interface *iface, int val);
int dhcp_individual_value_len (int val);
#endif

524
dhcpcd/dhcpconfig.c Normal file
View File

@@ -0,0 +1,524 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 <sys/stat.h>
#include <netinet/in.h>
#include <net/route.h>
#include <net/if.h>
#include <arpa/nameser.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <resolv.h>
#include <netdb.h>
#include "pathnames.h"
#include "client.h"
#include "arp.h"
extern int SetDHCPDefaultRoutes;
extern int DebugFlag;
extern int SetDomainName;
extern int SetHostName;
extern int ReplResolvConf;
extern int ReplNISConf;
extern int ReplNTPConf;
int resolv_renamed = 0;
int yp_renamed = 0;
int ntp_renamed = 0;
/* Note: Legths initialised to negative to allow us to distinguish between "empty" and "not set" */
char InitialHostName[HOSTNAME_MAX_LEN];
int InitialHostName_len=-1;
char InitialDomainName[HOSTNAME_MAX_LEN];
int InitialDomainName_len=-1;
/*****************************************************************************/
char *cleanmetas(char *cstr) /* this is to clean single quotes out of DHCP strings */
{
register char *c=cstr;
do
if ( *c == 39 )
*c = ' ';
while ( *c++ );
return cstr;
}
/*****************************************************************************/
unsigned long getgenmask(unsigned long ip_in) /* this is to guess genmask form network address */
{
unsigned long t,p=ntohl(ip_in);
if ( IN_CLASSA(p) )
t= ~IN_CLASSA_NET;
else
{
if ( IN_CLASSB(p) )
t= ~IN_CLASSB_NET;
else
{
if ( IN_CLASSC(p) )
t= ~IN_CLASSC_NET;
else
t=0;
}
}
while ( t & p )
t >>= 1;
return htonl(~t);
}
/*****************************************************************************/
int setResolvConf(dhcp_interface *iface)
{
FILE *f;
resolv_renamed = 1 + rename (RESOLV_CONF, ""RESOLV_CONF".sv");
f = fopen(RESOLV_CONF,"w");
if ( f )
{
int i;
#if 0
if ( iface->dchp_options.len[nisDomainName] )
fprintf(f,"domain %s\n",(char *)iface->dhcp_options.val[nisDomainName]);
else
if ( iface->dhcp_options.len[domainName] )
fprintf(f,"domain %s\n",(char *)iface->dhcp_options.val[domainName]);
#endif
for (i = 0; i < iface->dhcp_options.len[dns]; i += 4)
{
fprintf(f,"nameserver %u.%u.%u.%u\n",
((unsigned char *)iface->dhcp_options.val[dns])[i],
((unsigned char *)iface->dhcp_options.val[dns])[i+1],
((unsigned char *)iface->dhcp_options.val[dns])[i+2],
((unsigned char *)iface->dhcp_options.val[dns])[i+3]);
}
#if 0
if ( iface->dhcp_options.len[nisDomainName] + iface->dhcp_options.len[domainName] )
{
fprintf (f,"search");
if ( iface->dhcp_options.len[nisDomainName] )
fprintf (f," %s",(char *)iface->dhcp_options.val[nisDomainName]);
if ( iface->dhcp_options.len[domainName] )
fprintf (f," %s",(char *)iface->dhcp_options.val[domainName]);
fprintf (f,"\n");
}
#else
if ( iface->dhcp_options.len[domainName] )
fprintf(f,"search %s\n",(char *)iface->dhcp_options.val[domainName]);
#endif
fclose(f);
}
else
syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
/* moved the next section of code from before to after we've created
* resolv.conf. See below for explanation. <poeml@suse.de>
* res_init() is normally called from within the first function of the
* resolver which is called. Here, we want resolv.conf to be
* reread. Otherwise, we won't be able to find out about our hostname,
* because the resolver won't notice the change in resolv.conf
*/
(void)res_init();
return 0;
}
/*****************************************************************************/
int setNISConf(dhcp_interface *iface)
{
FILE *f;
yp_renamed = 1 + rename (NIS_CONF, ""NIS_CONF".sv");
f = fopen (NIS_CONF,"w");
if (f)
{
int i;
char *domain=NULL;
if ( iface->dhcp_options.len[nisDomainName] )
domain=(char *)iface->dhcp_options.val[nisDomainName];
else
domain=(char *)iface->dhcp_options.val[domainName];
for ( i = 0; i < iface->dhcp_options.len[nisServers]; i += 4)
{
fprintf( f,"domain %s server %u.%u.%u.%u\n", (domain ? domain : "localdomain"),
((unsigned char *)iface->dhcp_options.val[nisServers])[i],
((unsigned char *)iface->dhcp_options.val[nisServers])[i+1],
((unsigned char *)iface->dhcp_options.val[nisServers])[i+2],
((unsigned char *)iface->dhcp_options.val[nisServers])[i+3]);
}
if ( !iface->dhcp_options.len[nisServers] )
fprintf (f, "domain %s broadcast\n", (domain ? domain : "localdomain"));
fclose (f);
}
else
syslog (LOG_ERR, "dhcpConfig: fopen: %m\n");
return 0;
}
/*****************************************************************************/
int setNTPConf(dhcp_interface *iface)
{
FILE *f;
ntp_renamed = 1 + rename (NTP_CONF,""NTP_CONF".sv");
f = fopen(NTP_CONF,"w");
if ( f )
{
int net, mask;
memcpy (&mask, iface->dhcp_options.val[subnetMask], 4);
net = iface->ciaddr & mask;
/* Note: Revise drift/log file names and stratum for local clock */
fprintf(f,"restrict default noquery notrust nomodify\n");
fprintf(f,"restrict 127.0.0.1\n");
fprintf(f,"restrict %u.%u.%u.%u mask %u.%u.%u.%u\n",
((unsigned char *)&net)[0], ((unsigned char *)&net)[1],
((unsigned char *)&net)[2], ((unsigned char *)&net)[3],
((unsigned char *)&mask)[0], ((unsigned char *)&mask)[1],
((unsigned char *)&mask)[2], ((unsigned char *)&mask)[3]);
if ( iface->dhcp_options.len[ntpServers] >= 4 )
{
int i;
char addr[4*3+3*1+1];
for ( i = 0; i < iface->dhcp_options.len[ntpServers]; i += 4)
{
snprintf(addr,sizeof(addr),"%u.%u.%u.%u",
((unsigned char *)iface->dhcp_options.val[ntpServers])[i],
((unsigned char *)iface->dhcp_options.val[ntpServers])[i+1],
((unsigned char *)iface->dhcp_options.val[ntpServers])[i+2],
((unsigned char *)iface->dhcp_options.val[ntpServers])[i+3]);
fprintf(f,"restrict %s\nserver %s\n",addr,addr);
}
}
else
{ /* No servers found, use local clock */
fprintf(f, "fudge 127.127.1.0 stratum 3\n");
fprintf(f, "server 127.127.1.0\n");
}
fprintf(f, "driftfile /etc/ntp.drift\n");
fprintf(f, "logfile /var/log/ntp.log\n");
fclose(f);
}
else
syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
return 0;
}
/*****************************************************************************/
int setHostName (dhcp_interface *iface)
{
struct hostent *hp = NULL;
char *dname = NULL;
int dname_len = 0;
if ( !iface->dhcp_options.len[hostName] )
{
hp = gethostbyaddr ((char *)&iface->ciaddr, sizeof(iface->ciaddr), AF_INET);
if ( hp )
{
dname = hp->h_name;
while ( *dname > 32 )
#if 0
if ( *dname == '.' )
break;
else
#endif
dname++;
dname_len = dname-hp->h_name;
iface->dhcp_options.val[hostName] = (char *)malloc(dname_len+1);
iface->dhcp_options.len[hostName] = dname_len;
memcpy ((char *)iface->dhcp_options.val[hostName], hp->h_name, dname_len);
((char *)iface->dhcp_options.val[hostName])[dname_len] = 0;
iface->dhcp_options.num++;
}
}
if ( InitialHostName_len < 0 && gethostname(InitialHostName, sizeof(InitialHostName)) == 0 )
{
InitialHostName_len = strlen(InitialHostName);
if ( DebugFlag )
fprintf (stdout, "dhcpcd: orig hostname = %s\n", InitialHostName);
}
if ( iface->dhcp_options.len[hostName] )
{
sethostname (iface->dhcp_options.val[hostName], iface->dhcp_options.len[hostName]);
if ( DebugFlag )
fprintf(stdout,"dhcpcd: your hostname = %s\n", (char *)iface->dhcp_options.val[hostName]);
}
return 0;
}
/*****************************************************************************/
int setDomainName (dhcp_interface *iface)
{
struct hostent *hp = NULL;
char *dname = NULL;
int dname_len = 0;
if ( InitialDomainName_len < 0 && getdomainname(InitialDomainName,sizeof(InitialDomainName)) == 0 )
{
InitialDomainName_len = strlen(InitialDomainName);
if ( DebugFlag )
fprintf(stdout,"dhcpcd: orig domainname = %s\n",InitialDomainName);
}
#if 0
if ( iface->dhcp_options.len[nisDomainName] )
{
setdomainname (iface->dhcp_options.val[nisDomainName], iface->dhcp_options.len[nisDomainName]);
if ( DebugFlag )
fprintf(stdout, "dhcpcd: your domainname = %s\n", (char *)iface->dhcp_options.val[nisDomainName]);
}
else
{
#endif
if ( ! iface->dhcp_options.len[domainName] )
{
hp = gethostbyaddr((char *)&iface->ciaddr, sizeof(iface->ciaddr), AF_INET);
if ( hp )
{
dname=hp->h_name;
while ( *dname > 32 )
{
if ( *dname == '.' )
{
dname++;
break;
}
else
dname++;
}
dname_len = strlen (dname);
if ( dname_len )
{
iface->dhcp_options.val[domainName]=(char *)malloc(dname_len+1);
iface->dhcp_options.len[domainName]=dname_len;
memcpy((char *)iface->dhcp_options.val[domainName], dname,dname_len);
((char *)iface->dhcp_options.val[domainName])[dname_len]=0;
iface->dhcp_options.num++;
}
}
}
if ( iface->dhcp_options.len[domainName] )
{
setdomainname(iface->dhcp_options.val[domainName], iface->dhcp_options.len[domainName]);
if ( DebugFlag )
fprintf(stdout,"dhcpcd: your domainname = %s\n", (char *)iface->dhcp_options.val[domainName]);
}
#if 0
}
#endif
return 0;
}
/*****************************************************************************/
int setDefaultRoute (dhcp_interface *iface, char *route_addr)
{
struct rtentry rtent;
struct sockaddr_in *p;
memset (&rtent, 0, sizeof(struct rtentry));
p = (struct sockaddr_in *)&rtent.rt_dst;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0;
p = (struct sockaddr_in *)&rtent.rt_gateway;
p->sin_family = AF_INET;
memcpy (&p->sin_addr.s_addr, route_addr, 4);
p = (struct sockaddr_in *)&rtent.rt_genmask;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0;
rtent.rt_dev = iface->iface;
rtent.rt_metric = 1;
rtent.rt_window = iface->client_options->window;
rtent.rt_flags = RTF_UP | RTF_GATEWAY | ( rtent.rt_window ? RTF_WINDOW : 0);
if ( ioctl(iface->sk,SIOCADDRT,&rtent) == -1 )
{
if ( errno == ENETUNREACH ) /* possibly gateway is over the bridge */
{ /* try adding a route to gateway first */
struct rtentry rtent2;
memset (&rtent2, 0, sizeof(struct rtentry));
p = (struct sockaddr_in *)&rtent2.rt_dst;
p->sin_family = AF_INET;
p = (struct sockaddr_in *)&rtent2.rt_gateway;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0;
memcpy (&p->sin_addr.s_addr, route_addr, 4);
p = (struct sockaddr_in *)&rtent2.rt_genmask;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0xffffffff;
rtent2.rt_dev = iface->iface;
rtent2.rt_metric = 0;
rtent2.rt_flags = RTF_UP | RTF_HOST;
if ( ioctl (iface->sk, SIOCADDRT, &rtent2) == 0 )
{
if ( ioctl (iface->sk, SIOCADDRT, &rtent) == -1 )
{
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
return -1;
}
}
}
else
{
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
return -1;
}
}
return 0;
}
/*****************************************************************************/
int dhcpConfig(dhcp_interface *iface)
{
int i;
struct ifreq ifr;
struct rtentry rtent;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
/* setting IP address */
memset (&ifr, 0, sizeof(struct ifreq));
memcpy (ifr.ifr_name, iface->iface, strlen (iface->iface));
p->sin_family = AF_INET;
p->sin_addr.s_addr = iface->ciaddr;
if ( ioctl (iface->sk, SIOCSIFADDR, &ifr) == -1 )
{
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFADDR: %m\n");
return -1;
}
/* setting netmask */
memcpy(&p->sin_addr.s_addr,iface->dhcp_options.val[subnetMask],4);
if ( ioctl(iface->sk,SIOCSIFNETMASK,&ifr) == -1 )
{
p->sin_addr.s_addr = 0xffffffff; /* try 255.255.255.255 */
if ( ioctl(iface->sk,SIOCSIFNETMASK,&ifr) == -1 )
{
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFNETMASK: %m\n");
return -1;
}
}
/* setting broadcast address */
memcpy (&p->sin_addr.s_addr, iface->dhcp_options.val[broadcastAddr], 4);
if ( ioctl(iface->sk,SIOCSIFBRDADDR,&ifr) == -1 )
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFBRDADDR: %m\n");
/* setting static routes */
for ( i = 0; i < iface->dhcp_options.len[staticRoute]; i += 8)
{
struct sockaddr_in *dstp;
struct sockaddr_in *gwp;
struct sockaddr_in *mskp;
memset (&rtent,0,sizeof(struct rtentry));
dstp = (struct sockaddr_in *)&rtent.rt_dst;
dstp->sin_family = AF_INET;
memcpy(&dstp->sin_addr.s_addr,((char *)iface->dhcp_options.val[staticRoute])+i,4);
gwp = (struct sockaddr_in *)&rtent.rt_gateway;
gwp->sin_family = AF_INET;
memcpy(&gwp->sin_addr.s_addr,((char *)iface->dhcp_options.val[staticRoute])+i+4,4);
mskp = (struct sockaddr_in *)&rtent.rt_genmask;
mskp->sin_family = AF_INET;
mskp->sin_addr.s_addr = getgenmask (dstp->sin_addr.s_addr);
rtent.rt_flags = RTF_UP|RTF_GATEWAY;
if ( mskp->sin_addr.s_addr == 0xffffffff )
rtent.rt_flags |= RTF_HOST;
rtent.rt_dev = iface->iface;
rtent.rt_metric = 1;
if ( ioctl(iface->sk,SIOCADDRT,&rtent) )
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
}
if ( SetDHCPDefaultRoutes )
{
if ( iface->dhcp_options.len[routersOnSubnet] > 3 )
for ( i = 0; i < iface->dhcp_options.len[routersOnSubnet]; i += 4)
setDefaultRoute (iface, iface->dhcp_options.val[routersOnSubnet]);
}
else if ( iface->default_router.s_addr > 0 )
setDefaultRoute (iface, (char *)&(iface->default_router.s_addr));
arpInform(iface);
if ( DebugFlag )
fprintf(stdout,"dhcpcd: your IP address = %u.%u.%u.%u\n",
((unsigned char *)&iface->ciaddr)[0],
((unsigned char *)&iface->ciaddr)[1],
((unsigned char *)&iface->ciaddr)[2],
((unsigned char *)&iface->ciaddr)[3]);
if ( ReplResolvConf )
setResolvConf (iface);
if ( ReplNISConf )
setNISConf (iface);
if ( ReplNTPConf )
setNTPConf (iface);
if ( SetHostName )
setHostName (iface);
if ( SetDomainName )
setDomainName (iface);
#if 0
if ( iface->ciaddr == previous ip address )
{
/* execute_on_change("up"); */
}
else
{
/* IP address has changed */
/* execute_on_change("new"); */
}
if ( *(unsigned int *)iface->dhcp_options.val[dhcpIPaddrLeaseTime] == 0xffffffff )
{
syslog(LOG_INFO,"infinite IP address lease time. Exiting\n");
/* exit(0); */
}
#endif
return 0;
}
/*****************************************************************************/

119
dhcpcd/udpipgen.c Normal file
View File

@@ -0,0 +1,119 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 "udpipgen.h"
#include "client.h"
/*****************************************************************************/
unsigned short in_cksum(unsigned short *addr, int len)
{
register int sum = 0;
register u_short *w = addr;
register int nleft = len;
while ( nleft > 1 )
{
sum += *w++;
nleft -= 2;
}
if ( nleft == 1 )
{
u_char a = 0;
memcpy(&a,w,1);
sum += a;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
/*****************************************************************************/
void udpipgen (udpiphdr *udpip, unsigned int saddr, unsigned int daddr, unsigned short *ip_id)
{
/* Use local copy because udpip->ip is not aligned. */
struct ip ip_local;
struct ip *ip = &ip_local;
struct ipovly *io = (struct ipovly *)udpip->ip;
struct udphdr *udp = (struct udphdr *)udpip->udp;
io->ih_next = io->ih_prev = 0;
io->ih_x1 = 0;
io->ih_pr = IPPROTO_UDP;
io->ih_len = htons(sizeof(dhcpMessage) + sizeof(struct udphdr));
io->ih_src.s_addr = saddr;
io->ih_dst.s_addr = daddr;
udp->uh_sport = htons(DHCP_CLIENT_PORT);
udp->uh_dport = htons(DHCP_SERVER_PORT);
udp->uh_ulen = io->ih_len;
udp->uh_sum = 0;
udp->uh_sum = in_cksum((unsigned short *)udpip, sizeof(dhcpMessage) + sizeof(udpiphdr));
if ( udp->uh_sum == 0 )
udp->uh_sum = 0xffff;
memcpy(ip,(struct ip *)udpip->ip,sizeof(ip_local));
ip->ip_hl = 5;
ip->ip_v = IPVERSION;
ip->ip_tos = 0; /* normal service */
ip->ip_len = htons(sizeof(dhcpMessage) + sizeof(udpiphdr));
ip->ip_id = htons(*ip_id); *ip_id++;
ip->ip_off = 0;
ip->ip_ttl = IPDEFTTL; /* time to live, 64 by default */
ip->ip_p = IPPROTO_UDP;
ip->ip_src.s_addr = saddr;
ip->ip_dst.s_addr = daddr;
ip->ip_sum = 0;
memcpy(udpip->ip,ip,sizeof(ip_local));
ip->ip_sum = in_cksum((unsigned short *)&ip_local,sizeof(struct ip));
memcpy(udpip->ip,ip,sizeof(ip_local));
}
/*****************************************************************************/
int udpipchk(udpiphdr *udpip)
{
int hl;
struct ip save_ip;
struct ip *ip = (struct ip *)udpip->ip;
struct ipovly *io = (struct ipovly *)udpip->ip;
struct udphdr *udp = (struct udphdr *)udpip->udp;
udpiphdr *nudpip = udpip;
hl = ip->ip_hl<<2;
if ( in_cksum((unsigned short *)udpip,hl) )
return -1;
memcpy(&save_ip, udpip->ip, sizeof(struct ip));
hl -= sizeof(struct ip);
if ( hl )
{
/* thrash IP options */
nudpip = (udpiphdr *)((char *)udpip+hl);
memmove((char *)nudpip,udpip,sizeof(struct ip));
io = (struct ipovly *)nudpip->ip;
ip = (struct ip *)nudpip->ip;
udp = (struct udphdr *)nudpip->udp;
}
if ( udp->uh_sum == 0 )
return 0; /* no checksum has been done by sender */
io->ih_next = io->ih_prev = 0;
io->ih_x1 = 0;
io->ih_len = udp->uh_ulen;
hl = ntohs(udp->uh_ulen)+sizeof(struct ip);
if ( in_cksum((unsigned short *)nudpip,hl) )
return -2;
memcpy(udpip->ip, &save_ip, sizeof(struct ip));
return 0;
}

58
dhcpcd/udpipgen.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* dhcpcd - DHCP client daemon -
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
*
* This 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 UDPIPGEN_H
#define UDPIPGEN_H
#include <netinet/ip.h>
#ifndef IPDEFTTL
#define IPDEFTTL 64
#endif
struct ipovly
{
int ih_next,ih_prev;
u_char ih_x1;
u_char ih_pr;
u_short ih_len;
struct in_addr ih_src;
struct in_addr ih_dst;
} __attribute__((packed));
struct udphdr
{
u_int16_t uh_sport;
u_int16_t uh_dport;
u_int16_t uh_ulen;
u_int16_t uh_sum;
} __attribute__((packed));
typedef struct udpiphdr
{
char ip[sizeof(struct ip)];
char udp[sizeof(struct udphdr)];
} __attribute__((packed)) udpiphdr;
void udpipgen (udpiphdr *udpip, unsigned int saddr, unsigned int daddr, unsigned short *ip_id);
int udpipchk (udpiphdr *udpip);
#endif

View File

@@ -1,7 +1,7 @@
INCLUDES = -I${top_srcdir} INCLUDES = -I${top_srcdir}
CPPFLAGS = \ AM_CPPFLAGS = \
$(NM_CFLAGS) \ $(NM_CFLAGS) \
$(GTK_CFLAGS) \ $(GTK_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \ $(GDK_PIXBUF_CFLAGS) \

View File

@@ -5,7 +5,7 @@ NOTIFICATION_ICON_SOURCE=@NOTIFICATION_ICON_SRC@
INCLUDES = -I${top_srcdir} INCLUDES = -I${top_srcdir}
CPPFLAGS = \ AM_CPPFLAGS = \
$(NM_CFLAGS) \ $(NM_CFLAGS) \
$(GLADE_CFLAGS) \ $(GLADE_CFLAGS) \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \

View File

@@ -14,30 +14,33 @@ bin_PROGRAMS = NetworkManager
noinst_LTLIBRARIES = libnmbackend.la noinst_LTLIBRARIES = libnmbackend.la
NetworkManager_SOURCES = \ NetworkManager_SOURCES = \
NetworkManagerAP.c \ NetworkManagerAP.c \
NetworkManagerAP.h \ NetworkManagerAP.h \
NetworkManagerAPList.c \ NetworkManagerAPList.c \
NetworkManagerAPList.h \ NetworkManagerAPList.h \
NetworkManagerDbus.c \ NetworkManagerDbus.c \
NetworkManagerDbus.h \ NetworkManagerDbus.h \
NetworkManagerDevice.c \ NetworkManagerDHCP.c \
NetworkManagerDevice.h \ NetworkManagerDHCP.h \
NetworkManager.c \ NetworkManagerDevice.c \
NetworkManagerMain.h \ NetworkManagerDevice.h \
NetworkManagerPolicy.c \ NetworkManager.c \
NetworkManagerPolicy.h \ NetworkManagerMain.h \
NetworkManagerUtils.c \ NetworkManagerPolicy.c \
NetworkManagerUtils.h \ NetworkManagerPolicy.h \
NetworkManagerWireless.c \ NetworkManagerUtils.c \
NetworkManagerWireless.h \ NetworkManagerUtils.h \
backends/NetworkManagerSystem.h NetworkManagerWireless.c \
NetworkManagerWireless.h \
NetworkManagerSystem.c \
NetworkManagerSystem.h
if !WITH_GCRYPT if !WITH_GCRYPT
NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
endif endif
NetworkManager_LDADD = $(NM_LIBS) $(IWLIB) libnmbackend.la NetworkManager_LDADD = $(NM_LIBS) $(IWLIB) libnmbackend.la ../dhcpcd/libdhcpc.a
if WITH_GCRYPT if WITH_GCRYPT
NetworkManager_LDADD += $(LIBGCRYPT_LIBS) NetworkManager_LDADD += $(LIBGCRYPT_LIBS)
endif endif

View File

@@ -40,7 +40,7 @@
#include "NetworkManagerDbus.h" #include "NetworkManagerDbus.h"
#include "NetworkManagerAP.h" #include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h" #include "NetworkManagerAPList.h"
#include "backends/NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
/* /*

119
src/NetworkManagerDHCP.c Normal file
View File

@@ -0,0 +1,119 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "NetworkManagerDevice.h"
#include "NetworkManagerDHCP.h"
#include "NetworkManagerSystem.h"
#include "../dhcpcd/client.h"
/* Accessors to device data that only this file should need */
dhcp_interface *nm_device_get_dhcp_iface (NMDevice *dev);
void nm_device_set_dhcp_iface (NMDevice *dev, dhcp_interface *dhcp_iface);
/*
* nm_device_dhcp_run
*
* Start a DHCP transaction on particular device.
*
*/
int nm_device_dhcp_run (NMDevice *dev)
{
dhcp_interface *dhcp_iface;
dhcp_client_options opts;
int err;
const char *iface;
g_return_val_if_fail (dev != NULL, RET_DHCP_ERROR);
memset (&opts, 0, sizeof (dhcp_client_options));
opts.base_timeout = 25;
iface = nm_device_get_iface (dev);
if (!(dhcp_iface = dhcp_interface_init (iface, &opts)))
return RET_DHCP_ERROR;
nm_device_set_dhcp_iface (dev, dhcp_iface);
/* Start off in DHCP INIT state, get a completely new IP address
* and settings.
*/
err = dhcp_init (dhcp_iface);
if (err == RET_DHCP_BOUND)
{
int temp;
/* Replace basic info */
nm_system_device_set_ip4_address (dev, dhcp_iface->ciaddr);
if (dhcp_interface_dhcp_field_exists (dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dhcp_iface, subnetMask), dhcp_individual_value_len (subnetMask));
nm_system_device_set_ip4_netmask (dev, temp);
}
if (dhcp_interface_dhcp_field_exists (dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dhcp_iface, broadcastAddr), dhcp_individual_value_len (broadcastAddr));
nm_system_device_set_ip4_broadcast (dev, temp);
}
/* Default route */
if (dhcp_interface_dhcp_field_exists (dhcp_iface, routersOnSubnet))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dhcp_iface, routersOnSubnet), dhcp_individual_value_len (routersOnSubnet));
nm_system_device_set_ip4_default_route (dev, temp);
}
/* Update /etc/resolv.conf */
if (dhcp_interface_dhcp_field_exists (dhcp_iface, dns))
{
nm_system_device_update_resolv_conf (dhcp_interface_get_dhcp_field (dhcp_iface, dns),
dhcp_interface_get_dhcp_field_len (dhcp_iface, dns), dhcp_interface_get_dhcp_field (dhcp_iface, domainName));
}
}
dhcp_interface_free (dhcp_iface);
nm_device_set_dhcp_iface (dev, NULL);
return (err);
}
/*
* nm_device_dhcp_cease
*
* Signal dhcp that its supposed to stop and return.
*
*/
void nm_device_dhcp_cease (NMDevice *dev)
{
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_get_dhcp_iface (dev) != NULL);
dhcp_interface_cease (nm_device_get_dhcp_iface (dev));
}

31
src/NetworkManagerDHCP.h Normal file
View File

@@ -0,0 +1,31 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#ifndef NETWORK_MANAGER_DHCP_H
#define NETWORK_MANAGER_DHCP_H
#include "../dhcpcd/dhcpcd.h"
int nm_device_dhcp_run (NMDevice *dev);
void nm_device_dhcp_cease (NMDevice *dev);
#endif

View File

@@ -35,11 +35,13 @@
#include "NetworkManagerWireless.h" #include "NetworkManagerWireless.h"
#include "NetworkManagerPolicy.h" #include "NetworkManagerPolicy.h"
#include "NetworkManagerAPList.h" #include "NetworkManagerAPList.h"
#include "backends/NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "NetworkManagerDHCP.h"
/* Local static prototypes */ /* Local static prototypes */
static gboolean mii_get_link (NMDevice *dev); static gboolean mii_get_link (NMDevice *dev);
static gpointer nm_device_activation_worker (gpointer user_data); static gpointer nm_device_activation_worker (gpointer user_data);
static gboolean nm_device_activation_configure_ip (NMDevice *dev);
/******************************************************/ /******************************************************/
@@ -104,25 +106,27 @@ struct NMDevice
{ {
guint refcount; guint refcount;
char *udi; char *udi;
char *iface; char *iface;
NMDeviceType type; NMDeviceType type;
NMDriverSupportLevel driver_support_level; NMDriverSupportLevel driver_support_level;
gboolean link_active; gboolean link_active;
guint32 ip4_address; guint32 ip4_address;
/* FIXME: ipv6 address too */ /* FIXME: ipv6 address too */
NMData *app_data; unsigned char hw_addr[ETH_ALEN];
NMDeviceOptions options; NMData *app_data;
NMDeviceConfigInfo config_info; NMDeviceOptions options;
NMDeviceConfigInfo config_info;
struct dhcp_interface *dhcp_iface;
gboolean activating; /* Set by main thread before beginning activation */ gboolean activating; /* Set by main thread before beginning activation */
gboolean just_activated; /* Set by activation thread after successful activation */ gboolean just_activated; /* Set by activation thread after successful activation */
gboolean quit_activation; /* Flag to signal activation thread to stop activating */ gboolean quit_activation; /* Flag to signal activation thread to stop activating */
gboolean activation_failed; /* Did the activation fail? */ gboolean activation_failed; /* Did the activation fail? */
gboolean test_device; gboolean test_device;
gboolean test_device_up; gboolean test_device_up;
}; };
/******************************************************/ /******************************************************/
@@ -352,13 +356,15 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED) if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
{ {
/* Grab IP config data for this device from the system configuration files */
nm_device_update_ip4_address (dev);
nm_system_device_update_config_info (dev);
/* Have to bring the device up before checking link status. */ /* Have to bring the device up before checking link status. */
nm_device_bring_up (dev); nm_device_bring_up (dev);
nm_device_update_link_active (dev, TRUE); nm_device_update_link_active (dev, TRUE);
nm_device_update_ip4_address (dev);
nm_device_update_hw_address (dev);
/* Grab IP config data for this device from the system configuration files */
nm_system_device_update_config_info (dev);
} }
return (dev); return (dev);
@@ -409,6 +415,32 @@ void nm_device_unref (NMDevice *dev)
} }
/*
* nm_device_open_sock
*
* Get a control socket for network operations.
*
*/
int nm_device_open_sock (void)
{
int fd;
/* Try to grab a control socket */
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd >= 0)
return (fd);
fd = socket(PF_PACKET, SOCK_DGRAM, 0);
if (fd >= 0)
return (fd);
fd = socket(PF_INET6, SOCK_DGRAM, 0);
if (fd >= 0)
return (fd);
syslog (LOG_ERR, "nm_get_network_control_socket() could not get network control socket.");
return (-1);
}
/* /*
* Get/set functions for UDI * Get/set functions for UDI
*/ */
@@ -1021,11 +1053,12 @@ void nm_device_update_ip4_address (NMDevice *dev)
return; return;
} }
socket = nm_get_network_control_socket (); socket = nm_device_open_sock ();
if (socket < 0) if (socket < 0)
return; return;
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), 16); /* 16 == IF_NAMESIZE */ memset (&req, 0, sizeof (struct ifreq));
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), strlen (nm_device_get_iface (dev)));
err = ioctl (socket, SIOCGIFADDR, &req); err = ioctl (socket, SIOCGIFADDR, &req);
close (socket); close (socket);
if (err != 0) if (err != 0)
@@ -1056,6 +1089,51 @@ void nm_device_get_ip6_address(NMDevice *dev)
} }
/*
* nm_device_get_hw_address
*
* Get a device's hardware address
*
*/
void nm_device_get_hw_address(NMDevice *dev, unsigned char hw_addr[ETH_ALEN])
{
g_return_if_fail (dev != NULL);
memcpy (hw_addr, dev->hw_addr, ETH_ALEN);
}
void nm_device_update_hw_address (NMDevice *dev)
{
struct ifreq req;
int socket;
int err;
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->app_data != NULL);
g_return_if_fail (nm_device_get_iface (dev) != NULL);
/* Test devices get a nice, bogus IP address */
if (dev->test_device)
{
memset (dev->hw_addr, 0, ETH_ALEN);
return;
}
socket = nm_device_open_sock ();
if (socket < 0)
return;
memset (&req, 0, sizeof (struct ifreq));
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), strlen (nm_device_get_iface (dev)));
err = ioctl (socket, SIOCGIFHWADDR, &req);
close (socket);
if (err != 0)
return;
memcpy (dev->hw_addr, req.ifr_hwaddr.sa_data, ETH_ALEN);
}
/* /*
* nm_device_set_up_down * nm_device_set_up_down
* *
@@ -1081,7 +1159,7 @@ static void nm_device_set_up_down (NMDevice *dev, gboolean up)
if (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED) if (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED)
return; return;
iface_fd = nm_get_network_control_socket (); iface_fd = nm_device_open_sock ();
if (iface_fd < 0) if (iface_fd < 0)
return; return;
@@ -1138,7 +1216,7 @@ gboolean nm_device_is_up (NMDevice *dev)
if (dev->test_device) if (dev->test_device)
return (dev->test_device_up); return (dev->test_device_up);
iface_fd = nm_get_network_control_socket (); iface_fd = nm_device_open_sock ();
if (iface_fd < 0) if (iface_fd < 0)
return (FALSE); return (FALSE);
@@ -1310,7 +1388,7 @@ static gboolean nm_device_activation_should_cancel (NMDevice *dev)
* FALSE on unsuccessful activation (ie no best AP) * FALSE on unsuccessful activation (ie no best AP)
* *
*/ */
static gboolean nm_device_activate_wireless (NMDevice *dev, NMAccessPoint *ap, guint *bad_crypt_packets) static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap, NMDeviceAuthMethod auth)
{ {
gboolean success = FALSE; gboolean success = FALSE;
const char *essid = NULL; const char *essid = NULL;
@@ -1320,8 +1398,6 @@ static gboolean nm_device_activate_wireless (NMDevice *dev, NMAccessPoint *ap, g
g_return_val_if_fail (ap != NULL, FALSE); g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (nm_ap_get_essid (ap) != NULL, FALSE); g_return_val_if_fail (nm_ap_get_essid (ap) != NULL, FALSE);
*bad_crypt_packets = 0;
/* Force the card into Managed/Infrastructure mode */ /* Force the card into Managed/Infrastructure mode */
nm_device_set_mode_managed (dev); nm_device_set_mode_managed (dev);
nm_device_set_essid (dev, " "); nm_device_set_essid (dev, " ");
@@ -1334,14 +1410,16 @@ static gboolean nm_device_activate_wireless (NMDevice *dev, NMAccessPoint *ap, g
if (nm_ap_get_encrypted (ap) && nm_ap_get_enc_key_source (ap)) if (nm_ap_get_encrypted (ap) && nm_ap_get_enc_key_source (ap))
{ {
char *hashed_key = nm_ap_get_enc_key_hashed (ap); char *hashed_key = nm_ap_get_enc_key_hashed (ap);
nm_device_set_enc_key (dev, hashed_key, NM_DEVICE_AUTH_METHOD_SHARED_KEY); nm_device_set_enc_key (dev, hashed_key, auth);
g_free (hashed_key); g_free (hashed_key);
} }
nm_device_set_essid (dev, essid); nm_device_set_essid (dev, essid);
*bad_crypt_packets = nm_device_get_bad_crypt_packets (dev);
syslog (LOG_INFO, "nm_device_wireless_activate(%s) using essid '%s'", nm_device_get_iface (dev), essid); syslog (LOG_INFO, "nm_device_wireless_activate(%s) using essid '%s', with %s authentication.",
nm_device_get_iface (dev), essid, (auth == NM_DEVICE_AUTH_METHOD_NONE) ? "no" :
((auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM) ? "Open System" :
((auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY) ? "Shared Key" : "unknown")));
/* Bring the device up and pause to allow card to associate */ /* Bring the device up and pause to allow card to associate */
nm_device_bring_up (dev); nm_device_bring_up (dev);
@@ -1371,15 +1449,16 @@ gboolean AP_NEED_KEY (NMAccessPoint *ap)
return (FALSE); return (FALSE);
} }
gboolean HAVE_LINK (NMDevice *dev, guint32 bad_crypt_packets) gboolean HAVE_LINK (NMDevice *dev)
{ {
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE); g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
syslog (LOG_NOTICE, "HAVELINK: act=%d && (dev_crypt=%d <= prev_crypt=%d)\n", nm_device_get_link_active (dev), nm_device_get_bad_crypt_packets (dev), bad_crypt_packets); syslog (LOG_NOTICE, "HAVELINK: act=%d\n", nm_device_get_link_active (dev));
return (nm_device_get_link_active (dev) && (nm_device_get_bad_crypt_packets (dev) <= bad_crypt_packets)); return (nm_device_get_link_active (dev));
} }
#if 0
/* /*
* nm_device_activate_wireless_wait_for_link * nm_device_activate_wireless_wait_for_link
* *
@@ -1495,6 +1574,159 @@ out:
nm_ap_unref (best_ap); nm_ap_unref (best_ap);
dev->options.wireless.now_scanning = FALSE; dev->options.wireless.now_scanning = FALSE;
} }
#endif
/*
* nm_device_activate_wireless
*
* Activate a wireless ethernet device
*
*/
static gboolean nm_device_activate_wireless (NMDevice *dev)
{
NMAccessPoint *best_ap;
gboolean success = FALSE;
guint8 attempt = 1;
char last_essid [50] = "\0";
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE);
get_ap:
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev))
goto out;
/* Get a valid "best" access point we should connect to */
while (!(best_ap = nm_device_get_best_ap (dev)))
{
dev->options.wireless.now_scanning = TRUE;
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): waiting for an access point.", nm_device_get_iface (dev));
g_usleep (G_USEC_PER_SEC * 2);
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev))
goto out;
}
if (!nm_ap_get_encrypted (best_ap))
{
nm_device_set_wireless_config (dev, best_ap, NM_DEVICE_AUTH_METHOD_NONE);
/* If its unencrypted and we don't have a link, we can't use this AP.
* If we can't get an IP address off this AP, we can't use it either.
*/
if (!HAVE_LINK (dev) || !nm_device_activation_configure_ip (dev))
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no link to '%s', or couldn't get configure interface for IP. Trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_set_invalid (best_ap, TRUE);
nm_ap_list_append_ap (dev->app_data->invalid_ap_list, best_ap);
nm_ap_unref (best_ap);
nm_device_update_best_ap (dev);
goto get_ap;
}
success = TRUE;
}
else
{
NMDeviceAuthMethod auth = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
gboolean need_key = AP_NEED_KEY (best_ap);
need_key:
if (need_key)
{
char *essid = nm_ap_get_essid (best_ap);
if (strcmp (essid, last_essid) != 0)
attempt = 1;
strncpy (&last_essid[0], essid, 49);
/* Get a wireless key */
dev->options.wireless.user_key_received = FALSE;
nm_dbus_get_user_key_for_network (dev->app_data->dbus_connection, dev, best_ap, attempt);
attempt++;
need_key = FALSE;
/* Wait for the key to come back */
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): asking for user key.", nm_device_get_iface (dev));
while (!dev->options.wireless.user_key_received && !dev->quit_activation)
g_usleep (G_USEC_PER_SEC / 2);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev));
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev))
{
nm_ap_unref (best_ap);
goto out;
}
/* User may have cancelled the key request, so we need to update our best AP again.
* However, if they didn't, since there will now be a key, we won't get back here for
* the same access point until the key is deemed incorrect below.
*/
nm_ap_unref (best_ap);
goto get_ap;
}
while (auth > NM_DEVICE_AUTH_METHOD_NONE)
{
int ip_success = FALSE;
nm_device_set_wireless_config (dev, best_ap, auth);
if (!HAVE_LINK (dev) && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Shared Key mode, trying Open System.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
/* Back down to Open System mode */
auth--;
continue;
}
else if (!HAVE_LINK (dev))
{
/* Must be in Open System mode and it still didn't work, so
* we'll invalidate the current "best" ap and get another one */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Open System mode, trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_set_invalid (best_ap, TRUE);
nm_ap_list_append_ap (dev->app_data->invalid_ap_list, best_ap);
nm_ap_unref (best_ap);
nm_device_update_best_ap (dev);
goto get_ap;
}
ip_success = nm_device_activation_configure_ip (dev);
if (!ip_success && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
{
/* Back down to Open System mode */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Shared Key mode, trying Open System.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
auth--;
continue;
}
else if (!ip_success)
{
/* Open System mode failed, we must have bad WEP key */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Open System mode, asking for new key.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
need_key = TRUE;
goto need_key;
}
/* OK, we have a link and we have IP address info, we're good */
success = TRUE;
break;
}
}
if (success)
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): Success! Connected to access point '%s' and got an IP address.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
}
out:
return (success);
}
/* /*
@@ -1510,22 +1742,18 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev)
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
nm_system_delete_default_route ();
if (nm_device_config_get_use_dhcp (dev)) if (nm_device_config_get_use_dhcp (dev))
{ {
/* FIXME int err;
* Bringing the device up and then down evidentally helps with
* IPv6 for some reason, according to j bootlab org err = nm_device_dhcp_run (dev);
*/ if (err == RET_DHCP_BOUND)
nm_device_bring_down (dev);
nm_device_bring_up (dev);
if (nm_system_device_run_dhcp (dev))
success = TRUE; success = TRUE;
else else
{ {
/* Interfaces cannot be down if they are the active interface, /* Interfaces cannot be down if they are the active interface,
* otherwise we cannot use them for scanning or link detection. * otherwise we cannot use them for scanning or link detection.
* If dhclient doesn't get a DHCP address, it will take the interface
* down, so we reactivate it here.
*/ */
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
{ {
@@ -1533,7 +1761,8 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev)
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE); nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
} }
nm_device_bring_up (dev); if (!nm_device_is_up (dev))
nm_device_bring_up (dev);
} }
} }
else else
@@ -1556,88 +1785,42 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev)
static gpointer nm_device_activation_worker (gpointer user_data) static gpointer nm_device_activation_worker (gpointer user_data)
{ {
NMDevice *dev = (NMDevice *)user_data; NMDevice *dev = (NMDevice *)user_data;
unsigned char hostname[100] = "\0"; gboolean success = FALSE;
int host_err;
NMAccessPoint *best_ap = NULL;
g_return_val_if_fail (dev != NULL, NULL); g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (dev->app_data != NULL, NULL); g_return_val_if_fail (dev->app_data != NULL, NULL);
syslog (LOG_DEBUG, "nm_device_activation_worker (%s) started...", nm_device_get_iface (dev)); syslog (LOG_DEBUG, "nm_device_activation_worker (%s) started...", nm_device_get_iface (dev));
/* If its a wireless device, set the ESSID and WEP key */ /* Bring the device up */
if (!nm_device_is_up (dev));
nm_device_bring_up (dev);
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
{ success = nm_device_activate_wireless (dev);
nm_device_activate_wireless_wait_for_link (dev); else if (nm_device_is_wired (dev))
success = nm_device_activation_configure_ip (dev);
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev))
goto out;
best_ap = nm_device_get_best_ap (dev);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): using ESSID '%s'", nm_device_get_iface (dev),
best_ap ? nm_ap_get_essid (best_ap) : "none");
if (best_ap)
nm_ap_unref (best_ap);
}
else
{
/* Bring the device up */
if (!nm_device_is_up (dev));
nm_device_bring_up (dev);
}
nm_system_delete_default_route ();
nm_system_device_stop_dhcp (dev);
/* If we don't have a "best" ap, don't try to get a DHCP address or restart the name service cache */
if (nm_device_is_wireless (dev))
best_ap = nm_device_get_best_ap (dev);
if (nm_device_is_wired (dev) || best_ap)
{
gboolean success;
/* Save machine host name */
host_err = gethostname (&hostname[0], 100);
if (!(success = nm_device_activation_configure_ip (dev)))
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): could not retrieve and assign IP information to device\n", nm_device_get_iface (dev));
/* Set the hostname back to what it was before so that X11 doesn't
* puke when the hostname changes, and so users can actually launch stuff.
*/
if (host_err >= 0)
sethostname (hostname, strlen (hostname));
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev))
goto out;
if (!success)
{
dev->activating = FALSE;
dev->just_activated = FALSE;
dev->activation_failed = TRUE;
dev->quit_activation = FALSE;
goto out;
}
/* Make system aware of any new DNS settings from resolv.conf */
nm_system_update_dns ();
}
if (best_ap)
nm_ap_unref (best_ap);
/* If we were told to quit activation, stop the thread and return */ /* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev)) if (nm_device_activation_should_cancel (dev))
goto out; goto out;
nm_device_update_ip4_address (dev); if (!success)
{
dev->activating = FALSE;
dev->just_activated = FALSE;
dev->activation_failed = TRUE;
dev->quit_activation = FALSE;
goto out;
}
dev->just_activated = TRUE; dev->just_activated = TRUE;
dev->activating = FALSE; dev->activating = FALSE;
dev->activation_failed = FALSE; dev->activation_failed = FALSE;
dev->quit_activation = FALSE; dev->quit_activation = FALSE;
nm_device_update_ip4_address (dev);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev)); syslog (LOG_DEBUG, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev));
out: out:
@@ -1710,7 +1893,8 @@ void nm_device_activation_cancel (NMDevice *dev)
{ {
syslog (LOG_DEBUG, "nm_device_activation_cancel(%s): cancelling...", nm_device_get_iface (dev)); syslog (LOG_DEBUG, "nm_device_activation_cancel(%s): cancelling...", nm_device_get_iface (dev));
dev->quit_activation = TRUE; dev->quit_activation = TRUE;
nm_system_kill_all_dhcp_daemons (); /* dhcp daemons will block, so have to kill them to return control */ if (dev->dhcp_iface)
nm_device_dhcp_cease (dev);
/* Spin until cancelled. Possible race conditions or deadlocks here. /* Spin until cancelled. Possible race conditions or deadlocks here.
* The other problem with waiting here is that we hold up dbus traffic * The other problem with waiting here is that we hold up dbus traffic
@@ -1991,6 +2175,30 @@ gboolean nm_device_is_best_ap_frozen (NMDevice *dev)
} }
/*
* Accessor for dhcp_interface
*
*/
struct dhcp_interface *nm_device_get_dhcp_iface (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
return (dev->dhcp_iface);
}
void nm_device_set_dhcp_iface (NMDevice *dev, struct dhcp_interface *dhcp_iface)
{
g_return_if_fail (dev != NULL);
/* NOTE: this function should only be used from the activation worker thread
* which will take care of shutting down any active DHCP threads and cleaning
* up the dev->dhcp_iface structure.
*/
dev->dhcp_iface = dhcp_iface;
}
/* /*
* nm_device_get_path_for_ap * nm_device_get_path_for_ap
* *

View File

@@ -43,6 +43,8 @@ NMDevice * nm_device_new (const char *iface, const char *udi, gboolean test_
void nm_device_ref (NMDevice *dev); void nm_device_ref (NMDevice *dev);
void nm_device_unref (NMDevice *dev); void nm_device_unref (NMDevice *dev);
int nm_device_open_sock (void);
char * nm_device_get_udi (NMDevice *dev); char * nm_device_get_udi (NMDevice *dev);
void nm_device_set_udi (NMDevice *dev, const char *udi); void nm_device_set_udi (NMDevice *dev, const char *udi);
@@ -67,6 +69,9 @@ void nm_device_get_ap_address (NMDevice *dev, struct ether_addr *addr);
guint32 nm_device_get_ip4_address (NMDevice *dev); guint32 nm_device_get_ip4_address (NMDevice *dev);
void nm_device_update_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev);
void nm_device_get_hw_address (NMDevice *dev, unsigned char hw_addr[ETH_ALEN]);
void nm_device_update_hw_address (NMDevice *dev);
void nm_device_get_ip6_address (NMDevice *dev); void nm_device_get_ip6_address (NMDevice *dev);
gboolean nm_device_get_supports_wireless_scan (NMDevice *dev); gboolean nm_device_get_supports_wireless_scan (NMDevice *dev);

256
src/NetworkManagerSystem.c Normal file
View File

@@ -0,0 +1,256 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* Copyright (C) 2004 Red Hat, Inc.
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <net/route.h>
#include <net/if.h>
#include <arpa/nameser.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <resolv.h>
#include <netdb.h>
#include <glib.h>
#include "NetworkManagerSystem.h"
#include "NetworkManagerDevice.h"
static int nm_system_open_sock (void)
{
int fd;
/* Try to grab a control socket */
fd = socket (AF_PACKET, SOCK_PACKET, htons (ETH_P_ALL));
if (fd >= 0)
return (fd);
syslog (LOG_ERR, "nm_system_open_sock() could not get network control socket.");
return (-1);
}
gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address)
{
struct ifreq ifr;
const char *iface;
int sk;
gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (dev != NULL, FALSE);
iface = nm_device_get_iface (dev);
sk = nm_system_open_sock ();
if (sk < 0)
return FALSE;
memset (&ifr, 0, sizeof(struct ifreq));
memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_address;
if (ioctl (sk, SIOCSIFADDR, &ifr) == -1)
syslog (LOG_ERR,"nm_system_device_set_ip4_address (%s): failed to set IPv4 address!", iface);
else
{
success = TRUE;
fprintf(stderr, "Your IP address = %u.%u.%u.%u\n",
((unsigned char *)&ip4_address)[0],
((unsigned char *)&ip4_address)[1],
((unsigned char *)&ip4_address)[2],
((unsigned char *)&ip4_address)[3]);
}
close (sk);
return (success);
}
gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask)
{
struct ifreq ifr;
const char *iface;
int sk;
gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (dev != NULL, FALSE);
iface = nm_device_get_iface (dev);
sk = nm_system_open_sock ();
if (sk < 0)
return FALSE;
memset (&ifr, 0, sizeof(struct ifreq));
memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_netmask;
if (ioctl (sk, SIOCSIFNETMASK, &ifr) == -1)
syslog (LOG_ERR,"nm_system_device_set_ip4_netmask (%s): failed to set IPv4 netmask!", iface);
else
success = TRUE;
close (sk);
return (success);
}
gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast)
{
struct ifreq ifr;
const char *iface;
int sk;
gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (dev != NULL, FALSE);
iface = nm_device_get_iface (dev);
sk = nm_system_open_sock ();
if (sk < 0)
return FALSE;
memset (&ifr, 0, sizeof(struct ifreq));
memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_broadcast;
if (ioctl (sk, SIOCSIFBRDADDR, &ifr) == -1)
syslog (LOG_ERR,"nm_system_device_set_ip4_netmask (%s): failed to set IPv4 netmask!", iface);
else
success = TRUE;
close (sk);
return (success);
}
gboolean nm_system_device_set_ip4_default_route (NMDevice *dev, int ip4_def_route)
{
const char *iface;
int sk;
gboolean success = FALSE;
struct rtentry rtent;
struct sockaddr_in *p;
g_return_val_if_fail (dev != NULL, FALSE);
iface = nm_device_get_iface (dev);
sk = nm_system_open_sock ();
if (sk < 0)
return FALSE;
memset (&rtent, 0, sizeof (struct rtentry));
p = (struct sockaddr_in *)&rtent.rt_dst;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0;
p = (struct sockaddr_in *)&rtent.rt_gateway;
p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_def_route;
p = (struct sockaddr_in *)&rtent.rt_genmask;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0;
rtent.rt_dev = (char *)iface;
rtent.rt_metric = 1;
rtent.rt_window = 0;
rtent.rt_flags = RTF_UP | RTF_GATEWAY | ( rtent.rt_window ? RTF_WINDOW : 0);
if ( ioctl (sk, SIOCADDRT, &rtent) == -1 )
{
if ( errno == ENETUNREACH ) /* possibly gateway is over the bridge */
{ /* try adding a route to gateway first */
struct rtentry rtent2;
memset (&rtent2, 0, sizeof(struct rtentry));
p = (struct sockaddr_in *)&rtent2.rt_dst;
p->sin_family = AF_INET;
p = (struct sockaddr_in *)&rtent2.rt_gateway;
p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_def_route;
p = (struct sockaddr_in *)&rtent2.rt_genmask;
p->sin_family = AF_INET;
p->sin_addr.s_addr = 0xffffffff;
rtent2.rt_dev = (char *)iface;
rtent2.rt_metric = 0;
rtent2.rt_flags = RTF_UP | RTF_HOST;
if ( ioctl (sk, SIOCADDRT, &rtent2) == 0 )
{
if ( ioctl (sk, SIOCADDRT, &rtent) == 0 )
success = TRUE;
else
syslog (LOG_ERR,"nm_system_device_set_ip4_default_route (%s): failed to set IPv4 default route! errno = %d", iface, errno);
}
}
else
syslog (LOG_ERR,"nm_system_device_set_ip4_default_route (%s): failed to set IPv4 default route! errno = %d", iface, errno);
}
else
success = TRUE;
close (sk);
return (success);
}
/*****************************************************************************/
gboolean nm_system_device_update_resolv_conf (void *data, int len, const char *domain_name)
{
FILE *f;
g_return_val_if_fail (data != NULL, FALSE);
if ((f = fopen ("/etc/resolv.conf", "w")))
{
int i;
fprintf (f, "; generated by NetworkManager\n");
if (domain_name)
fprintf (f, "search %s\n", (char *)domain_name);
for (i = 0; i < len; i += 4)
{
fprintf (f,"nameserver %u.%u.%u.%u\n",
((unsigned char *)data)[i],
((unsigned char *)data)[i+1],
((unsigned char *)data)[i+2],
((unsigned char *)data)[i+3]);
}
fclose(f);
}
else
syslog (LOG_ERR,"nm_system_device_update_resolv_conf(): could not open /etc/resolv.conf\n");
/* Reload DNS info for all apps */
(void)res_init();
return 0;
}

View File

@@ -26,31 +26,29 @@
#include "NetworkManagerDevice.h" #include "NetworkManagerDevice.h"
/* Prototypes for system/distribution dependent functions */ /* Prototypes for system/distribution dependent functions,
* implemented in the backend files in backends/ directory
*/
void nm_system_init (void); void nm_system_init (void);
gboolean nm_system_device_run_dhcp (NMDevice *dev); gboolean nm_system_device_run_dhcp (NMDevice *dev);
void nm_system_device_stop_dhcp (NMDevice *dev); void nm_system_device_stop_dhcp (NMDevice *dev);
gboolean nm_system_device_has_active_routes (NMDevice *dev); gboolean nm_system_device_has_active_routes (NMDevice *dev);
void nm_system_device_flush_routes (NMDevice *dev); void nm_system_device_flush_routes (NMDevice *dev);
void nm_system_device_flush_addresses (NMDevice *dev); void nm_system_device_flush_addresses (NMDevice *dev);
void nm_system_device_update_config_info (NMDevice *dev); void nm_system_device_update_config_info (NMDevice *dev);
gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev); gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev);
void nm_system_enable_loopback (void); void nm_system_enable_loopback (void);
void nm_system_delete_default_route (void); void nm_system_delete_default_route (void);
void nm_system_kill_all_dhcp_daemons (void); void nm_system_kill_all_dhcp_daemons (void);
void nm_system_update_dns (void); void nm_system_update_dns (void);
void nm_system_load_device_modules (void); void nm_system_load_device_modules (void);
/* Prototyps for system-layer network functions (ie setting IP address, etc) */
gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address);
gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask);
gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast);
gboolean nm_system_device_set_ip4_default_route (NMDevice *dev, int ip4_def_route);
gboolean nm_system_device_update_resolv_conf (void *data, int len, const char *domain_name);
#endif #endif

View File

@@ -104,32 +104,6 @@ int nm_null_safe_strcmp (const char *s1, const char *s2)
/*
* nm_get_network_control_socket
*
* Get a control socket for network operations.
*
*/
int nm_get_network_control_socket (void)
{
int fd;
/* Try to grab a control socket */
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd >= 0)
return (fd);
fd = socket(PF_PACKET, SOCK_DGRAM, 0);
if (fd >= 0)
return (fd);
fd = socket(PF_INET6, SOCK_DGRAM, 0);
if (fd >= 0)
return (fd);
syslog (LOG_ERR, "nm_get_network_control_socket() could not get network control socket.");
return (-1);
}
/* /*
* nm_ethernet_address_is_valid * nm_ethernet_address_is_valid
* *

View File

@@ -38,8 +38,6 @@ void nm_unlock_mutex (GMutex *mutex, const char *func);
int nm_null_safe_strcmp (const char *s1, const char *s2); int nm_null_safe_strcmp (const char *s1, const char *s2);
int nm_get_network_control_socket (void);
gboolean nm_ethernet_address_is_valid (struct ether_addr *test_addr); gboolean nm_ethernet_address_is_valid (struct ether_addr *test_addr);
void nm_dispose_scan_results (wireless_scan *result_list); void nm_dispose_scan_results (wireless_scan *result_list);

View File

@@ -1,6 +1,6 @@
INCLUDES = -I${top_srcdir} INCLUDES = -I${top_srcdir}
CPPFLAGS = \ AM_CPPFLAGS = \
$(NM_CFLAGS) \ $(NM_CFLAGS) \
-DDBUS_API_SUBJECT_TO_CHANGE \ -DDBUS_API_SUBJECT_TO_CHANGE \
-DBINDIR=\"$(bindir)\" \ -DBINDIR=\"$(bindir)\" \